Commit 5109cd00 authored by Lionel Gauthier's avatar Lionel Gauthier

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@6117 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent ff1913f8
......@@ -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_delete_collection_ip_fragments(void)
{
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 void
_gtpurh_target_reassembly(struct sk_buff *orig_skb, const struct xt_gtpurh_target_info *tgi)
static int
_gtpurh_target_reassembly(struct sk_buff *orig_skb_pP, const struct xt_gtpurh_target_info *tgi_pP)
{
struct iphdr *iph = ip_hdr(orig_skb);
struct sk_buff *skb = NULL;
struct sk_buff *new_skb = NULL;
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;
key = iph->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);
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_p->id;
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) {
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;
}
skb_set_network_header(new_skb, 0);
if (_gtpurh_route_packet(new_skb, tgi) != GTPURH_SUCCESS)
}
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)
{
kfree_skb(new_skb);
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));
}
} else {
pr_info("GTPURH: Failed in skb allocation (%u bytes)\n",
last_frag_offset + skb_headroom(orig_skb));
}
}
if (1) {
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);
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->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("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("%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.
//---------------------------
// 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 = (struct udphdr*)skb_pull(skb, (iph->ihl << 2));
udph_p = (struct udphdr*)skb_pull(skb_p, (iph_p->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);
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);
if (gtp_payload_size != ntohs(iph2->tot_len)) {
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_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");
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment