一、SOCK_RAW 内幕 首先在讲SOCK_RAW 之前,先来看创建socket 的函数: int socket(int domain, int type, int protocol); domain 如果参数对不匹配而且”type" 为 SOCK_RAW,则返回wildcard entry 指针 假设现在这样调用 socket(AF_INET, SOCK_RAW, 30); 则使用pffindproto 二、SOCK_RAW 应用 1、packet sniffer sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); while(1) { data_size 上述程序只可以接收tcp 包,当然udp 和 icmp 可以这样写: sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP); sock_raw = socket (AF_INET , SOCK_RAW , IPPROTO_ICMP); 但是不能以为 sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_IP); 就能接收所有种类的
1.代码分析 1) 首先,在链路层或者IP层,在把包交到上一层之前,系统会检查有没进程创建了socket(AF_PACKET,SOCK_DGRAM,…)或socket(AF_INET,SOCK_RAW, …)等类型的套接字(即原始套接字sock_raw),如果有,这个包就会被复制一份并发送到这个socket的缓冲区。 在tcpcopy中不同版本所使用的抓包函数不同,在0.3版本中是: int sock = socket(AF_PACKET,SOCK_RAW,htons(ETH_P_IP)); 而在0.4版本中,用的是 : int sock = socket(AF_INET,SOCK_RAW,IPPROTO_TCP); 以上两个函数分别工作在链路层和IP层,前者会把进来和出去的包都抓取到,后者只 抓取到进来的包。 六、附录 项目主页:http://code.google.com/p/tcpcopy/; Sock_raw:http://sock-raw.org/papers/sock_raw; Netlink:http
在linux下,首先建立一个接收所有数据的socket socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 对于多个网卡的需要先绑定网卡 memset(&sl_receive struct sockaddr *)&sl_receive, &addr_len); 发送也一样,建立socket,绑定,然后发送 sock_raw_send = socket(PF_PACKET, SOCK_RAW
14.04 send(虚拟机,自定义模式 VMnet1) Ubuntu 16.04 recv(虚拟机,自定义模式 VMnet1) 1、send int main() { sock_raw =socket(AF_PACKET,SOCK_RAW,IPPROTO_RAW); if(sock_raw == -1) printf("error in socket"); \n"); while(1) { send_len = sendto(sock_raw,sendbuff,64,0,(const struct sockaddr*)&sadr_ll,sizeof \n"); sock_r=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL)); if(sock_r<0) { printf("error in
AF_UNIX用于同一台机器上的进程通信,AF_INET用于IPV4协议的TCP和UDP,AF_INET6用于IPV6协议; type代表套接字类型,一般为SOCK_STREAM,SOCK_DGRAM和SOCK_RAW SOCK_STREAM为流式套接字,用于TCP通信,SOCK_DGRAM为数据报式套接字,用于UDP通信,SOCK_RAW为原始套接字,可以用于处理ICMP、IGMP等网络报文,这是普通套接字无法处理的
= SOCK_RAW) { // 已经绑定了端口 if (sk->num ! = SOCK_RAW) { /* Make sure we are allowed to bind here. */ cli(); for(sk2 = sk->prot->sock_array
ipv4 因特网域 AF_INET6 ipv6 因特网域 AF_UNIX UNIX 域 参数type 确定套接字的类型,进一步确定通信特征 SOCK_DGRAM 长度固定的,无连接的不可靠报文传递 SOCK_RAW 在AF_INET 通信域中套接字类型SOCK_STREAAM 的默认协议时TCP(传输控制协议) 在AF_INET 通信域中套接字类型SOCK_DGRAM的默认协议时UDP(用户数据报协议) SOCK_RAW
默认协议TCP SOCK_RAW IP协议的数据包接口(IP层接口) SOCK_SEQPACKET 和SOCK_STREAM类似,只不过是报文,而非字节流 字节流是无法分辨报文界限的,而报文传输直接可以获取发送方所发的数据 需要注意的是SOCK_RAW它提供的并非是传输层的套接字接口,它所提供的接口位于TCP/IP协议栈的网络层。也就是说,这时候传输层被越过了,需要应用程序开发者自行设计自己的协议头。
familyAF_UNIX unix系统进程间传输数据 AF_INETIPv4网络传输数据AF_INET6IPv6网络传输数据typeSOCK_STREAM 流式数据,TCP SOCK_DGRAM数据报式数据,UDP SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造
= SOCK_RAW) { // 已经绑定了端口 if (sk->num ! = SOCK_RAW) { /* Make sure we are allowed to bind here. */ cli(); // 遍历哈希表
失败返回INVALID_SOCKET 套接字类型: SOCK_STREAM:流套接字,使用TCP提供有连接的可靠传输 SOCK_DGRAW:数据包套接字,使用UDP提供无连接的不可靠的传输 SOCK_RAW
对于socket(AF_INET, SOCK_RAW, IPPROTO_IP),其原型为 int socket (int domain, int type, int protocol); 1 参数
指定应用程序使用的通信协议的协议族,af一般置为AF_INET(表示internetwork: UDP, TCP等); 第二个参数type为协议的Socket类型,常用的有3种:SOCK_STREAM、SOCK_DGRAM和SOCK_RAW SOCK_RAW称为原始Socket,可以读写ICMP、IGMP、IP报文。前两种类型使用得最多。 第三个参数protocol指定所使用的协议。
socket , for TCP socket.SOCK_DGRAM 数据报式socket , for UDP socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW 可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
. */ #define SOCK_DGRAM SOCK_DGRAM SOCK_RAW = 3, /* Raw protocol interface. */ #define SOCK_RAW SOCK_RAW SOCK_RDM = 4, /* Reliably-delivered messages. */ #define SOCK_RDM
msg.msg_namelen=sizeof(sa); 30 msg.msg_iov=&iov; 31 msg.msg_iovlen=1; 32 33 sockfd=socket(AF_NETLINK,SOCK_RAW MonitorNetlinkUevent(); 53 return 0; 54 } 创建socket描述符的时候指定协议族为AF_NETLINK或者PF_NETLINK,套接字type选择SOCK_RAW
在Windows平台,可以通过SOCK_RAW套接字类型来创建原始套接字。本文的代码示例基于Winsock2库实现,允许我们以最底层的方式捕获网络数据包。 SOCKET SockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP); 绑定本地IP地址 为了接收网络数据包,我们需要绑定本地IP地址。 = 0) return -1; // 创建原始套接字,过滤IP数据包 SOCKET SockRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
注意事项: 使用IPPROTO_RAW:socket(AF_INET6, SOCK_RAW, IPPROTO_RAW); 目标端口需要设置为0,否则会报错参数错误,发送失败:dest_addr.sin6 message); // 创建原始套接字,应该使用IPPROTO_RAW,使用IPPROTO_IDP会导致发送的数据异常 int sockfd = socket(AF_INET6, SOCK_RAW
Multiprotocol bridge */省略...type类型,相关定义在include/linux/net.henum sock_type {SOCK_STREAM= 1,SOCK_DGRAM= 2,SOCK_RAW 有的则更多用于自定义,SOCK_RAW。protocol协议,和地址族支持一致。Protocol families, same as address families. 比如使用跳过TCP层的SOCK_RAW类型。(注意风险)
字符串转入地址 inet_aton(dstip,&toaddr.sin_addr); //字符串转入地址 //建立原始TCP包方式IP+TCP信息包 sock = socket(AF_INET, SOCK_RAW ,IPPROTO_RAW); //IP方式 // sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP); if (sock>0) {printf("