2012-10-24 59 views
7

在linux中,如何使用0.0.0.0作为源地址传输UDP包。传输源地址为0.0.0.0的UDP包

这是我到目前为止尝试过的。

#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; 
} 

问题是源地址只设置为0.0.0.0如果没有接口具有IPv4地址。如果只有一个接口具有IPv4地址,则将该地址用作源地址。

我查看了一些现有的DHCP客户端的源代码,发现他们使用RAW套接字并手动构建IP和UDP头。这是可能的,但我想避免手动进行此操作。

+0

如果没有接口具有IPv4地址,则根本无法发送数据包... – glglgl

+1

@glglgl那么您将如何发送DHCP发现(那需要完全相同)? – KillianDS

+1

可能使用原始插座... – glglgl

回答

4

你应该使用RAW SOCKET和自己的努力构建数据包。

举个例子,你可以采取这样的:https://github.com/fycth/DHCP-server-scanner/blob/master/src/dhcpd-detector.c

这是我的教育项目。它很小,你可以看看这个任务如何在那里解决。

+0

这是我试图避免的......但我想没有其他方式做到这一点。 – Allan

+3

对不起,令人失望,但似乎没有办法避免这个令人兴奋的经历... – fycth

0

我想如果有可能通过UDP套接字来做,他们会做,而不是手动建立一个。所以我认为它根本不起作用...