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