失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 10_libpcap以及libnet

10_libpcap以及libnet

时间:2021-04-01 05:42:58

相关推荐

10_libpcap以及libnet

知识点1【飞秋欺骗】

1、windwos安装飞秋 双击运行

2、ubuntu安装飞秋 sudo apt-get install iptux

ubuntu运行飞秋:iptux&

3、飞秋的格式:

版本:包编号:用户名:主机名:命令字:附加消息

飞秋的端口是2425固定的

1表示上线 32表示普通消息

1_iptux_0#5#2:8:edu:edu:259:edu

#include<stdio.h>#include<sys/socket.h>#include<netinet/ether.h>#include <sys/ioctl.h>//ioctl#include <net/if.h>//struct ifreq#include <netpacket/packet.h>//struct sockaddr_ll#include<unistd.h>//_exit#include<string.h>//strncpy#include <net/ethernet.h>//struct ether_header#include <net/if_arp.h>//struct arphdr#include <netinet/ip.h>//struct iphdr#include <netinet/udp.h>//struct udphdrvoid my_sendto(int sockfd, char *out, unsigned char *msg, int msg_len);typedef struct{u_int32_t saddr;//源IPu_int32_t daddr;//目的IPu_int8_t flag;//标记(0)u_int8_t type;//udp协议 17u_int16_t len;//长度}WEIHDR;unsigned short checksum(unsigned short *buf, int len){int nword = len/2;unsigned long sum;if(len%2 == 1)nword++;for(sum = 0; nword > 0; nword--){sum += *buf;buf++;}sum = (sum>>16) + (sum&0xffff);sum += (sum>>16);return ~sum;}int main(){//1、创建原始套接字int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));if(sockfd < 0){perror("socket");return 0;}//获取要发送的消息printf("请输入要发送的消息:");char data[128]="1_iptux_0#5#2:123:edu:edu:32:loveyou";int data_len = strlen(data);//如果data_len不是偶数 补0为偶数if(data_len%2 != 0)//奇数data_len++;/*目的mac地址 XPmac*/unsigned char dst_mac[6]={0x70,0x5A,0x0F,0x63,0xF5,0x9D};//win_macunsigned char dst_ip[4]={192,168,0,110};//win_ipunsigned char src_mac[6]={0x00,0x0c,0x29,0x9a,0xeb,0x23};//伪装的mac!!!!unsigned char src_ip[4]={192,168,0,105};//伪装的IP !!!!!unsigned char msg[1024]="";//1、组mac头部struct ether_header *eth_addr = (struct ether_header *)msg;//赋值目的mac地址memcpy(eth_addr->ether_dhost, dst_mac, 6);//赋值源mac地址memcpy(eth_addr->ether_shost, src_mac, 6);//赋值帧类型 eth_addr->ether_type = htons(0x0800);//2、组IP报文struct iphdr *ip_hdr = (struct iphdr *)(msg+14);ip_hdr->version = 4;//IPv4版本ip_hdr->ihl = 5;//IP头部长度 单位4B 所以赋值5其实就是5*4=20Bip_hdr->tos = 0;//服务类型ip_hdr->tot_len = htons(20+8+data_len);//总长度=IP首部长度+IP数据长度ip_hdr->id = htons(0);//标识ip_hdr->frag_off = htons(0);//标志 + 片偏移ip_hdr->ttl = 128;//64或128都可以 生命周期ip_hdr->protocol = 17;//udp 17 tcp 6ip_hdr->check = htons(0);//首部校验???? 后续校验memcpy(&ip_hdr->saddr, src_ip, 4);//源IPmemcpy(&ip_hdr->daddr, dst_ip, 4);//目的IP//ip报文头部校验ip_hdr->check = checksum(ip_hdr, 20);//3、udp头部struct udphdr *udp_hdr = (struct udphdr *)(msg+14+20);udp_hdr->source = htons(2425);//源端口 !!!!udp_hdr->dest = htons(2425);//目的端口 !!!!udp_hdr->len = htons(8+data_len);//udp总长度=udp报文头+数据长udp_hdr->check = htons(0);//???? udp校验//将data拷贝到udp的数据部分memcpy(msg+14+20+8, data, data_len);//准备udp校验unsigned char wei_head[1024]="";WEIHDR *wei_hdr = (WEIHDR *)wei_head;memcpy(&wei_hdr->saddr, src_ip, 4);//源IPmemcpy(&wei_hdr->daddr, dst_ip, 4);//目的IPwei_hdr->flag = 0;wei_hdr->type = 17;//协议wei_hdr->len = htons(8+data_len);//udp的总长度//将msg中的udp头部信息以及data数据 拷贝到为头部后方memcpy(wei_head+12, udp_hdr, 8+data_len);//校验udp: 为头部+udp头部+data部分udp_hdr->check = checksum(wei_head, 12+8+data_len);//发送arp请求帧数据my_sendto(sockfd, "eth0",msg, 14+20+8+data_len);sleep(5);close(sockfd);return 0;}void my_sendto(int sockfd, char *out, unsigned char *msg, int msg_len){//通过ioctl得到网络接口struct ifreq ethreq;strncpy(ethreq.ifr_name, out, IFNAMSIZ);if(-1 == ioctl(sockfd, SIOCGIFINDEX, &ethreq)){perror("ioctl");close(sockfd);_exit(-1);}//帧数据 出去的本地接口struct sockaddr_ll sll;bzero(&sll,sizeof(sll));sll.sll_ifindex = ethreq.ifr_ifindex;//2、发送组好报文的帧数据sendto(sockfd, msg, msg_len, 0, (struct sockaddr *)&sll, sizeof(sll));}

