PCAP - 我没有捕获正确的 TCP 端口号
PCAP - I'm not capturing the right TCP port number
我在使用 Windows 10.
的虚拟机上使用 Ubuntu 16.04.2 LTS
我正在尝试捕获 1-100 范围内的端口。但它并没有这样做,而且它似乎提供了不正确的端口号。例如,当我尝试使用 telnet 命令连接到另一个虚拟机时,我发现目标端口为 23;但是,我得到了一个完全不同的端口号。我还检查了 wireshark,但目标端口号和源端口号不匹配。
这是我尝试 telnet 到 10.0.2.5
时得到的屏幕截图:
这是我的代码:
#include <pcap.h>
#include <stdio.h>
#include <arpa/inet.h>
//Ethernet addresses are 6 bytes
#define ETHER_ADDR_LEN 6
//ethernet header
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
//ip header
struct ipheader {
unsigned char iph_ihl:4, //IP header length
iph_ver:4; //IP version
unsigned char iph_tos; //Type of service
unsigned short int iph_len; //IP Packet length (data + header)
unsigned short int iph_ident; //Identification
unsigned short int iph_flag: 3, //Fragmenation flags
iph_offset:13; //Flags offset
unsigned char iph_ttl; //Time to live
unsigned char iph_protocol; //Protocol type
unsigned short int iph_chksum; //IP datagram checksum
struct in_addr iph_sourceip; //Source IP address
struct in_addr iph_destip; //Destination IP address
};
//tcp header
typedef u_int tcp_seq;
struct sniff_tcp {
u_short th_sport;/* source port */
u_short th_dport;/* destination port */
tcp_seq th_seq;/* sequence number */
tcp_seq th_ack;/* acknowledgement number */
u_char th_offx2;/* data offset, rsvd */
#define TH_OFF(th)(((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win;/* window */
u_short th_sum;/* checksum */
u_short th_urp;/* urgent pointer */
};
void got_packet(u_char *args, const struct pcap_pkthdr * header,
const u_char * packet)
{
struct sniff_ethernet *eth = (struct sniff_ethernet *)packet;
if(ntohs(eth->ether_type)== 0x0800){ // 0x0800 is IP type
struct ipheader *ip = (struct ipheader *) (packet + sizeof(struct sniff_ethernet));
printf(" From: %s\n", inet_ntoa(ip->iph_sourceip));
printf(" To: %s\n", inet_ntoa(ip->iph_destip));
int ip_header_len = ip->iph_ihl * 4;
struct sniff_tcp *tcp = (struct sniff_tcp*) (packet + sizeof(struct sniff_ethernet) + ip_header_len);
printf("tcp source port: %hu\n",tcp->th_sport);
printf("tcp destination port: %hu\n", tcp->th_dport);
}
}
int main(int argc, char* argv[])
{
char* dev = argv[1];
printf("Device: %s\n", dev);
//session handle
pcap_t *handle;
//error string
char errbuf[PCAP_ERRBUF_SIZE];
//the compiled filter expression
struct bpf_program fp;
char filter_exp[] = "tcp and portrange 10-100";
//the ip of our sniffing device
bpf_u_int32 net;
// open pcap session
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
//Compile filter_exp into BPF pseudo-code
pcap_compile(handle, &fp, filter_exp, 0, net);
pcap_setfilter(handle,&fp);
//Capture packets
pcap_loop(handle,-1,got_packet,NULL);
pcap_close(handle);
return (0);
}
需要将网络字节顺序转换为主机字节顺序:
printf("tcp source port: %hu\n", ntohs(tcp->th_sport));
printf("tcp destination port: %hu\n", ntohs(tcp->th_dport));
我在使用 Windows 10.
的虚拟机上使用 Ubuntu 16.04.2 LTS我正在尝试捕获 1-100 范围内的端口。但它并没有这样做,而且它似乎提供了不正确的端口号。例如,当我尝试使用 telnet 命令连接到另一个虚拟机时,我发现目标端口为 23;但是,我得到了一个完全不同的端口号。我还检查了 wireshark,但目标端口号和源端口号不匹配。
这是我尝试 telnet 到 10.0.2.5
时得到的屏幕截图:
这是我的代码:
#include <pcap.h>
#include <stdio.h>
#include <arpa/inet.h>
//Ethernet addresses are 6 bytes
#define ETHER_ADDR_LEN 6
//ethernet header
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
//ip header
struct ipheader {
unsigned char iph_ihl:4, //IP header length
iph_ver:4; //IP version
unsigned char iph_tos; //Type of service
unsigned short int iph_len; //IP Packet length (data + header)
unsigned short int iph_ident; //Identification
unsigned short int iph_flag: 3, //Fragmenation flags
iph_offset:13; //Flags offset
unsigned char iph_ttl; //Time to live
unsigned char iph_protocol; //Protocol type
unsigned short int iph_chksum; //IP datagram checksum
struct in_addr iph_sourceip; //Source IP address
struct in_addr iph_destip; //Destination IP address
};
//tcp header
typedef u_int tcp_seq;
struct sniff_tcp {
u_short th_sport;/* source port */
u_short th_dport;/* destination port */
tcp_seq th_seq;/* sequence number */
tcp_seq th_ack;/* acknowledgement number */
u_char th_offx2;/* data offset, rsvd */
#define TH_OFF(th)(((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win;/* window */
u_short th_sum;/* checksum */
u_short th_urp;/* urgent pointer */
};
void got_packet(u_char *args, const struct pcap_pkthdr * header,
const u_char * packet)
{
struct sniff_ethernet *eth = (struct sniff_ethernet *)packet;
if(ntohs(eth->ether_type)== 0x0800){ // 0x0800 is IP type
struct ipheader *ip = (struct ipheader *) (packet + sizeof(struct sniff_ethernet));
printf(" From: %s\n", inet_ntoa(ip->iph_sourceip));
printf(" To: %s\n", inet_ntoa(ip->iph_destip));
int ip_header_len = ip->iph_ihl * 4;
struct sniff_tcp *tcp = (struct sniff_tcp*) (packet + sizeof(struct sniff_ethernet) + ip_header_len);
printf("tcp source port: %hu\n",tcp->th_sport);
printf("tcp destination port: %hu\n", tcp->th_dport);
}
}
int main(int argc, char* argv[])
{
char* dev = argv[1];
printf("Device: %s\n", dev);
//session handle
pcap_t *handle;
//error string
char errbuf[PCAP_ERRBUF_SIZE];
//the compiled filter expression
struct bpf_program fp;
char filter_exp[] = "tcp and portrange 10-100";
//the ip of our sniffing device
bpf_u_int32 net;
// open pcap session
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
//Compile filter_exp into BPF pseudo-code
pcap_compile(handle, &fp, filter_exp, 0, net);
pcap_setfilter(handle,&fp);
//Capture packets
pcap_loop(handle,-1,got_packet,NULL);
pcap_close(handle);
return (0);
}
需要将网络字节顺序转换为主机字节顺序:
printf("tcp source port: %hu\n", ntohs(tcp->th_sport));
printf("tcp destination port: %hu\n", ntohs(tcp->th_dport));