Herramienta de captura de paquetes y depuración de redes Linux

Tabla de contenido

 

1. Herramienta de subcontratación

1.1 enviarip

1,2 tcpreviamente

2. Herramienta de captura de paquetes

2.1 、 tcpdump

2.2 tcpflow

3. Herramienta de prueba de velocidad

4. Herramienta de cifrado

4.1 tcpcryptd

5.Programación de red Linux

5,1 、 tcp

5,2 、 udp


1. Herramienta de subcontratación

1.1 enviarip

Sendip es una herramienta de envío de paquetes de datos de línea de comandos para la plataforma Linux. Actualmente (febrero de 2018) los protocolos admitidos son ipv4, ipv6, icmp, tcp, udp, bgp, rip, ntp.

instalación de ubuntu:

sudo apt-get install sendip

Dirección de descarga del código fuente:

https://github.com/rickettm/SendIP

 Fácil de usar:

Opciones generales:

-d    要携带的数据。rN随机产生N个字节,0x之后带十六进制,0之后带8进制。
-f    从文件中读取要携带的数据。
-p    加载协议模块,只有加载了才能使用。
-v    打印整个发出的包。

módulo ipv4:

-iv x      版本               Default: 4
-ih x      首部长度       Default: Correct
-iy x      区分服务       Default: 0
-il x      总长度           Default: Correct
----------------------------------------------32bit
-ii x      标识               Default: Random
-ifr x     标志               Default: 0 (options are 0,1,r)
-if x      片偏移           Default: 0
----------------------------------------------32bit
-it x      生存时间       Default: 255
-ip x      协议             Default: 0, or set by underlying protocol
-ic x      首部检验和   Default: Correct
----------------------------------------------32bit
-is x      源地址          Default: 127.0.0.1
----------------------------------------------32bit
-id x      目的地址      Default: Correct
----------------------------------------------32bit
下面全是可选字段(比较少用,不译):

-ifd x IP don't fragment flag (see README)
       Default: 0 (options are 0,1,r)
-ifm x IP more fragments flag (see README)
       Default: 0 (options are 0,1,r)
-ionum x
       IP option as string of hex bytes (length is always correct)
       Default: (no options)
-ioeol IP option: end of list
-ionop IP option: no-op
-iorr x
       IP option: record route. Format: pointer:addr1:addr2:...
-iots x
       IP option: timestamp. Format: pointer:overflow:flag:(ip1:)ts1:(ip2:)ts2:...
-iolsr x
       IP option: loose source route. Format: pointer:addr1:addr2:...
-iosid x
       IP option: stream identifier
-iossr x
       IP option: strict source route. Format: pointer:addr1:addr2:...

módulo tcp:

-ts x  源端口       Default: 0
-td x  目的端口       Default: 0
----------------------------------------------32bit
-tn x  序号       Default: Random
----------------------------------------------32bit
-ta x  确认号       Default: 0
----------------------------------------------32bit
-tt x  数据偏移       Default: Correct
-tr x  保留(ECN、CWR看rfc2481)       Default: 0
-tfu x URG       Default: 0, or 1 if -tu specified (options are 0,1,r)
-tfa x ACK       Default: 0, or 1 if -ta specified (options are 0,1,r)
-tfp x PSH       Default: 0 (options are 0,1,r)
-tfr x RST       Default: 0 (options are 0,1,r)
-tfs x SYN       Default: 1 (options are 0,1,r)
-tff x FIN       Default: 0 (options are 0,1,r)
-tw x  窗口       Default: 65535
----------------------------------------------32bit
-tc x  检验和       Default: Correct
-tu x  紧急指针       Default: 0
----------------------------------------------32bit
下面全是可选字段(比较少用,不译):
-tonum x       TCP option as string of hex bytes (length is always correct)
       Default: (no options)
-toeol TCP option: end of list
-tonop TCP option: no op
-tomss x
       TCP option: maximum segment size
-towscale x
       TCP option: window scale (rfc1323)
-tosackok
       TCP option: allow selective ack (rfc2018)
-tosack x
       TCP option: selective ack (rfc2018), format is l_edge1:r_edge1,l_edge2:r_edge2...
-tots x
       TCP option: timestamp (rfc1323), format is tsval:tsecr

módulo udp:

-us x  源端口    Default: 0
-ud x  目的端口    Default: 0
-ul x 长度    Default: Correct
-uc x  检验和    Default: Correct

Cabe señalar que los paquetes se encapsulan en orden de izquierda a derecha, por lo que los paquetes ip deben escribirse antes que otros paquetes. Si se requieren sumas de verificación en el acuerdo, simplemente presione las predeterminadas, ahorrándose el dolor del cálculo. Aquí están algunos ejemplos:

1. Enviar mensaje ICMPv4, -p icmp enviará un mensaje de solicitud de eco ICMP por defecto, la opción -v puede imprimir el mensaje enviado en el terminal

sendip -v -p ipv4 -es 192.168.2.129 -id 192.168.2.1 -p icmp -d 0xcafecafecafe 192.168.2.1


2. Envía mensajes ICMPv6

enviarip -p ipv6 -6s 2 :: 3 -p icmp -d 0xcafecafecafe 2 :: 1


3. Para enviar paquetes IPv4 UDP, solo necesita reemplazar udp con tcp para enviar TCP

sendip -p ipv4 -es 192.168.2.129 -p udp -d 0xcafe 192.168.2.1


4. Para enviar paquetes IPv6 UDP, el mismo TCP de envío solo necesita reemplazar udp con tcp

enviarip -p ipv6 -6s 2 :: 3 -p udp -d 0xcafe 2 :: 1

5. Envíe el contenido del archivo de prueba al puerto udp

sendip -v -p ipv4 -id 14.215.177.39 -p udp -f test www.baidu.com

sendip -p ipv4 -is 192.168.1.2 -id 192.168.1.1 -p icmp -d 0x89ABCDEF www.google.com
 

La estructura principal es sendip 网络层 上一层 数据 domainque el dominio es el host de destino, que puede ser www.baidu.como 192.168.1.1similar. Si hay algún error, se imprimirá el mensaje de ayuda y habrá una línea que indica la causa del error. En cuanto a si se pueden enviar paquetes irregulares (como datos y longitudes de mensajes que no coinciden, sumas de verificación y garabatos, etc.), no se prueba si realmente se enviarán.

1,2 tcpreviamente

tcpreplay es una herramienta de reproducción para paquetes pcap. Puede reproducir los paquetes capturados con las herramientas ethreal y wirehark tal como están o después de modificarlos arbitrariamente. Le permite realizar cambios en el mensaje (principalmente se refiere a la segunda capa, Capa 3, Encabezado del mensaje de capa 4), especifique la velocidad de reproducción del mensaje, etc., de modo que tcpreplay se pueda utilizar para reproducir la escena de captura de paquetes para localizar errores y reproducir a una velocidad extremadamente rápida para realizar pruebas de estrés.

Referencia de instalación y uso:

https://blog.csdn.net/zhaomax/article/details/82773381

2. Herramienta de captura de paquetes

2.1 、 tcpdump

tcpdump : tcpdump puede interceptar completamente los paquetes de datos transmitidos en la red para proporcionar análisis. Admite el filtrado de capas de red, protocolos, hosts, redes o puertos, y proporciona oraciones lógicas como y, o, no para ayudarlo a eliminar información inútil.

método de instalación de ubuntu:

sudo apt-get install tcpdump

Dirección de descarga del código fuente:

http://www.tcpdump.org/

Método de referencia de trasplante integrado:

https://www.cnblogs.com/baiduboy/p/6243450.html

 Utilice la sintaxis:

En el sistema operativo Linux, debe utilizar la autoridad de administrador del sistema para ejecutar.

tcpdump [-adeflnNOpqStvx][-c<数据包数目>][-dd][-ddd][-F<表达文件>][-i<网络界面>][-r<数据包文件>][-s<数据包大小>][-tt][-T<数据包类型>][-vv][-w<数据包文件>][输出数据栏位]

