在本地电脑的虚拟机上搭建一个tcp服务器,代码如下
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define BUFFER_SIZE 128
int main(int argc, char *argv[])
{
int listenfd,confd;
int val,ret;
struct sockaddr_in servaddr,cliaddr;
socklen_t peerlen;
char buffer[BUFFER_SIZE] = {0};
if (argc < 3)
{
printf("usage : %s<ip><port>",argv[0]);
exit(-1);
}
if((listenfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
exit(-1);
}
ret = setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(val));
if(ret == -1)
{
perror("setsockopt");
exit(-1);
}
printf("listen1 = %d\n",listenfd);
//set sockaddr_in
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2]));
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
//bind
if(bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
{
perror("bind");
exit(-1);
}
printf("bind successfully");
if (listen(listenfd,10) == -1)
{
perror("listen");
exit(-1);
}
printf("listen the socket");
//accept()
peerlen = sizeof(cliaddr);
while(1)
{
if((confd = accept(listenfd,(struct sockaddr *)&cliaddr,&peerlen)) < 0)
{
perror("accept");
exit(-1);
}
memset(buffer,0,sizeof(buffer));
if(recv(confd, buffer, BUFFER_SIZE,0) == -1)
{
perror("recv");
exit(-1);
}
printf("the receive data is %s\n",buffer);
memset(buffer,0,sizeof(buffer));
strcpy(buffer, "welcome to beijing");
send(confd, buffer, BUFFER_SIZE, 0);
close(confd);
}
close(listenfd);
exit(0);
}
手机上安装一个tcp客户端,连接上服务器的过程分析
手机ip为:192.168.1.15 port:34705
手机ip为:192.168.1.43 port:8653
- tcp的端口过滤:
tcp.port eq 80 // 不管端口是来源的还是目标的都显示
tcp.port == 80
tcp.port eq 2722
tcp.port eq 80 or udp.port eq 80
tcp.dstport == 80 // 只显tcp协议的目标端口80
tcp.srcport == 80 // 只显tcp协议的来源端口80
udp.port eq 15000
过滤端口范围
tcp.port >= 1 and tcp.port <= 80
- 协议过滤
tcp udp arp icmp http smtp ftp dns msnms ip ssl oicq bootp(dhcp) 等等
排除arp包,如!arp 或者 not arp
-
- mac过滤
-
太以网头过滤
-
eth.dst == A0:00:00:04:C5:84 // 过滤目标mac
-
eth.src eq A0:00:00:04:C5:84 // 过滤来源mac
eth.dst==A0:00:00:04:C5:84
eth.dst==A0-00-00-04-C5-84
eth.addr eq A0:00:00:04:C5:84 // 过滤来源MAC和目标MAC都等于A0:00:00:04:C5:84的
less than 小于 < lt
小于等于 le 等于 eq 大于 gt 大于等于 ge 不等 ne
-
- 包长度过滤
-
udp.length == 26 这个长度是指udp本身固定长度8加上udp下面那块数据包之和
tcp.len >= 7 指的是ip数据包(tcp下面那块数据),不包括tcp本身
ip.len == 94 除了以太网头固定长度14,其它都算是ip.len,即从ip本身到最后
frame.len == 119 整个数据包长度,从eth开始到最后
eth —> ip or arp —> tcp or udp —> data
-
- http的模式过滤
http.request.method == “GET”
http.request.method == “POST”
http.request.uri == “/img/logo-edu.gif”
http contains “GET”
http contains “HTTP/1.”
// GET包
http.request.method == “GET” && http contains “Host: “
http.request.method == “GET” && http contains “User-Agent: “
// POST包
http.request.method == “POST” && http contains “Host: “
http.request.method == “POST” && http contains “User-Agent: “
// 响应包
http contains “HTTP/1.1 200 OK” && http contains “Content-Type: “
http contains “HTTP/1.0 200 OK” && http contains “Content-Type: “
一定包含如下Content-Type:
- TCP参数过滤
tcp.flags 显示包含TCP标志的封包。
tcp.flags.syn == 0x02 显示包含TCP SYN标志的封包。
tcp.window_size == 0 && tcp.flags.reset != 1
- DHCP
注意:DHCP协议的检索规则不是dhcp/DHCP, 而是bootp
以寻找伪造DHCP服务器为例,介绍Wireshark的用法。在显示过滤器中加入过滤规则,
显示所有非来自DHCP服务器并且bootp.type==0x02(Offer/Ack/NAK)的信息:
bootp.type==0x02 and not ip.src==192.168.1.1