2012-07-09 265 views
1

運行本程序後,它拋出Errno-101。我只是想用DGRAM Socket發送一個廣播數據包。沒有什麼比這個更重要。有人能幫我理解這段代碼中的錯誤嗎?套接字sendto投擲Errno-101

//###########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; 
} 
+0

你可以使用'client_addr.sin_addr.s_addr = INADDR_BROADCAST'替換'inet_aton'嗎? – cnicutar 2012-07-09 21:32:51

+0

即使在建議的更改後仍然發生同樣的錯誤。也看到與SOCK_RAW類型相同。 – Kesava 2012-07-09 21:37:38

+1

適合我。將來,請報告出錯的名稱(例如'ENETUNREACH')或'strerror(errno)'的輸出,因爲只有原始數字對人類沒有意義,並且錯誤編號可能會甚至沒有從一個操作系統分配到另一個操作系統。 – Celada 2012-07-10 01:56:58

回答

0

由於功能要求mark a comment as an answer繼續下降,我在這裏複製上面的解決方案。

最後發現問題不在於代碼&它與默認網關。我的電腦上沒有配置默認網關&因此看到ERR-101。一旦配置了默認GW後,廣播包就會出現。對不起。 - Kesava