diff options
| author | lijia <[email protected]> | 2018-11-14 21:09:41 +0800 |
|---|---|---|
| committer | lijia <[email protected]> | 2018-11-14 21:09:41 +0800 |
| commit | ffef9008ed60102670127ae9ee024cbbd293abff (patch) | |
| tree | fccf32cbd37986aaa87eefe5a7d39d0f7a5d6b35 | |
| parent | a6a34b3ba4b4f8bcf78456687240cace0641a66b (diff) | |
支持-g参数, 可以按最内层IP,PORT过滤, 支持BPF过滤规则.
| -rw-r--r-- | Makefile.in | 3 | ||||
| -rw-r--r-- | configure | 1 | ||||
| -rw-r--r-- | mesa_net.h | 811 | ||||
| -rw-r--r-- | net_common.c | 826 | ||||
| -rw-r--r-- | stream_base.h | 520 | ||||
| -rw-r--r-- | tcp.h | 5 | ||||
| -rw-r--r-- | tcpdump.c | 181 | ||||
| -rw-r--r-- | udp.h | 5 |
8 files changed, 2327 insertions, 25 deletions
diff --git a/Makefile.in b/Makefile.in index 853b8ca..8f832b2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -55,6 +55,7 @@ LDFLAGS = @LDFLAGS@ # Standard LIBS LIBS = @LIBS@ +LIBS += -lpthread INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -70,7 +71,7 @@ DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@ @rm -f $@ $(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c -CSRC = setsignal.c tcpdump.c util.c +CSRC = setsignal.c tcpdump.c util.c net_common.c LIBNETDISSECT_SRC=\ addrtoname.c \ @@ -5631,6 +5631,7 @@ if ${ac_cv_lib_pcap_main+:} false; then : else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcap $LIBS" +LIBS += -lpthread cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ diff --git a/mesa_net.h b/mesa_net.h new file mode 100644 index 0000000..ab46da4 --- /dev/null +++ b/mesa_net.h @@ -0,0 +1,811 @@ +#ifndef _MESA_NET_H_
+#define _MESA_NET_H_
+
+#include <stdio.h>
+#include <endian.h>
+#include <netinet/in_systm.h>
+#include "netdissect.h"
+#include "ip.h"
+#include "ip6.h"
+#include "tcp.h"
+#include "udp.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define BYTE_ALIGNED(n) __attribute__((packed, aligned(n)))
+
+
+#define SENDPACKET_ARP_H 0x1c /* ARP header: 28 bytes */
+#define SENDPACKET_ETH_H 0xe /* Etherner header: 14 bytes */
+#define SENDPACKET_IP_H 0x14 /* IP header: 20 bytes */
+/* See sendpacket-ospf.h for OSPF related header sizes */
+#define SENDPACKET_RIP_H 0x18 /* RIP header base: 24 bytes */
+#define SENDPACKET_TCP_H 0x14 /* TCP header: 20 bytes */
+#define SENDPACKET_UDP_H 0x8 /* UDP header: 8 bytes */
+
+/*
+ * Ethernet packet header prototype. Too many O/S's define this differently.
+ * Easy enough to solve that and define it here.
+ */
+#ifndef ETHER_ADDR_LEN
+#define ETHER_ADDR_LEN 6
+#endif
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#define ETHERTYPE_IPv6 0x86dd /* IPv6 protocol */
+#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
+#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
+#define ETHERTYPE_VLAN 0x8100 /* IEEE 802.1Q VLAN tagging */
+#define ETHERTYPE_LOOPBACK 0x9000 /* used to test interfaces */
+
+#define ETH_P_MAC_IN_MAC 0x88A8 /* pangu��Ŀ����88a8����, ���ڻ���MAC_IN_MAC���ݰ� */
+
+#define ETHERTYPE_PANGU_MAC_IN_MAC 0x88A8 /* 2018-08-16 lijia add, for pangu MAC-in-MAC */
+
+#if 0
+#define ETHERTYPE_IP_NET 0x0008 /* IP protocol network order */
+#define ETHERTYPE_IPv6_NET 0xdd86 /* IPv6 protocol network order */
+#define ETHERTYPE_VLAN_NET 0x0081 /* IEEE 802.1Q VLAN tagging network order*/
+#define ETH_P_PPP_SES_NET 0x6488 /* PPPoE session messages network order */
+#define ETH_P_MPLS_UC_NET 0x4788 /* MPLS Unicast traffic network order */
+#define ETH_P_ARP_NET 0x0608 /* Address Resolution packet network order */
+#endif
+
+#define ETHERNET_HDR_LEN (14)
+struct mesa_ethernet_hdr
+{
+ u_int8_t ether_dhost[ETHER_ADDR_LEN]; /* destination ethernet address */
+ u_int8_t ether_shost[ETHER_ADDR_LEN]; /* source ethernet address */
+ u_int16_t ether_type; /* packet type ID */
+}BYTE_ALIGNED(1);
+
+
+/*
+ * IPv4 packet header prototype.
+ */
+#ifndef IP_RF
+#define IP_RF 0x8000 /* reserved fragment flag */
+#endif
+#ifndef IP_DF
+#define IP_DF 0x4000 /* dont fragment flag */
+#endif
+#ifndef IP_MF
+#define IP_MF 0x2000 /* more fragments flag */
+#endif
+#ifndef IP_OFFMASK
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+#endif
+
+
+#define IPPROTO_L2TPV3 (115) /* L2TPv3, RFC3931-page17 */
+
+struct mesa_ip4_hdr
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int8_t ip_hl:4, /* header length */
+ ip_v:4; /* version */
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ u_int8_t ip_v:4, /* version */
+ ip_hl:4; /* header length */
+#else
+#error "Please check <endian.h>"
+#endif
+ u_int8_t ip_tos; /* type of service */
+ u_int16_t ip_len; /* total length */
+ u_int16_t ip_id; /* identification */
+ u_int16_t ip_off;
+ u_int8_t ip_ttl; /* time to live */
+ u_int8_t ip_p; /* protocol */
+ u_int16_t ip_sum; /* checksum */
+ struct in_addr ip_src, ip_dst; /* source and dest address */
+};
+
+
+/*
+ * ARP packet header prototype. Too many O/S's define this differently.
+ * Easy enough to solve that and define it here.
+ */
+#define ARPOP_REQUEST 1 /* req to resolve address */
+#define ARPOP_REPLY 2 /* resp to previous request */
+#define ARPOP_REVREQUEST 3 /* req protocol address given hardware */
+#define ARPOP_REVREPLY 4 /* resp giving protocol address */
+#define ARPOP_INVREQUEST 8 /* req to identify peer */
+#define ARPOP_INVREPLY 9 /* resp identifying peer */
+
+
+#define ARPHRD_ETHER 1 /* ethernet hardware format */
+struct mesa_arp_hdr
+{
+ u_short ar_hrd; /* format of hardware address */
+
+ u_short ar_pro; /* format of protocol address */
+ u_char ar_hln; /* length of hardware address */
+ u_char ar_pln; /* length of protocol addres */
+ u_short ar_op; /* operation type */
+
+ /*
+ * These should implementation defined but I've hardcoded eth/IP.
+ */
+ u_char ar_sha[6]; /* sender hardware address */
+ u_char ar_spa[4]; /* sender protocol address */
+ u_char ar_tha[6]; /* target hardware address */
+ u_char ar_tpa[4]; /* target protocol address */
+};
+
+
+/*
+ * IPv6 packet header prototype, add by LiJia 2012-03-19.
+ */
+struct mesa_ip6_hdr
+{
+ u_int8_t ip6_flags[4]; /* version, traffic-class, flow-label */
+ u_int16_t ip6_payload_len; /* payload length, not contain header */
+ u_int8_t ip6_nxt_hdr; /* next header, same as protocol in IPv4 */
+ u_int8_t ip6_hop; /* hop limit, same as TTL in IPv4 */
+ struct in6_addr ip6_src; /* source address */
+ struct in6_addr ip6_dst; /* dest address */
+};
+
+
+struct mesa_icmp_echo_hdr{
+ unsigned char icmp_type;
+ unsigned char icmp_code;
+ unsigned short icmp_cksum;
+ unsigned short icd_id;
+ unsigned short icd_seq;
+ //char echo_data[];
+};
+
+
+/*
+ * ICMP packet header prototype. // from libnet-headers.h
+ */
+struct mesa_icmp_hdr
+{
+ u_char icmp_type;
+/*
+ * ICMP types.
+ */
+#ifndef ICMP_ECHOREPLY
+#define ICMP_ECHOREPLY 0
+#endif
+#ifndef ICMP_UNREACH
+#define ICMP_UNREACH 3
+#endif
+#ifndef ICMP_SOURCEQUENCH
+#define ICMP_SOURCEQUENCH 4
+#endif
+#ifndef ICMP_REDIRECT
+#define ICMP_REDIRECT 5
+#endif
+#ifndef ICMP_ECHO
+#define ICMP_ECHO 8
+#endif
+#ifndef ICMP_ROUTERADVERT
+#define ICMP_ROUTERADVERT 9
+#endif
+#ifndef ICMP_ROUTERSOLICIT
+#define ICMP_ROUTERSOLICIT 10
+#endif
+#ifndef ICMP_TIMXCEED
+#define ICMP_TIMXCEED 11
+#endif
+#ifndef ICMP_PARAMPROB
+#define ICMP_PARAMPROB 12
+#endif
+#ifndef ICMP_TSTAMP
+#define ICMP_TSTAMP 13
+#endif
+#ifndef ICMP_TSTAMPREPLY
+#define ICMP_TSTAMPREPLY 14
+#endif
+#ifndef ICMP_IREQ
+#define ICMP_IREQ 15
+#endif
+#ifndef ICMP_IREQREPLY
+#define ICMP_IREQREPLY 16
+#endif
+#ifndef ICMP_MASKREQ
+#define ICMP_MASKREQ 17
+#endif
+#ifndef ICMP_MASKREPLY
+#define ICMP_MASKREPLY 18
+#endif
+ u_char icmp_code;
+/*
+ * ICMP codes.
+ */
+#ifndef ICMP_UNREACH_NET
+#define ICMP_UNREACH_NET 0
+#endif
+#ifndef ICMP_UNREACH_HOST
+#define ICMP_UNREACH_HOST 1
+#endif
+#ifndef ICMP_UNREACH_PROTOCOL
+#define ICMP_UNREACH_PROTOCOL 2
+#endif
+#ifndef ICMP_UNREACH_PORT
+#define ICMP_UNREACH_PORT 3
+#endif
+#ifndef ICMP_UNREACH_NEEDFRAG
+#define ICMP_UNREACH_NEEDFRAG 4
+#endif
+#ifndef ICMP_UNREACH_SRCFAIL
+#define ICMP_UNREACH_SRCFAIL 5
+#endif
+#ifndef ICMP_UNREACH_NET_UNKNOWN
+#define ICMP_UNREACH_NET_UNKNOWN 6
+#endif
+#ifndef ICMP_UNREACH_HOST_UNKNOWN
+#define ICMP_UNREACH_HOST_UNKNOWN 7
+#endif
+#ifndef ICMP_UNREACH_ISOLATED
+#define ICMP_UNREACH_ISOLATED 8
+#endif
+#ifndef ICMP_UNREACH_NET_PROHIB
+#define ICMP_UNREACH_NET_PROHIB 9
+#endif
+#ifndef ICMP_UNREACH_HOST_PROHIB
+#define ICMP_UNREACH_HOST_PROHIB 10
+#endif
+#ifndef ICMP_UNREACH_TOSNET
+#define ICMP_UNREACH_TOSNET 11
+#endif
+#ifndef ICMP_UNREACH_TOSHOST
+#define ICMP_UNREACH_TOSHOST 12
+#endif
+#ifndef ICMP_UNREACH_FILTER_PROHIB
+#define ICMP_UNREACH_FILTER_PROHIB 13
+#endif
+#ifndef ICMP_UNREACH_HOST_PRECEDENCE
+#define ICMP_UNREACH_HOST_PRECEDENCE 14
+#endif
+#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15
+#endif
+#ifndef ICMP_REDIRECT_NET
+#define ICMP_REDIRECT_NET 0
+#endif
+#ifndef ICMP_REDIRECT_HOST
+#define ICMP_REDIRECT_HOST 1
+#endif
+#ifndef ICMP_REDIRECT_TOSNET
+#define ICMP_REDIRECT_TOSNET 2
+#endif
+#ifndef ICMP_REDIRECT_TOSHOST
+#define ICMP_REDIRECT_TOSHOST 3
+#endif
+#ifndef ICMP_TIMXCEED_INTRANS
+#define ICMP_TIMXCEED_INTRANS 0
+#endif
+#ifndef ICMP_TIMXCEED_REASS
+#define ICMP_TIMXCEED_REASS 1
+#endif
+#ifndef ICMP_PARAMPROB_OPTABSENT
+#define ICMP_PARAMPROB_OPTABSENT 1
+#endif
+
+ u_short icmp_sum;
+
+ union
+ {
+ struct
+ {
+ u_short id;
+ u_short seq;
+ }echo;
+
+#undef icmp_id
+#undef icmp_seq
+#define icmp_id hun.echo.id
+#define icmp_seq hun.echo.seq
+
+ u_long gateway;
+ struct
+ {
+ u_short pad;
+ u_short mtu;
+ }frag;
+ }hun;
+ union
+ {
+ struct
+ {
+ n_time its_otime;
+ n_time its_rtime;
+ n_time its_ttime;
+ }ts;
+ struct
+ {
+ struct ip idi_ip;
+ /* options and then 64 bits of data */
+ }ip;
+ u_long mask;
+ char data[1];
+
+#undef icmp_mask
+#define icmp_mask dun.mask
+#undef icmp_data
+#define icmp_data dun.data
+
+#undef icmp_otime
+#define icmp_otime dun.ts.its_otime
+#undef icmp_rtime
+#define icmp_rtime dun.ts.its_rtime
+#undef icmp_ttime
+#define icmp_ttime dun.ts.its_ttime
+ }dun;
+
+};
+
+/*
+ * TCP packet header prototype.
+ */
+#ifndef TH_FIN
+#define TH_FIN 0x01
+#endif
+#ifndef TH_SYN
+#define TH_SYN 0x02
+#endif
+#ifndef TH_RST
+#define TH_RST 0x04
+#endif
+#ifndef TH_PUSH
+#define TH_PUSH 0x08
+#endif
+#ifndef TH_ACK
+#define TH_ACK 0x10
+#endif
+#ifndef TH_URG
+#define TH_URG 0x20
+#endif
+struct mesa_tcp_hdr
+{
+ u_int16_t th_sport; /* source port */
+ u_int16_t th_dport; /* destination port */
+ u_int32_t th_seq; /* sequence number */
+ u_int32_t th_ack; /* acknowledgement number */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ u_int8_t th_x2:4, /* (unused) */
+ th_off:4; /* data offset */
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ u_int8_t th_off:4, /* data offset */
+ th_x2:4; /* (unused) */
+#else
+#error "Please check <endian.h>"
+#endif
+ u_int8_t th_flags; /* control flags */
+ u_int16_t th_win; /* window */
+ u_int16_t th_sum; /* checksum */
+ u_int16_t th_urp; /* urgent pointer */
+};
+
+
+/*
+ * UDP packet header prototype.
+ */
+struct mesa_udp_hdr
+{
+ u_int16_t uh_sport; /* soure port */
+ u_int16_t uh_dport; /* destination port */
+ u_int16_t uh_ulen; /* length */
+ u_int16_t uh_sum; /* checksum */
+};
+
+
+#define PPPOE_HDR_LEN (sizeof(struct mesa_pppoe_session_hdr))
+#define PPP_PROTOCOL_PAD (0x0001)
+#define PPP_PROTOCOL_IPv4 (0x0021)
+#define PPP_PROTOCOL_PAP (0xC023)
+#define PPP_PROTOCOL_CHAP (0xC223)
+#define PPP_PROTOCOL_IPv6 (0x0057)
+#define PPP_COMPRESS_DATA (0x00FD)
+
+#define PPP_PROTOCOL_LCP (0xC021)
+#define PPP_PROTOCOL_CCP (0x80FD)
+#define PPP_PROTOCOL_IPCP (0x8021)
+
+struct mesa_pppoe_session_hdr{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ver:4;
+ unsigned int type:4;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int type:4;
+ unsigned int ver:4;
+#else
+#error "Please check <endian.h>"
+#endif
+ unsigned char code;
+ unsigned short session_id;
+ unsigned short len;
+ /* to do:
+ pppӦ�õ�����Ϊһ�����, Ϊ�˼���, ǿ�ƽ����PPPOE_SES����һ��,
+ �����Ҫ����PPPЭ�̹���, �˽ṹ��Ҫ�Ķ�.
+ */
+ unsigned short ppp_protocol;
+}BYTE_ALIGNED(1);
+
+
+struct mesa_ppp_hdr{
+ unsigned char address;
+ unsigned char control;
+ unsigned short protocol;
+}BYTE_ALIGNED(1);
+
+#define PPP_LCP_CODE_REQUEST (1)
+#define PPP_LCP_CODE_ACK (2)
+#define PPP_LCP_CODE_NAK (3)
+#define PPP_LCP_CODE_REJECT (4)
+#define PPP_LCP_CODE_TERMINATE_REQ (5)
+#define PPP_LCP_CODE_TERMINATE_ACK (6)
+
+/* refer to RFC1661 */
+#define PPP_LCP_OPT_RESERVED (0)
+#define PPP_LCP_OPT_MAX_RCV_UNIT (1)
+#define PPP_LCP_OPT_AUTH_PRO (3)
+#define PPP_LCP_OPT_QA_PRO (4)
+#define PPP_LCP_OPT_MAGIC (5)
+#define PPP_LCP_OPT_PRO_FIELD_COMPRESS (7)
+#define PPP_LCP_OPT_ADDR_CTRL_FIELD_COMPRESS (8)
+
+#define PPP_LCP_OPT_AUTH_PRO_PAP (0xC023)
+#define PPP_LCP_OPT_AUTH_PRO_CHAP (0xC223)
+
+#define PPP_LCP_OPT_AUTH_PRO_CHAP_ALGO_MS_CHAP_V2 (0x81)
+#define PPP_LCP_OPT_AUTH_PRO_CHAP_ALGO_CHAP_MD5 (0x05)
+
+
+/* refer to RFC1962 Page6 */
+#define PPP_CCP_OPT_OUI (0)
+#define PPP_CCP_OPT_MS_PPC (18)
+
+struct mesa_ppp_lcp_ack_hdr{ /* RFC1661-Page29 */
+ unsigned char code;
+ unsigned char identifier;
+ unsigned short length;
+}BYTE_ALIGNED(1);
+
+struct mesa_ppp_ccp_ack_hdr{ /* RFC1661-Page29 */
+ unsigned char code;
+ unsigned char identifier;
+ unsigned short length;
+}BYTE_ALIGNED(1);
+
+#define PPP_CHAP_CHALLENGE (1)
+#define PPP_CHAP_RESPONSE (2)
+#define PPP_CHAP_SUCCESS (3)
+#define PPP_CHAP_FAILURE (4)
+
+struct mesa_ppp_chap_hdr{
+ unsigned char code;
+ unsigned char identifier;
+ unsigned short length;
+}BYTE_ALIGNED(1);
+
+struct mesa_ppp_ipcp_ack_hdr{
+ unsigned char code;
+ unsigned char identifier;
+ unsigned short length;
+}BYTE_ALIGNED(1);
+
+enum pptp_control_message_type{
+ PPTP_CTRL_START_CONN_REQ = 1,
+ PPTP_CTRL_START_CONN_REPLY = 2,
+ PPTP_CTRL_STOP_CONN_REQ = 3,
+ PPTP_CTRL_STOP_CONN_REPLY = 4,
+ PPTP_CTRL_ECHO_REQ = 5,
+ PPTP_CTRL_ECHO_REPLY = 6,
+ PPTP_CTRL_OUT_GO_REQ = 7,
+ PPTP_CTRL_OUT_GO_REPLY = 8,
+ PPTP_CTRL_IN_CALL_REQ = 9,
+ PPTP_CTRL_IN_CALL_REPLY = 10,
+ PPTP_CTRL_IN_CALL_CONN = 11,
+ PPTP_CTRL_CALL_CLEAR_REQ = 12,
+ PPTP_CTRL_CALL_DISCONN_NOTIFY = 13,
+ PPTP_CTRL_WAN_ERROR_NOTIFY = 14,
+ PPTP_CTRL_SET_LINK_INFO = 15,
+};
+
+struct mesa_pptp_control_hdr{
+ unsigned short length; /* ȫ�����ݳ���, ������ͷ�� */
+ unsigned short pptp_message_type;
+ unsigned int magic_cookie;
+ unsigned short control_message_type;
+ char ignore_bytes[0]; /* �����ֶ��ݲ�����, ����Ҳ��һ�� */
+};
+
+struct mesa_vlan_hdr{
+ unsigned short pri_cfi_id;
+ unsigned short type;
+};
+
+struct mesa_vlan_detail_hdr{
+ unsigned int priority:3;
+ unsigned int del_flag:1;
+ unsigned int vlan_id:12;
+ unsigned short type;
+};
+
+/* 2018-08-28 lijia add, for pangu ��Ŀmac_in_mac���� */
+struct mesa_mac_in_mac_net_hdr{
+ unsigned int route_dir:1;
+ unsigned int link_id:3;
+ unsigned int dev_id:6;
+ unsigned int region_id:5;
+ unsigned int __pad1:1;
+ unsigned int encap_type:4;
+ unsigned int __pad2:20;
+ unsigned int __pad3:8;
+};
+
+struct mesa_gre_base_hdr_v0{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned char recur:3;
+ unsigned char strict_src_route_flag:1;
+ unsigned char seq_flag:1;
+ unsigned char key_flag:1;
+ unsigned char route_flag:1;
+ unsigned char checksum_flag:1;
+
+ unsigned char version:3;
+ unsigned char flags:5; /* version 0 flags is 5 bit */
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char checksum_flag:1;
+ unsigned char route_flag:1;
+ unsigned char key_flag:1;
+ unsigned char seq_flag:1;
+ unsigned char strict_src_route_flag:1;
+ unsigned char recur:3;
+
+ unsigned char flags:5; /* version 0 flags is 5 bit */
+ unsigned char version:3;
+#else
+#error "Please check <endian.h>"
+#endif
+ unsigned short protocol;
+};
+
+struct mesa_gre_base_hdr_v1{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned char recur:3;
+ unsigned char strict_src_route_flag:1;
+ unsigned char seq_flag:1;
+ unsigned char key_flag:1;
+ unsigned char route_flag:1;
+ unsigned char checksum_flag:1;
+
+ unsigned char version:3;
+ unsigned char flags:4; /* version 1 flags is 4 bit */
+ unsigned char ack_flag:1;
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char checksum_flag:1;
+ unsigned char route_flag:1;
+ unsigned char key_flag:1;
+ unsigned char seq_flag:1;
+ unsigned char strict_src_route_flag:1;
+ unsigned char recur:3;
+
+ unsigned char ack_flag:1;
+ unsigned char flags:4; /* version 1 flags is 4 bit */
+ unsigned char version:3;
+#else
+#error "Please check <endian.h>"
+#endif
+ unsigned short protocol;
+};
+
+#define GRE_SRE_MAX_LEN (256) /* �����Ϊһ���ֽ�, 256 */
+struct gre_source_route_entry_hdr{
+ unsigned short address_family;
+ unsigned char sre_offset;
+ unsigned char sre_length;
+ unsigned char sre_entry_list[GRE_SRE_MAX_LEN];
+};
+
+/* ���п��ܵ�ֵ����, ��Ҫ����mesa_gre_base_hdr����bit��ֵ, �ж��Ƿ�������ֵ */
+struct mesa_gre_extend_hdr{
+ unsigned short checksum; //version0
+ unsigned short offset; //version0, if checksum present, then offset also present
+ unsigned short payload_len; //version1
+ unsigned short call_id; //version1
+ unsigned int key; //version0
+ unsigned int seq_num; //version0 and version1
+ unsigned int ack_num; //version1
+ //struct gre_source_route_entry_hdr sre_list;
+};
+
+struct mesa_gre_hdr{
+ /* version0��version1��ͷ����, version�ֶ�ʱһ�µ�, ������С����, Ĭ��ʹ��v0��ʽ���� */
+ struct mesa_gre_base_hdr_v0 gre_base;
+ struct mesa_gre_extend_hdr gre_extend;
+};
+
+
+#define MPLS_LABEL_MASK (0xFFFFF000)
+#define MPLS_EXP_MASK (0x00000E00)
+#define MPLS_BLS_MASK (0x00000100)
+#define MPLS_TTL_MASK (0x000000FF)
+struct mesa_mpls_hdr{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned short mpls_label_low;
+ unsigned char mpls_bls:1; /* bottom of label stack */
+ unsigned char mpls_exp:3;
+ unsigned char mpls_label_high:4;
+ unsigned char mpls_ttl;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char mpls_ttl;
+ unsigned char mpls_label_high:4;
+ unsigned char mpls_exp:3;
+ unsigned char mpls_bls:1; /* bottom of label stack */
+ unsigned short mpls_label_low;
+#else
+#error "Please check <endian.h>"
+#endif
+};
+
+#define L2TP_REGISTERED_IP_PRO (115)
+#define L2TP_REGISTERED_PORT (1701)
+
+#define L2TP_HDR_TYPE_DATA (0)
+#define L2TP_HDR_TYPE_CONTROL (1)
+
+struct l2tp_hdr_v2{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned char priority:1;
+ unsigned char offset_present:1;
+ unsigned char reserved2:1;
+ unsigned char seq_present:1;
+ unsigned char reserved1:2;
+ unsigned char length_present:1;
+ unsigned char type:1;
+
+ unsigned char version:4;
+ unsigned char reserved3:4;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char reserved3:4;
+ unsigned char version:4;
+
+ unsigned char type:1;
+ unsigned char length_present:1;
+ unsigned char reserved1:2;
+ unsigned char seq_present:1;
+ unsigned char reserved2:1;
+ unsigned char offset_present:1;
+ unsigned char priority:1;
+#else
+#error "Please check <endian.h>"
+#endif
+};
+
+/* refer to RFC2661-Page12 */
+#define L2TP_CTRL_MSG_RESERVED0 (0)
+#define L2TP_CTRL_MSG_SCCRQ (1)
+#define L2TP_CTRL_MSG_SCCRP (2)
+#define L2TP_CTRL_MSG_SCCCN (3)
+#define L2TP_CTRL_MSG_STOP_CCN (4)
+#define L2TP_CTRL_MSG_RESERVED5 (5)
+#define L2TP_CTRL_MSG_HELLO (6)
+#define L2TP_CTRL_MSG_OCRQ (7)
+#define L2TP_CTRL_MSG_OCRP (8)
+#define L2TP_CTRL_MSG_OCCN (9)
+#define L2TP_CTRL_MSG_ICRQ (10)
+#define L2TP_CTRL_MSG_ICRP (11)
+#define L2TP_CTRL_MSG_ICCN (12)
+#define L2TP_CTRL_MSG_RESERVED13 (13)
+#define L2TP_CTRL_MSG_CDN (14)
+#define L2TP_CTRL_MSG_WEN (15)
+#define L2TP_CTRL_MSG_SLI (16)
+
+#define L2TP_AVP_GET_LEN(u) (ntohs(u) & 0x3F)
+struct l2tp_avp{
+ unsigned short M_H_rsvd_len_union;
+ unsigned short vendor_id;
+ unsigned short attribute_type;
+}BYTE_ALIGNED(1);
+
+/* RFC2408-Page23 */
+#define ISAKMP_PAYLOAD_TYPE_NONE (0)
+#define ISAKMP_PAYLOAD_TYPE_SA (1)
+#define ISAKMP_PAYLOAD_TYPE_PROPOSAL (2)
+#define ISAKMP_PAYLOAD_TYPE_TRANSFORM (3)
+#define ISAKMP_PAYLOAD_TYPE_KEY_EXCHANGE (4)
+#define ISAKMP_PAYLOAD_TYPE_ID (5)
+#define ISAKMP_PAYLOAD_TYPE_CERT (6)
+#define ISAKMP_PAYLOAD_TYPE_CR (7)
+#define ISAKMP_PAYLOAD_TYPE_HASH (8)
+#define ISAKMP_PAYLOAD_TYPE_SIG (9)
+#define ISAKMP_PAYLOAD_TYPE_NONCE (10)
+#define ISAKMP_PAYLOAD_TYPE_NOTIFY (11)
+#define ISAKMP_PAYLOAD_TYPE_DELETE (12)
+#define ISAKMP_PAYLOAD_TYPE_VENDOR_ID (13)
+#define ISAKMP_PAYLOAD_TYPE_RESERVED_BEGIN (14) /* 14 - 127 */
+#define ISAKMP_PAYLOAD_TYPE_RESERVED_END (127) /* 14 - 127 */
+#define ISAKMP_PAYLOAD_TYPE_PRIVATE_USE_BEGIN (128) /* 128-255 */
+#define ISAKMP_PAYLOAD_TYPE_PRIVATE_USE_END (255) /* 128-255 */
+
+/* RFC2408-Page23 */
+#define ISAKMP_EXCHANGE_TYPE_NONE (0)
+#define ISAKMP_EXCHANGE_TYPE_BASE (1)
+#define ISAKMP_EXCHANGE_TYPE_ID_PROT (2) /* RFC-2409 page8, main mode is instantiation os ISAKMP Identity Protect Exchange */
+#define ISAKMP_EXCHANGE_TYPE_AUTH (3)
+#define ISAKMP_EXCHANGE_TYPE_AGGRESS (4)/* RFC-2409 page8, Aggressive mode is instantiation os ISAKMP Aggressive Exchange */
+#define ISAKMP_EXCHANGE_TYPE_INFO (5)
+#define ISAKMP_EXCHANGE_TYPE_FEATURE_USE_BEGIN (6) /* 6-31��ֵ�ݲ����� */
+#define ISAKMP_EXCHANGE_TYPE_FEATURE_USE_END (31) /* 6-31��ֵ�ݲ����� */
+
+struct mesa_isakmp_hdr{ /* RFC2408-Page22 */
+ unsigned long long init_cookie;
+ unsigned long long resp_cookie;
+ unsigned char next_payload;
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned char minor_version:4;
+ unsigned char major_version:4;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned char major_version:4;
+ unsigned char minor_version:4;
+#else
+#error "Please check <endian.h>"
+#endif
+
+ unsigned char exchange_type;
+ unsigned char flags;
+ unsigned int message_id;
+ unsigned int length;
+};
+
+struct mesa_isakmp_payload_hdr{ /* RFC2408-Page22 */
+ unsigned char next_payload;
+ unsigned char reserver;
+ unsigned short payload_len;
+};
+
+#define GTP_MSG_TYPE_T_PDU (0xFF)
+
+struct gtp_hdr{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned char flags;
+ unsigned char msg_type;
+ unsigned short len;
+ unsigned int teid;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int teid;
+ unsigned short len;
+ unsigned char msg_type;
+ unsigned char flags;
+#else
+#error "Please check <endian.h>"
+#endif
+};
+
+#define MAX_ADDR_TYPE_STRING_LEN (64)
+#define MAX_ADDR_LIST_STRING_LEN (2048)
+#define MAX_ADDR_EMBED_LAYER_NUM (20) /* ����ַǶ�ײ��� */
+#define MAX_ADDR_BIN_VALUE_LEN (40) /* paddrʵ���������, Ŀǰ��tuple4v6� */
+
+/* ����ģʽ��, ��¼MAC��ַ���ڷ��� */
+struct packet_io_mac_addr{
+ struct mesa_ethernet_hdr eth_hdr;
+ char route_dir;
+ char __pad__; /* ����ṹ8�ֽڶ��� */
+};
+
+unsigned char net_layer_to_ipv4_protocol(int addr_type);
+unsigned char net_layer_to_ipv6_protocol(int addr_type);
+unsigned short net_layer_to_ethernet_protocol(int addr_type);
+int net_common_build_send_mac(unsigned char *buf, const struct mesa_ethernet_hdr *raw_eth_hdr, int addr_type, int dir_reverse, int net_topology_mode);
+int net_common_adjust_forward_mac(struct mesa_ethernet_hdr *raw_eth_hdr,int net_topology_mode);
+const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, int expect_layer_type);
+const void *MESA_net_jump_to_layer_greedy(const void *raw_data, int raw_layer_type, int expect_layer_type);
+char MESA_ascii_to_hex(char ascii);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/net_common.c b/net_common.c new file mode 100644 index 0000000..4a80624 --- /dev/null +++ b/net_common.c @@ -0,0 +1,826 @@ +
+#include <linux/if_ether.h>
+#include <net/if_arp.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "netdissect-stdinc.h"
+#include "netdissect.h"
+#include "stream_base.h"
+#include "mesa_net.h"
+#include "ip.h"
+#include "ip6.h"
+#include "tcp.h"
+#include "udp.h"
+#include "ppp.h"
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static int eth_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
+static int vlan8021q_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
+static int ipv4_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
+static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type);
+
+static int treat_vlan_as_mac_in_mac_sw = 1;
+
+/* ascii�ַ�ת16���� */
+char MESA_ascii_to_hex(char ascii)
+{
+ char c = 0;
+
+ switch(ascii)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ c = ascii - 0x30;
+ break;
+
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ c = 10 + ascii - 0x61;
+ break;
+
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ c = 10 + ascii - 0x41;
+ break;
+ }
+
+ return c;
+}
+
+
+
+static int arp_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ /* arpЭ�鲻�����κ��ϲ�����Э�� */
+ return -1;
+}
+
+
+static int gtp_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ const struct gtp_hdr *gh = (struct gtp_hdr *)raw_data;
+ int opt_len = 0; /* ��ѡ��� */
+ const unsigned char *next_ip_layer_hdr;
+ int skip_len;
+
+ if(ADDR_TYPE_GPRS_TUNNEL == expect_layer_type){
+ return 0;
+ }
+
+ if(gh->flags & 0x2){
+ opt_len += sizeof(int); /* sequence */
+ }
+
+ next_ip_layer_hdr = (unsigned char *)raw_data + opt_len + sizeof(struct gtp_hdr);
+
+ if((*next_ip_layer_hdr & 0x40) == 0x40){
+ skip_len = ipv4_jump_to_layer((char *)next_ip_layer_hdr, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ }else if((*next_ip_layer_hdr & 0x60) == 0x60){
+ skip_len = ipv6_jump_to_layer((char *)next_ip_layer_hdr, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
+ }else{
+ ////sapp_runtime_log(20, "TODO: jmp unsupport type in GTP, 0x%x!\n", (*next_ip_layer_hdr));
+ return -1;
+ }
+
+ return opt_len + sizeof(struct gtp_hdr) + skip_len;
+}
+
+static int udp_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ const struct mesa_udp_hdr *uh = (const struct mesa_udp_hdr *)raw_data;
+ unsigned short usport, udport;
+ int skip_len;
+
+ if(ADDR_TYPE_UDP == expect_layer_type){
+ return 0;
+ }
+
+ usport = ntohs(uh->uh_sport);
+ udport = ntohs(uh->uh_dport);
+
+ if((2152 == usport) && (2152 == udport)){
+ skip_len = gtp_jump_to_layer(raw_data+sizeof(struct mesa_udp_hdr), ADDR_TYPE_UDP, expect_layer_type);
+ }else if((3544 == usport) || (3544 == udport)){
+ ;
+ //TODO
+ //skip_len = teredo_jump_to_layer(raw_data+sizeof(struct mesa_udp_hdr), ADDR_TYPE_UDP, expect_layer_type);
+ }else{
+ /* ����UDP���Ͳ�֧������ת */
+ return -1;
+ }
+
+ return skip_len + sizeof(struct mesa_udp_hdr);
+}
+
+static int ipv4_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ struct ip *p_ip_hdr = (struct ip *)raw_data;
+ int skip_len = 0;
+ int ip_hdr_len = IP_HL(p_ip_hdr) * 4;
+ //const char *next_layer_data = raw_data + ip_hdr_len;
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+
+ switch(p_ip_hdr->ip_p){
+ case IPPROTO_TCP:
+ if(ADDR_TYPE_TCP == expect_layer_type){
+ skip_len = 0;
+ break;
+ }else{
+ skip_len = -1; /* tcp ��֮�ϲ���������Э�� */
+ }
+ break;
+
+ case IPPROTO_UDP:
+ if(ADDR_TYPE_UDP == expect_layer_type){
+ skip_len = 0;
+ break;
+ }else{
+ skip_len = udp_jump_to_layer(raw_data+ip_hdr_len, ADDR_TYPE_UDP, expect_layer_type);
+ }
+ break;
+
+ case IPPROTO_IPV6:
+ if(__ADDR_TYPE_IP_PAIR_V6 == expect_layer_type){
+ skip_len = 0;
+ break;
+ }else{
+ skip_len = ipv6_jump_to_layer(raw_data+ip_hdr_len, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
+ }
+ break;
+
+ default:
+ skip_len = -1;
+ break;
+ }
+
+ if(skip_len < 0){
+ return -1;
+ }
+
+ return skip_len + sizeof(struct ip);
+}
+
+static int ipv6_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ const struct mesa_ip6_hdr *a_packet = (const struct mesa_ip6_hdr *)raw_data;
+ UINT8 next_hdr_type = a_packet->ip6_nxt_hdr;
+ UINT8 *next_hdr_ptr = (UINT8 *)a_packet + sizeof(struct mesa_ip6_hdr);
+ int skip_len = 0;
+ int offset_to_ip6 = 0;
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+
+ while(1){
+ offset_to_ip6 = 0;
+ switch(next_hdr_type)
+ {
+ case 0: //NEXTHDR_HOP:
+ case 43://NEXTHDR_ROUTING:
+ case 51://NEXTHDR_AUTH:
+ case 60://NEXTHDR_DEST:
+ offset_to_ip6 = (*(next_hdr_ptr + 1))*8 + 8; /* ѡ�����8�ֽ�Ϊ��λ */
+ break;
+
+ case 4://NEXTHDR_IPIP:
+ if(__ADDR_TYPE_IP_PAIR_V4 == expect_layer_type){
+ skip_len = next_hdr_ptr - (UINT8 *)raw_data;
+ }else{
+ skip_len = ipv4_jump_to_layer((const char *)next_hdr_ptr, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ if(skip_len < 0){
+ return -1;
+ }else{
+ return skip_len + next_hdr_ptr - (UINT8 *)raw_data;
+ }
+ }
+ goto done;
+ break;
+
+ case 59://NEXTHDR_NONE:
+ skip_len = -1;
+ goto done;
+ break;
+
+ case 58://NEXTHDR_ICMP: /* IMCP���ٳ�������Э�� */
+ skip_len = -1;
+ goto done;
+ break;
+
+ case 6://NEXTHDR_TCP:
+ if(ADDR_TYPE_TCP == expect_layer_type){
+ skip_len = next_hdr_ptr - (UINT8 *)raw_data;
+ }else{
+ skip_len = -1;
+ }
+ goto done;
+ break;
+
+ case 17://NEXTHDR_UDP:
+ if(ADDR_TYPE_UDP == expect_layer_type){
+ skip_len = next_hdr_ptr - (UINT8 *)raw_data;
+ }else{
+ skip_len = -1;
+ }
+ goto done;
+ break;
+
+ case 44:///NEXTHDR_FRAGMENT:
+ offset_to_ip6 = 8; // 8 == sizeof(struct ipv6_frag_hdr);
+ break;
+
+ case 50://NEXTHDR_ESP:
+ skip_len = -1;
+ goto done;
+
+ default:
+ printf("TODO:jmp Unknown IPv6 header type:0x%x!\n", next_hdr_type);
+ skip_len = -1;
+ goto done;
+ break;
+ }
+
+ next_hdr_type = *next_hdr_ptr;
+ next_hdr_ptr += offset_to_ip6;
+ }
+
+done:
+ if(skip_len < 0){
+ return -1;
+ }
+
+ return skip_len;
+}
+
+static int ppp_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ int skip_len = 0;
+ struct mesa_pppoe_session_hdr *pppoe_ses_hdr;
+ char *next_hdr;
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+ pppoe_ses_hdr = (struct mesa_pppoe_session_hdr *)raw_data;
+ next_hdr = (char *)raw_data + sizeof(struct mesa_pppoe_session_hdr);
+
+ switch(ntohs(pppoe_ses_hdr->ppp_protocol)){
+ case PPP_PROTOCOL_IPv4:
+ if(__ADDR_TYPE_IP_PAIR_V4 == expect_layer_type){
+ break;
+ }else{
+ skip_len = ipv4_jump_to_layer(next_hdr, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ }
+ break;
+
+ case PPP_IPV6:
+ if(__ADDR_TYPE_IP_PAIR_V6 == expect_layer_type){
+ break;
+ }else{
+ skip_len = ipv6_jump_to_layer(next_hdr, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ }
+ break;
+
+ case PPP_COMP:
+ case PPP_CCP:
+ case PPP_IPCP:
+ case PPP_PAP:
+ case PPP_CHAP:
+ case 0xC025: ///PPP_LQR:
+ case PPP_PROTOCOL_LCP:
+
+ /* ������Ӧ�ò�Э�� */
+ skip_len = -1;
+ break;
+
+ default:
+ printf("TODO: jmp unsupport ppp pro:0x%x!\n", ntohs(pppoe_ses_hdr->ppp_protocol));
+ break;
+
+ }
+
+ if(skip_len < 0){
+ return -1;
+ }
+
+ return skip_len + sizeof(struct mesa_pppoe_session_hdr);
+}
+
+
+static int mpls_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ int skip_len = 0;
+ const struct mesa_mpls_hdr *mpls_hdr = (const struct mesa_mpls_hdr *)raw_data;
+ const char *next_layer_data = raw_data + sizeof(struct mesa_mpls_hdr);
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+
+ if(0 == mpls_hdr->mpls_bls){ /* ��MPLSջ��, �ݹ�������� */
+ return mpls_jump_to_layer(next_layer_data, ADDR_TYPE_MPLS, expect_layer_type) + sizeof(struct mesa_mpls_hdr);
+ }
+
+ /* MPLSû���ֶα�ʶ��һ����ʲô, ���²���һ���IP���� */
+ if((*next_layer_data & 0x40) == 0x40){
+ skip_len = ipv4_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ }else if((*next_layer_data & 0x60) == 0x60){
+ skip_len = ipv6_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
+ }else{
+ //sapp_runtime_log(20, "TODO: jmp unsupport type in MPLS, 0x%x!\n", (unsigned char)(*next_layer_data));
+ return -1;
+ }
+
+ return skip_len + sizeof(struct mesa_mpls_hdr); /* mpls header is 4 byte */
+}
+
+static int __common_eth_type_dispatch(UINT16 eth_type, const char *next_layer_data, int raw_layer_type, int expect_layer_type)
+{
+ int skip_len = 0;
+
+ switch(eth_type){
+ case ETH_P_ARP:
+ if(ADDR_TYPE_ARP == expect_layer_type){
+ break;
+ }else{
+ skip_len = arp_jump_to_layer(next_layer_data, ADDR_TYPE_ARP, expect_layer_type);
+ }
+ break;
+
+ case ETH_P_8021Q:
+ if(ADDR_TYPE_VLAN == expect_layer_type){
+ break;
+ }else{
+ if(treat_vlan_as_mac_in_mac_sw){
+ skip_len = eth_jump_to_layer(next_layer_data, ADDR_TYPE_MAC, expect_layer_type);
+ }else{
+ skip_len = vlan8021q_jump_to_layer(next_layer_data, ADDR_TYPE_VLAN, expect_layer_type);
+ }
+ }
+ break;
+
+ case ETH_P_IP:
+ if(__ADDR_TYPE_IP_PAIR_V4 == expect_layer_type){
+ break;
+ }else{
+ skip_len = ipv4_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ }
+ break;
+
+ case ETH_P_IPV6:
+ if(__ADDR_TYPE_IP_PAIR_V6 == expect_layer_type){
+ break;
+ }else{
+ skip_len = ipv6_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
+ }
+ break;
+
+ case ETH_P_PPP_SES:
+ if(ADDR_TYPE_PPPOE_SES == expect_layer_type){
+ break;
+ }else{
+ skip_len = ppp_jump_to_layer(next_layer_data, ADDR_TYPE_PPPOE_SES, expect_layer_type);
+ }
+ break;
+
+ case 0x88A8: /* MAC_IN_MAC */
+ skip_len = eth_jump_to_layer(next_layer_data, ADDR_TYPE_MAC, expect_layer_type);
+ break;
+
+ case 0x8847: /* MPLS, ETH_P_MPLS_UC */
+ skip_len = mpls_jump_to_layer(next_layer_data, ADDR_TYPE_MPLS, expect_layer_type);
+ break;
+
+ default:
+ skip_len = -1;
+ break;
+ }
+
+ return skip_len;
+}
+
+static int vlan8021q_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ int skip_len = 0;
+ const struct mesa_vlan_hdr *vlan_hdr = (const struct mesa_vlan_hdr *)raw_data;
+ const char *next_layer_data = raw_data + sizeof(struct mesa_vlan_hdr);
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+
+ switch(ntohs(vlan_hdr->type)){
+ case ETH_P_ARP:
+ if(ADDR_TYPE_ARP == expect_layer_type){
+ break;
+ }else{
+ skip_len = arp_jump_to_layer(next_layer_data, ADDR_TYPE_ARP, expect_layer_type);
+ }
+ break;
+
+ case ETH_P_IP:
+ if(__ADDR_TYPE_IP_PAIR_V4 == expect_layer_type){
+ break;
+ }else{
+ skip_len = ipv4_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V4, expect_layer_type);
+ }
+ break;
+
+ case ETH_P_IPV6:
+ if(__ADDR_TYPE_IP_PAIR_V6 == expect_layer_type){
+ break;
+ }else{
+ skip_len = ipv6_jump_to_layer(next_layer_data, __ADDR_TYPE_IP_PAIR_V6, expect_layer_type);
+ }
+ break;
+
+ case ETH_P_PPP_SES:
+ if(ADDR_TYPE_PPPOE_SES == expect_layer_type){
+ break;
+ }else{
+ skip_len = ppp_jump_to_layer(next_layer_data, ADDR_TYPE_PPPOE_SES, expect_layer_type);
+ }
+ break;
+
+ case ETH_P_PPP_DISC: /* pppoe���ֽ� */
+ skip_len = -1;
+ break;
+
+ case 0x8200: /* XinJing�������ִ�����, δ֪ʲô�� */
+ skip_len = -1;
+ break;
+
+ default:
+ printf("TODO: jmp unsupport type in vlan8021q, 0x%x!\n", ntohs(vlan_hdr->type));
+ skip_len = -1;
+ }
+
+ if(skip_len < 0){
+ return -1;
+ }
+
+ return skip_len + sizeof(struct mesa_vlan_hdr);
+}
+
+static int eth_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ struct ethhdr *p_eth_hdr = (struct ethhdr *)raw_data;
+ unsigned short eth_type = ntohs(p_eth_hdr->h_proto);
+ //int skip_len = -1;
+ const char *next_layer_data = raw_data + sizeof(struct ethhdr);
+ int layer_skip_len;
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+
+ layer_skip_len = __common_eth_type_dispatch(eth_type, next_layer_data, raw_layer_type, expect_layer_type);
+ if(layer_skip_len < 0){
+ return -1;
+ }
+
+ return layer_skip_len + sizeof(struct ethhdr);
+}
+
+
+static int mac_in_mac_jump_to_layer(const char *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ struct ethhdr *inner_eth_hdr = (struct ethhdr *)(raw_data + sizeof(struct ethhdr ));
+ unsigned short inner_eth_type = ntohs(inner_eth_hdr->h_proto);
+ //int skip_len = -1;
+ const char *next_layer_data = raw_data + sizeof(struct ethhdr);
+ int layer_skip_len;
+
+ if(raw_layer_type == expect_layer_type){
+ return 0;
+ }
+
+ layer_skip_len = __common_eth_type_dispatch(inner_eth_type, next_layer_data, raw_layer_type, expect_layer_type);
+ if(layer_skip_len < 0){
+ return -1;
+ }
+
+ return layer_skip_len + sizeof(struct ethhdr) * 2;
+}
+
+/*
+ return value:
+ Non-NULL: the pointer to expect layer;
+ NULL: not found expect layer.
+*/
+const void *MESA_net_jump_to_layer(const void *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ int ret;
+
+ if(raw_layer_type <= __ADDR_TYPE_INIT || raw_layer_type >= __ADDR_TYPE_MAX){
+ return NULL;
+ }
+
+ if(expect_layer_type <= __ADDR_TYPE_INIT || expect_layer_type >= __ADDR_TYPE_MAX){
+ return NULL;
+ }
+
+ if(ADDR_TYPE_IPV4 == expect_layer_type){
+ /* ת�ɴ�IPv4��ַ���� */
+ expect_layer_type = __ADDR_TYPE_IP_PAIR_V4;
+ }
+
+ if(ADDR_TYPE_IPV6 == expect_layer_type){
+ /* ת�ɴ�IPv6��ַ���� */
+ expect_layer_type = __ADDR_TYPE_IP_PAIR_V6;
+ }
+
+ if(raw_layer_type == expect_layer_type){
+ return raw_data;
+ }
+
+ switch(raw_layer_type){
+ case ADDR_TYPE_MAC:
+ ret = eth_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ break;
+
+ case ADDR_TYPE_ARP:
+ ret = arp_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ break;
+ case ADDR_TYPE_VLAN:
+ if(treat_vlan_as_mac_in_mac_sw){
+ ret = mac_in_mac_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ }else{
+ ret = vlan8021q_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V4:
+ ret = ipv4_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ ret = ipv6_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ break;
+
+ case ADDR_TYPE_MAC_IN_MAC:
+ ret = mac_in_mac_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ break;
+
+ case ADDR_TYPE_UDP:
+ ret = udp_jump_to_layer((const char *)raw_data, raw_layer_type, expect_layer_type);
+ break;
+
+ case ADDR_TYPE_PPPOE_SES:
+ case ADDR_TYPE_MPLS:
+ case ADDR_TYPE_GRE:
+ default:
+ printf("TODO: jmp unsupport raw_layer_type:%d in MESA_net_jump_to_layer()!\n", raw_layer_type);
+ return NULL;
+ }
+
+ if(ret < 0){
+ return NULL;
+ }
+
+ return ((const char *)raw_data + ret);
+}
+
+/*
+ ��MESA_net_jump_to_layer()������:
+ MESA_net_jump_to_layer()������㿪ʼ, �ҵ���һ�����������IJ���˳�;
+ MESA_net_jump_to_layer_greedy()��һֱ���������ڲ�Э��ͷ, �ʺ�����ģʽ.
+
+ return value:
+ Non-NULL: the pointer to expect layer;
+ NULL: not found expect layer.
+*/
+const void *MESA_net_jump_to_layer_greedy(const void *raw_data, int raw_layer_type, int expect_layer_type)
+{
+ const void *expect_layer;
+ const void *success_layer = NULL; /* ���һ�γɹ��ҵ��IJ� */
+ int new_raw_layer_type = raw_layer_type; /* ����ת������, ���ܻ�����м����Ϣ */
+ const char *new_next_layer_data = (char *)raw_data;
+
+ expect_layer = MESA_net_jump_to_layer(new_next_layer_data, new_raw_layer_type, expect_layer_type);
+ while(expect_layer){
+ success_layer = expect_layer;
+
+ switch(expect_layer_type){
+ case __ADDR_TYPE_IP_PAIR_V4:
+ {
+ const struct mesa_ip4_hdr *ip4hdr = (const struct mesa_ip4_hdr *)expect_layer;
+ if(IPPROTO_UDP == ip4hdr->ip_p){
+ new_next_layer_data = (char *)expect_layer + ip4hdr->ip_hl * 4;
+ new_raw_layer_type = ADDR_TYPE_UDP; /* IP�������������һ��ƫ��, ֻ֧��UDP, IPIP, GRE, L2TPv3. */
+ }else{
+ //TODO 2, GRE, IPIP, L2TPv3
+ goto done;
+ }
+ }
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ {
+ //TODO2,
+ //sapp_runtime_log(20, "MESA_net_jump_to_layer_greedy() not support IPv6 layer yet\n");
+ goto done;
+ }
+ break;
+
+ default:
+ //sapp_runtime_log(20, "MESA_net_jump_to_layer_greedy() not support layer type:%d\n", expect_layer_type);
+ goto done;
+ }
+
+ expect_layer = MESA_net_jump_to_layer(new_next_layer_data, new_raw_layer_type, expect_layer_type);
+ }
+
+done:
+ return success_layer;
+}
+
+UINT8 net_layer_to_ipv4_protocol(int addr_type)
+{
+ UINT8 proto = 0;
+
+ switch(addr_type){
+ case __ADDR_TYPE_IP_PAIR_V4:
+ proto = IPPROTO_IPIP;
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ proto = IPPROTO_IPV6;
+ break;
+
+ case ADDR_TYPE_TCP:
+ proto = IPPROTO_TCP;
+ break;
+
+ case ADDR_TYPE_UDP:
+ proto = IPPROTO_UDP;
+ break;
+
+ case ADDR_TYPE_GRE:
+ proto = IPPROTO_GRE;
+ break;
+
+ default:
+ printf("unknown ip4 protocolr:%d\n", addr_type);
+ proto = 0xFF;
+ break;
+ }
+
+ return proto;
+}
+
+UINT8 net_layer_to_ipv6_protocol(int addr_type)
+{
+ UINT8 proto = 0;
+
+ switch(addr_type){
+ case ADDR_TYPE_TCP:
+ proto = 6; //NEXTHDR_TCP;
+ break;
+
+ case ADDR_TYPE_UDP:
+ proto = 17;///NEXTHDR_UDP;
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V4:
+ proto = 4;///NEXTHDR_IPIP;
+ break;
+
+ default:
+ printf("unknown ip6 next-hdr:%d\n", addr_type);
+ return 0xFF;
+ break;
+ }
+
+ return proto;
+}
+
+/*
+ ��MESA��ַ����ת��Ϊ��Ethernet����;
+
+ return value:
+ ethernet type, host order.
+*/
+UINT16 net_layer_to_ethernet_protocol(int addr_type)
+{
+ UINT16 ether_type = 0;
+
+ switch(addr_type){
+ case __ADDR_TYPE_IP_PAIR_V4:
+ ether_type = ETH_P_IP;
+ break;
+
+ case __ADDR_TYPE_IP_PAIR_V6:
+ ether_type = ETH_P_IPV6;
+ break;
+
+ case ADDR_TYPE_VLAN:
+ ether_type = ETHERTYPE_VLAN;
+ break;
+
+ case ADDR_TYPE_TCP:
+ case ADDR_TYPE_UDP:
+ //sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Ethernet can't carry addr type:%d directly!\n", __FILE__, __LINE__,addr_type);
+ //assert(0);
+ ether_type = -1;
+ break;
+
+ case ADDR_TYPE_PPPOE_SES:
+ ether_type = ETH_P_PPP_SES;
+ break;
+
+ case ADDR_TYPE_MPLS:
+ ether_type = ETH_P_MPLS_UC;
+ break;
+
+ case ADDR_TYPE_ARP:
+ ether_type = ETH_P_ARP;
+ break;
+
+ default:
+ /* to do, unknown type */
+ ///sapp_runtime_log(RLOG_LV_FATAL, "%s:%d: Ethernet addr type:%d!\n", __FILE__, __LINE__, addr_type);
+ ether_type = -1;
+ break;
+ }
+
+ return ether_type;
+}
+
+
+/* ɾ��ĩβ�Ļ��з�"\r\n" */
+void del_last_rn(char *data, int max_len)
+{
+ int i;
+ for(i = 0; i < max_len; i++){
+ if(('\r' == data[i]) || ('\n' == data[i])){
+ data[i] = '\0';
+ return;
+ }
+ }
+
+ return;
+}
+
+/*
+ ����ֵ:
+ ethernet����, ����ethͷ��.
+*/
+int get_pkt_len_from_eth_hdr(const struct mesa_ethernet_hdr *ehdr)
+{
+ int raw_pkt_len = -1;
+
+ switch(ntohs(ehdr->ether_type)){
+ case ETHERTYPE_IP:
+ {
+ struct mesa_ip4_hdr *ip4hdr = (struct mesa_ip4_hdr *)((char *)ehdr + sizeof(struct mesa_ethernet_hdr));
+ raw_pkt_len = ntohs(ip4hdr->ip_len) + sizeof(struct mesa_ethernet_hdr);
+ }
+ break;
+
+ case ETHERTYPE_IPv6:
+ {
+ struct mesa_ip6_hdr *ip6hdr = (struct mesa_ip6_hdr *)((char *)ehdr + sizeof(struct mesa_ethernet_hdr));
+ raw_pkt_len = ntohs(ip6hdr->ip6_payload_len) + sizeof(struct mesa_ip6_hdr) + sizeof(struct mesa_ethernet_hdr);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return raw_pkt_len;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/stream_base.h b/stream_base.h new file mode 100644 index 0000000..2311cee --- /dev/null +++ b/stream_base.h @@ -0,0 +1,520 @@ +#ifndef _APP_STREAM_BASE_H_
+#define _APP_STREAM_BASE_H_
+
+#define STREAM_BASE_H_VERSION (20170616)
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef UINT8
+typedef unsigned char UINT8;
+#endif
+#ifndef UCHAR
+typedef unsigned char UCHAR;
+#endif
+#ifndef UINT16
+typedef unsigned short UINT16;
+#endif
+
+#ifndef UINT32
+typedef unsigned int UINT32;
+#endif
+#ifndef UINT64
+typedef unsigned long long UINT64;
+#endif
+
+/* CHN : ������� */
+/* ENG : stream direction definition*/
+#define DIR_C2S 0x01
+#define DIR_S2C 0x02
+#define DIR_DOUBLE 0x03
+
+/* CHN : ����ײ㴫�䷽����,����ģʽ������ */
+/* ENG : network topology route direction, is valid in serial mode */
+#define DIR_ROUTE_UP 0x00
+#define DIR_ROUTE_DOWN 0x01
+
+/* CHN : ���������Ͷ��� */
+/* ENG : single packet type definition */
+#define PKT_TYPE_NORMAL (0x0) /* normal, common */
+#define PKT_TYPE_IPREBUILD (1<<0) /* ip frag reassembled packet; ip��Ƭ���鱨�� */
+#define PKT_TYPE_TCPUNORDER (1<<1) /* TCP out of order packet; TCP������ */
+#define PKT_TYPE_TCPREORDER (1<<2) /* TCP sequential packet; TCP��������õ����ݰ� */
+#define PKT_TYPE_TCPRETRANS (1<<3) /* TCP retransmit packet; TCP�ش����� */
+#define PKT_TYPE_IP_FRAG (1<<4) /* IP frag packet; IP��Ƭ�� */
+#define PKT_TYPE_IP_FRAG_LAST (1<<5) /* last IP frag packet; ͬ����һ��ԭʼ����IP�������һ��IP��Ƭ�� */
+
+/* CHN : ��ַ���Ͷ���, ��ͨ������ addr_type_to_string() ת���ַ�����ʽ. */
+/* ENG : address type, transform to string mode by call addr_type_to_string(). */
+enum addr_type_t{
+ __ADDR_TYPE_INIT = 0,
+ ADDR_TYPE_IPV4, /* 1, struct stream_tuple4_v4 */
+ ADDR_TYPE_IPV6, /* 2, struct stream_tuple4_v6 */
+ ADDR_TYPE_VLAN, /* 3 */
+ ADDR_TYPE_MAC, /* 4 */
+ ADDR_TYPE_ARP = 5, /* 5 */
+ ADDR_TYPE_GRE, /* 6 */
+ ADDR_TYPE_MPLS, /* 7 */
+ ADDR_TYPE_PPPOE_SES, /* 8 */
+ ADDR_TYPE_TCP, /* 9 */
+ ADDR_TYPE_UDP = 10, /* 10 */
+ ADDR_TYPE_L2TP, /* 11 */
+ __ADDR_TYPE_IP_PAIR_V4, /* 12, ipv4 layer in tunnel mode */
+ __ADDR_TYPE_IP_PAIR_V6, /* 13, ipv6 layer in tunnel mode */
+ ADDR_TYPE_PPP, /* 14 */
+ ADDR_TYPE_PPTP, /* 15 */
+ ADDR_TYPE_MAC_IN_MAC, /* 16 */
+ ADDR_TYPE_GPRS_TUNNEL, /* 17 */
+ __ADDR_TYPE_MAX, /* 18 */
+};
+
+#define TCP_TAKEOVER_STATE_FLAG_OFF 0
+#define TCP_TAKEOVER_STATE_FLAG_ON 1
+
+
+/* CHN : Ӧ�ò㿴��������״̬���� */
+/* ENG : stream state for protocol or business plug*/
+#define OP_STATE_PENDING 0
+#define OP_STATE_REMOVE_ME 1
+#define OP_STATE_CLOSE 2
+#define OP_STATE_DATA 3
+
+/* CHN : Ӧ�ò㷵�ؽ������ */
+/* ENG : return value of plug */
+#define APP_STATE_GIVEME 0x00
+#define APP_STATE_DROPME 0x01
+#define APP_STATE_FAWPKT 0x00
+#define APP_STATE_DROPPKT 0x10
+
+/* CHN : �������Ͷ��� */
+/* ENG : stream type */
+enum stream_type_t{
+ STREAM_TYPE_NON = 0, /* No stream concept indeed, such as vlan, IP, etc.; �����ĸ���, ��VLAN, IP��� */
+ STREAM_TYPE_TCP,
+ STREAM_TYPE_UDP, /* there is no stream of UDP in RFC, but in MESA platform, we build a UDP stream with same tuple4 packet */
+ STREAM_TYPE_VLAN,
+ STREAM_TYPE_SOCKS4,
+ STREAM_TYPE_SOCKS5,
+ STREAM_TYPE_HTTP_PROXY,
+ STREAM_TYPE_PPPOE,
+ STREAM_TYPE_L2TP,
+ STREAM_TYPE_OPENVPN,
+ STREAM_TYPE_PPTP,
+ STREAM_TYPE_ISAKMP,
+};
+
+/*
+ CHN: ���ĵײ������������,
+ ��ͬ��stream_type_t, ���統ǰ��ΪSTREAM_TYPE_TCP, ���ײ��������Ϳ�����STREAM_TUNNLE_PPTP.
+ ��Ϊ���������Ƕ��ֲ�ͬ����Ƕ�����, ֻ��¼��ײ�(��MAC�������)��������.
+*/
+enum stream_carry_tunnel_t{
+ STREAM_TUNNLE_NON = 0, /* default is 0, not tunnel; Ĭ��Ϊ0, ������; */
+ STREAM_TUNNLE_6OVER4 = 1 << 0,
+ STREAM_TUNNLE_4OVER6 = 1 << 1,
+ STREAM_TUNNLE_GRE = 1 << 2,
+ STREAM_TUNNLE_IP_IN_IP = 1 << 3,
+ STREAM_TUNNLE_PPTP = 1 << 4,
+ STREAM_TUNNLE_L2TP = 1 << 5,
+ STREAM_TUNNLE_TEREDO = 1 << 6,
+ STREAM_TUNNEL_GPRS_TUNNEL = 1 << 7,
+};
+
+typedef struct raw_ipfrag_list{
+ void *frag_packet;
+ int pkt_len;
+ int type; /* IPv4 or IPv6 */
+ struct raw_ipfrag_list *next;
+}raw_ipfrag_list_t;
+
+
+#ifndef STRUCT_TUPLE4_DEFINED
+#define STRUCT_TUPLE4_DEFINED (1)
+/* compat for start, papp; ����start, papp */
+struct tuple4 {
+ u_int saddr;
+ u_int daddr;
+ u_short source;
+ u_short dest;
+};
+#endif
+
+struct tuple6
+{
+ UCHAR saddr[16] ;
+ UCHAR daddr[16] ;
+ UINT16 source;
+ UINT16 dest;
+};
+
+/* network-order */
+struct stream_tuple4_v4{
+ UINT32 saddr; /* network order */
+ UINT32 daddr; /* network order */
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+
+#ifndef IPV6_ADDR_LEN
+#define IPV6_ADDR_LEN (sizeof(struct in6_addr))
+#endif
+
+struct stream_tuple4_v6
+{
+ UCHAR saddr[IPV6_ADDR_LEN] ;
+ UCHAR daddr[IPV6_ADDR_LEN] ;
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+
+#define GRE_TAG_LEN (4)
+struct layer_addr_gre
+{
+ UINT16 call_id; /* network order */
+};
+
+
+#define VLAN_ID_MASK (0x0FFF)
+#define VLAN_TAG_LEN (4)
+struct layer_addr_vlan
+{
+ UINT16 vlan_id; /* network order */
+};
+
+#define VLAN_ID_LEN 4
+struct tuplevlan
+{
+ UCHAR vlan_id[VLAN_ID_LEN];
+};
+
+struct layer_addr_pppoe_session
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int ver:4;
+ unsigned int type:4;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int type:4;
+ unsigned int ver:4;
+#endif
+ unsigned char code;
+ unsigned short session_id;
+};
+
+#ifndef MAC_ADDR_LEN
+#define MAC_ADDR_LEN (6)
+#endif
+
+struct layer_addr_mac
+{
+ UCHAR dst_mac[MAC_ADDR_LEN]; /* network order */
+ UCHAR src_mac[MAC_ADDR_LEN]; /* network order */
+};
+
+struct layer_addr_ipv4
+{
+ UINT32 saddr; /* network order */
+ UINT32 daddr; /* network order */
+ /* 2014-04-21 lijia add,
+ Ϊ�˽�Լ�ڴ�ռ䡢�ʹ���Ч��, ��ǿ�ư�Э���δ���,
+ IP���TCP����Ϊһ����,
+ �����������IP, �˿���ϢΪ0;
+ */
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+struct layer_addr_ipv6
+{
+ UCHAR saddr[IPV6_ADDR_LEN] ; /* network order */
+ UCHAR daddr[IPV6_ADDR_LEN] ; /* network order */
+ /* 2014-04-21 lijia add,
+ Ϊ�˽�Լ�ڴ�ռ䡢�ʹ���Ч��, ��ǿ�ư�Э���δ���,
+ IP���TCP����Ϊһ����,
+ �����������IP, �˿���ϢΪ0;
+ */
+ UINT16 source;/* network order */
+ UINT16 dest;/* network order */
+};
+
+struct layer_addr_tcp
+{
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+struct layer_addr_udp
+{
+ UINT16 source; /* network order */
+ UINT16 dest; /* network order */
+};
+
+
+struct layer_addr_l2tp_v2_t{
+ UINT16 tunnelid_C2S; /* network order, �Դ���㴴�����ķ���Ϊ */
+ UINT16 tunnelid_S2C; /* network order, �Դ���㴴�����ķ���Ϊ */
+ UINT16 sessionid_C2S; /* network order, �Դ���㴴�����ķ���Ϊ */
+ UINT16 sessionid_S2C; /* network order, �Դ���㴴�����ķ���Ϊ */
+};
+
+struct layer_addr_l2tp_v3_t{
+ UINT32 sessionlid; /* network order */
+};
+
+struct layer_addr_l2tp
+{
+ UCHAR version; /* v2 or v3 */
+ union
+ {
+ struct layer_addr_l2tp_v2_t l2tp_addr_v2;
+ struct layer_addr_l2tp_v3_t l2tp_addr_v3;
+ }l2tpun;
+};
+
+#define MAX_MPLS_ADDR_LAYER 4
+struct layer_addr_mpls
+{
+ unsigned int mpls_pkt[MAX_MPLS_ADDR_LAYER];
+ char mpls_layer_num;
+};
+
+struct layer_addr_pptp
+{
+ UINT16 C2S_call_id; /* C2S�Դ����Э�鷽��Ϊ, TCP SYNΪC2S, UDPԴ�˿ڴ��ΪC2S, callid, network order */
+ UINT16 S2C_call_id; /* S2Ck�Դ����Э�鷽��Ϊ, TCP SYN/ACKΪS2C, UDPĿ�Ķ˿ڴ��ΪS2C, callid, network order */
+};
+
+struct layer_addr_gtp
+{
+ unsigned long long source;
+ unsigned int src_seq;
+ unsigned long long dest;
+ unsigned int dest_seq;
+}__attribute__ ((aligned (1)));
+
+#define MAC_IN_MAC_HDR_LEN (sizeof(struct mesa_ethernet_hdr) + sizeof(struct mesa_ethernet_hdr))
+struct layer_addr_mac_in_mac
+{
+ UCHAR outer_dst_mac[MAC_ADDR_LEN]; /* �����mac��ַ, network order */
+ UCHAR outer_src_mac[MAC_ADDR_LEN]; /* �����mac��ַ, network order */
+ UCHAR inner_dst_mac[MAC_ADDR_LEN]; /* �ڲ�mac��ַ, network order */
+ UCHAR inner_src_mac[MAC_ADDR_LEN]; /* �ڲ�mac��ַ, network order */
+};
+
+struct layer_addr
+{
+ UCHAR addrtype; /* definition in enum addr_type_t */
+ UCHAR addrlen;
+ UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */
+ UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */
+
+ UCHAR __pad[4]; /* pad for alignment */
+ union
+ {
+ struct stream_tuple4_v4 *tuple4_v4;
+ struct stream_tuple4_v6 *tuple4_v6;
+ struct layer_addr_ipv4 *ipv4;
+ struct layer_addr_ipv6 *ipv6;
+ struct layer_addr_vlan *vlan;
+ struct layer_addr_mac *mac;
+ struct layer_addr_gre *gre;
+ struct layer_addr_tcp *tcp;
+ struct layer_addr_udp *udp;
+ struct layer_addr_pppoe_session *pppoe_ses;
+ struct layer_addr_l2tp *l2tp;
+ struct layer_addr_pptp *pptp;
+ struct layer_addr_mac_in_mac *mimac;
+ struct layer_addr_gtp *gtp;
+ void *paddr;
+ };
+
+};
+
+/* CHN : �����˽ṹ���ں�papp����, ����ָ��ʱ, ����struct layer_addrǿת */
+/* ENG : compat for papp, can be transform to struct layer_addr pointer */
+struct ipaddr
+{
+ UCHAR addrtype; /* definition in enum addr_type_t */
+ UCHAR addrlen;
+ UCHAR pkttype; /* packet special features, definition in MACRO PKT_TYPE_xxx */
+ UCHAR pktipfragtype; /* ip frag packetfeatures, definition in MACRO PKT_TYPE_xxx */
+ UCHAR __pad[4]; /* pad for alignment */
+ union
+ {
+ struct stream_tuple4_v4 *v4;
+ struct stream_tuple4_v6 *v6;
+ void *paddr;
+ };
+
+};
+
+struct tcpdetail
+{
+ void *pdata;
+ UINT32 datalen;
+ UINT32 lostlen; /* lost data len, not accumulated, current procedure */
+ UINT32 serverpktnum; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT32 clientpktnum; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT32 serverbytes; /* C2S, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT32 clientbytes; /* S2C, this value indicate TCP-ALL packet, include syn, ack, rst, if want get tcp data status, use stream_project.h : struct tcp_flow_stat */
+ UINT64 createtime;
+ UINT64 lastmtime;
+};
+
+struct udpdetail
+{
+ void *pdata;
+ UINT32 datalen;
+ UINT32 pad;
+ UINT32 serverpktnum; /* C2S, you should better use stream_project.h : struct udp_flow_stat */
+ UINT32 clientpktnum; /* S2C, you should better use stream_project.h : struct udp_flow_stat */
+ UINT32 serverbytes; /* C2S, you should better use stream_project.h : struct udp_flow_stat */
+ UINT32 clientbytes; /* S2C, you should better use stream_project.h : struct udp_flow_stat */
+ UINT64 createtime;
+ UINT64 lastmtime;
+};
+
+struct streaminfo
+{
+ struct layer_addr addr;
+ struct streaminfo *pfather; /* this stream's carry layer stream; �ϲ����ṹ�� */
+ UCHAR type; /* stream type, definition in enum stream_type_t */
+ UCHAR threadnum;
+ UCHAR dir; /* valid in all stream life, current stream direction state, 0x01:c-->s; 0x02:s-->c; 0x03 c<-->s; */
+ UCHAR curdir; /* valid in current procedure, current packet direction, 0x01:c-->s; 0x02:s-->c */
+ UCHAR opstate; /* stream state, definition in MACRO OP_STATE_xxx */
+ UCHAR pktstate; /* for TCPALL plug, stream state, definition in MACRO OP_STATE_xxx */
+ UCHAR routedir; /* network topology route direction, is valid in serial mode */
+ UCHAR stream_state; /* stream management state, for example, in TCP stream, maybe SYN, DATA, NOUSE */
+ UINT32 hash_index; /* stream hash index, maybe reduplicate with other stream when hash algorithm collide */
+ UINT32 stream_index; /* stream global index per thread */
+ union
+ {
+ struct tcpdetail *ptcpdetail;
+ struct udpdetail *pudpdetail;
+ void *pdetail;
+ };
+ };
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CHN : �ڴ������غ���, ����ƽ̨�IJ������ʹ�ô��ຯ��������ͷ��ڴ� */
+/* ENG : memory management function, plugs must call these functions instead of malloc, free in <stdlib.h> */
+void *dictator_malloc(int thread_seq,size_t size);
+void dictator_free(int thread_seq,void *pbuf);
+void *dictator_realloc(int thread_seq, void* pbuf, size_t size);
+
+/* CHN : ��ȡ��ǰϵͳ���еIJ��������߳����� */
+/* ENG : get current total thread of platfomr */
+int get_thread_count(void);
+
+/* CHN : ����enum addr_type_tַ����ת���ɿɴ�ӡ���ַ�����ʽ */
+/* ENG : transform binary addr_type_t to string mode */
+const char *addr_type_to_string(enum addr_type_t type);
+
+/*
+ ENG : transform tuple4 to string mode, must used in packet process thread context;
+ CHN : ��layer_addr��ַת�����ַ�����ʽ, �������ڰ������߳�.
+*/
+const char *printaddr (const struct layer_addr *paddrinfo, int threadindex);
+
+/*
+ ENG : a reentrant version of printaddr, thread safe;
+ CHN : printaddr�Ŀ�����汾, ���̰߳�ȫ��.
+*/
+const char *printaddr_r(const struct layer_addr *paddrinfo, char *out_buf, int out_buf_len);
+
+
+/*
+ ENG : transform layer address to string mode, must used in packet process thread context,
+ the return value is read-only, user can't free it;
+ CHN : ��layer_addr��ַת�����ַ�����ʽ, �������ڰ������߳�, ���ص�ָ��Ϊֻ��, ʹ���߲���free.
+*/
+const char *layer_addr_ntop(const struct streaminfo *pstream);
+
+/*
+ ENG : a reentrant version of layer_addr_ntop, thread safe, return a pointer to the destination string 'out_buf';
+ CHN : layer_addr_ntop_r�Ŀ�����汾, ���̰߳�ȫ��, ���ص�ָ��ִ��ʹ�����ṩ��out_buf, ���ڴ�����֯.
+*/
+char *layer_addr_ntop_r(const struct streaminfo *pstream, char *out_buf, int out_buf_len);
+
+/*
+ ENG : transform layer type to abbr string mode, is reentrant, the return value is read-only, user can't free it;.
+ CHN : ��layer_addr��ַ����ת������д�ַ�����ʽ, �������̰߳�ȫ, ���ص�ָ��Ϊֻ��, ʹ���߲���free..
+*/
+const char *layer_addr_prefix_ntop(const struct streaminfo *pstream);
+
+
+/*
+ ENG : duplicate a same layer_addr struct, memory obtained with malloc(3);
+ CHN : ����һ����ȫ��ͬ��layer_addr�ṹ��, �ڴ�ͨ��malloc(3)��ȡ.
+*/
+struct layer_addr * layer_addr_dup(const struct layer_addr *paddrinfo);
+
+/*
+ ENG: used to free all memory of paddrinfo;
+ CHN: �����ͷ�paddrinfo�ڴ�.
+*/
+void layer_addr_free(struct layer_addr *paddrinfo);
+
+
+/*
+ ENG : duplicate a same streaminfo list, memory obtained with malloc(3);
+ CHN : ����һ����ȫ��ͬ��streaminfo�ṹ�弰�����ṹ, �ڴ�ͨ��malloc(3)��ȡ.
+*/
+struct streaminfo *streaminfo_dup(const struct streaminfo *stream);
+
+/*
+ ENG: used to free all memory of streaminfo;
+ CHN: �����ͷŽṹ�弰�����ṹ���ڴ�.
+*/
+void streaminfo_free(struct streaminfo *stream);
+
+
+/*
+ addr list transform function, like inet_ntop(), inet_pton(),
+ use '<' as delimitation between layer,
+ if direction is double, for ip, port, use '-' as delimitation between source and destination,
+
+ for example:
+ "T4T:6005-1673<IP4:61.147.112.53-11.215.62.23<MAC:0000ea60040d-0200000003b6"
+
+ args:
+ pstream : stream info;
+ dst : buf to store result;
+ size : dst buf's size;
+ addr_list_str: addr list string;
+ thread_index : thread index;
+
+ ����ֵ:
+ >0:ת����Ľ��ʵ��ռ���ڴ泤��, stream_addr_list_ntop()�������ַ���ĩβ��'\0';
+ -1:dst����ռ䳤�Ȳ���;
+ -2:��ʽ����;
+ -3:��������;
+*/
+int stream_addr_list_ntop(const struct streaminfo *pstream, char *dst, int size);
+int stream_addr_list_pton(const char *addr_list_str, void *dst, int size, int thread_index);
+
+/*
+ TCP,UDP��ģʽ��, ��ȡ��ǰIP����ԭʼ��Ƭ��.
+*/
+const raw_ipfrag_list_t *get_raw_frag_list(const struct streaminfo *stream);
+
+/*
+ IP���ģʽ��, ��ȡ��ǰIP����ԭʼ��Ƭ��.
+*/
+const raw_ipfrag_list_t *ip_plug_get_raw_ipfrag_list(int thread_num, enum addr_type_t addr_type);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
@@ -32,6 +32,8 @@ * * @(#)tcp.h 8.1 (Berkeley) 6/10/93 */ +#ifndef _tcpdump_tcp_h +#define _tcpdump_tcp_h 1 typedef uint32_t tcp_seq; /* @@ -157,3 +159,6 @@ struct tcphdr { #ifndef REDIS_PORT #define REDIS_PORT 6379 #endif + +#endif + @@ -44,13 +44,15 @@ #define MESA_DUMP (1) #if MESA_DUMP #include "mesa_pkt_dump.h" -const int tcpdump_mesa_version_VERSION_20180119 = 20180119; +const int tcpdump_mesa_version_VERSION_20181114 = 20181114; int tcpdump_data_offset = 0; /* ��������ijЩ�ײ�����, ��vxlan, ����ֱ�ӻ�ȡ�����ù���������vxlan���ڲ����ݰ����� */ unsigned char tcpdump_thread_index_array[64]; /* ���������߳�id����, �����Ⱦ���id����, ÿ��ռ1�ֽ�, ����������֧�ֶ��ŷָ� */ int tcpdump_thread_index_array_num = 0; const char *tcpdump_thread_index_str; int tcpdump_perceptive_flag = 0; unsigned int perceptive_pkt_seq[256]; /* ���֧��256���߳� */ +static int greedy_seek_flag = 0; /* ƫ�Ƶ����ڲ�IP, ��������ģʽ�²���BUG */ +static int dump_to_file_flag = 0; /* �Ƿ���-w ���� */ #endif #ifndef lint @@ -485,8 +487,8 @@ show_devices_and_exit (void) #define Q_FLAG #endif -#if MESA_DUMP /* lijia add, ��������k, o, P */ -#define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "k:KlLm:M:nNo:OP:pq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#" +#if MESA_DUMP /* lijia add, ��������g, k, o, P */ +#define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:gG:hHi:" I_FLAG j_FLAG J_FLAG "k:KlLm:M:nNo:OP:pq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#" #else #define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#" #endif @@ -786,7 +788,85 @@ set_dumper_capsicum_rights(pcap_dumper_t *p) #endif #if MESA_DUMP +#include "mesa_net.h" +#include "stream_base.h" +static int MESA_dump_seek_to_inner(char *pkt_buf, int pktlen) +{ + struct mesa_ethernet_hdr *ehdr = (struct mesa_ethernet_hdr *)pkt_buf; + char *first_ip_layer = NULL; + struct mesa_ip4_hdr *ip4hdr_greedy; + struct mesa_ip6_hdr *ip6hdr_greedy; + int bpf_match_pkt_len = -1; + int bpf_match_ipv4 = 0, bpf_match_ipv6 = 0; + + if(ETHERTYPE_IP == ntohs(ehdr->ether_type)){ + first_ip_layer = pkt_buf + sizeof(struct mesa_ethernet_hdr); + }else if(ETHERTYPE_IPv6 == ntohs(ehdr->ether_type)){ + first_ip_layer = pkt_buf + sizeof(struct mesa_ethernet_hdr); + }else{ + first_ip_layer = NULL; + } + + ip4hdr_greedy = (struct mesa_ip4_hdr *)MESA_net_jump_to_layer_greedy(pkt_buf, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V4); + if(ip4hdr_greedy){ + if((char *)ip4hdr_greedy == first_ip_layer){ + bpf_match_pkt_len = pktlen; /* ���ڲ�͵�һ��IPһ��, ˵���DZ�ethernet->IPv4��, ����memmove���� */ + }else{ + memmove(pkt_buf + sizeof(struct mesa_ethernet_hdr), + ip4hdr_greedy, + pktlen - ((char *)ip4hdr_greedy - pkt_buf)); + bpf_match_pkt_len = pktlen - ((char *)ip4hdr_greedy - pkt_buf) + sizeof(struct mesa_ethernet_hdr); + ehdr->ether_type = htons(ETHERTYPE_IP); /* ��һ����ܲ���IPV4, ����MPLS, VLAN��, ��Ҫ�ij�IP, �Ա�bpf����������ȷִ�� */ + } + if(bpf_match_pkt_len <= 0){ + return -1; + } + + /* �������ȷ�Ĺ�������, ���������, ��֤��������ȫ, ���ϵ�������ͼ; + ���û�й�������, ��ȫ����ģʽ, Ϊ�˾�����Ӱ��������߳�, ���ݲ�����ֻ��һ���ְ�. + */ + + bpf_match_ipv4 = 1; + }else{ + bpf_match_ipv4 = 0; + } + + ip6hdr_greedy = (struct mesa_ip6_hdr *)MESA_net_jump_to_layer_greedy(pkt_buf, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V6); + if(ip6hdr_greedy){ + if((char *)ip6hdr_greedy == first_ip_layer){ + bpf_match_pkt_len = pktlen; /* ���ڲ�͵�һ��IPһ��, ˵���DZ�ethernet->IPv6��, ����memmove���� */ + }else{ + memmove(pkt_buf + sizeof(struct mesa_ethernet_hdr), + ip6hdr_greedy, + pktlen - ((char *)ip6hdr_greedy - pkt_buf)); + bpf_match_pkt_len = pktlen - ((char *)ip4hdr_greedy - pkt_buf) + sizeof(struct mesa_ethernet_hdr); + ehdr->ether_type = htons(ETHERTYPE_IPv6); /* ��һ����ܲ���IPV6, ����MPLS, VLAN��,��Ҫ�ij�IP,�Ա�bpf����������ȷִ�� */ + } + + if(bpf_match_pkt_len <= 0){ + ///sapp_runtime_log(20, "cycle_pkt_dump_seek_to_inner_ip() length error!\n"); + return -1; + } + + + /* �������ȷ�Ĺ�������, ���������, ��֤��������ȫ, ���ϵ�������ͼ; + ���û�й�������, ��ȫ����ģʽ, Ϊ�˾�����Ӱ��������߳�, ���ݲ�����ֻ��һ���ְ�. + */ + bpf_match_ipv6 = 1; + }else{ + bpf_match_ipv6 = 0; + } + + if(bpf_match_ipv4 || bpf_match_ipv6){ + return bpf_match_pkt_len; /* ����ͷ�����м������ */ + } + + return -1; +} + + +/* ��֧�ֶ���߳�, �ö��ŷָ�"1,3,5,7" */ static int MESA_dump_thread_index_convert(const char *raw_index_str) { char *index_str = strdup(raw_index_str); @@ -878,6 +958,24 @@ static int pkt_dump_recv_ack(int connfd) return 0; } +#include <pthread.h> +static void *detect_sapp_thread(void *arg) +{ + int tcp_cmd_fd = (int)arg; + int ret; + char nouse_buf[1500]; + + while(1){ + ret = read(tcp_cmd_fd, nouse_buf, 1500); + if(0 == ret){ + printf("\033[33m[INFO]sapp is not running, tcpdump_mesa exit!\033[0m\n"); + exit(1); + } + } + + return NULL; +} + static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_port, char *filter) { int tcp_cmd_fd = -1; @@ -887,6 +985,7 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_ struct pkt_dump_handshake pkt_hdr; unsigned int opt_num = 1; /* ���˽��ն˿�Ϊ��ѡ�� */ struct pkt_dump_opt opt; + pthread_t pid; tcp_cmd_fd = socket(AF_INET, SOCK_STREAM, 0); @@ -923,7 +1022,7 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_ /************** pkt handshake *************/ pkt_hdr.magic = htonl(PKT_DUMP_HDR_MAGIC); - pkt_hdr.version = htonl(tcpdump_mesa_version_VERSION_20180119); + pkt_hdr.version = htonl(tcpdump_mesa_version_VERSION_20181114); pkt_hdr.opt_num = htonl(opt_num); ret = write(tcp_cmd_fd, &pkt_hdr, sizeof(pkt_hdr)); if(ret < 0){ @@ -1012,6 +1111,8 @@ static int MESA_dump_start(unsigned short udp_rcv_port, unsigned short sapp_cmd_ exit(1); } + pthread_create(&pid, NULL, detect_sapp_thread, (void *)tcp_cmd_fd); + return tcp_cmd_fd; } @@ -1066,7 +1167,7 @@ static void MESA_dump(pcap_handler callback, u_char *pcap_userdata, char *filter int tot_pkt, unsigned short sapp_cmd_port ) { unsigned short udp_default_port = 12345; - int opt, pkt_len; + int opt, pkt_len, inner_pkt_len; unsigned char pkt_buf[65536]; struct pcap_pkthdr phony_pcap_hdr; int udp_rcv_fd = -1; @@ -1119,10 +1220,24 @@ static void MESA_dump(pcap_handler callback, u_char *pcap_userdata, char *filter } perceptive_pkt_seq[pperceptive->thread_id] = cur_pkt_seq; } - phony_pcap_hdr.caplen = pkt_len; - phony_pcap_hdr.len = pkt_len; + + /* �����-g����, ��д��-w, ����Ҫ����ԭʼ�����ļ�, ����seek����, + ֻ����û��-w ����ʱ, ��tcpdump�ܴ�ӡ��������Ϣ, �Ž���seek����. + */ + if((greedy_seek_flag != 0) && (dump_to_file_flag == 0)){ + inner_pkt_len = MESA_dump_seek_to_inner(pkt_buf, pkt_len); + if(inner_pkt_len < 0){ + continue; + } + phony_pcap_hdr.caplen = inner_pkt_len; + phony_pcap_hdr.len = inner_pkt_len; + }else{ + phony_pcap_hdr.caplen = pkt_len; + phony_pcap_hdr.len = pkt_len; + } gettimeofday(&phony_pcap_hdr.ts, NULL); - callback(pcap_userdata, &phony_pcap_hdr, pkt_buf); /* ˢ��ģʽ����print_packet(); ����ģʽ����: dump_packet() */ + + callback(pcap_userdata, &phony_pcap_hdr, pkt_buf); /* NOTE: ˢ��ģʽ����print_packet(); ����ģʽ����: dump_packet() */ actual_rcv_pkt_num++; } } @@ -1302,6 +1417,13 @@ main(int argc, char **argv) case 'F': infile = optarg; break; + +#if MESA_DUMP + case 'g': + greedy_seek_flag = 1; + break; +#endif + case 'G': Gflag = atoi(optarg); @@ -1385,6 +1507,21 @@ main(int argc, char **argv) break; #endif +#if MESA_DUMP + case 'k': + tcpdump_thread_index_str = optarg; + if(MESA_dump_thread_index_convert(tcpdump_thread_index_str) < 0){ + printf("thread index invalid: %s\n", optarg); + exit(1); + } + break; +#endif + + case 'K': + ++ndo->ndo_Kflag; + break; + + case 'l': #ifdef _WIN32 /* @@ -1409,20 +1546,6 @@ main(int argc, char **argv) case 'L': Lflag++; break; - -#if MESA_DUMP - case 'k': - tcpdump_thread_index_str = optarg; - if(MESA_dump_thread_index_convert(tcpdump_thread_index_str) < 0){ - printf("thread index invalid: %s\n", optarg); - exit(1); - } - break; -#endif - - case 'K': - ++ndo->ndo_Kflag; - break; case 'm': #ifdef USE_LIBSMI @@ -1503,7 +1626,12 @@ main(int argc, char **argv) #endif /* HAVE_PCAP_SETDIRECTION */ case 'r': +#if MESA_DUMP + printf("tcpdump_mesa not support -r arg, only support capture from sapp so far, TODO!\n"); + exit(1); +#else RFileName = optarg; +#endif break; case 's': @@ -1582,6 +1710,9 @@ main(int argc, char **argv) case 'w': WFileName = optarg; +#if MESA_DUMP + dump_to_file_flag = 1; +#endif break; case 'W': @@ -2863,9 +2994,11 @@ print_usage(void) (void)fprintf(stderr, "----------------------------------------------------------------------------------------------.\n"); (void)fprintf(stderr, -"\t\tThe follow args is customized for tcpdump_mesa:\n"); +"\t\tThe follow args is customized for tcpdump_mesa(%d):\n", tcpdump_mesa_version_VERSION_20181114); + (void)fprintf(stderr, +"\t\t[ -a ] enable perceptive mode, can detect loss packet number.\n"); (void)fprintf(stderr, -"\t\t[ -a ] to enable perceptive mode, can detect loss packet number.\n"); +"\t\t[ -g greedy-seek ] enable greedy seek to most inner IP layer, for tunnel, embed protocol.\n"); (void)fprintf(stderr, "\t\t[ -k thread-id ] to assign sapp recv thread id, support multi-range, for example: 1,3,5,7.\n"); (void)fprintf(stderr, @@ -32,6 +32,8 @@ * * @(#)udp.h 8.1 (Berkeley) 6/10/93 */ +#ifndef _tcpdump_udp_h +#define _tcpdump_udp_h 1 /* * Udp protocol header. @@ -314,3 +316,6 @@ struct udphdr { #ifndef LWAPP_CONTROL_PORT #define LWAPP_CONTROL_PORT 12223 /* RFC 5412 */ #endif + +#endif + |
