Linux network debugging and packet capture tool

table of Contents

 

1. Outsourcing tool

1.1 sendip

1.2 tcpreply

2. Packet capture tool

2.1、tcpdump

2.2 tcpflow

3. Speed ​​test tool

4. Encryption tool

4.1 tcpcryptd

5.Linux network programming

5.1、tcp

5.2、udp


1. Outsourcing tool

1.1 sendip

Sendip is a command-line data packet sending tool for Linux platform. Currently (February 2018) the supported protocols are ipv4, ipv6, icmp, tcp, udp, bgp, rip, ntp.

ubuntu installation:

sudo apt-get install sendip

Source code download address:

https://github.com/rickettm/SendIP

 Simple to use:

General options:

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

ipv4 module:

-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:...

tcp module:

-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

udp module:

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

It should be noted that packets are encapsulated in order from left to right, so ip packets must be written before other packets. If checksums are required in the agreement, just press the default ones, saving the pain of calculation. Here are a few examples:

1. Send ICMPv4 message, -p icmp will send ICMP echo request message by default, -v option can print the sent message on the terminal

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


2. Send ICMPv6 messages

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


3. To send IPv4 UDP packets, only need to replace udp with tcp to send TCP

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


4. To send IPv6 UDP packets, the same sending TCP only needs to replace udp with tcp

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

5. Send the content of the test file to the udp port

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
 

The main structure is sendip 网络层 上一层 数据 domainthat domain is the destination host, which can be www.baidu.comor 192.168.1.1the like. If there is any error, the help message will be printed out, and there is a line in it that indicates the cause of the error, don't miss it. As to whether irregular packets can be sent (such as data and message lengths that do not match, checksums and scribbles, etc.), whether they will actually be sent is not tested.

1.2 tcpreply

tcpreplay is a replay tool for pcap packages. It can replay the packages captured with the ethreal and wireshark tools as they are or after arbitrarily modified. It allows you to make any changes to the message (mainly refers to the second layer , Layer 3, Layer 4 message header), specify the speed of replaying the message, etc., so that tcpreplay can be used to reproduce the scene of packet capture to locate bugs, and replay at extremely fast speed to achieve stress testing.

Installation and usage reference:

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

2. Packet capture tool

2.1、tcpdump

tcpdump : tcpdump can completely intercept data packets transmitted on the network to provide analysis. It supports filtering for network layers, protocols, hosts, networks or ports, and provides logical statements such as and, or, not to help you remove useless information.

ubuntu installation method:

sudo apt-get install tcpdump

Source code download address:

http://www.tcpdump.org/

Embedded transplantation reference method:

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

 Use syntax:

In the Linux operating system, you must use the system administrator authority to execute.

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

Parameter description :

  • -a Attempt to convert network and broadcast addresses into names.
  • -c<number of data packets> After receiving the specified number of data packets, stop dumping.
  • -d Convert the compiled data packet encoding into a readable format and dump it to standard output.
  • -dd Convert the compiled data packet encoding into C language format and dump it to standard output.
  • -ddd Convert the compiled packet code into decimal format and dump it to standard output.
  • -e Display the file header of the connection level on each row of dump data.
  • -f displays the Internet address in numbers.
  • -F<Expression file> Specify the file containing the expression.
  • -i<Network interface> Send data packets using the specified network section.
  • -l Use the buffer for standard output columns.
  • -n Does not convert the host's network address into a name.
  • -N Does not list domain names.
  • -O does not optimize packet encoding.
  • -p Do not let the network interface enter promiscuous mode.
  • -q Quick output, only lists a few transmission protocol information.
  • -r<data packet file> Read packet data from the specified file.
  • -s<data packet size> Set the size of each packet.
  • -S lists the TCP association numbers in absolute rather than relative numbers.
  • -t Do not display a time stamp on each row of dumping data.
  • -tt Display an unformatted time stamp on each row of dumping data.
  • -T<data packet type> Force the translation of the specified data packet into the set data packet type.
  • -v displays the instruction execution process in detail.
  • -vv displays the instruction execution process in more detail.
  • -x lists the data packet data in hexadecimal code.
  • -w<data packet file> Write the packet data to the specified file.

Examples of use:

1. tcpdump -D gets a list of network adapters, the following are the results obtained on Ubuntu:

hegaozhi@ubuntu:~$ tcpdump -D
1.ens33 [Up, Running]
2.any (Pseudo-device that captures on all interfaces) [Up, Running]
3.lo [Up, Running, Loopback]
4.bluetooth0 (Bluetooth adapter number 0)
5.nflog (Linux netfilter log (NFLOG) interface)
6.nfqueue (Linux netfilter queue (NFQUEUE) interface)
7.usbmon1 (USB bus number 1)
8.usbmon2 (USB bus number 2)
9.usbmon3 (USB bus number 3)
10.usbmon4 (USB bus number 4)

2. tcpdump -i <the number of the network adapter to be monitored>, for example, to monitor the network card ens33, use tcpdump -i 1. 

hegaozhi@ubuntu:~$ sudo tcpdump -i 1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ens33, link-type EN10MB (Ethernet), capture size 262144 bytes

3. Use the wireless network card ens33 to monitor the TCP protocol on port 443 on the IP address of 172.16.86.111:

sudo tcpdump -i 1 host 172.16.86.111 and tcp port 443

