#ifndef _TYPES_H_ #define _TYPES_H_ #ifdef __cpluscplus extern "C" { #endif #include #include #include #include #include #include #include enum addr_type { ADDR_TYPE_UNKNOWN, ADDR_TYPE_MAC, ADDR_TYPE_ARP, ADDR_TYPE_IPV4, ADDR_TYPE_IPV6, ADDR_TYPE_TCP, ADDR_TYPE_UDP, ADDR_TYPE_ICMPV4, ADDR_TYPE_ICMPV6, ADDR_TYPE_PPTP, ADDR_TYPE_L2TP, ADDR_TYPE_SOCKS, ADDR_TYPE_GTPU, ADDR_TYPE_PPPOE, ADDR_TYPE_GRE, ADDR_TYPE_VLAN, ADDR_TYPE_MPLS, ADDR_TYPE_PPP, ADDR_TYPE_VXLAN, ADDR_TYPE_MAX }; struct layer_addr_mac { struct ethhdr smac; struct ethhdr dmac; }; struct layer_addr_ipv4 { uint32_t saddr; /* network order */ uint32_t daddr; /* network order */ }; struct layer_addr_ipv6 { struct in6_addr saddr; struct in6_addr daddr ; }; struct layer_addr_tuple4 { struct layer_addr_ipv4 ipv4; uint16_t source; /* network order */ uint16_t dest; /* network order */ }; struct layer_addr_tuple6 { struct layer_addr_ipv6 ipv6; uint16_t source; /* network order */ uint16_t dest; /* network order */ }; /* * https://datatracker.ietf.org/doc/html/rfc2637 * https://wwwdisc.chimica.unipd.it/luigino.feltre/pubblica/unix/winnt_doc/pppt/understanding_pptp.html#:~:text=Introduction-,Point%2Dto%2DPoint%20Tunneling%20Protocol%20(PPTP)%20is%20a,%2FIP%2Dbased%20data%20networks. * 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |C|R|K|S|s|Recur|A| Flags | Ver | Protocol Type | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Key (HW) Payload Length | Key (LW) Call ID | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number (Optional) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number (Optional) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ struct pptp_gre_header { uint16_t checksum:1; /* Checksum Bit: Checksum field Present */ uint16_t routing:1; /* Routing Bit: Routing field Present */ uint16_t key:1; /* Key Bit: Key field Present */ uint16_t sequence:1; /* Sequence Bit: sequence present. Set to one (1) if a payload (data) packet is present. Set to zero (0) if payload is not present (GRE packet is an Acknowledgment only) */ uint16_t strict:1; /* Strict Bit: Strict source route present*/ uint16_t recursion:3; /* Recursion Bit: Recursion control */ uint16_t acknowledgment:1; /* Acknowledgment Bit: Acknowledgment sequence number present */ uint16_t flags:4; /* Must be set to zero */ uint16_t version:3; /* Must contain 1 (enhanced GRE) */ }; struct layer_addr_pptp { uint16_t pac_call_id; /* callid, network order */ uint16_t pns_call_id; /* callid, network order */ }; /* * https://en.wikipedia.org/wiki/Layer_2_Tunneling_Protocol * The two endpoints of an L2TP tunnel are called the L2TP access concentrator (LAC) and the L2TP network server (LNS). * https://docs.huihoo.com/doxygen/linux/kernel/3.7/l2tp__core_8c_source.html * Do receive processing of L2TP data frames. We handle both L2TPv2 * and L2TPv3 data frames here. * * L2TPv2 Data Message Header * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |T|L|x|x|S|x|O|P|x|x|x|x| Ver | Length (opt) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Tunnel ID | Session ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Ns (opt) | Nr (opt) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Offset Size (opt) | Offset pad... (opt) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Data frames are marked by T=0. All other fields are the same as * those in L2TP control frames. * * L2TPv3 Data Message Header * * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | L2TP Session Header | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | L2-Specific Sublayer | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Tunnel Payload ... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * L2TPv3 Session Header Over IP * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Session ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Cookie (optional, maximum 64 bits)... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * L2TPv3 L2-Specific Sublayer Format * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |x|S|x|x|x|x|x|x| Sequence Number | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * * Cookie value, sublayer format and offset (pad) are negotiated with * the peer when the session is set up. Unlike L2TPv2, we do not need * to parse the packet header to determine if optional fields are * present. * * Caller must already have parsed the frame and determined that it is * a data (not control) frame before coming here. Fields up to the * session-id have already been parsed and ptr points to the data * after the session-id. */ struct layer_ppp_header { uint8_t address; uint8_t control; uint16_t protocol; /* network order */ }; struct layer_ppp_compress_header { uint8_t protocol; }; struct layer_addr_l2tp_v2 { uint16_t lac_tunnelid; /* network order */ uint16_t lns_tunnelid; /* network order */ uint16_t lac_sessionid; /* network order */ uint16_t lns_sessionid; /* network order */ uint8_t ppp_compress_hdr_enable; union { struct layer_ppp_header ppp_hdr; struct layer_ppp_compress_header ppp_compress_hdr; }; }; struct layer_addr_l2tp_v3 { uint32_t sessionlid; /* network order */ }; struct l2tp_packet_type { uint16_t type:1; /* */ uint16_t length:1; /* Lenght Bit: length field is not present */ uint16_t padding1:2; uint16_t sequence:1; /* Sequence Bit: sequence(ns and nr) field is not present */ uint16_t padding2:1; uint16_t offset:1; /* Offset Bit: Offset size filed is present */ uint16_t priority:1; /* Priority Bit */ uint16_t padding:4; uint16_t version:4; }; struct layer_addr_l2tp { struct l2tp_packet_type l2tp_packet; union { struct layer_addr_l2tp_v2 v2; struct layer_addr_l2tp_v3 v3; }; }; struct layer_addr_gtp { uint32_t c2s_teid; /* network order */ uint32_t s2c_teid; /* network order */ }; #define VLAN_ID_MASK (0x0FFF) #define VLAN_TAG_LEN (4) #define MAX_VLAN_ADDR_LAYER (8) /* refer to https://en.wikipedia.org/wiki/IEEE_802.1Q */ struct layer_addr_single_vlan { uint8_t PCP; /* Priority code point */ uint8_t DEI; /* Drop eligible indicator */ uint16_t TPID; /* Tag protocol identifier, network order */ uint16_t VID; /* VLAN identifier, network order */ }; struct layer_addr_vlan { uint8_t c2s_layer_num; uint8_t s2c_layer_num; struct layer_addr_single_vlan c2s_addr_array[MAX_VLAN_ADDR_LAYER]; struct layer_addr_single_vlan s2c_addr_array[MAX_VLAN_ADDR_LAYER]; }; #define MAX_MPLS_ADDR_LAYER 4 /* refer to RFC3032 */ struct layer_addr_single_mpls { uint32_t label; /* network order */ uint8_t experimental; uint8_t bottom; uint8_t ttl; }; struct layer_addr_mpls { struct layer_addr_single_mpls c2s_addr_array[MAX_MPLS_ADDR_LAYER]; struct layer_addr_single_mpls s2c_addr_array[MAX_MPLS_ADDR_LAYER]; uint8_t c2s_layer_num; /* mpls layer number */ uint8_t s2c_layer_num; /* mpls layer number */ uint8_t c2s_ctrl_word_flag; uint8_t s2c_ctrl_word_flag; uint32_t c2s_ctrl_word; /* refer to RFC4623 */ uint32_t s2c_ctrl_word; /* refer to RFC4623 */ }; #if 0 https://en.wikipedia.org/wiki/Generic_Routing_Encapsulation struct layer_addr_gre { uint16_t call_id; /* network order */ }; #endif struct layer_addr_pppoe { #if __BYTE_ORDER == __LITTLE_ENDIAN uint32_t ver:4; uint32_t type:4; #elif __BYTE_ORDER == __BIG_ENDIAN uint32_t type:4; uint32_t ver:4; #endif uint8_t code; uint16_t session_id; }; struct raw_ipfrag_list { void *packet_frag; /* not ip header, the original header obtained from the underlying network card */ uint32_t packet_len; int32_t packet_type; /* IPv4 or IPv6 */ struct raw_ipfrag_list *next; }; #ifdef __cpluscplus } #endif #endif