Descripción de parámetros :

  • -a Intente convertir las direcciones de red y difusión en nombres.
  • -c <número de paquetes de datos> Después de recibir el número especificado de paquetes de datos, detenga el volcado.
  • -d Convierte la codificación del paquete de datos compilado en un formato legible y lo vuelca a la salida estándar.
  • -dd Convierte la codificación del paquete de datos compilado en formato de lenguaje C y lo vuelca a la salida estándar.
  • -ddd Convierte el código del paquete compilado a formato decimal y lo vuelca a la salida estándar.
  • -e Muestra el encabezado del archivo del nivel de conexión en cada fila de datos de volcado.
  • -f muestra la dirección de Internet en números.
  • -F <Archivo de expresión> Especifica el archivo que contiene la expresión.
  • -i <Interfaz de red> Envía paquetes de datos utilizando la sección de red especificada.
  • -l Usa el búfer para columnas de salida estándar.
  • -n No convierte la dirección de red del host en un nombre.
  • -N No incluye nombres de dominio.
  • -O no optimiza la codificación de paquetes.
  • -p No permita que la interfaz de red entre en modo promiscuo.
  • -q Salida rápida, solo enumera algunos datos del protocolo de transmisión.
  • -r <archivo de paquete de datos> Lee los datos del paquete del archivo especificado.
  • -s <tamaño del paquete de datos> Establece el tamaño de cada paquete.
  • -S enumera los números de asociación de TCP en números absolutos en lugar de números relativos.
  • -t No muestra una marca de tiempo en cada fila de datos de volcado.
  • -tt Muestra una marca de tiempo sin formato en cada fila de datos de volcado.
  • -T <tipo de paquete de datos> Fuerza la traducción del paquete de datos especificado en el tipo de paquete de datos establecido.
  • -v muestra el proceso de ejecución de instrucciones en detalle.
  • -vv muestra el proceso de ejecución de instrucciones con más detalle.
  • -x enumera los datos del paquete de datos en código hexadecimal.
  • -w <archivo de paquete de datos> Escribe los datos del paquete en el archivo especificado.

Ejemplos de uso:

1. tcpdump -D obtiene una lista de adaptadores de red, los siguientes son los resultados obtenidos en Ubuntu:

hegaozhi @ ubuntu: ~ $ tcpdump -D
1.ens33 [Up, Running]
2.any (Pseudo-dispositivo que captura en todas las interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.bluetooth0 (Bluetooth número de adaptador 0)
5.nflog (interfaz Linux netfilter log (NFLOG))
6.nfqueue ( interfaz Linux netfilter queue (NFQUEUE))
7.usbmon1 (bus USB número 1)
8.usbmon2 (bus USB número 2)
9.usbmon3 ( Bus USB número 3)
10.usbmon4 (bus USB número 4)

2. tcpdump -i <el número del adaptador de red a monitorear>, por ejemplo, para monitorear la tarjeta de red ens33, use tcpdump -i 1. 

hegaozhi @ ubuntu: ~ $ sudo tcpdump -i 1
tcpdump: salida detallada suprimida, use -v o -vv para decodificación de protocolo completo
escuchando en ens33, tipo de enlace EN10MB (Ethernet), tamaño de captura 262144 bytes

3. Utilice la tarjeta de red inalámbrica ens33 para monitorear el protocolo TCP en el puerto 443 en la dirección IP 172.16.86.111:

sudo tcpdump -i 1 host 172.16.86.111 y puerto tcp 443

4. Utilice la tarjeta de red inalámbrica ens33 para monitorear el protocolo udp del puerto 8308 en la dirección IP 172.16.86.111:

sudo tcpdump -i 1 host 172.16.86.111 y puerto udp 8308

5. Si desea mostrar el contenido del paquete de datos, debe usar el parámetro -X. Por ejemplo, quiero mostrar el contenido del encabezado http del paquete de datos https capturado:

sudo tcpdump -X -i 1 host 172.16.86.111 y puerto tcp 443

    Puede ver que el resultado solo muestra una parte del encabezado https, no el todo, porque tcpdump trunca la longitud de los datos mostrados de forma predeterminada, puede usar -s después de la longitud de los datos para establecer la longitud de visualización de los datos:

sudo tcpdump -X -s 0 -i 1 host 172.16.86.111 y puerto tcp 443

En el ejemplo anterior, -s 0 significa establecer automáticamente la longitud para que se puedan mostrar todos los datos.

  6. Utilice el parámetro -w para almacenar los datos capturados como un archivo .cap:

sudo tcpdump -X -s 0 -i 1 -w tcplog.cap host 192.9.200.59 y puerto tcp 8000

Utilice el parámetro -r para ver el archivo .cap:

sudo tcpdump -X -s 0 -i 1 -r tcplog.cap host 172.16.86.111 y tcp puerto 443

7. Capture paquetes en el puerto 80 de 192.168.1.123 y otros puertos que no sean 110 y 25 

sudo tcpdump -i eth1 host 192.168.1.123 y! puerto 80 y! puerto 25 y! puerto 110 -w /tmp/xxx.cap

8. Toma la contraseña de pppoe 

sudo tcpdump -i eth1 pppoes -w /tmp/xxx.cap

9. El fondo captura paquetes, la salida de la consola no afectará: 

sudo nohup tcpdump -i eth1 puerto 110 -w /tmp/xxx.cap & 

10. Divida y guarde el archivo en un tamaño de 100 m, abra otro archivo de más de 100 m-C 100 m 

sudo tcpdump -i eth1 pppoes -w /tmp/xxx.cap -C 100m 

11. Salir después de tomar 10000 paquetes -c 10000 

sudo tcpdump -i eth1 pppoes -w /tmp/xxx.cap -c 10000 

 

El archivo .cap capturado se puede abrir directamente con ethereal o wirehark.

2.2 tcpflow

Tcpflow es en realidad una herramienta de captura de paquetes. La diferencia entre tcpflow y tcpdump es que muestra el contenido de datos en unidades de flujo, mientras que tcpdump muestra los datos en unidades de paquetes. Para analizar datos HTTP, será más conveniente usar tcpflow.

#Intercepte los datos entre la máquina (192.168.31.147) y el host 114.114.114.114
tcpdump -n -i eth0 host 192.168.31.147 y 114.114.114.114 #Intercepte
todos los datos que ingresan al servidor puede usar el siguiente formato
tcpdump -n -i eth0 dst 192.168.31.147 #El
servidor tiene varias IP y puede utilizar los parámetros
tcpdump -n -i eth0 dst 192.168.31.147 o 192.168.31.157 #Paquetes
de datos de esta máquina
tcpdump -n -i eth0 src 192.168.31.147 o 192.168. 31.157

-C: Antes de escribir un paquete de datos original en un archivo guardado, verifique si el archivo es más grande que file_size, si es así, cierre el archivo guardado actual y abra un nuevo archivo. El archivo guardado después del primer archivo guardado tendrá el nombre especificado con la bandera -w, seguido de un número, comenzando en 1 y continuando hacia arriba. La unidad de file_size es millones de bytes (1,000,000 bytes, no 1,048,576 bytes).

-w: escribe el paquete de datos original en el archivo en lugar de analizarlo e imprimirlo. Pueden usar la opción -r para imprimir más tarde. Si el archivo es "-", se utiliza la salida estándar.

-W: Cuando se usa con la opción -C, esto limitará el número de archivos creados al número especificado y sobrescribirá los archivos desde el principio, creando un búfer "rotativo". Además, nombrará los archivos con suficientes ceros a la izquierda para admitir el número máximo de archivos para que puedan ordenarse correctamente. Cuando se usa con la opción -G, esto limitará el número de archivos de volcado rotados creados y saldrá con el estado 0 cuando se alcance el límite. Si se usa con -C, el comportamiento dará como resultado un archivo de bucle para cada segmento de tiempo

 

3. Herramienta de prueba de velocidad

  El comando ping es la herramienta más básica para probar la conectividad de la máquina a la ip de destino. Como se muestra en la figura siguiente, el comando ping sin ningún parámetro envía un paquete de datos por segundo por defecto y devuelve el resultado. Presione CTRL + C al final, y si se usa El parámetro -f puede enviar paquetes de datos icmp de forma rápida y continua. Puede usar el parámetro -f para ver la tasa aproximada de pérdida de paquetes. En el resultado de retorno del comando ping, puede ver cuántos paquetes fueron enviados y cuántos paquetes se recibieron correctamente. La tasa de pérdida de paquetes es cuánto, cuál es la duración total del ping, etc.

Resumen de varias herramientas de diagnóstico de red de uso común para Linux

El formato del paquete de big data de ping en Linux;

Sintaxis: ping [-aAbBdDfhLnOqrRUvV] [-I nombre de la tarjeta de red local o dirección IP] [-c <número de finalizaciones>] [- i <intervalo de segundos>] [- l <número especificado de paquetes>] [- p <configuración El contenido de los datos del mensaje icmp>] [- s <tamaño del paquete de datos en bytes (B),>] [- t <valor de supervivencia>] [-w especifica el tiempo de espera] [-W tiempo de espera] [nombre de host O Dirección IP]

 

4. Herramienta de cifrado

4.1 tcpcryptd

5.Programación de red Linux

5,1 、 tcp

Servidor server.c código:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<termios.h>
#include<sys/types.h>   
#include<sys/stat.h>    
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<signal.h>
 
#define MAXLINE 256
#define PORT	6666
int listenfd;
int connfd;
pthread_t read_id, write_id;
 
/*
linux ctrl + C 会产生 SIGINT信号
接收到SIGINT 信号进入该函数
*/
void stop(int signo)
{
	printf("stop\n");
	close(connfd);	
	close(listenfd);
	 _exit(0);
}
 
/*
当客户端断开连接的时候,
在服务端socket send进程可以收到收到信号SIGPIPE,
收到SIGPIPE信号进入该函数结束创建的线程。
*/
void signal_pipe(int signo)
{
	pthread_kill(read_id,SIGQUIT);//向read线程发送SIGQUIT
	pthread_join(read_id,NULL);	  //阻塞线程运行,直到read 线程退出。
	
	close(connfd);                //关闭连接
	printf("read pthread out \n");
	
	pthread_exit(0);              //结束write 线程
}
 
/*
read 线程接收到SIGQUIT信号,
执行线程退出操作
*/
void pthread_out(int signo)
{
	pthread_exit(0);
}
 
/*
read 线程执行函数
*/
void* read_func(void* arg)
{
	char readbuff[MAXLINE];
	int n = 0;
	int fd;
 
	fd = *(int*)arg;    /*main 主进程传递过来的连接文件描述符*/
	memset(&readbuff,0,sizeof(readbuff));
 
	signal(SIGQUIT,pthread_out); /* 注册SIGQUIT 信号*/ 
	while(1)
	{
    	n = recv(fd, readbuff, MAXLINE, 0);  /*recv 在这里是阻塞运行*/
		if(n > 0)
		{
			printf("server recv data: %s \n",readbuff);
		}
	};
}
/*
write 线程执行函数
*/
void* write_func(void* arg)
{
	char writebuff[MAXLINE];
	char* write = "I am server";
	unsigned char i = 0;
	int num = 0;
	int fd;
 
	fd = *(int*)arg;
	memset(&writebuff,0,sizeof(writebuff));
	
	signal(SIGPIPE,signal_pipe); /* 注册 SIGPIPE信号 */
	while(1)
	{
		sleep(1);
		send(fd,write,strlen(write)+1,0);/*向客户端发送数据*/
	}
}
 
int main(int argc, char** argv)
{
	char buff[MAXLINE];
	int num;
	int addrlen;
	struct sockaddr_in server_addr;  /*服务器地址结构*/
	struct sockaddr_in client_addr;  /*客户端地址结构*/
 
	if((listenfd = socket(AF_INET,SOCK_STREAM,0)) == -1)/*建立一个流式套接字*/
	{
		printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
		exit(0);
	}
	
	/*设置服务端地址*/
	addrlen = sizeof(struct sockaddr_in);
	memset(&server_addr, 0, addrlen);
	server_addr.sin_family = AF_INET;    /*AF_INET表示 IPv4 Intern 协议*/
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /*INADDR_ANY 可以监听任意IP */
	server_addr.sin_port = htons(PORT); /*设置端口*/
    
	/*绑定地址结构到套接字描述符*/
	if( bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
	{
		printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
		exit(0);
	}
 
	/*设置监听队列,这里设置为1,表示只能同时处理一个客户端的连接*/
	if( listen(listenfd, 1) == -1)
	{
		printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
		exit(0);
	}
	
	signal(SIGINT,stop); /*注册SIGINT 信号*/
	while(1)
	{	
		printf("wait client accpt \n");
		if( (connfd = accept(listenfd, (struct sockaddr*)&client_addr, &addrlen)) == -1)/*接收客户端的连接,这里会阻塞,直到有客户端连接*/
		{
			printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
			continue;
		}
	
		if(pthread_create(&read_id,NULL,read_func,&connfd))/*创建 read 线程*/
		{
			printf("pthread_create read_func err\n");
		}
 
		if(pthread_create(&write_id,NULL,write_func,&connfd))/*创建 write 线程*/
		{
			printf("pthread_create write_func err\n");
		}
		
		pthread_join(write_id,NULL); /*阻塞,直到write进程退出后才进行新的客户端连接*/
		printf("write pthread out \n");
	}
}

Código cliente client.c:

#include<stdio.h>       
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<termios.h>
#include<sys/types.h>   
#include<sys/stat.h>    
#include<fcntl.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<signal.h>
 
#define MAXLINE 256
#define PORT    6666
int fd;
/*
linux ctrl + C 会产生 SIGINT信号
接收到SIGINT 信号进入该函数
*/
void stop(int signo)
{
    printf("client stop\n");
	close(fd);  
	_exit(0);
}
 
/*客户端处理函数*/
void client_process(void)
{
	char readbuff[MAXLINE];
	char writebuff[MAXLINE];
	char * write = "I am client";
	int num = 0;
	
	while(1)
	{
		num = recv(fd,readbuff,MAXLINE,0);/*接收服务端的数据,recv在这里如果没有数据会阻塞*/
		if(num > 0)
		{
			printf("client read data : %s \n",readbuff);
			send(fd, write, strlen(write)+1, 0); /*接收到数据后再向服务端发送一个字符串*/
		}
		else if(num == 0)/*recv返回值为0 的时候表示服务端已经断开了连接*/
		{
			stop(1); /*执行退出操作*/
		}
	}
}
 
int main(int argc, char** argv)
{
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int ret;
 
	fd = socket(AF_INET,SOCK_STREAM,0);/*建立流式套接字*/
	if(fd < 0)
	{
		printf("clinet socket err \n");
	}
 
	/*设置服务端地址*/
	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family = AF_INET; 				/*AF_INET表示 IPv4 Intern 协议*/
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);/*INADDR_ANY 可以监听任意IP */
	server_addr.sin_port = htons(PORT);				/*设置端口*/
 
	inet_pton(AF_INET,argv[1],&server_addr.sin_addr);/*将用户输入的字符串类型的IP地址转为整型*/
	connect(fd,(struct sockaddr*)&server_addr,sizeof(server_addr));/*连接服务器*/
	
	signal(SIGINT,stop);	/*注册SIGINT信号*/
	client_process();		/*进入处理函数*/
	
	close(fd);/*关闭文件*/
	return 0;
}

Makefile:

CC      = gcc
CPP     = g++
RM      = rm -rf

## debug flag
DBG_ENABLE   = 1

## source file path
SRC_PATH   := .

## get all source files
SRCS         += $(wildcard $(SRC_PATH)/*.c)

## target exec file name
TARGET     := $(SRCS:.c=)

## all .o based on all .c
OBJS        := $(SRCS:.c=.o)


## need libs, add at here
LIBS := pthread

## used headers  file path
INCLUDE_PATH := .

## used include librarys file path
LIBRARY_PATH := /lib

## debug for debug info, when use gdb to debug
ifeq (1, ${DBG_ENABLE}) 
	CFLAGS += -D_DEBUG -O0 -g -DDEBUG=1
endif

## get all include path
CFLAGS  += $(foreach dir, $(INCLUDE_PATH), -I$(dir))

## get all library path
LDFLAGS += $(foreach lib, $(LIBRARY_PATH), -L$(lib))

## get all librarys
LDFLAGS += $(foreach lib, $(LIBS), -l$(lib))


all: clean build $(TARGET)

build:
	gcc client.c -o client -lpthread
	gcc server.c -o server -lpthread

clean:
	$(RM) $(OBJS) $(TARGET)

 Compilar:

hegaozhi @ ubuntu: ~ / tcp $ make

 correr:

Ejecute el servidor primero:

./servidor

 Cree una nueva terminal para ejecutar el cliente, donde 127.0.0.1 es la dirección IP del servidor:

./client 127.0.0.1

5,2 、 udp

Cliente service.cpp código:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<string.h>
 
#define MYPORT 8308
 
 
#define ERR_EXIT(m) \
    do { \
    perror(m); \
    exit(EXIT_FAILURE); \
    } while (0)
 
void echo_ser(int sock)
{
    char recvbuf[1024] = {0};
    struct sockaddr_in peeraddr;
    socklen_t peerlen;
    int n;
    
    while (1)
    {
        
        peerlen = sizeof(peeraddr);
        memset(recvbuf, 0, sizeof(recvbuf));
        n = recvfrom(sock, recvbuf, sizeof(recvbuf), 0,
                     (struct sockaddr *)&peeraddr, &peerlen);
        if (n <= 0)
        {
            
            if (errno == EINTR)
                continue;
            
            ERR_EXIT("recvfrom error");
        }
        else if(n > 0)
        {
            printf("接收到的数据:%s\n",recvbuf);
            sendto(sock, recvbuf, n, 0,
                   (struct sockaddr *)&peeraddr, peerlen);
            printf("回送的数据:%s\n",recvbuf);
        }
    }
    close(sock);
}
 
int main(void)
{
    int sock;
    if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
        ERR_EXIT("socket error");
    
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(MYPORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    printf("监听%d端口\n",MYPORT);
    if (bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
        ERR_EXIT("bind error");
    
    echo_ser(sock);
    
    return 0;
}

Cliente código client.cpp:

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
 
#define MYPORT 8308
char* SERVERIP = "127.0.0.1";
 
#define ERR_EXIT(m) \
    do \
{ \
    perror(m); \
    exit(EXIT_FAILURE); \
    } while(0)
 
void echo_cli(int sock)
{
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(MYPORT);
    //servaddr.sin_addr.s_addr = inet_addr(SERVERIP);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    
    int ret;
    char sendbuf[1024] = {0};
    char recvbuf[1024] = {0};
    while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
    {
        
        printf("向服务器发送:%s\n",sendbuf);
        sendto(sock, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
        
        ret = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
        if (ret == -1)
        {
            if (errno == EINTR)
                continue;
            ERR_EXIT("recvfrom");
        }
        printf("从服务器接收:%s\n",recvbuf);
        
        memset(sendbuf, 0, sizeof(sendbuf));
        memset(recvbuf, 0, sizeof(recvbuf));
    }
    
    close(sock);
    
    
}
 
int main(void)
{
    int sock;
    if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
        ERR_EXIT("socket");
    
    echo_cli(sock);
    
    return 0;
}

Contenido de Makefile:

CC      = gcc
CPP     = g++
RM      = rm -rf

## debug flag
DBG_ENABLE   = 1

## source file path
SRC_PATH   := .

## get all source files
SRCS         += $(wildcard $(SRC_PATH)/*.cpp)

## target exec file name
TARGET     := $(SRCS:.cpp=)

## all .o based on all .cpp
OBJS        := $(SRCS:.cpp=.o)


## need libs, add at here
LIBS := pthread

## used headers  file path
INCLUDE_PATH := .

## used include librarys file path
LIBRARY_PATH := /lib

## debug for debug info, when use gdb to debug
ifeq (1, ${DBG_ENABLE}) 
	CFLAGS += -D_DEBUG -O0 -g -DDEBUG=1
endif

## get all include path
CFLAGS  += $(foreach dir, $(INCLUDE_PATH), -I$(dir))

## get all library path
LDFLAGS += $(foreach lib, $(LIBRARY_PATH), -L$(lib))

## get all librarys
LDFLAGS += $(foreach lib, $(LIBS), -l$(lib))


all: clean build $(TARGET)

build:
	g++ client.cpp -o client -lpthread
	g++ service.cpp -o service -lpthread

clean:
	$(RM) $(OBJS) $(TARGET)

correr:

Ejecute el servidor primero:

hegaozhi @ ubuntu: ~ / test / socket / udp $ ./service
monitor port 2368
Velodyne socket fd es 3

Cree una nueva terminal para ejecutar el cliente e ingrese hola:

hegaozhi @ ubuntu: ~ / test / socket / udp $ ./client
hello
envía al servidor: hello

6. Detección de IP en línea de la red de área local

Escanee la LAN con nmap y luego verifique la tabla de caché arp para conocer el mac correspondiente a la ip en el área local. Nmap es más potente y puede escanear direcciones mac y puertos directamente. Después de realizar el escaneo, puede cat / proc / net / arp para ver la tabla de caché arp.

             Realice un escaneo de ping e imprima los hosts que respondieron al escaneo:  

$ nmap -sP 192.168.1.0/24  

Solo enumere cada host en la red especificada, sin enviar ningún mensaje al host de destino: 

$ nmap -sL 192.168.1.0/24 

Para detectar los puertos abiertos del host de destino, puede especificar una lista de puertos separados por comas (como -PS 22, 23, 25, 80):  

$ nmap -PS 192.168.1.234  

Utilice ping UDP para detectar el host:

$ nmap -PU 192.168.1.0/24  

La opción de escaneo más utilizada (escaneo SYN, también conocido como escaneo semiabierto), no abre una conexión TCP completa y se ejecuta rápidamente: 

$ nmap -sS 192.168.1.0/24

 

 

 

 

 

 

 

 

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/hgz_gs/article/details/89848536
Recomendado
Clasificación