windows下不能获取数据链路层的数据
所以拿不到mac地址,RawSocket 编程
要用管理员权限打开
看到这张图,我又想起了期末考试的时候,考了tcp源地址和目的地址,记反了,丢了四分,我现在还记忆深刻。唉~
1 #include <winsock2.h> 2 #include <ws2tcpip.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 #define MAX_HOSTNAME_LAN 255 6 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) 7 #define MAX_ADDR_LEN 16 8 9 struct ipheader{ 10 unsigned char ip_h1:4; //先存低位,再存高位。这样两个的顺序就反了 11 unsigned char ip_v:4; 12 unsigned char ip_tos; //服务类型 8位 13 unsigned short int ip_len; //ip数据包总长度 14 unsigned short int ip_id; //16位标识 15 unsigned short int ip_off; //标志加偏移量(16)位 16 unsigned char ip_ttl; //8位 生成时间 17 unsigned char ip_p; //8位协议 18 unsigned short int ip_sum; //16位首部校验和 19 unsigned int ip_src; //32位长 20 unsigned int ip_dst; 21 }; 22 typedef struct tcpheader{ 23 unsigned short int sport; 24 unsigned short int dport; 25 unsigned int th_seq; 26 unsigned int th_ack; 27 unsigned char th_x:4; 28 unsigned char th_off:4; 29 unsigned char Flags; 30 unsigned short int th_win; 31 unsigned short int th_sum; 32 unsigned short int th_urp; 33 }TCP_HDR; 34 35 typedef struct udphdr{ 36 unsigned short sport; 37 unsigned short dport; 38 unsigned short len; 39 unsigned short cksum; 40 }UDP_HDR; 41 42 int main(){ 43 SOCKET sock; 44 WSADATA wsd; 45 DWORD dwBytesRet; 46 unsigned int optval =1; 47 unsigned char *dataudp,*datatcp; 48 int i,pCount=0,lentcp,lenudp; 49 SOCKADDR_IN sa,saSource,saDest; 50 struct hostent FAR *pHostent; //域名和网络地址结构体 51 /* 52 struct hostent 53 { 54 char *h_name; //主机名,即官方域名 55 char **h_aliases; //主机所有别名构成的字符串数组,同一IP可绑定多个域名 56 int h_addrtype; //主机IP地址的类型,例如IPV4(AF_INET)还是IPV6 57 int h_length; //主机IP地址长度,IPV4地址为4,IPV6地址则为16 58 char **h_addr_list; // 主机的ip地址,以网络字节序存储。若要打印出这个IP,需要调用inet_ntoa()。 59 };*/ 60 61 char FAR name[MAX_HOSTNAME_LAN]; 62 char szSourceIP[MAX_ADDR_LEN],szDestIP[MAX_ADDR_LEN],RecvBuf[65535]={0}; 63 struct udphdr *pUdpheader; 64 struct ipheader *pIpheader; 65 struct tcpheader *pTcpheader; 66 WSAStartup(MAKEWORD(2,1),&wsd); 67 if((sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP))==SOCKET_ERROR) 68 { 69 printf("创建Socket失败!"); 70 exit(1); 71 } 72 /*struct sockaddr_in 73 { 74 short sin_family; 75 unsigned short sin_port; 76 struct in_addr sin_addr; 77 char sin_zero[8]; 78 } 79 struct in_addr{ 80 in_addr_t s_addr; 81 };*/ 82 //因为 sin_addr里面只有一个,所以指向sin_addr.s_addr和sin_addr是一样的。 83 84 gethostname(name,MAX_HOSTNAME_LAN); //获得本主机的姓名 85 pHostent = gethostbyname(name); //成功返回Hostent地址指针 失败返回NULL 86 sa.sin_family=AF_INET; //使用ipv4地址 87 sa.sin_port =htons(6000); //端口 88 memcpy(&sa.sin_addr.s_addr,pHostent->h_addr_list[0],pHostent->h_length); //ip地址(本主机ip地址) 89 90 /*u_long ippppp = inet_addr("10.1.12.78"); 91 sa.sin_addr.s_addr = ippppp; 92 char ccc[16]; 93 strncpy(ccc,inet_ntoa(sa.sin_addr),16); 94 printf("%s",ccc); 95 */ 96 97 bind(sock,(SOCKADDR*)&sa,sizeof(sa)); //将ip和端口信息和sock绑定在一起 98 //connect(sock,(SOCKADDR*)&sa,sizeof(sa)); 99 if(WSAGetLastError()==10013) 100 exit(1); 101 //控制一个套接字的模式,我也不知道干什么的 102 WSAIoctl(sock,SIO_RCVALL,&optval,sizeof(optval),NULL,0,&dwBytesRet,NULL,NULL); 103 pIpheader = (struct ipheader*)RecvBuf;//把RecvBuf首地址给ip首部指针 104 pTcpheader = (struct tcpheader*)(RecvBuf+sizeof(struct ipheader));//往后挪了一个IP首部的大小 105 pUdpheader = (struct udphdr*)(RecvBuf+sizeof(struct ipheader));//udp也是和tcp共用一个地址 106 107 while(1){ 108 memset(RecvBuf,0,sizeof(RecvBuf));//初始化RecvBuf 109 //接受从所有的ip包 110 recv(sock,RecvBuf,sizeof(RecvBuf),0); 111 saSource.sin_addr.s_addr = pIpheader->ip_src;//原地址 112 //将ip地址转换成存储在数组里面 113 strncpy(szSourceIP,inet_ntoa(saSource.sin_addr),MAX_ADDR_LEN); 114 saDest.sin_addr.s_addr = pIpheader->ip_dst;//目的地址 115 strncpy(szDestIP,inet_ntoa(saDest.sin_addr),MAX_ADDR_LEN); 116 lentcp = (ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct tcpheader))); 117 lenudp = (ntohs(pIpheader->ip_len)-(sizeof(struct ipheader)+sizeof(struct udphdr))); 118 119 if((pIpheader->ip_p)==IPPROTO_TCP&&lentcp!=0){ 120 printf("**************************\n"); 121 pCount++; 122 //datatcp指向数据部分,跳过了前面的ip首部和tcp首部 123 datatcp =(unsigned char *) RecvBuf+sizeof(struct ipheader)+sizeof(struct tcpheader); 124 printf("TCP\n"); 125 printf("源IP地址:%s:%d\n",szSourceIP,ntohs(pTcpheader->sport)); 126 printf("目的IP地址:%s:%d\n",szDestIP,ntohs(pTcpheader->dport)); 127 printf("TCP数据包地址:%x\n",datatcp); 128 printf("IP首部长度:%d\n",4*(pIpheader->ip_h1)); 129 printf("IP包总长度:%d\n",ntohs(pIpheader->ip_len)); 130 printf("char packet %d [%d]=\n\"\n",pCount,lentcp); 131 132 for(int i =0;i<lentcp;i++){ 133 if(i%10==0&&i!=0) 134 printf("\"\n\""); 135 printf("\\x%.2x",*(datatcp+i)); 136 } 137 printf("\";\n\n"); //最后的引号 并且换行 138 //输出内容 139 printf("%s",datatcp); 140 printf("\n\n************************************\n"); 141 } 142 if(pIpheader->ip_p==IPPROTO_UDP&&lentcp!=0){ 143 pCount++; 144 dataudp=(unsigned char *)RecvBuf+sizeof(struct ipheader)+sizeof(struct udphdr); 145 printf("-UDP-\n"); 146 printf("源IP地址:%s:%d\n",szSourceIP,ntohs(pUdpheader->sport)); 147 printf("目的IP地址:%s:%d\n",szDestIP,ntohs(pUdpheader->dport)); 148 printf("UDP数据报地址:%x\n",datatcp); 149 printf("IP首部长度:%d\n",4*(pIpheader->ip_h1)); 150 printf("IP包总长度:%d\n",ntohs(pIpheader->ip_len)); 151 printf("UDP长度:%d\n",ntohs(pUdpheader->len)); 152 printf("这是第%d个包[%d]=\n\"",pCount,lenudp); 153 for(int i=0;i<lenudp;i++){ 154 if(i%10==0&&i!=0) 155 printf("\"\n\""); 156 printf("\\x%.2x",*(dataudp+i)); 157 } 158 printf("\";\n\n"); 159 //输出内容 160 printf("数据内容是:\n%s",dataudp); 161 printf("\n\n************************************\n"); 162 } 163 getchar(); 164 } 165 }
这个就是移动指针就可以得到你要的东西了。
来源:https://www.cnblogs.com/tangdingkang/p/12298215.html