本文介绍了实施DHCP客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在UNIX上使用C,我的客户正在侦听端口68超级用户模式。发送DHCP后发现的消息,当我尝试接收,它recvfrom的块意味着没有收到任何消息或者是像系统有一个过程(DHCP客户端)监听接收邮件和多数民众赞成我的进程不能同一个端口68上接收消息。有什么问题?

我已经设置了套接字选项SO_REUSEADDR和SO_BROADCAST。我发送到端口67。

 结构dhcpmessage
{
    uint8_t有运;
    uint8_t有HTYPE;
    uint8_t有hLen的;
    uint8_t有啤酒花;
    uint32_t的XID;
    uint16_t秒;
    uint16_t标志;
    uint32_t的CIADDR;
    uint32_t的YIADDR;
    uint32_t的的siaddr;
    uint32_t的GIADDR;
    焦炭CHADDR [16];
    字符SNAME [64];
    字符文件[128];
    炭魔[4];
    炭选择[3];
} __attribute __((__ packed__));#包括LT&;&stdio.h中GT;
#包括LT&;&文件ctype.h GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&;&signal.h中GT;
#包括LT&; SYS / wait.h>
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>
#包括LT&; ARPA / inet.h>
#包括LT&;&errno.h中GT;
#包括LT&; SYS / file.h>
#包括LT&; SYS / msg.h>
#包括LT&; SYS / ipc.h>
#包括LT&;&time.h中GT;
的#include的defs.h
诠释主(){
INT的sockfd,listenfd,connfd;
关于= 1 const int的;
结构SOCKADDR_IN servaddr,cliaddr,rservaddr;
如果((的sockfd =插座(AF_INET,SOCK_DGRAM,0))小于0)
    死(插座);
如果(setsockopt的(的sockfd,SOL_SOCKET,SO_REUSEADDR,&放大器;上,的sizeof(上))小于0)
    死(setsockopt的);如果(setsockopt的(的sockfd,SOL_SOCKET,SO_BROADCAST,&放大器;上,的sizeof(上))小于0)
    死(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);
如果(绑定(的sockfd,(结构sockaddr *)及cliaddr,sizeof的(cliaddr))小于0)
    死(绑定);servaddr.sin_port = htons(67);
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(255.255.255.255);
结构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] = 0×00;
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;
如果(SENDTO(的sockfd,&放大器; dhcpmsg,sizeof的(dhcpmsg),0,(结构sockaddr *)及servaddr,sizeof的(servaddr))小于0)
    死(SENDTO);
结构dhcpmessage recvdhcpmsg;
socklen_t的rservlen = sizeof的(rservaddr);
如果(recvfrom的(的sockfd,&放大器; recvdhcpmsg,sizeof的(recvdhcpmsg),0,(结构sockaddr *)及rservaddr,&放大器; rservlen)℃的)
    死(recvfrom的);
字符*海峡=(字符*)及recvdhcpmsg;
INT I;
对于(i = 0; I<的sizeof(recvdhcpmsg);我++)
    的printf(%d个_,海峡[I]);
的printf(\\ n);
返回0;
}


解决方案

需要注意的是,你没有一个IP地址,你想获得的。 - 大多数操作系统不会允许你绑定/上网卡发送UDP消息W / O的IP地址。 DHCP客户端通常使用原始套接字用于这一目的/并应设置SRC地址为0.0.0.0)

这种原始套接字将得到所有的数据包,您的应用程序不会,如果有运行的系统DHCP客户端

On unix using C, my client is listening on port 68 with superuser mode. After sending DHCP discover message, when I try to receive, it blocks in recvfrom means there is no message received or is it like system has a process (DHCP client) listening on same port 68 which receives the message and thats my process are not able to receive the message. What is the problem?

I have set the socket option SO_REUSEADDR and SO_BROADCAST. I am sending to port 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;
}
解决方案

The caveat is, you don't have an IP address, you want to obtain one. - most OSs won't allow you to bind/send UDP messages on a NIC w/o an IP address. dhcp clients typically use raw sockets for that purpose/and should set the src address to 0.0.0.0)

Such a raw socket will get all the packets, and your application will not if there's a system dhcp client running

这篇关于实施DHCP客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-26 03:56