4. Use the wireless network card ens33 to monitor the udp protocol of port 8308 on the IP address of 172.16.86.111:

sudo tcpdump -i 1 host 172.16.86.111 and udp port 8308

5. If you want to display the content of the data packet, you need to use the -X parameter. For example, I want to display the content of the http header of the captured https data packet:

sudo tcpdump -X -i 1 host 172.16.86.111 and tcp port 443

    You can see that the result only shows a part of the https header, not the whole, because tcpdump truncates the displayed data length by default. You can use -s after the data length to set the data display length:

sudo tcpdump -X -s 0 -i 1 host 172.16.86.111 and tcp port 443

In the above example, -s 0 means to automatically set the length so that all data can be displayed.

  6. Use the -w parameter to store the captured data as a .cap file:

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

Use the -r parameter to view the .cap file:

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

7. Capture packets on port 80 of 192.168.1.123 and other ports other than 110 and 25 

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

8. Grab the password of pppoe 

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

9. The background captures packets, the console exit will not affect: 

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

10. Divide and save the file in 100m size, open another file if it exceeds 100m-C 100m 

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

11. Exit after grabbing 10000 packets -c 10000 

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

 

The captured .cap file can be opened directly with ethereal or wireshark.

2.2 tcpflow

Tcpflow is actually a packet capture tool. The difference between tcpflow and tcpdump is that it displays data content in units of flow, while tcpdump displays data in units of packets. To analyze HTTP data, it will be more convenient to use tcpflow.

#Intercept the data between the machine (192.168.31.147) and the host 114.114.114.114
tcpdump -n -i eth0 host 192.168.31.147 and 114.114.114.114 #Intercept
all the data entering the server can use the following format
tcpdump -n -i eth0 dst 192.168.31.147 #The
server has multiple IPs and you can use the parameters
tcpdump -n -i eth0 dst 192.168.31.147 or 192.168.31.157 #Data
packets from this machine
tcpdump -n -i eth0 src 192.168.31.147 or 192.168.31.157

-C: Before writing an original data packet to a save file, please check whether the file is larger than file_size, if so, close the current save file and open a new file. The save file after the first save file will have the name specified with the -w flag, followed by a number, starting at 1 and continuing upward. The unit of file_size is millions of bytes (1,000,000 bytes, not 1,048,576 bytes).

-w: Write the original data packet to the file instead of parsed and printed out. They can use the -r option to print later. If the file is "-", standard output is used.

-W: When used with the -C option, this will limit the number of files created to the specified number and overwrite the files from the beginning, creating a "rotating" buffer. In addition, it will name files with enough leading zeros to support the maximum number of files so that they can be sorted correctly. When used with the -G option, this will limit the number of rotated dump files created and exit with status 0 when the limit is reached. If used with -C, the behavior will result in a loop file for each time slice

 

3. Speed ​​test tool

  The ping command is the most basic tool to test the connectivity of the machine to the destination ip. As shown in the figure below, the ping command without any parameters sends one packet per second by default and returns the result. Press CTRL+C to end, and if you use it The -f parameter can quickly and continuously send icmp data packets. You can use the -f parameter to view the approximate packet loss rate. In the return result of the ping command, you can see how many packets were sent and how many packets were successfully received. The packet loss rate is How much, what is the total duration of ping, etc.

Summary of several commonly used network diagnostic tools for Linux

The format of ping big data packet under Linux;

Syntax: ping [-aAbBdDfhLnOqrRUvV] [-I local network card name or IP address] [-c<number of completions>][-i<interval seconds>][-l<specified number of packets>][-p<settings The content of icmp message data>][-s<data packet size in bytes (B),>][-t<survival value>] [-w specifies the waiting timeout time] [-W timeout time] [host name Or IP address]

 

4. Encryption tool

4.1 tcpcryptd

5.Linux network programming

5.1、tcp

Server server.c code:

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

Client client.c code:

#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)

 Compile:

hegaozhi@ubuntu:~/tcp$ make

 run:

Run the server first:

./server

 Create a new terminal to run the client, where 127.0.0.1 is the ip address of the server:

./client 127.0.0.1

5.2、udp

Client service.cpp code:

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

Client client.cpp code:

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

Content of 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)

run:

Run the server first:

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

Create a new terminal to run the client, and enter hello:

hegaozhi@ubuntu:~/test/socket/udp$ ./client
hello
sends to the server: hello

6. Local area network online IP detection

Scan the LAN with nmap, and then check the arp cache table to know the mac corresponding to the ip in the local area. Nmap is more powerful and can scan mac addresses and ports directly. After performing the scan, you can cat /proc/net/arp to view the arp cache table.

             Perform a ping scan and print out the hosts that responded to the scan:  

$ nmap -sP 192.168.1.0/24  

Only list each host on the specified network, without sending any message to the target host: 

$ nmap -sL 192.168.1.0/24 

To detect the open ports of the target host, you can specify a comma-separated port list (such as -PS 22, 23, 25, 80):  

$ nmap -PS 192.168.1.234  

Use UDP ping to detect the host:

$ nmap -PU 192.168.1.0/24  

The most frequently used scan option (SYN scan, also known as semi-open scan), it does not open a complete TCP connection and executes quickly: 

$ nmap -sS 192.168.1.0/24

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/hgz_gs/article/details/89848536