原始套接字学习笔记(1)
一般来说,我们会用到如下三种套接字:
TCP:SOCK_STREAM套接字
UDP:SOCK_DGRAM套接字
原始套接字:SOCK_RAW套接字
对于TCP和UDP两种套接字,相对来说只要配置好IP地址和端口号就可以了,比较简单,这里我们主要介绍原始套接字的使用。
1.原始套接字简介
原始套接字的强大之处在于,不同与UDP和TCP套接字只能访问传输层和传输层以上的数据包,原始套接字可以访问传输层以下的数据包,实现上至应用层下至链路层的数据操作,尤其适合用来进行抓包等工作。
2.原始套接字的建立
常用的原始套接字的建立方式有如下两种:
int sockfd=socket(PF_PACKET,SOCK_PACKET,htons(ETH_P_ALL));//这个socket可以访问处理链路层及以上所有的数据包
int sockfd=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_IP));//这个socket可以访问处理链路层及以上所有的IP数据包
3.原始套接字权限
原始套接字需要root权限即管理员权限才能够创建,所以需要sudo和su进入root模式,而且在使用原始套接字进行抓包的过程中需要设置网卡为混杂模式。
下面给出两个例子,供大家参考:
第一个,利用原始套接字进行发包,使用wireshark抓包查看;
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <time.h>#include <sys/types.h> #include <sys/socket.h> #include <sys/errno.h> #include <sys/time.h> #include <sys/ioctl.h> #include <sys/stat.h>#include <net/if.h> #include <net/ethernet.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/if_ether.h> #include <netpacket/packet.h> #include <netdb.h>#include <arpa/inet.h> #include <unistd.h> #include <pthread.h> #include <time.h> #include <errno.h> #include <fcntl.h> #include <dirent.h> #include <resolv.h> #include <signal.h> #include <getopt.h> #ifdef HAVE_CONFIG_H #include <config.h> #endif//首先定义网卡端口 #define PHYSICALPORT "eth0" #define PHYSICALPORT_LEN 30//创建实际网卡端口数组 char physical_port[30];//定义缓存大小 #define BUFSIZE 1024*5 char sendbuf[BUFSIZE]={0};int main() {memcpy(physical_port,PHYSICALPORT,PHYSICALPORT_LEN);int sock_send;sock_send=socket(PF_PACKET,SOCK_PACKET,htons(ETH_P_ALL));if(sock_send<0){perror("scoket created"); }//设置发包地址struct sockaddr send_addr;memset(&send_addr,0,sizeof(send_addr));strcpy(send_addr.sa_data,physical_port);//创建发送程序while(fgets(sendbuf,sizeof(sendbuf),stdin)!=0){int len=sendto(sock_send,&sendbuf,strlen(sendbuf),0,&send_addr,sizeof(send_addr));memset(sendbuf,0,sizeof(sendbuf));}return 0; }
使用wireshark抓包可以得到如下结果:
第二个,使用原始套接字建立一个接收程序,抓取本机的数据进行分析:
代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <time.h>#include <sys/types.h> #include <sys/socket.h> #include <sys/errno.h> #include <sys/time.h> #include <sys/ioctl.h> #include <sys/stat.h>#include <net/if.h> #include <net/ethernet.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/if_ether.h> #include <netpacket/packet.h> #include <netdb.h>#include <arpa/inet.h> #include <unistd.h> #include <pthread.h> #include <time.h> #include <errno.h> #include <fcntl.h> #include <dirent.h> #include <resolv.h> #include <signal.h> #include <getopt.h> #ifdef HAVE_CONFIG_H #include <config.h> #endif//首先定义网卡端口 #define PHYSICALPORT "eth0" #define PHYSICALPORT_LEN 30//创建实际网卡端口数组 char physical_port[30];//定义缓存大小 #define BUFSIZE 1024*5 char recvbuf[BUFSIZE]={0};void ethernet_setpormisc(int fd,int i_flags);int main() {memcpy(physical_port,PHYSICALPORT,PHYSICALPORT_LEN);//首先创建一个原始套接字int sock_recv;sock_recv=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL));if(sock_recv<0){perror("physicl socket created");}//设置网卡为混杂模式;ethernet_setpormisc(sock_recv,1);//setsockoptint recvbuf_size=BUFSIZE;setsockopt(sock_recv,SOL_SOCKET,SO_RCVBUF,&recvbuf,sizeof(char));//获取物理网卡接口索,用以传输数据struct ifreq ifr_recv;strcpy(ifr_recv.ifr_name,physical_port);if(ioctl(sock_recv,SIOCGIFINDEX,&ifr_recv)<0){perror("[3]get interface index");} //绑定物理网卡struct sockaddr_ll local_addr;local_addr.sll_family=PF_PACKET;local_addr.sll_ifindex=ifr_recv.ifr_ifindex;local_addr.sll_protocol=htons(ETH_P_ALL);if((bind(sock_recv,(struct sockaddr *)&local_addr,sizeof(local_addr)))<0){perror("[4]bind physical address");} //开始接收数据包while(1){recvfrom(sock_recv,recvbuf,BUFSIZE,0,NULL,NULL);printf("%s",recvbuf);memset(recvbuf,0,sizeof(recvbuf));} close(sock_recv); }//创建设置网卡混杂模式函数 void ethernet_setpormisc(int fd,int i_flags) {//首先获取网卡接口标志位struct ifreq ifr_s;memcpy(ifr_s.ifr_name,physical_port,sizeof(physical_port));if(ioctl(fd,SIOCGIFFLAGS,&ifr_s)<0){perror("[1]get interface flags");}if(i_flags==0){//取消混杂模式ifr_s.ifr_flags &= ~IFF_PROMISC;}else{//设置为混杂模式ifr_s.ifr_flags |= IFF_PROMISC;} //将接口设置为相应的模式if(ioctl(fd,SIOCSIFFLAGS,&ifr_s)<0){perror("[2]set interface flags");} }
抓取到的数据包如下所示:
因为以%s字符串形式打印出来,所以有很多乱码,这里需要再写包解析函数进行解析!
转载于:https://www.cnblogs.com/zuilehongdou/p/5127762.html
原始套接字学习笔记(1)相关推荐
- Linux原始套接字学习总结
Linux网络编程:原始套接字的魔力[上] http://blog.chinaunix.net/uid-23069658-id-3280895.html 基于原始套接字编程 在开发面向连 ...
- 黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第三章 网络工程-原始套接字与嗅探(1)主机发现工具与包嗅探
黑帽python第二版(Black Hat Python 2nd Edition)读书笔记 之 第三章 网络工程-原始套接字与嗅探(1)主机发现工具 文章目录 黑帽python第二版(Black Ha ...
- 《Python黑帽子:黑客与渗透测试编程之道》读书笔记(二):原始套接字和流量嗅探
目录 前言 1.Windows和Linux上的包嗅探 2.解码IP层 3.解码ICMP层 4.发现主机 结语 前言 <Python黑帽子:黑客与渗透测试编程之道>的读书笔记,会包括书中源码 ...
- 补充学习——原始套接字中协议结构体
原始套接字中使用结构体,快速获取数据中字节含义 struct iphdr{#if __BYTE_ORDER==__LITTLE_ENDIANunsigned int inl:4;unsigned in ...
- 【LWIP】原始套接字(SOCK_RAW)
收录于: [LWIP]LWIP协议|相关知识汇总|LWIP学习笔记 通常情况下我们接触到的套接字为两类: (1)字节流套接字(SOCK_STREAM):面向连接的socket套接字,用于TCP服务应用 ...
- 基于原始套接字的嗅探器
嗅探器这个代码我去年的时候就已经写过了,这个学期并不是非常忙,顺手复习网络,就又尝试着写了一遍. 其实在写嗅探器的时候,最主要的还是要将网卡设置为混杂模式.在此基础之上,对抓到的数据包进行分析. 这个 ...
- linux串口编程实例_Linux 网络编程——原始套接字实例:发送 UDP 数据包
以太网报文格式: IP 报文格式: UDP 报文格式: 校验和函数: /*******************************************************功能:校验和函数参 ...
- Linux原始网络编程,Linux操作系统网络编程 原始套接字 (1)
Linux操作系统网络编程--原始套接字 (1) http://soft.zdnet.com.cn/software_zone/2007/1020/568223.shtml 我们在前面已经学习过了网络 ...
- 原始套接字编程——Teardrop
文章目录 一.介绍套接字 二.著名的Teardrop 三.伪造虚假地址的IP包 四.在Ubuntu下使用Wireshark抓包进行验证 五.总结 六.参考资料 一.介绍套接字 流套接字(SOCK_ST ...
最新文章
- 关联规则挖掘算法_#数据挖掘初体验 使用weka做关联规则
- api.533.net 文章迁移计划
- CComboBox 置空
- Golang 入门系列(十) mysql数据库的使用
- 基于正态分布的图片高斯模糊算法
- BZOJ.2597.[WC2007]剪刀石头布(费用流zkw)
- php sqlite存入文件夹,PHP_小文件php+SQLite存储方案,我们草根站长购买的虚拟主机 - phpStudy...
- C/C++ linux下光标定位和清屏函数
- 十八掌教育_徐培成_Hadoop3.0-01.简介
- 奇虎360 replugin 插件化框架集成
- (一)遗传算法基本概念总结
- 神秘贼掉包二维码,支付宝赔偿200多,烧烤小哥为何还骂支付宝没良心?
- 手把手教你学习Solidity|Solidity开发【一】
- 【改】[火光摇曳]神奇的伽玛函数(上)——markdown排版
- asp.net session 串值 串号 变值
- 个人头像人工智能生成工具,上线一天就已赚了1万美金
- 【GMOJ6377】幽曲[埋骨于弘川]
- Linux下nano编辑器的快捷键使用
- 易语言开发控制台程序教程
- 2019腾讯前端技术大会 - 记录与思考