diff --git a/openair-cn/GTPV1-U/GTPURH/xt_GTPURH.c b/openair-cn/GTPV1-U/GTPURH/xt_GTPURH.c index e84222202f..b9119967fe 100755 --- a/openair-cn/GTPV1-U/GTPURH/xt_GTPURH.c +++ b/openair-cn/GTPV1-U/GTPURH/xt_GTPURH.c @@ -157,12 +157,14 @@ static inline void hash_del_rcu(struct hlist_node *node) * @name: hashtable to iterate * @bkt: integer to use as bucket loop cursor * @obj: the type * to use as a loop cursor for each entry + * @pos: the &struct hlist_node to use as a loop cursor. * @member: the name of the hlist_node within the struct */ -#define hash_for_each(name, bkt, obj, member) \ +#define hash_for_each(name, bkt, obj, pos, member) \ for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\ (bkt)++)\ - hlist_for_each_entry(obj, &name[bkt], member) + hlist_for_each_entry(obj, pos, &name[bkt], member) + /** * hash_for_each_rcu - iterate over a rcu enabled hashtable @@ -247,12 +249,6 @@ static inline void hash_del_rcu(struct hlist_node *node) #endif - - - - - - struct gtpuhdr { char flags; @@ -275,8 +271,8 @@ struct gtpuhdr static char _gtpurh_print_buffer[GTPURH_2_PRINT_BUFFER_LEN]; -typedef struct ip_fragment_entry_s { - struct sk_buff *skb; +/*typedef struct ip_fragment_entry_s { + struct sk_buff *skb_p; //struct timeval first_ts; // TO DO WITH IP_FRAG_TIME int flags; //ip header field int offset; //ip header field @@ -286,17 +282,20 @@ typedef struct ip_fragment_entry_s { typedef struct ip_reassembly_entry_s { }ip_reassembly_entry_t; +*/ - - -#define MAX_IP_FRAGMENTS 16; +static inline bool _gtpurh_ip_is_fragment(const struct iphdr *iph_p) +{ + return (iph_p->frag_off & htons(IP_MF | IP_OFFSET)) != 0; +} +#define MAX_IP_FRAGMENTS 16 #define GTPURH_HASHTABLE_BITS 7 DEFINE_HASHTABLE(ip_fragments, GTPURH_HASHTABLE_BITS); //----------------------------------------------------------------------------- -void _gtpurh_print_hex_octets(unsigned char* dataP, unsigned short sizeP) +void _gtpurh_print_hex_octets(unsigned char* data_pP, unsigned short sizeP) //----------------------------------------------------------------------------- { unsigned long octet_index = 0; @@ -306,9 +305,12 @@ void _gtpurh_print_hex_octets(unsigned char* dataP, unsigned short sizeP) char timeofday[64]; unsigned int h,m,s; - if (dataP == NULL) { + if (data_pP == NULL) { return; } + if (sizeP > 2000) { + return; + } do_gettimeofday(&tv); h = (tv.tv_sec/3600) % 24; @@ -319,17 +321,19 @@ void _gtpurh_print_hex_octets(unsigned char* dataP, unsigned short sizeP) buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday); buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday); buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday); + pr_info("%s",_gtpurh_print_buffer);buffer_marker = 0; for (octet_index = 0; octet_index < sizeP; octet_index++) { if ((octet_index % 16) == 0){ if (octet_index != 0) { buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n"); + pr_info("%s",_gtpurh_print_buffer);buffer_marker = 0; } buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, "%s %04ld |",timeofday, octet_index); } /* * Print every single octet in hexadecimal form */ - buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " %02x", dataP[octet_index]); + buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " %02x", data_pP[octet_index]); /* * Align newline and pipes according to the octets in groups of 2 */ @@ -346,17 +350,18 @@ void _gtpurh_print_hex_octets(unsigned char* dataP, unsigned short sizeP) } -static bool _gtpurh_route_packet(struct sk_buff *skb, const struct xt_gtpurh_target_info *info) +#if defined(ROUTE_PACKET) +static bool _gtpurh_route_packet(struct sk_buff *skb_pP, const struct xt_gtpurh_target_info *info_pP) { - int err = 0; - struct rtable *rt = NULL; - struct iphdr *iph = ip_hdr(skb); - int daddr = iph->daddr; - struct flowi fl = { + int err = 0; + struct rtable *rt = NULL; + struct iphdr *iph_p = ip_hdr(skb_pP); + int daddr = iph_p->daddr; + struct flowi fl = { .u = { .ip4 = { .daddr = daddr, - .flowi4_tos = RT_TOS(iph->tos), + .flowi4_tos = RT_TOS(iph_p->tos), .flowi4_scope = RT_SCOPE_UNIVERSE, } } @@ -364,18 +369,18 @@ static bool _gtpurh_route_packet(struct sk_buff *skb, const struct xt_gtpurh_tar #if 0 pr_info("GTPURH(%d): Routing packet: %d.%d.%d.%d --> %d.%d.%d.%d Proto: %d, Len: %d Mark: %u\n", - info->action, - iph->saddr & 0xFF, - (iph->saddr & 0x0000FF00) >> 8, - (iph->saddr & 0x00FF0000) >> 16, - iph->saddr >> 24, - iph->daddr & 0xFF, - (iph->daddr & 0x0000FF00) >> 8, - (iph->daddr & 0x00FF0000) >> 16, - iph->daddr >> 24, - iph->protocol, - ntohs(iph->tot_len), - skb->mark); + info_pP->action, + iph_p->saddr & 0xFF, + (iph_p->saddr & 0x0000FF00) >> 8, + (iph_p->saddr & 0x00FF0000) >> 16, + iph_p->saddr >> 24, + iph_p->daddr & 0xFF, + (iph_p->daddr & 0x0000FF00) >> 8, + (iph_p->daddr & 0x00FF0000) >> 16, + iph_p->daddr >> 24, + iph_p->protocol, + ntohs(iph_p->tot_len), + skb_pP->mark); #endif rt = ip_route_output_key(&init_net, &fl.u.ip4); @@ -396,17 +401,17 @@ static bool _gtpurh_route_packet(struct sk_buff *skb, const struct xt_gtpurh_tar } #endif - //if (info->action == PARAM_GTPURH_ACTION_ADD) //LG was commented + //if (info_pP->action == PARAM_GTPURH_ACTION_ADD) //LG was commented { - skb_dst_drop(skb); - skb_dst_set(skb, &rt->dst); - skb->dev = skb_dst(skb)->dev; + skb_dst_drop(skb_pP); + skb_dst_set(skb_pP, &rt->dst); + skb_pP->dev = skb_dst(skb_pP)->dev; } - skb->protocol = htons(ETH_P_IP); + skb_pP->protocol = htons(ETH_P_IP); /* Send the GTPu message out...gggH */ - err = dst_output(skb); + err = dst_output(skb_pP); if (err == 0) { @@ -417,14 +422,30 @@ static bool _gtpurh_route_packet(struct sk_buff *skb, const struct xt_gtpurh_tar return GTPURH_FAILURE; } } - - +#endif +/* static void -_gtpurh_target_reassembly(struct sk_buff *orig_skb, const struct xt_gtpurh_target_info *tgi) +_gtpurh_delete_collection_ip_fragments(void) { - struct iphdr *iph = ip_hdr(orig_skb); - struct sk_buff *skb = NULL; - struct sk_buff *new_skb = NULL; + int bucket_loop_cursor = 0; + struct ip_fragment_entry_s *ip_fragment_p = NULL; + struct hlist_node *pos_p = NULL; + + hash_for_each(ip_fragments, bucket_loop_cursor, ip_fragment_p, pos_p, node) { + pr_info("GTPURH: %s struct ip_fragment_entry_s* %p, struct hlist_node* %p\n", + __FUNCTION__, + ip_fragment_p, + pos_p); + } +} + + +static int +_gtpurh_target_reassembly(struct sk_buff *orig_skb_pP, const struct xt_gtpurh_target_info *tgi_pP) +{ + struct iphdr *iph_p = ip_hdr(orig_skb_pP); + struct sk_buff *skb_p = NULL; + struct sk_buff *new_skb_p = NULL; uint16_t key = 0; int flags, offset, last_frag_offset; int ihl, end; @@ -432,207 +453,248 @@ _gtpurh_target_reassembly(struct sk_buff *orig_skb, const struct xt_gtpurh_targe struct hlist_node *pos_p = NULL; int all_segments_availables = 1; - offset = ntohs(iph->frag_off); - flags = offset & ~IP_OFFSET; - offset &= IP_OFFSET; /* offset is in 8-byte chunks */ - offset <<= 3; - ihl = ip_hdrlen(skb); - end = offset + skb->len - ihl; + if ((orig_skb_pP) && (tgi_pP)) { + offset = ntohs(iph_p->frag_off); + flags = offset & ~IP_OFFSET; + offset &= IP_OFFSET; // offset is in 8-byte chunks + offset <<= 3; + ihl = ip_hdrlen(orig_skb_pP); + end = offset + orig_skb_pP->len - ihl; - key = iph->id; + key = iph_p->id; - /* Is this the final fragment? */ - if ((flags & IP_MF) == 0) { - pr_info("GTPURH: try reassembly last segment id %u len %u offset %u end %u\n", - key,orig_skb->len, offset, end); - // may be the last segment received - // normally iterator gives elements from head to tail, but elements - // have been inserted at the head, so iterator should retrieve fragments - // in reverse order. - last_frag_offset = offset; - hash_for_each_possible(ip_fragments, ip_fragment_p, pos_p, node, key) { - pr_info("GTPURH: try reassembly segment id %u len %u offset %u end %u\n", - key,ip_fragment_p->skb->len, ip_fragment_p->offset, ip_fragment_p->end); - if (ip_fragment_p->end == offset) { - offset = ip_fragment_p->offset; - } else { - pr_info("GTPURH: try reassembly segment id %u failed\n", - key); - all_segments_availables = 0; - break; - } - } - if (all_segments_availables) { - // not optimal, but optimize later - new_skb = skb_copy_expand(orig_skb, - last_frag_offset + skb_headroom(orig_skb), - skb_tailroom(orig_skb), - GFP_ATOMIC); - if (new_skb != NULL) - { - hash_for_each_possible(ip_fragments, ip_fragment_p, pos_p, node, key) { - skb = ip_fragment_p->skb; - skb_pull(new_skb, ihl); - - pr_info("GTPURH: reassembly segment id %u len %u offset %u end %u\n", - key, skb->len, ip_fragment_p->offset, ip_fragment_p->end); - - iph = (struct iphdr*)skb_push(new_skb, skb->len); - ihl = ip_hdrlen(skb); - memcpy(iph, skb_network_header(skb), skb->len); - } - skb_set_network_header(new_skb, 0); - if (_gtpurh_route_packet(new_skb, tgi) != GTPURH_SUCCESS) - { - kfree_skb(new_skb); - } - - } else { - pr_info("GTPURH: Failed in skb allocation (%u bytes)\n", - last_frag_offset + skb_headroom(orig_skb)); - } - } - if (1) { + pr_info("---------------GTPURH: Dump fragment:------------------------------------------------\n"); + _gtpurh_print_hex_octets((unsigned char*)iph_p, orig_skb_pP->len); + // Is this the final fragment? + if ((flags & IP_MF) == 0) { + pr_info("GTPURH: try reassembly last segment id %u len %u offset %u end %u\n", + key,orig_skb_pP->len, offset, end); + // may be the last segment received + // normally iterator gives elements from head to tail, but elements + // have been inserted at the head, so iterator should retrieve fragments + // in reverse order. + last_frag_offset = offset; hash_for_each_possible(ip_fragments, ip_fragment_p, pos_p, node, key) { - kfree_skb(ip_fragment_p->skb); - hash_del(pos_p); - kfree(ip_fragment_p); + pr_info("GTPURH: try reassembly segment id %u len %u offset %u end %u\n", + key,ip_fragment_p->skb_p->len, ip_fragment_p->offset, ip_fragment_p->end); + if (ip_fragment_p->end == offset) { + offset = ip_fragment_p->offset; + } else { + pr_info("GTPURH: try reassembly segment id %u failed\n", + key); + all_segments_availables = 0; + break; + } + } + if (all_segments_availables) { + // not optimal, but optimize later + new_skb_p = skb_copy_expand(orig_skb_pP, + last_frag_offset + skb_headroom(orig_skb_pP), + skb_tailroom(orig_skb_pP), + GFP_ATOMIC); + if (new_skb_p != NULL) + { + hash_for_each_possible(ip_fragments, ip_fragment_p, pos_p, node, key) { + skb_p = ip_fragment_p->skb_p; + skb_pull(new_skb_p, ihl); + + pr_info("GTPURH: reassembly segment id %u len %u offset %u end %u\n", + key, skb_p->len, ip_fragment_p->offset, ip_fragment_p->end); + + iph_p = (struct iphdr*)skb_push(new_skb_p, skb_p->len); + ihl = ip_hdrlen(skb_p); + memcpy(iph_p, skb_network_header(skb_p), skb_p->len); + } + skb_set_network_header(new_skb_p, 0); + if (_gtpurh_route_packet(new_skb_p, tgi_pP) != GTPURH_SUCCESS) + { + kfree_skb(new_skb_p); + } + + } else { + pr_info("GTPURH: Failed in skb_p allocation (%u bytes)\n", + last_frag_offset + skb_headroom(orig_skb_pP)); + } + } + if (1) { + hash_for_each_possible(ip_fragments, ip_fragment_p, pos_p, node, key) { + kfree_skb(ip_fragment_p->skb_p); + hash_del(pos_p); + kfree(ip_fragment_p); + } + } + } else { + pr_info("GTPURH: but in buffer not last segment id %u len %u offset %u end %u\n", + key,orig_skb_pP->len, offset, end); + // not the last fragment received + // assuming no out of order + ip_fragment_p = kmalloc(sizeof(struct ip_fragment_entry_s), GFP_KERNEL); + + if (NULL != ip_fragment_p) { + ip_fragment_p->skb_p = skb_copy(orig_skb_pP, GFP_ATOMIC); // may use skb_clone(), TODO + ip_fragment_p->flags = flags; + ip_fragment_p->offset = offset; + ip_fragment_p->end = end; + pr_info("GTPURH: adding in hashtable key %04x ip_fragment %p skbuff %p\n", + key, ip_fragment_p, ip_fragment_p->skb_p); + + INIT_HLIST_NODE(&ip_fragment_p->node); + hash_add(ip_fragments, &ip_fragment_p->node, key); + return 0; + } else { + pr_info("GTPURH: ERROR could not allocate memory for buffering IP fragment\n"); } } } else { - pr_info("GTPURH: but in buffer not last segment id %u len %u offset %u end %u\n", - key,orig_skb->len, offset, end); - // not the last fragment received - // assuming no out of order - ip_fragment_p = kmalloc(sizeof(struct ip_fragment_entry_s), GFP_KERNEL); - - if (NULL != ip_fragment_p) { -#if defined(ROUTE_PACKET) - ip_fragment_p->skb = orig_skb; -#else - ip_fragment_p->skb = skb_copy(orig_skb, GFP_ATOMIC); // may use skb_clone(), TODO -#endif - ip_fragment_p->flags = flags; - ip_fragment_p->offset = offset; - ip_fragment_p->end = end; - - INIT_HLIST_NODE(&ip_fragment_p->node); - hash_add(ip_fragments, &ip_fragment_p->node, key); - } else { - pr_info("GTPURH: ERROR could not allocate memory for buffering IP fragment\n"); - } + pr_info("%s(skb_p=%p,tgi_pP=%p) parameter skb_p or tgi_pP is NULL\n", + __FUNCTION__, orig_skb_pP, tgi_pP); } -} + return -1; +}*/ static unsigned int -_gtpurh_target_rem(struct sk_buff *orig_skb, const struct xt_gtpurh_target_info *tgi) +_gtpurh_target_rem(struct sk_buff *orig_skb_pP, const struct xt_gtpurh_target_info *tgi_pP) { - struct iphdr *iph = ip_hdr(orig_skb); - struct iphdr *iph2 = NULL; - struct udphdr *udph = NULL; - struct gtpuhdr *gtpuh = NULL; - struct sk_buff *skb = NULL; + struct iphdr *iph_p = ip_hdr(orig_skb_pP); + struct iphdr *iph2_p = NULL; + struct udphdr *udph_p = NULL; + struct gtpuhdr *gtpuh_p = NULL; + struct sk_buff *skb_p = NULL; uint16_t gtp_payload_size = 0; - /* Create a new copy of the original skb...can't avoid :-( LG: WHY???*/ + /* Create a new copy of the original skb_p...can't avoid :-( LG: WHY???*/ #if defined(ROUTE_PACKET) - skb = skb_copy(orig_skb, GFP_ATOMIC); - if (skb == NULL) + skb_p = skb_copy(orig_skb_pP, GFP_ATOMIC); + if (skb_p == NULL) { return NF_ACCEPT; } - skb->skb_iif = orig_skb->skb_iif; - skb->protocol = orig_skb->protocol; + skb_p->skb_iif = orig_skb_pP->skb_iif; + skb_p->protocol = orig_skb_pP->protocol; #else - skb = orig_skb; + skb_p = orig_skb_pP; #endif - - if (ip_is_fragment(iph)) { - _gtpurh_target_reassembly(skb, tgi); - return NF_DROP; // orig_skb is copied, original can be destroyed. - } - - /* Remove IP header */ - udph = (struct udphdr*)skb_pull(skb, (iph->ihl << 2)); - - if (iph->protocol != IPPROTO_UDP) { - pr_info("GTPURH(%d): ERROR in decapsulating packet: %d.%d.%d.%d --> %d.%d.%d.%d Bad Proto: %d, Total Len (IP): %u mark %u Frag offset %u Flags 0x%0x\n", - tgi->action, - iph->saddr & 0xFF, - (iph->saddr & 0x0000FF00) >> 8, - (iph->saddr & 0x00FF0000) >> 16, - iph->saddr >> 24, - iph->daddr & 0xFF, - (iph->daddr & 0x0000FF00) >> 8, - (iph->daddr & 0x00FF0000) >> 16, - iph->daddr >> 24, - iph->protocol, - ntohs(iph2->tot_len), - skb->mark, - ntohs(iph->frag_off) & 0x1FFFFFFF, - ntohs(iph->frag_off) >> 13); + //--------------------------- + // check if is GTPU TUNNEL + if (iph_p->protocol != IPPROTO_UDP) { + pr_info("GTPURH(%d): Not GTPV1U packet (not UDP)\n",tgi_pP->action); return NF_ACCEPT; } + //--------------------------- + // check if is fragment + // but should not happen since MTU should have been set bigger than 1500 + GTP encap. + // TO DO later segment, but did not succeed in getting in this target all framents of an ip packet! + if (_gtpurh_ip_is_fragment(iph_p)) { + pr_info("GTPURH(%d): ip_is_fragment YES, FLAGS %04X & %04X = %04X\n", + tgi_pP->action, + iph_p->frag_off, + htons(IP_MF | IP_OFFSET), + iph_p->frag_off & htons(IP_MF | IP_OFFSET)); + /*if ((rc = _gtpurh_target_reassembly(skb_p, tgi_pP)) == 0) { + return NF_DROP; // orig_skb_pP is copied, original can be destroyed. + } else {*/ + return NF_ACCEPT; + //} + } /*else { + pr_info("GTPURH(%d): ip_is_fragment NO, FLAGS %04X & %04X = %04X\n", + tgi_pP->action, + iph_p->frag_off, + htons(IP_MF | IP_OFFSET), + iph_p->frag_off & htons(IP_MF | IP_OFFSET)); + }*/ + + if (skb_p->len <= sizeof (struct udphdr) + sizeof (struct gtpuhdr) + sizeof (struct iphdr)) { + pr_info("GTPURH(%d): Thought was GTPV1U packet but too short length\n",tgi_pP->action); + return NF_ACCEPT; + } + /* Remove IP header */ + udph_p = (struct udphdr*)skb_pull(skb_p, (iph_p->ihl << 2)); + + if (udph_p->dest != htons(GTPURH_PORT)) { + pr_info("GTPURH(%d): Not GTPV1U packet (bad UDP dest port)\n",tgi_pP->action); + skb_push(skb_p, (iph_p->ihl << 2)); + return NF_ACCEPT; + } + +/* if (iph_p->protocol != IPPROTO_UDP) { + pr_info("GTPURH(%d): ERROR in decapsulating packet: %d.%d.%d.%d --> %d.%d.%d.%d Bad Proto: %d, Total Len (IP): %u mark %u Frag offset %u Flags 0x%0x\n", + tgi_pP->action, + iph_p->saddr & 0xFF, + (iph_p->saddr & 0x0000FF00) >> 8, + (iph_p->saddr & 0x00FF0000) >> 16, + iph_p->saddr >> 24, + iph_p->daddr & 0xFF, + (iph_p->daddr & 0x0000FF00) >> 8, + (iph_p->daddr & 0x00FF0000) >> 16, + iph_p->daddr >> 24, + iph_p->protocol, + ntohs(iph2_p->tot_len), + skb_p->mark, + ntohs(iph_p->frag_off) & 0x1FFFFFFF, + ntohs(iph_p->frag_off) >> 13); + return NF_ACCEPT; + }*/ + /* Remove UDP header */ - gtpuh = (struct gtpuhdr*)skb_pull(skb, sizeof(struct udphdr)); - gtp_payload_size = ntohs(gtpuh->length); + gtpuh_p = (struct gtpuhdr*)skb_pull(skb_p, sizeof(struct udphdr)); + gtp_payload_size = ntohs(gtpuh_p->length); - skb->mark = ntohl(gtpuh->tunid); + skb_p->mark = ntohl(gtpuh_p->tunid); /* Remove GTPu header */ - skb_pull(skb, sizeof(struct gtpuhdr)); + skb_pull(skb_p, sizeof(struct gtpuhdr)); /* If additional fields are present in header, remove them also */ - if (gtpuh->flags & GTPURH_ANY_EXT_HDR_BIT) + if (gtpuh_p->flags & GTPURH_ANY_EXT_HDR_BIT) { - skb_pull(skb, sizeof(short) + sizeof(char) + sizeof(char)); /* #Seq, #N-PDU, #ExtHdr Type */ + skb_pull(skb_p, sizeof(short) + sizeof(char) + sizeof(char)); /* #Seq, #N-PDU, #ExtHdr Type */ gtp_payload_size = gtp_payload_size - sizeof(short) - sizeof(char) - sizeof(char); } - //skb->mac_len = 0; - //skb_set_mac_header(skb, 0); - skb_set_network_header(skb, 0); - iph2 = ip_hdr(skb); - skb_set_transport_header(skb, iph2->ihl << 2); + //skb_p->mac_len = 0; + //skb_set_mac_header(skb_p, 0); + skb_set_network_header(skb_p, 0); + iph2_p = ip_hdr(skb_p); + skb_set_transport_header(skb_p, iph2_p->ihl << 2); - if ((iph2->version != 4 ) && (iph2->version != 6)) { + if ((iph2_p->version != 4 ) && (iph2_p->version != 6)) { pr_info("\nGTPURH: Decapsulated packet dropped because not IPvx protocol see all GTPU packet here:\n"); - _gtpurh_print_hex_octets((unsigned char*)iph, ntohs(iph->tot_len)); + _gtpurh_print_hex_octets((unsigned char*)iph_p, ntohs(iph_p->tot_len)); return NF_DROP; } //#if 0 - if ((skb->mark == 0) || (gtp_payload_size != ntohs(iph2->tot_len))) { + if ((skb_p->mark == 0) || (gtp_payload_size != ntohs(iph2_p->tot_len))) { pr_info("\nGTPURH(%d): Decapsulated packet: %d.%d.%d.%d --> %d.%d.%d.%d Proto: %d, Total Len (IP): %u mark %u Frag offset %u Flags 0x%0x\n", - tgi->action, - iph2->saddr & 0xFF, - (iph2->saddr & 0x0000FF00) >> 8, - (iph2->saddr & 0x00FF0000) >> 16, - iph2->saddr >> 24, - iph2->daddr & 0xFF, - (iph2->daddr & 0x0000FF00) >> 8, - (iph2->daddr & 0x00FF0000) >> 16, - iph2->daddr >> 24, - iph2->protocol, - ntohs(iph2->tot_len), - skb->mark, - ntohs(iph->frag_off) & 0x1FFFFFFF, - ntohs(iph->frag_off) >> 13); + tgi_pP->action, + iph2_p->saddr & 0xFF, + (iph2_p->saddr & 0x0000FF00) >> 8, + (iph2_p->saddr & 0x00FF0000) >> 16, + iph2_p->saddr >> 24, + iph2_p->daddr & 0xFF, + (iph2_p->daddr & 0x0000FF00) >> 8, + (iph2_p->daddr & 0x00FF0000) >> 16, + iph2_p->daddr >> 24, + iph2_p->protocol, + ntohs(iph2_p->tot_len), + skb_p->mark, + ntohs(iph_p->frag_off) & 0x1FFFFFFF, + ntohs(iph_p->frag_off) >> 13); - if (gtp_payload_size != ntohs(iph2->tot_len)) { + if (gtp_payload_size != ntohs(iph2_p->tot_len)) { pr_info("GTPURH(%d): Mismatch in lengths GTPU length: %u -> %u, IP length %u\n", - tgi->action, - ntohs(gtpuh->length), + tgi_pP->action, + ntohs(gtpuh_p->length), gtp_payload_size, - ntohs(iph2->tot_len)); + ntohs(iph2_p->tot_len)); - _gtpurh_print_hex_octets((unsigned char*)iph, ntohs(iph->tot_len)); + _gtpurh_print_hex_octets((unsigned char*)iph_p, ntohs(iph_p->tot_len)); } } //#endif /* Route the packet */ #if defined(ROUTE_PACKET) - _gtpurh_route_packet(skb, tgi); + _gtpurh_route_packet(skb_p, tgi_pP); return NF_DROP; #else return NF_ACCEPT; @@ -641,19 +703,19 @@ _gtpurh_target_rem(struct sk_buff *orig_skb, const struct xt_gtpurh_target_info static unsigned int -xt_gtpurh_target(struct sk_buff *skb, const struct xt_action_param *par) +xt_gtpurh_target(struct sk_buff *skb_pP, const struct xt_action_param *par) { - const struct xt_gtpurh_target_info *tgi = par->targinfo; + const struct xt_gtpurh_target_info *tgi_p = par->targinfo; int result = NF_ACCEPT; - if (tgi == NULL) + if (tgi_p == NULL) { return result; } - if (tgi->action == PARAM_GTPURH_ACTION_REM) + if (tgi_p->action == PARAM_GTPURH_ACTION_REM) { - result = _gtpurh_target_rem(skb, tgi); + result = _gtpurh_target_rem(skb_pP, tgi_p); } return result; } @@ -674,13 +736,15 @@ static int __init xt_gtpurh_init(void) { pr_info("GTPURH: Initializing module (KVersion: %d)\n", KVERSION); pr_info("GTPURH: Copyright Polaris Networks 2010-2011\n"); - hash_init(ip_fragments); + pr_info("GTPURH: Modified by EURECOM Lionel GAUTHIER 2014\n"); + //hash_init(ip_fragments); return xt_register_target(&xt_gtpurh_reg); } static void __exit xt_gtpurh_exit(void) { xt_unregister_target(&xt_gtpurh_reg); + //_gtpurh_delete_collection_ip_fragments(); pr_info("GTPURH: Unloading module\n"); }