知识点2【libpcap】接受收原始套接字的数据

1、Libpcap主要的作用

Libpcap主要的作用如下:

1、捕获各种数据包

列如:网络流量统计

2、过滤网络数据包

列如:过滤掉本地上的一些数据,类似防火墙

3、分析网络数据包

列如:分析网络协议,数据的采集

4、存储网络数据包

列如:保存捕获的数据以为将来进行分析

2、Libpcap的安装

sudo apt-get install libpcap-dev

需要的头文件:

#include <pcap.h>

编译的时候 -lpcap

3、libpcap开发实例

利用libpcap函数库开发应用程序的基本步骤:

1、打开网络设备

2、设置过滤规则(可选)

3、捕获数据

4、关闭网络设备

捕获网络数据包常用函数

1、pcap_lookupdev( )(可选) 查看设备名

2、pcap_open_live( ) 打开设备

3、pcap_lookupnet( )(可选) 获取的设备IP

4、pcap_compile( )、 pcap_setfilter( ) (可选) 设置过滤规则

5、pcap_next( 调用一次捕获一个报文 )、pcap_loop( 调用一次 不停捕获报文 ) 捕获数据

6、pcap_close( )

4、打开设备 获得设备的句柄

pcap_t *pcap_open_live(const char *device,int snaplen,int promisc,int to_ms,char *ebuf)功能:打开一个用于捕获数据的网络接口返回值:返回一个Libpcap句柄参数:device:网络接口的名字snaplen:捕获数据包的长度promise:1代表混杂模式,其它非混杂模式to_ms:等待时间ebuf:存储错误信息

5、关闭句柄

void pcap_close(pcap_t *p)

功能:

关闭Libpcap操作,并销毁相应的资源

参数

p:需要关闭的Libpcap句柄

返回值:

例如

const u_char *pcap_next(pcap_t *p,struct pcap_pkthdr *h)功能:捕获一个网络数据包参数:p:Libpcap句柄h:数据包头返回值:捕获的数据包的地址

struct pcap_pkthdr结构体信息:记录接受数据的时间以及报文的长度

案例:

#include<stdio.h>#include <pcap.h>int main(){//1、创建一个pcap句柄pcap_t *pcap_handle = NULL;pcap_handle = pcap_open_live("eth0",1500,0,0,NULL);//2、接受数据struct pcap_pkthdr pck_hdr;//记录收到数据的时间和报文长度unsigned char *msg = NULL;//存放接受到的帧数据msg = pcap_next(pcap_handle, &pck_hdr);printf("报文长度:%u\n", pck_hdr.caplen);//msg:mac ip udp/tcp data//msg的mac地址解析 和 原始套接字一样//解析msg的mac地址char src_mac[18]="";char dst_mac[18]="";sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]);sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]);printf("%s--->%s\n", src_mac, dst_mac);//关闭句柄pcap_close(pcap_handle);return 0;}

运行结果:

7、循环的接受网络数据pcap_loop

