2012-10-24 24 views
7

Trong linux, làm thế nào tôi có thể truyền gói UDP bằng cách sử dụng 0.0.0.0 làm địa chỉ nguồn.Truyền gói UDP với địa chỉ nguồn 0.0.0.0

Đây là những gì tôi đã thử cho đến nay.

#include <stdio.h> 
#include <stdint.h> 
#include <stdlib.h> 
#include <net/if.h> 
#include <string.h> 
#include <unistd.h> 
#include <assert.h> 
#include <arpa/inet.h> 
#include <sys/types.h> 
#include <sys/socket.h> 

int main(int argc, const char *argv[]) 
{ 
    struct sockaddr_in dst, src; 
    struct ifreq ifr; 
    int sock, tmp; 
    char payload[128]; 

    memset(payload, 0, 128); 

    memset(&dst, 0, sizeof(dst)); 
    dst.sin_family = AF_INET; 
    dst.sin_addr.s_addr = inet_addr("255.255.255.255"); 
    dst.sin_port = htons(67); 

    memset(&src,0,sizeof(src)); 
    src.sin_family = AF_INET; 
    src.sin_addr.s_addr = inet_addr("0.0.0.0"); 
    src.sin_port = htons(68); 

    sock = socket(AF_INET, SOCK_DGRAM, 0); 
    if (sock < 0) 
     perror("Failed to create socket"); 

    tmp = 1; 
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &tmp, sizeof(tmp)) < 0) 
     perror("SO_BROADCAST failed"); 

    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &tmp, sizeof(tmp)) < 0) 
     perror("SO_REUSEADDR failed"); 

    if (setsockopt(sock, IPPROTO_IP, IP_FREEBIND, &tmp, sizeof(tmp)) < 0) 
     perror("IP_FREEBIND failed"); 

    memset(&ifr, 0, sizeof(ifr)); 
    strncpy(ifr.ifr_name, "eth1", sizeof(ifr.ifr_name)); 

    if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) 
     perror("SO_BINDTODEVICE failed"); 

    if (bind(sock, (const struct sockaddr*)&src, sizeof(struct sockaddr_in)) < 0) 
     perror("bind failed"); 

    if (connect(sock, (const struct sockaddr*)&dst, sizeof(struct sockaddr_in)) < 0) 
     perror("bind failed"); 

    if (write(sock, payload, 128) < 0) 
     perror("Write failed"); 

    close(sock); 
    return 0; 
} 

Vấn đề là địa chỉ nguồn chỉ được đặt thành 0.0.0.0 nếu không có giao diện nào có địa chỉ IPv4. Nếu chỉ có một giao diện có địa chỉ IPv4, địa chỉ này được sử dụng làm địa chỉ nguồn.

Tôi đã xem mã nguồn của một số máy khách DHCP hiện có và thấy rằng chúng đang sử dụng ổ cắm RAW và xây dựng tiêu đề IP và UDP theo cách thủ công. Đây là khả năng, nhưng tôi muốn tránh làm điều này bằng tay.

+0

Nếu không có giao diện nào có địa chỉ IPv4, bạn không thể gửi gói nào cả ... – glglgl

+1

@glglgl làm cách nào để gửi DHCP phát hiện sau đó (cần chính xác điều này)? – KillianDS

+1

Có thể sử dụng ổ cắm RAW ... – glglgl

Trả lời

4

Bạn nên sử dụng RAW SOCKET và xây dựng gói với nỗ lực của riêng bạn.

Ví dụ: bạn có thể thực hiện việc này: https://github.com/fycth/DHCP-server-scanner/blob/master/src/dhcpd-detector.c

Đây là dự án giáo dục của tôi. Nó nhỏ và bạn có thể xem chính xác nhiệm vụ này được giải quyết ở đó như thế nào.

+0

Đây là những gì tôi đã cố gắng tránh ... Nhưng tôi đoán không có cách nào khác để làm điều này. – Allan

+3

Xin lỗi vì đã thất vọng nhưng có vẻ như không có cách nào để tránh trải nghiệm thú vị này ... – fycth

0

Tôi nghĩ rằng nếu có thể thực hiện điều đó thông qua ổ cắm UDP, họ sẽ thực hiện thay vì xây dựng một cách thủ công. Vì vậy, tôi cho rằng nó không hoạt động ...

Các vấn đề liên quan