1、概述

原始套接字(SOCK_RAW)

2、创建原始套接字

int socket(PF_PACKET, SOCK_RAW, protocol)

功能:创建链路层的原始套接字

protocol:指定可以接收或发送的数据包类型

• ETH_P_IP:IPV4数据包

• ETH_P_ARP:ARP数据包

• ETH_P_ALL:任何协议类型的数据包

返回值:

• 成功(>0):链路层套接字

• 失败(<0):出错

创建链路层的原始套接字

#include <sys/socket.h> #include <netinet/ether.h> sock_raw_fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));

发送数据:

用sendto发送原始套接字数据

sendto(sock_raw_fd, msg, msg_len, 0,(struct sockaddr*)&sll, sizeof(sll));注意:

• sock_raw_fd:原始套接字• msg:发送的消息(封装好的协议数据)• sll:本机网络接口,指发送的数据应该从本机的哪个网卡出去,而不是以前的目的地址

发送数据的整体过程:

//创建套接字 int sock_raw_fd = socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP));//ETH_P_IP if(sock_raw_fd < 0) { perror("socket"); exit(-1); } printf("sock_raw_fd=%d\n",sock_raw_fd); struct ifreq ethreq; strncpy(ethreq.ifr_name,"ens33",IFNAMSIZ); if(ioctl(sock_raw_fd,SIOCGIFINDEX,ðreq)==-1) { perror("ioctl"); close(sock_raw_fd); exit(-1); } struct sockaddr_ll sll; bzero(&sll,sizeof(sll)); sll.sll_ifindex = ethreq.ifr_ifindex; char msg[1024]={0}; strcpy(msg,"hello"); int len= sendto(sock_raw_fd,msg,sizeof(msg),0,(struct sockaddr *)&sll,sizeof(sll)); printf("len=%d\n",len); close(sock_raw_fd);

备注:执行文件时,需要使用超级管理员。