📄 ppp.c
字号:
/*本程序是通过libpcap来对数据链路层直接访问。这里面用到的函数都是来自包:libpcap下面主要是介绍它的函数的使用情况及如何对包进行过滤,它的整个流程如下: ********************* *查找有效的网络设备** * ******************* * * * ******************** 获得网络地址及网络掩码 ******************** * * * ******************** 打开网络设备 ******************** * * * ******************** 将用户输入的字串符编译到过滤程序中 ******************** * * * ******************** 设置过滤器 ******************* * *工 * * * ****************** * * * * * * ********************* * 捕获包 * ********************* * * * * * * * *********************** * 缓冲满? * *********************** * * * * * *Y N ********* ***************显示包*** ************************ * ********************* 退出 ******************** */ #include<pcap.h>#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>#define PCAP_ERRBUF_SIZE 200void Display(const u_char *packet, const size_t length);void my_callback(u_char *none, const struct pcap_pkthdr *pkthdr, const u_char *packet){ Display((u_char *)packet, (size_t)(pkthdr->caplen)); return;}int main(int argc, char **argv){ int i; char *dev; char errbuf[PCAP_ERRBUF_SIZE]; //程序中的错误信息放在这里 /*网络设备符结构: pcap_t { int fd; int snapshort; int linktype; int tzoff; int offset; struct pcap_sf sf; struct pcap_md md; int bufsize; u_char *buffer; u_char bp; int cc; u_char pkt; struct bpf_programe fcode; char errbuf[PCAP_ERRBUF_SIZE]; } 结构pcap_pkthdr struct pcap_pkthdr { struct timeval ts; bpf_u_int32 caplen; bpf_u_int32 len; }; */ pcap_t *descr; //网络设备描述符 const u_char *packet; struct pcap_pkthdr hdr; struct ether_header *eptr; struct bpf_program fp; bpf_u_int32 maskp; //子网掩 码 bpf_u_int32 netp; //网络号 if (argc != 2) { fprintf(stdout, "Usage:%s\"filter program\"\n", argv[0]); return 0; } dev = pcap_lookupdev(errbuf); //调用它返回网络设备名指针,如果出错则把 printf("用到的网络设备是:%s\n", dev); //错误放在errbuf中 if (dev == NULL) { fprintf(stderr, "%s\n", errbuf); exit(1); } pcap_lookupnet(dev, &netp, &maskp, errbuf); //获得指定网络设备名的网络号 和掩码 /*char *netnum; char *masknum; itoa(netp, netnum, 2); itoa(netp, masknum, 2);*/ printf("网络号及掩码:%x\n%x\n", netp, maskp); descr = pcap_open_live(dev, BUFSIZ, 1, 5, errbuf); //获得捕获数据包的描 //述符BUFSIZ是定接收包的最大长度,5是指超时时间(毫秒) if (descr == NULL) { printf("pcap_open_live():%s\n", errbuf); exit(1); } /*将指定的argv[1]编译到过滤程序中,netp是网络掩码*/ if (pcap_compile(descr, &fp, argv[1], 0, netp) == -1) { fprintf(stderr, "Error calling pcap_compile\n"); exit(1); } if (pcap_setfilter(descr, &fp) == -1) //对指定的网络设备指定一个过滤程序 { fprintf(stderr, "Error setting filter\n"); exit(1); } /*捕获数据包,并进行处理。-1表是函数返回前所处理数据包的最大值,为-1表示 * 在一个缓冲区中处理所有的数据包,为0时表示处理所有数据包,直到遇到以下错误(EOF, 超时读取),my_callback是一个带有三个参数的回调函数, NULL传递给回调 * 函数的参数额,在回调函数时对捕获的数所包进行处理*/ pcap_loop(descr, -1, my_callback, NULL); return 0;}void Display(const u_char *packet, const size_t length)//用于显示捕获到的包的数据{ u_long offset; int i, j, k; printf("packet[%d] bytes:\n", (long unsigned int)length); if (length <= 0) { return; } i = 0; offset = 0; for (k = length/16; k>0; k--, offset += 16)//显示时排列成K排,每行有16个16进制数 { printf("%08X\n", (unsigned int)offset); for (j=0; j<16; j++, i++) { if (j == 8) { printf("-%02X", packet[i]); } else { printf("%02X", packet[i]); } } printf(" "); i -= 16; for (j=0; j<16; j++, i++) { if ((packet[i] >= ' ') && (packet[i] <= 128)) { printf("%c", packet[i]); } else { printf("."); } } printf("\n"); } k = length - i; if (k <= 0) { return; } printf("%08X", (unsigned int)offset); for (j=0; j<k; j++, i++) { if (j == 8) { printf("-%02X", packet[i]); } else { printf("%02X", packet[i]); } } i -= k; for (j=16-k; j>0; j--) { printf(" "); } printf(" "); for (j=0; j<k; j++, i++) { if ((packet[i] >= ' ') && (packet[i] <= 128)) { printf("%c", packet[i]); } else { printf("."); } } printf("\n"); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -