10_libpcap and libnet

Knowledge point 1 [Feiqiu deception]

1. Double-click to run Windows installation Feiqiu

2. Install Feiqiu on ubuntu sudo apt-get install iptux

ubuntu runs Feiqiu: iptux&

3. Feiqiu format:

version: package number: username: hostname: command word: additional message

Feiqiu’s port is fixed at 2425

1 means online, 32 means ordinary messages.

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 udphdr
void my_sendto(int sockfd, char *out, unsigned char *msg, int msg_len);
typedef struct
{
	u_int32_t saddr;//源IP
	u_int32_t daddr;//目的IP
	u_int8_t flag;//标记(0)
	u_int8_t type;//udp协议 17
	u_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_mac
	unsigned char dst_ip[4]={192,168,0,110};//win_ip
	unsigned 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=20B
	ip_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 6
	ip_hdr->check = htons(0);//首部校验???? 后续校验
	memcpy(&ip_hdr->saddr, src_ip, 4);//源IP
	memcpy(&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);//源IP
	memcpy(&wei_hdr->daddr, dst_ip, 4);//目的IP
	wei_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));
}

Knowledge point 2 [libpcap] accepts raw socket data

1. The main function of Libpcap

The main functions of Libpcap are as follows:

1. Capture various data packets

For example: network traffic statistics

2. Filter network data packets

For example: filter out some local data, similar to a firewall

3. Analyze network data packets

For example: analyzing network protocols, collecting data

4. Store network data packets

Examples: Save captured data for future analysis

2. Installation of Libpcap

sudo apt-get install libpcap-dev

Required header files:

#include <pcap.h>

When compiling -lpcap

3. libpcap development example

Basic steps for developing applications using the libpcap function library:

1. Open the network device

2. Set filtering rules (optional)

3. Capture data

4. Turn off network equipment

Common functions for capturing network packets

1. pcap_lookupdev() (optional) View device name

2. pcap_open_live() opens the device

3. pcap_lookupnet() (optional) Obtained device IP

4. pcap_compile( ), pcap_setfilter( ) (optional) Set filtering rules

5. pcap_next (call once to capture one message), pcap_loop (call once to capture messages continuously) to capture data

6、pcap_close( )

4. Open the device and obtain the handle of the device

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. Close the handle

void pcap_close(pcap_t *p)

Function:

Close Libpcap operation and destroy corresponding resources

parameter

   p: Libpcap handle that needs to be closed

return value:

none

For example

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

 struct pcap_pkthdr structure information: record the time of receiving data and the length of the message

 Case:

#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;
}

operation result:

7. Cyclically receive network data pcap_loop

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

How to define callback function: 

Parameter 1: argument stores the user user data passed by pcap_loop

Parameter 2: packet_heaher stores the time and length of the received message

Parameter 3: Network frame data received by packet_content

Case:

#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;
}

 operation result:

8. Set filtering rules and use the following two functions together.

pcap_compile: Convert user-identified rules into pcap-identified rules

pcap_setfilter: Set the rules recognized by pcap to the handle of pcap end data

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过滤规则

 Filter rules:

 

 Case:

#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;
}

 

Knowledge point 3 [libnet sends raw socket data]

Professional development toolkit for constructing and sending network packets

It is a high-level API function library that allows developers to construct and send network data packets themselves.

Header file: include

Compiled by adding: -lnet

Libnet installation

Libnet development process

Basic steps for developing applications using the libnet function library:

1. Data packet memory initialization

2. Construct a data package

3. Send data

4. Release resources

1. Memory management related functions

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. Release resources

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

3. Construct udp message 

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:负载,可设置为NULL
    payload_s:负载长度,或为0
    l: libnet句柄
    ptag:协议标记(其值为0创建一个新的协议数据,不为0,修改由ptag表示的协议数据)

 4. Construct an IPv4 data packet

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:负载,可设置为NULL
    payload_s:负载长度,或为0
    l: libnet句柄
    ptag:协议标记
 
返回值:
    成功返回协议标记;失败返回-1

5. Construct an Ethernet data packet

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:目的mac
    src:源mac
    type:上层协议类型
    payload:负载,即附带的数据
    payload_s:负载长度
    l:libnet句柄
    ptag:协议标记
 
返回值:
    成功返回协议标记;失败返回-1

6. Send data to the network

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

Comprehensive case: sending udp data

#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;
}

Knowledge point 4 [BS development overview] Browser and server development

HTML: Hypertext Markup Language for static display of web pages

CSS: Cascading Style Sheets render web pages

XML: refers to extensible markup language to transmit web pages

Javascript: Script language and web page interaction (partially refresh the web page)

AJAX: Technology based on Javascript language (interacting between web pages and servers)

CGI: Common Gateway Interface (the server uses CGI to control peripherals (databases, sensor devices, files))

2. B/S architecture is the browser and server architecture

Browser/Server (browser/server structure) is a change or improvement to the C/S structure with the rise of Internet technology.

The user interface is completely implemented through the www browser. Some transaction logic is implemented on the front end, but the main transaction logic is implemented on the server side.

Comparison between B/S architecture and C/S architecture

angle

C/S

B/S

Hardware environment

private network

Wan

security requirements

Targeting a relatively fixed user group

Strong information security control capabilities

Targeting an agnostic user group

Relatively weak control over security

Program architecture

Pay more attention to process

System running speed can be less considered

Consideration should be given to security and access speed

B/S structure program architecture is the development trend

software reuse

Difference

good

system maintenance

Difficult to upgrade

Low cost and easy to upgrade

solving issues

concentrated

dispersion

user interface

Closely related to the operating system

Cross-platform, browser-dependent

Information Flow

Low interactivity

Interaction intensive

Knowledge point 5 [Building boa server under ubuntu]

boa-0.94.13-src.tar.gz

1. Copy boa-0.94.13-src.tar.gz to ubuntu and extract it to the current directory

Unzip in ubuntu: tar -xvf boa-0.94.13-src.tar.gz

Successful decompression will generate: boa-0.94.13-src folder

cd boa-0.94.13-src

 ls displays the contents of the current folder as follows:

Enter the src directory

cd src

 ls to view directory contents:

 2. Analysis of the directory structure of the future boa server

Create boa directory:

mkdir ~/share/boa/boa -p

Create log directory

mkdir ~/share/boa/log

Create www and cgi-bin directories

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

3. Copy the boa.conf server configuration file and mime.types to the /home/edu/share/boa/boa directory

boa.conf is in the boa-0.94.13-src directory:

Copy boa.conf to /home/edu/share/boa/boa

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

Copy /etc/mime.types to /home/edu/share/boa/boa

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

4. Configure the boa server to search for the configuration file boa.conf under /home/edu/share/boa/boa when starting up.

Note that the above path is configured in boa-0.94.13-src/src/defines.h

Edit the defines.h file 

5. Compile the source code of boa server

1, ./configure generate Makefile

2. Make compiles the source code

make

If the first make occurs: make: bison: command not found.

Solution: sudo apt-get install bison

If the second make occurs: make: flex: command not found.

Solution: sudo apt-get install flex

The third make: If successful, you will see the server boa executable file in the current directory.

3. Copy the server boa under the current path to /home/edu/share/boa/boa:

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

6. Add two files error_log access_log in the log directory.

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

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

Success is as shown below

7. Create an index.html web page in the www directory

Open path via samba

 Edit web page: The code is as follows

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

8. Modify /home/edu/share/boa/boa/boa.conf

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

 

 Open with notepad++:

 1. Change nobody and nogroup to 0 in lines 48 and 49.

 2. Change ErrorLog /root/arm-boa/log/error_log to ErrorLog /home/edu/share/boa/log/error_log on line 62

 3. Change AccessLog /root/arm-boa/log/access_log to AccessLog /home/edu/share/boa/log/access_log on line 74

 4. In line 111, change DocumentRoot /root/arm-boa/www to DocumentRoot /home/edu/share/boa/www

 5. Change DirectoryIndex homepage.html to DirectoryIndex index.html on line 123.

6. Change MimeTypes /etc/mime.types to MimeTypes /home/edu/share/boa/boa/mime.types on line 155 

 7. Change ScriptAlias ​​/cgi-bin/ /root/arm-boa/www/cgi-bin/ on line 193 to ScriptAlias ​​/cgi-bin/ /home/edu/share/boa/www/cgi-bin/

9. Start boa server 

cd /home/edu/share/boa/boa

sudo ./boa

ps -A | grep boa indicates that boa runs successfully

10. Test whether the server works well

Open windows, open the browser and enter the ip of ubuntu

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/buhuidage/article/details/127956018
10