clinux原始套接字
一、基本概念
原始套接字(Raw Socket)是一种特殊的网络套接字,它允许应用程序直接访问底层传输协议,绕过操作系统提供的传输层接口,这种套接字通常用于实现新的协议或对现有协议进行低级别的操作,如自定义IP包的构造和发送,在Linux中,原始套接字广泛应用于 网络诊断工具 (如ping、Traceroute)、网络攻击与防御以及某些类型的网络测试。
二、创建方法
创建原始套接字的过程与创建其他类型的套接字相似,但需要指定特定的协议族(如AF_INET表示IPv4)和套接字类型(SOCK_RAW表示原始套接字),以下是一个创建用于IPv4和ICMP的原始套接字的示例:
int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (sockfd == -1) {perror("socket");exit(EXIT_FAILURE);}
三、权限需求
由于原始套接字允许直接访问底层协议,并可能被用于伪造数据包,因此它通常需要特殊权限(如root权限)才能创建和使用。
四、工作方式
发送数据
当使用原始套接字发送数据时,应用程序需要负责构建完整的传输层头部(如TCP、UDP或ICMP头部),这给了我们控制头部字段的能力,例如伪造源IP地址,以下是一个发送自定义ICMP回显请求的示例:
struct icmphdr hdr;memset(&hdr, 0, sizeof(hdr));hdr.type = ICMP_ECHO;hdr.code = 0;hdr.checksum = 0;hdr.un.echo.id = getpid();for (int i = 0; i < sizeof(hdr)/2; i++) {hdr.checksum += ((u_short *)&hdr)[i];}hdr.checksum += (hdr.checksum >> 16);sendto(sockfd, &hdr, sizeof(hdr), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
接收数据
当使用原始套接字接收数据时,会得到底层协议的完整头部,应用程序需要解析这些头部以获取所需的信息,以下是一个接收ICMP回显应答的示例:
char buffer[BUFFER_SIZE];recvfrom(sockfd, buffer, BUFFER_SIZE, 0, NULL, NULL);struct icmphdr *recv_icmp = (struct icmphdr *)buffer;if (recv_icmp->type == ICMP_ECHOREPLY) {printf("Received ICMP echo reply");}
五、用途与限制
用途
网络诊断工具 :如ping、traceroute等,用于测试网络连通性和诊断网络问题。
网络攻击与防御 :用于实现自定义的网络攻击或防御策略。
网络测试 :用于测试网络协议的正确性和性能。
限制
操作系统处理 :大多数操作系统默认会处理某些协议(如ICMP回显请求和回显应答),这可能会导致原始套接字无法接收到这些协议的数据包。
跨平台差异 :不同的操作系统在实现和行为上可能存在细微差别,这需要在编写跨平台代码时特别注意。

安全风险 :由于原始套接字的强大功能,滥用可能导致网络安全问题或被视为恶意活动。
六、链路层原始套接字
链路层原始套接字允许直接与链路层设备(如以太网适配器)交互,发送和接收链路层帧(如以太网帧),这对于需要直接处理链路层数据的应用非常有用,如包捕获工具、桥接和交换应用程序。
创建一个链路层原始套接字的示例如下:
int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));if (sockfd == -1) {perror("socket");exit(EXIT_FAILURE);}
绑定到特定网络接口并启用混杂模式的示例如下:
struct sockaddr_ll sa;memset(&sa, 0, sizeof(struct sockaddr_ll));sa.sll_family = AF_PACKET;sa.sll_protocol = htons(ETH_P_ALL);sa.sll_iFindex = if_nametoindex("eth0");if (bind(sockfd, (struct sockaddr *)&sa, sizeof(struct sockaddr_ll)) == -1) {perror("bind");exit(EXIT_FAILURE);}// Enable promiscuous modestrncpy(ifr.ifr_name, "eth0", IFNAMSIZ);if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) == -1) {perror("ioctl SIOCGIFFLAGS");close(sockfd);exit(EXIT_FAILURE);}ifr.ifr_flags |= IFF_PROMISC;if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) == -1) {perror("ioctl SIOCSIFFLAGS");close(sockfd);exit(EXIT_FAILURE);}
发送和接收链路层帧的示例如下:
// Send a framechar frame[] = { /* Ethernet frame>七、注意事项与常见问题解答问题1:如何确保原始套接字发送的数据包格式正确?
答:由于原始套接字需要手动构建数据包,因此必须仔细按照协议规范构建数据包,并计算校验和等必要字段,建议参考相关RFC文档或使用现有的库函数来辅助构建。
问题2:为什么原始套接字无法接收某些协议的数据包?
答:这是因为操作系统可能会对某些协议(如ICMP回显请求和回显应答)进行特殊处理,导致这些数据包不会被传递给原始套接字,可以通过设置套接字选项或使用其他机制来绕过这种限制。
问题3:如何在多网卡系统中指定原始套接字使用的网络接口?
答:可以使用bind函数将原始套接字绑定到指定的网络接口,在绑定之前,需要查找网络接口的索引号,并将其设置为sockaddr_ll结构体的sll_ifindex字段。
小伙伴们,上文介绍了“clinux原始套接字”的内容,你了解清楚吗?希望对你有所帮助,任何问题可以给我留言,让我们下期再见吧。
【请问】网络抓包的实现方法
我觉得对网络内的通信过程由于异常因素导致的数据包丢失,应该在数据链路层!为了弥补物理层上的不足,为上层提供无差错的数据传输,就要能对数据进行检错和纠错.数据链路的建立,拆除,对数据的检错,纠错是数据链路层的基本任务.
word显示被“另一个用户锁定”是怎么回事啊?
!!!!被设置了“工具”——“保护文档”的缘故!!!Word文档保护的破解一般来说,WORD文档有两种密码打开密码和文档保护密码,下面介绍几种破解文档保护密码的方法。 方法1:插入文件法 启动WORD,新建一个空白文档,执行“插入”→“文件”打开“插入文件”对话框,定位到需要解除保护的文档所在的文件夹,选中相应文档,单击“插入”按钮,将加密保护的文档插入到新文档中,文档保护会被自动撤销。 方法2:文件另存法第一步:将受保护的Word文档另存为web页。 具体操作是在“文件”菜单下点击“另存为web页”。 第二步:右击刚另存为的web文件,选择“打开方式”中的“记事本”打开。 第三步:在文档中查找到“forms” 套接字,该套接字之间的内容就是Word文档实际保护的内容。 我们只需将语句Forms更改为Forms,即属性“DocumentProtection”前面加上前缀“un”变为“unDocumentProtection”,由原来的“文档保护”属性变更为目前的“非文档保护”属性。 第四步:保存退出记事本文件,右击web文件,选择“打开方式”中的“Microsoft Word for Windows”,这个时候你会发现,原来受保护的Word文件,现在已经不受保护,可以任意编辑了。 秘密提示(更简便的另存法):打开保护的文档,执行“文件”—“另存为”命令—打开“另存为”对话框—“保存类型”选定为“Web页”,确定保存;右击刚另存的Web文件,选择“打开方式”中的“Microsoft Word for Windows”打开,执行“工具”菜单下的“解除文档保护”命令即可。 方法3:写字板法右击受保护的WORD文档,选择“打开方式”中的“写字板”,再另存为WORD文档,同时可以取消对文档的保护。 但此方法可能会使文档中的图片等要素丢失。 方法4:第三方软件法(即一般所说的解密软件)
发表评论