原始套接字-TCP/IP下三层数据显示

 1 #include <stdio.h>
 2 #include <errno.h>
 3 #include <unistd.h>
 4 #include <sys/socket.h>
 5 #include <sys/types.h>
 6 #include <linux/in.h>
 7 #include <linux/if_ether.h>
 8
 9 int main(int argc, char **argv)
10 {
11     int sock, n;
12     char buffer[2048];
13     unsigned char *iphead, *ethhead;
14
15     if ( (sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)))<0) ///建立套接字。PF_PACKET:底层包访问协议;SOCK_RAW:提供原始网络协议访问;
16     {
17         perror("socket");
18         exit(1);
19     }
20
21     while (1)
22     {
23         printf("----------\n");
24         n = recvfrom(sock,buffer,2048,0,NULL,NULL);///接收数据包
25         printf("%d bytes read\n",n);
26         /* Check to see if the packet contains at least
27          *      * complete Ethernet (14), IP (20) and TCP/UDP
28          *           * (8) headers.
29          *                */
30         if (n<42)
31         {
32             perror("recvfrom():");
33             printf("Incomplete packet (errno is %d)\n",errno);
34             close(sock);
35             exit(0);
36         }
37         ethhead = buffer;
38         ///打印顺序可以通过wireshark包分析出来!!!
39         printf("Source MAC address:%02x:%02x:%02x:%02x:%02x:%02x\n",ethhead[6],ethhead[7],ethhead[8],ethhead[9],ethhead[10],ethhead[11]);
40         printf("Destination MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",ethhead[0],ethhead[1],ethhead[2],ethhead[3],ethhead[4],ethhead[5]);
41
42         iphead = buffer+14; /* Skip Ethernet header */
43         if (*iphead==0x45)
44         {
45             /* Double check for IPv4 and no options present */
46             printf("Source host %d.%d.%d.%d\n",iphead[12],iphead[13],iphead[14],iphead[15]);
47             printf("Dest host %d.%d.%d.%d\n",iphead[16],iphead[17],iphead[18],iphead[19]);
48             ///这里只是取协议的前四个字节
49             printf("Source %d ,Dest ports %d\n",(iphead[20]<<8)+iphead[21],(iphead[22]<<8)+iphead[23]);///端口占两个字节所以要使高位左移8位然后再加上低位值
50             printf("Layer-4 protocol %d\n",iphead[9]);
51         }
52     }
53
54 }

输出:

----------
74 bytes read
Source MAC address:48:8a:d2:12:59:ec
Destination MAC address: 00:21:6a:85:2c:8c
Source host 220.181.57.232
Dest host 192.168.0.118
Souce port front:80 ,Dest port front:80 ----
Source 80 ,Dest ports 59472
Layer-4 protocol 6

时间: 2024-12-24 13:33:15

原始套接字-TCP/IP下三层数据显示的相关文章

原始套接字-自定义IP首部和TCP首部

1 /* ===================================================================================== 2 * 3 * Filename: raw.c 4 * Description: 使用原始套接字发送TCP协议,并外带自己的数据. 5 * 6 * ====================================================================================*

【转】网络编程原始套接字

转自:http://www.cnblogs.com/hnrainll/archive/2011/09/20/2182423.html SOCKET_STREAM 流式套接字      SOCKET_DGRAM        SOCKET_RAW 原始套接字    IPPROTO_IP IP协议    IPPROTO_ICMP INTERNET控制消息协议,配合原始套接字可以实现ping的功能    IPPROTO_IGMP INTERNET 网关服务协议,在多播中用到 在AF_INET地址族下,

关于原始套接字的两个小问题

1.原始套接字的协议是否可以设置为IPPRORO_TCP?UDP和TCP分组没有对应的套接字,此时会不会将其传递到原始套接口? 答: (1) 可以.对于socket()函数,在流式套接字编程中第二个参数是SOCK_STREAM,而对于数据报套接字编程,第二个参数是SOCK_DGRAM,在这两种情况下,第三个参数可以填0,这样系统会自动匹配相应的协议. 而原始套接字编程中,第二个参数是SOCK_RAW,在这种情况下,第三个参数必须指明相应的协议,协议类型的常用取值有 IPPROTO_IP.IPPR

python使用原始套接字 解析原始ip头数据

使用底层套接字解码底层流量,是这次做的重点工作. 首先来捕获第一个包 # coding:utf-8import socket # 监听的主机IP host = "192.168.1.100" socket_protocol = socket.IPPROTO_ICMP sniffer = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket_protocol) sniffer.bind((host, 0)) sniffer.setso

Windows下利用原始套接字实现的一个抓包程序Demo

早就学过了套接字编程,但是原始套接字还没用过.最近听了网络安全老师的课,心血来潮,写了个抓包程序Demo,把代码分享给大家,感兴趣的可以看看.引用一句网络安全老师的话:"你们要本着技术的心态去实践,哎,一部分人,写着写着就成黑客了". #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <WinSock2.h> #include <WS2tcpip.h> #include <s

ip欺骗(原始套接字系列九)

由于使用Raw Socket的时候,IP报头可完全由程序员自定义,所以我们可以任意地修改本地发送包的IP地址,使得接收方错误的认为IP报文是由欺骗地址发出的. 下面的程序演示了向某目标发送IP地址伪装的UDP报文的过程: void sendPesuoIpUDP(void){ WSADATA wsd; if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) { printf("WSAStartup() failed: %d ", GetLastErr

关于linux 原始套接字编程

关于linux 网络编程最权威的书是<<unix网络编程>>,但是看这本书时有些内容你可能理解的不是很深刻,或者说只知其然而不知其所以然,那么如果你想搞懂的话那么我建议你可以看看网络协议栈的实现. 函数原型是 int socket(int domain, int type, int protocol); 其中domain 中AF_INET , AF_UNIT 较为常用,分别创建inet 域套接字和unix域套接字,unix套接字与文件相关.平时80%用的套接字都是AF_INET.这

原始套接字SOCK_RAW

原始套接字SOCK_RAW 实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现,用户只需要填充应用层报文即可,由系统完成底层报文头的填充并发送.然而在某些情况下需要执行更底层的操作,比如修改报文头.避开系统协议栈等.这个时候就需要使用其他的方式来实现. 一 原始套接字 原始套接字(SOCK_RAW)是一种不同于SOCK_STREAM.SOCK_DGR

Linux Socket 原始套接字编程

对于linux网络编程来说,可以简单的分为标准套接字编程和原始套接字编程,标准套接字主要就是应用层数据的传输,原始套接字则是可以获得不止是应用层的其他层不同协议的数据.与标准套接字相区别的主要是要开发之自己构建协议头.对于原始套接字编程有些细节性的东西还是需要注意的. 1. 原始套接字创建 原始套接字的编程和udp网络编程的流程有点类似,但是原始套接字编程中不需要bind操作,因为在数据接收和发送过程中使用sendto和recvfrom函数实现数据的接收和发送.不过不是说原始套接字不能使用bin