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