sockets - 套接字发送到抛出 Errno-101

标签 sockets

运行此程序后,它会抛出 Errno-101。我只是想使用 DGRAM 套接字发送一个广播数据包。仅此而已。有人可以帮助我理解这段代码中的错误吗??

    //###########ALGORITHM FOR CHECKSUM CALCULATION################################
unsigned short csum(unsigned short*buf,int nwords) {
   unsigned long sum;
  for(sum=0; nwords>0;nwords--)
      sum += *buf++;
   sum = (sum >> 16) + (sum &0xffff);
   sum += (sum >>16);
   return (unsigned short) (~sum);
 }
//##############################################################################


int main() {

//######################### Variable Declarataions#################################
int optval,optlen,opt_broadcast = 1,one=1;
const int* val = &one;
int sockfd,bytes_read,bytes_send,addr_len,n,i,j,dhcp_msg_type,fn_return = -5,z=0,temp;
unsigned char txmsg[1024],buffer[10],original[1024];
unsigned char* rxmsg;
socklen_t abc;
char str[50];

struct sockaddr_in server_addr,client_addr,recv_addr;
struct iphdr *iph,*iph_trans;struct udphdr *udph,*udph_trans;

BOOTP *dhcp_ptr;
//##########################################################################################

//######################Original Implementation#############################################
if((sockfd = socket(PF_INET,SOCK_RAW,IPPROTO_UDP)) < 0) {
perror("Error in Socket Creation \n");
exit(1);
}

fn_return = setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&opt_broadcast,sizeof(opt_broadcast));
optval = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
if(setsockopt(sockfd,IPPROTO_IP,IP_HDRINCL,val,sizeof(one)) < 0) {
  perror("Socket() Error \n");
  }

client_addr.sin_family=AF_INET;
client_addr.sin_port=htons(68);
client_addr.sin_addr.s_addr=INADDR_BROADCAST;
bzero(&(client_addr.sin_zero),8);
addr_len = sizeof(client_addr);


bzero(txmsg,sizeof(txmsg));

