/*
________________________________________________________ //4Byte
|____type_____|____code_____|_____________chksum_________| //4Byte
|_________data______________|_____________data___________|
| |
| |
*/
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<arpa/inet.h> 4 #include<sys/socket.h> 5 #include<fcntl.h> 6 #include<unistd.h> 7 #include<netdb.h> 8 9 int main(){ 10 int s = socket(PF_INET,SOCK_RAW,1);//建立//原始套接字能夠讀寫內核沒有處理的IP數據包,而流式套接字只能讀取TCP協議的數據,數據報套接字只能讀取UDP協議的數據 11 // printf("--%d--\n",s); 12 if (s <= 0){ 13 perror("socket erro"); 14 exit(0); 15 } 16 typedef struct{ //ICMP請求頭部 17 uint8_t type; 18 uint8_t code; 19 uint16_t chksum; 20 uint32_t data; 21 }icmp_hdr_t; 22 23 icmp_hdr_t pckt; 24 25 pckt.type=8; //1Byte 26 pckt.code=0; //1Byte 27 pckt.chksum=0xfff7;//2Byte 28 pckt.data=0; //4Byte 29 30 struct sockaddr_in addr;//目的地的信息 31 32 addr.sin_family=AF_INET; 33 addr.sin_port=0; 34 addr.sin_addr.s_addr=inet_addr("8.8.8.8");//Ping的目的地址 35 //addr.sin_zero[]="";
36 int actionSendResult=sendto(s,&pckt,sizeof(pckt),0,(struct sockaddr *)&addr,sizeof(addr)); 37 38 if(actionSendResult<=0){ 39 perror("ping erro"); 40 exit(0); 41 } 42 unsigned int resAddressSize; 43 unsigned char res[100]=""; 44 struct sockaddr resAddress; 45 //printf("%u\n",resAddressSize);
46 int ressponse=recvfrom(s,res,sizeof(res),0,&resAddress,&resAddressSize); 47 if(ressponse>0){ 48 printf("message is %d bytes long, and looks like this :\n",ressponse); 49 for(int i=0;i<ressponse;i++) printf("%02hhx ",res[i]); 50 printf("\n"); 51 //exit(0); 52 53 }else{ 54 perror("ressponse error"); 55 exit(0); 56 } 57 printf("resAddressSize:%u\n",resAddressSize); 58 struct sockaddr_in * temp; 59 temp=(struct sockaddr_in *)&resAddress; 60 printf("protocol:%d\n",temp->sin_family); 61 printf("port:%d\n",temp->sin_port); 62 return 0; 63 }
1.從下圖得網絡
發送:ICMP-->IP-->Ethernetsocket
2.接收:Ethenet-->IP-->ICMPui
recvfrom()直接從Ethenet接收內容this
3.recvfrom()接收任意ICMP數據spa
4.WireShark沒有ICMP協議的數據包,但程序有返回信息,說明recvfrom並未操做在ICMP之上,而是接收數據鏈路層處理完的數據(原始套接字能夠讀寫內核沒有處理的IP數據包,而流式套接字只能讀取TCP協議的數據,數據報套接字只能讀取UDP協議的數據)code
目的地址不可達,recvfrom()爲何會接收到「消息」,哪裏來的消息?什麼協議?blog
網絡層(IP)沒法發送?get