int pcap_loop(pcap_t *p,int cnt,pcap_handler callback,u_char *user)功能:循环捕获网络数据包,直到遇到错误或者满足退出条件;每次捕获一个数据包就会调用callback指示的回调函数,所以,可以在回调函数中进行数据包的处理操作返回值:成功返回0,失败返回负数参数:p:Libpcap句柄cnt:指定捕获数据包的个数,如果是-1,就会永无休止的捕获callback:回调函数user:向回调函数中传递的参数

回调函数如何定义:

参数1:argument存放pcap_loop传递过来的user用户数据

参数2:packet_heaher 存放接收到的报文的时间以及长度

参数3:packet_content接收到的网络帧数据

案例:

#include<stdio.h>#include <pcap.h>//pcap_loop每收到一个报文 就会调用一次回调函数void callback(u_char *arg, const struct pcap_pkthdr *packet_header, \const u_char *packet_content){unsigned char *msg = packet_content;printf("报文长度:%u\n", packet_header->caplen);//解析msg的mac地址char src_mac[18]="";char dst_mac[18]="";sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]);sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]);printf("%s--->%s\n", src_mac, dst_mac);}int main(){//1、创建一个pcap句柄pcap_t *pcap_handle = NULL;pcap_handle = pcap_open_live("eth0",1500,0,0,NULL);//2、接受数据 带阻塞pcap_loop(pcap_handle, 5, callback, NULL);//关闭句柄pcap_close(pcap_handle);return 0;}

运行结果:

8、设置过滤规则 下面两个函数配合使用

pcap_compile: 将用户识别的规则 转换成 pcap识别的规则

pcap_setfilter:将pcap识别的规则 设置到pcap结束数据的句柄中

int pcap_compile(pcap_t *p,struct bpf_program *program,char *buf,int optimize,bpf_u_int32 mask)功能:编译BPF过滤规则返回值:成功返回0,失败返回-1参数:p:Libpcap句柄program:bpf过滤规则(pcap识别的规则)buf:过滤规则字符串(用户识别的规则 重心)optimize:优化mask:掩码

int pcap_setfilter(pcap *p,struct bpf_program*fp)功能:设置BPF过滤规则返回值:成功返回0,失败返回-1参数:p:Libpcap句柄fp:BPF过滤规则

过滤规则:

案例:

#include<stdio.h>#include <pcap.h>//pcap_loop每收到一个报文 就会调用一次回调函数void callback(u_char *arg, const struct pcap_pkthdr *packet_header, \const u_char *packet_content){unsigned char *msg = packet_content;printf("报文长度:%u\n", packet_header->caplen);//解析msg的mac地址char src_mac[18]="";char dst_mac[18]="";sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \msg[0],msg[1],msg[2],msg[3],msg[4],msg[5]);sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x", \msg[0+6],msg[1+6],msg[2+6],msg[3+6],msg[4+6],msg[5+6]);printf("%s--->%s\n", src_mac, dst_mac);}int main(){//1、创建一个pcap句柄pcap_t *pcap_handle = NULL;pcap_handle = pcap_open_live("eth0",1500,0,0,NULL);//设置过滤规则struct bpf_program program;pcap_compile(pcap_handle,&program, "src port 9000", 0, 0xffffff00);pcap_setfilter(pcap_handle, &program);//2、接受数据 带阻塞pcap_loop(pcap_handle, 5, callback, NULL);//关闭句柄pcap_close(pcap_handle);return 0;}

知识点3【libnet发送原始套接字数据】

专业的构造和发送网络数据包的开发工具包

是个高层次的API函数库,允许开发者自己构造和发送网络数据包

头文件:include

编译的是加:-lnet

Libnet的安装

Libnet开发流程

利用libnet函数库开发应用程序的基本步骤:

1、数据包内存初始化

2、构造数据包

3、发送数据

4、释放资源

1、内存管理相关函数

libnet_t *libnet_init(int injection_type, char *device, char *err_buf)功能:数据包内存初始化及环境建立参数:injection_type: 构造的类型(LIBNET_LINK,LIBNET_RAW4,LIBNET_LINK_ADV(推荐),LIBNET_RAW4_ADV)device:网络接口,如"eth0",或IP地址,亦可为NULL(自动查询搜索)err_buf: 存放出错的信息返回值:成功返回一个libnet句柄;失败返回NULL

injection_type:构造的类型(LIBNET_LINK,LIBNET_RAW4,LIBNET_LINK_ADV,LIBNET_RAW4_ADV)

2、释放资源

void libnet_destroy(libnet_t *l);功能:释放资源参数:l: libnet句柄返回值:

3、构建udp报文

libnet_ptag_t libnet_build_udp(u_int16_t sp,u_int16_t dp,u_int16_t len,u_int16_t sum,u_int8_t *payload,u_int32_t payload_s,libnet_t *l,libnet_ptag_t ptag)功能:构造udp数据包返回值:成功返回协议标记;失败返回-1参数:sp: 源端口号dp:目的端口号len:udp包总长度sum:校验和,设为0,libnet自动填充payload:负载,可设置为NULLpayload_s:负载长度,或为0l: libnet句柄ptag:协议标记(其值为0创建一个新的协议数据,不为0,修改由ptag表示的协议数据)

4、构造一个IPv4数据包

libnet_ptag_t libnet_build_ipv4(u_int16_t ip_len,u_int8_t tos,u_int16_t id,u_int16_t flag,u_int8_t ttl,u_int8_t prot,u_int16 sum,u_int32_t src,u_int32_t dst,u_int8_t *payload,u_int32_t payload_s,libnet_t *l,libnet_ptag_t ptag)功能:构造一个IPv4数据包参数:ip_len:ip包总长tos:服务类型id:ip标识flag:片偏移ttl:生存时间prot:上层协议sum:校验和,设为0,libnet自动填充src: 源ip地址dst:目的ip地址payload:负载,可设置为NULLpayload_s:负载长度,或为0l: libnet句柄ptag:协议标记返回值:成功返回协议标记;失败返回-1

5、构造一个以太网数据包

libnet_ptag_t libnet_build_ethernet(u_int8_t *dst,u_int8_t *src,u_int16_t type,u_int8_t *payload,u_int32_t payload_s,libnet_t *l,libnet_ptag_t ptag)功能:构造一个以太网数据包参数:dst:目的macsrc:源mactype:上层协议类型payload:负载,即附带的数据payload_s:负载长度l:libnet句柄ptag:协议标记返回值:成功返回协议标记;失败返回-1

6、发送数据到网络

int libnet_write(libnet_t * l)功能:发送数据到网络参数:l:libnet句柄返回值:失败返回-1,成功返回其他

综合案例:发送udp数据

#include<stdio.h>#include <libnet.h>#include<string.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>int main(){//1、初始化内存libnet_t *lib_handle = libnet_init(LIBNET_LINK_ADV,"eth0",NULL);char data[128]="";printf("请输入要发送的udp数据:");fgets(data,sizeof(data),stdin);data[strlen(data)-1]=0;int data_len = strlen(data)+strlen(data)%2;//长度为偶数//构建数据包:从应用层--->链路层//1、构建udp数据libnet_ptag_t ptag_udp = libnet_build_udp(8000,9000,8+data_len,\0,data,data_len, lib_handle, 0);//2、构建IP报文libnet_ptag_t ptag_ip = libnet_build_ipv4(20+8+data_len,0,0,0,128,\17,0,inet_addr("192.168.0.111"),inet_addr("192.168.0.110"),\NULL,0, lib_handle, 0);//3、构建mac数据报文unsigned char src_mac[6]={0x00,0x0c,0x29,0x79,0xf9,0x7f};unsigned char dst_mac[6]={0x70,0x5A,0x0F,0x63,0xF5,0x9D};libnet_ptag_t ptag_mac = libnet_build_ethernet(dst_mac, src_mac, 0x0800,\NULL,0, lib_handle, 0);//4、发送帧数据libnet_write(lib_handle);//循环的发送5次int i=0;for(i=0;i<5;i++){printf("请输入要发送的udp数据:");fgets(data,sizeof(data),stdin);data[strlen(data)-1]=0;data_len = strlen(data)+strlen(data)%2;//长度为偶数//重新构建udp报文ptag_udp = libnet_build_udp(8000,9000,8+data_len,\0,data,data_len, lib_handle, ptag_udp);//重新构建IP报文ptag_ip = libnet_build_ipv4(20+8+data_len,0,0,0,128,\17,0,inet_addr("192.168.0.111"),inet_addr("192.168.0.110"),\NULL,0, lib_handle, ptag_ip);//发送帧数据libnet_write(lib_handle);}//释放资源libnet_destroy(lib_handle);return 0;}

知识点4【BS开发概述】浏览器和服务器开发

HTML:超文本标记语言 静态的 显示网页

CSS:层叠样式表 渲染网页

XML:指可扩展标记语言 传输网页

Javascript:脚本语言 和 网页交互 (局部刷新网页)

AJAX:基于Javascript语言的技术 (将网页 和 服务器 交互)

CGI:通用网关接口(服务器 借助 CGI 控制 外设(数据库、传感器设备、文件))

2、B/S架构就是浏览器和服务器架构

Browser/Server(浏览器/服务器结构),是随着Internet技术的兴起,是对C/S结构的一种变化或者改进的结构。

用户界面完全通过www浏览器实现,一部分事物逻辑在前端实现,但是主要事务逻辑在服务器端实现。

B/S架构 与 C/S架构对比

知识点5【ubuntu下的boa服务器搭建】

boa-0.94.13-src.tar.gz

1、将boa-0.94.13-src.tar.gz拷贝到ubuntu中 并解压到当前目录

在ubuntu中解压:tar -xvf boa-0.94.13-src.tar.gz

解压成功会生成:boa-0.94.13-src文件夹

cd boa-0.94.13-src

ls查看当前文件夹的内容 如下:

进入src目录

cd src

ls查看目录内容:

2、将来的boa服务器的目录结构分析

创建boa目录:

mkdir ~/share/boa/boa -p

创建log目录

mkdir ~/share/boa/log

创建www以及cgi-bin目录

mkdir ~/share/boa/www/cgi-bin -p

3、将boa.conf服务器的配置文件以及mime.types 拷贝 到/home/edu/share/boa/boa目录中

boa.conf在boa-0.94.13-src目录下:

将boa.conf拷贝到/home/edu/share/boa/boa下

cp boa.conf /home/edu/share/boa/boa

将/etc/mime.types拷贝/home/edu/share/boa/boa下

sudo cp /etc/mime.types /home/edu/share/boa/boa/

4、配置boa服务器在启动的时候 去/home/edu/share/boa/boa下查找配置文件boa.conf

注意上述路径配置在boa-0.94.13-src/src/defines.h中

编辑defines.h文件

5、编译boa服务器的源码

1、./configure 生成Makefile

2、make编译源码

make

如果第一次make出现:make: bison:命令未找到。

解决方法:sudo apt-get install bison

如果第二次make出现:make: flex:命令未找到。

解决方法:sudo apt-get install flex

第三次make:就成功 就会在当前目录下 看到服务器boa可执行文件

3、将当前路径下服务器boa拷贝到 /home/edu/share/boa/boa下:

cp boa /home/edu/share/boa/boa/

6、在log目录下添加error_log access_log两个文件

touch /home/edu/share/boa/log/error_log

touch /home/edu/share/boa/log/access_log

成功如下图

7、在www目录下创建一个index.html网页

通过samba打开路径

编辑网页:代码如下

<html><head><title>NZ2001</title></head><body>NZ2001 good good good!!!!</body></html

8、修改/home/edu/share/boa/boa/boa.conf

cd /home/edu/share/boa/boa/

用notepad++打开:

1、在48、49行将nobody、nogroup改成0

2、在62行将ErrorLog /root/arm-boa/log/error_log改成ErrorLog /home/edu/share/boa/log/error_log

3、在74行将AccessLog /root/arm-boa/log/access_log改成AccessLog /home/edu/share/boa/log/access_log

4、在111行将DocumentRoot /root/arm-boa/www改成DocumentRoot /home/edu/share/boa/www

5、在123行将DirectoryIndex homepage.html改成DirectoryIndex index.html

6、在155行将MimeTypes /etc/mime.types改成MimeTypes /home/edu/share/boa/boa/mime.types

7、在193行将ScriptAlias /cgi-bin/ /root/arm-boa/www/cgi-bin/改成ScriptAlias /cgi-bin/ /home/edu/share/boa/www/cgi-bin/

9、启动boa服务器

cd /home/edu/share/boa/boa

sudo ./boa

ps -A | grep boa 说明boa运行成功

10、测试服务器是否好使

打开windows打开浏览器输入ubuntu的ip

如果觉得《10_libpcap以及libnet》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。