实现DHCP客户端
在使用C的unix上,我的客户端以超级用户模式在端口68上侦听。在发送DHCP发现消息后,当我尝试接收时,它在recvfrom中阻塞意味着没有收到消息,或者它是否像系统有一个进程(DHCP客户端)正在侦听收到该消息的同一端口68并且我的进程不能接收消息。问题是什么?实现DHCP客户端
我已经设置了套接字选项SO_REUSEADDR和SO_BROADCAST。我发送给端口67
struct dhcpmessage
{
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
uint32_t ciaddr;
uint32_t yiaddr;
uint32_t siaddr;
uint32_t giaddr;
char chaddr[16];
char sname[64];
char file[128];
char magic[4];
char opt[3];
} __attribute__((__packed__));
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<signal.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<errno.h>
#include<sys/file.h>
#include<sys/msg.h>
#include<sys/ipc.h>
#include<time.h>
#include"defs.h"
int main() {
int sockfd,listenfd,connfd;
const int on=1;
struct sockaddr_in servaddr,cliaddr,rservaddr;
if((sockfd=socket(AF_INET,SOCK_DGRAM,0)) < 0)
die("socket");
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0)
die("setsockopt");
if(setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on)) < 0)
die("setsockopt");
bzero(&servaddr,sizeof(servaddr));
bzero(&cliaddr,sizeof(cliaddr));
cliaddr.sin_port = htons(68);
cliaddr.sin_family = AF_INET;
cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr*)&cliaddr,sizeof(cliaddr)) < 0)
die("bind");
servaddr.sin_port = htons(67);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("255.255.255.255");
struct dhcpmessage dhcpmsg;
bzero(&dhcpmsg,sizeof(dhcpmsg));
dhcpmsg.op = 1;
dhcpmsg.htype = 1;
dhcpmsg.hlen = 6;
dhcpmsg.hops = 0;
dhcpmsg.xid = htonl(1000);
dhcpmsg.secs = htons(0);
dhcpmsg.flags = htons(0x8000);
dhcpmsg.chaddr[0] = 0x00;
dhcpmsg.chaddr[1] = 0x1A;
dhcpmsg.chaddr[2] = 0x80;
dhcpmsg.chaddr[3] = 0x80;
dhcpmsg.chaddr[4] = 0x2C;
dhcpmsg.chaddr[5] = 0xC3;
dhcpmsg.magic[0]=99;
dhcpmsg.magic[1]=130;
dhcpmsg.magic[2]=83;
dhcpmsg.magic[3]=99;
dhcpmsg.opt[0]=53;
dhcpmsg.opt[1]=1;
dhcpmsg.opt[2]=1;
if(sendto(sockfd,&dhcpmsg,sizeof(dhcpmsg),0,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
die("sendto");
struct dhcpmessage recvdhcpmsg;
socklen_t rservlen = sizeof(rservaddr);
if(recvfrom(sockfd,&recvdhcpmsg,sizeof(recvdhcpmsg),0,(struct sockaddr*)&rservaddr,&rservlen) < 0)
die("recvfrom");
char *str = (char*)&recvdhcpmsg;
int i;
for(i=0;i<sizeof(recvdhcpmsg);i++)
printf("%d_",str[i]);
printf("\n");
return 0;
}
需要注意的是,您没有IP地址,您想获得IP地址。 - 大多数操作系统不允许您在不带IP地址的NIC上绑定/发送UDP消息。 DHCP客户端通常使用原始套接字用于这一目的/并应设置src地址为0.0.0.0)
这种原始套接字将得到所有的数据包,您的应用程序不会,如果有运行系统DHCP客户端
你的意思是说我在68端口上创建一个原始套接字绑定,然后系统会将接收到的数据放在我的原始套接字和系统的DHCP客户端原始套接字上。你能给我一些代码/片段给出一个关于如何去做这件事的想法吗? – avd 2009-11-25 02:29:13
你可以看看源代码,用于现有DHCP客户端,并了解它是如何工作:
您可能还需要发布相关的片段的源代码,以便人们可以确切地看到你是如何尝试这样做的。
现在添加了源代码 – avd 2009-11-24 17:31:20
我刚分叉dhclient为dhcprobe。这是一个Linux的dhcp客户端。
这是非常简单的黑客攻击,可能是您的项目的一个很好的起点。
我看了一下dhcprobe的代码,尽管我同意这是一个很好的起点,值得注意的是它基本上指向了服务器。所以它基本上不会涉及与广播有关的协议的一些重要部分。 – 2017-05-29 13:55:10
为什么有人投票结束这个问题? – avd 2009-11-24 17:27:20