//####################Packet Receiving#####################################################
while(1) {

bytes_read = recvfrom(sockfd, original,4096,0,(struct sockaddr*)&recv_addr, &addr_len);

printf("\n\n******************STARTING HERE***************\n");
printf("No:of Bytes Read are %d \n",bytes_read);
/*for(i=0;i<=bytes_read;i++) {
printf("%d-%x:",i,rxmsg[i]);
} */

iph = (struct iphdr*)original;
udph = (struct udphdr*)(original + (4*(iph->ihl)));

//printf("The Value of iph is %p \n",iph);
//printf("The Value of udph is %p \n",udph);
printf("The Value in UDP Header Source Port  was %d \n",ntohs(udph->source));
printf("The Value in UDP Header Destination Port  was %d \n",ntohs(udph->dest));

iph_trans = (struct iphdr*)txmsg;
//udph_trans = (struct udphdr*)(txmsg + sizeof(struct iphdr));
udph_trans = (struct udphdr*)(txmsg + (4*(iph->ihl)));
dhcp_ptr = (BOOTP *)(txmsg + sizeof(struct iphdr) + sizeof(struct udphdr));

//Filling the IP Header & UDP Header
iph_trans->ihl=5;
iph_trans->version=4; 
iph_trans->tos=16;
iph_trans->tot_len=sizeof(struct iphdr) + sizeof(struct udphdr);
iph_trans->id=htons(54321);
//iph_trans->frag_off = ;
iph_trans->ttl=64;
iph_trans->protocol=17;
iph_trans->saddr=inet_addr("192.168.117.129");
iph_trans->daddr=client_addr.sin_addr.s_addr;

udph_trans->source=htons(67);
udph_trans->dest=htons(68);
udph_trans->len=htons(sizeof(struct udphdr));
//udph_trans->check=0;
//htons(csum((unsigned short*)dhcp_ptr,sizeof(struct iphdr)+sizeof(struct udphdr)));


if(ntohs(udph->dest) == 67) {

rxmsg = original+28;

if(rxmsg[240] == 53 && rxmsg[242] == 1) {
printf("DHCP DISCOVER Packet was received....\n");


//printf("The Value of txmsg was %p \n",txmsg);
//printf("The Value of iph is %p \n",iph_trans);
//printf("The Value of udph is %p \n",udph_trans);
//printf("The Value of dhcp_ptr is %p \n",dhcp_ptr);

dhcp_ptr->op = 2;
dhcp_ptr->htype = 1; 
dhcp_ptr->hlen = 6;
dhcp_ptr->hops = 2;
dhcp_ptr->xid[0] = (unsigned char)rxmsg[4];
dhcp_ptr->xid[1] = (unsigned char)rxmsg[5];
dhcp_ptr->xid[2] = (unsigned char)rxmsg[6];
dhcp_ptr->xid[3] = (unsigned char)rxmsg[7];
dhcp_ptr->secs = 0; 
dhcp_ptr->flags= 0;
inet_pton(AF_INET,"0.0.0.0",&(dhcp_ptr->ciaddr.s_addr));
inet_pton(AF_INET,"8.5.5.5",&(dhcp_ptr->yiaddr.s_addr));
inet_pton(AF_INET,"192.168.117.129",&(dhcp_ptr->siaddr.s_addr));
inet_pton(AF_INET,"0.0.0.0",&(dhcp_ptr->giaddr.s_addr));
dhcp_ptr->chaddr[0]=(unsigned char)rxmsg[28];
dhcp_ptr->chaddr[1]=(unsigned char)rxmsg[29];
dhcp_ptr->chaddr[2]=(unsigned char)rxmsg[30];
dhcp_ptr->chaddr[3]=(unsigned char)rxmsg[31];
dhcp_ptr->chaddr[4]=(unsigned char)rxmsg[32];
dhcp_ptr->chaddr[5]=(unsigned char)rxmsg[33];
for(i=6;i<=15;i++){dhcp_ptr->chaddr[i]=0;}
strcpy(dhcp_ptr->sname,"Test_DHCP_SERVER\0"); /* 40: Server name */
strcpy(dhcp_ptr->file,"bc.txt\0"); /* 104: Boot filename */
dhcp_ptr->magic_cookie[0] = 99; 
dhcp_ptr->magic_cookie[1] = 130;
dhcp_ptr->magic_cookie[2] = 83;
dhcp_ptr->magic_cookie[3] = 99;

dhcp_ptr->options[0]=53;
dhcp_ptr->options[1]=1 ;
dhcp_ptr->options[2]=2;

dhcp_ptr->options[3]=54;
dhcp_ptr->options[4]=4;
dhcp_ptr->options[5]= 0xc0;
dhcp_ptr->options[6]= 0xa8;
dhcp_ptr->options[7]= 0x38;
dhcp_ptr->options[8]= 0x65;

dhcp_ptr->options[9]=1;
dhcp_ptr->options[10]=4;
dhcp_ptr->options[11]= 0xff;
dhcp_ptr->options[12]= 0xff;
dhcp_ptr->options[13]= 0x00;
dhcp_ptr->options[14]= 0x00;


//Address Lease Time
dhcp_ptr->options[15]=51;
dhcp_ptr->options[16]=4;
dhcp_ptr->options[17]=0x00;
dhcp_ptr->options[18]=0x00;
dhcp_ptr->options[19]=0x0e;
dhcp_ptr->options[20]=0x10;


//END OPTION
dhcp_ptr->options[21]=0xff;

//PADDING
for(i=22;i<=298;i++) {
dhcp_ptr->options[i] = 0;
}
}

else {
printf("DHCP Request Packet was Recieved...\n");

dhcp_ptr->op = 2;
dhcp_ptr->htype = 1; 
dhcp_ptr->hlen = 6;
dhcp_ptr->hops = 2;
dhcp_ptr->xid[0] = (unsigned char)rxmsg[4];
dhcp_ptr->xid[1] = (unsigned char)rxmsg[5];
dhcp_ptr->xid[2] = (unsigned char)rxmsg[6];
dhcp_ptr->xid[3] = (unsigned char)rxmsg[7];
dhcp_ptr->secs = 0; 
dhcp_ptr->flags= 0;
inet_pton(AF_INET,"0.0.0.0",&(dhcp_ptr->ciaddr.s_addr));
inet_pton(AF_INET,"8.5.5.5",&(dhcp_ptr->yiaddr.s_addr));
inet_pton(AF_INET,"0.0.0.0",&(dhcp_ptr->siaddr.s_addr));
inet_pton(AF_INET,"0.0.0.0",&(dhcp_ptr->giaddr.s_addr));
dhcp_ptr->chaddr[0]=(unsigned char)rxmsg[28];
dhcp_ptr->chaddr[1]=(unsigned char)rxmsg[29];
dhcp_ptr->chaddr[2]=(unsigned char)rxmsg[30];
dhcp_ptr->chaddr[3]=(unsigned char)rxmsg[31];
dhcp_ptr->chaddr[4]=(unsigned char)rxmsg[32];
dhcp_ptr->chaddr[5]=(unsigned char)rxmsg[33];
for(i=6;i<=15;i++){dhcp_ptr->chaddr[i]=0;}
strcpy(dhcp_ptr->sname,"Test_DHCP_SERVER\0"); /* 40: Server name */
strcpy(dhcp_ptr->file,"bc.txt\0"); /* 104: Boot filename */
dhcp_ptr->magic_cookie[0] = 99; 
dhcp_ptr->magic_cookie[1] = 130;
dhcp_ptr->magic_cookie[2] = 83;
dhcp_ptr->magic_cookie[3] = 99;

//DHCP Message Type
dhcp_ptr->options[0]=53;
dhcp_ptr->options[1]=1 ;
dhcp_ptr->options[2]=5;

//DHCP Server Identifier
dhcp_ptr->options[3]=54;
dhcp_ptr->options[4]=4;
dhcp_ptr->options[5]=0xc0;
dhcp_ptr->options[6]=0xa8;
dhcp_ptr->options[7]=0x38;
dhcp_ptr->options[8]=0x65;

//Address Lease Time
dhcp_ptr->options[9]=51;
dhcp_ptr->options[10]=4;
dhcp_ptr->options[11]=0x00;
dhcp_ptr->options[12]=0x00;
dhcp_ptr->options[13]=0x0e;
dhcp_ptr->options[14]=0x10;

// Subnet Mask
dhcp_ptr->options[15]=1;
dhcp_ptr->options[16]=4;
dhcp_ptr->options[17]=0xff;
dhcp_ptr->options[18]=0xff;
dhcp_ptr->options[19]=0x00;
dhcp_ptr->options[20]=0x00;

//END OPTION
dhcp_ptr->options[21]= 0xff;

//PADDING
for(i=22;i<=299;i++) {
dhcp_ptr->options[i] = 0;
}
}


iph_trans->check = htons(csum((unsigned short*)txmsg,sizeof(struct iphdr)+sizeof(struct udphdr)+sizeof(BOOTP)));

// SENDING THE STRUCTURE VIA SENDTO
if(bytes_send=sendto(sockfd,txmsg,1024,0,(struct sockaddr *)&client_addr, sizeof(client_addr)) < 0) {
   printf("Send to ERROR %d\n",errno); }
else {
   printf("Packet Sent \n"); }


}}

close(sockfd);
return 1;
}

最佳答案

由于功能请求到 mark a comment as an answer仍然被拒绝,我在这里复制上面的解决方案。

最终发现问题不在于代码,而在于默认网关。我的 PC 上没有配置默认网关,因此看到了 ERR-101。配置默认网关后,广播数据包就会出来。对不起。 – 凯萨瓦

关于sockets - 套接字发送到抛出 Errno-101,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11403348/

相关文章:

java - java中如何从socket读取多种类型的数据

sockets - 从 lisp 中的套接字流读取行

sockets - 欢迎端口和监听端口一样吗?

http 请求对象上的 Node.js 主体与快速请求对象上的主体

c++ - 如何通过 usb Lacewing::Client 接收数据?

sockets - 是否为RequestHandler.write提供了 Tornado 回调?

.net 数据包嗅探 : attempt to create socket causes access error

使用 select() 调用的并发 UDP 服务器

c++ - 套接字编程中的客户端到客户端消息传递

javascript - 无法从 Java Socket Server 向 NodeJS 客户端发送数据