diff --git a/core/rtw_br_ext.c b/core/rtw_br_ext.c index 1a71c49..813d191 100644 --- a/core/rtw_br_ext.c +++ b/core/rtw_br_ext.c @@ -59,8 +59,8 @@ /*----------------------------------------------------------------- How database records network address: - 0 1 2 3 4 5 6 7 8 9 10 - |----|----|----|----|----|----|----|----|----|----|----| + 0 1 2 3 4 5 6 7 8 9 10 + |----|----|----|----|----|----|----|----|----|----|----| IPv4 |type| | IP addr | IPX |type| Net addr | Node addr | IPX |type| Net addr |Sckt addr| @@ -70,7 +70,7 @@ /* Find a tag in pppoe frame and return the pointer */ -static __inline__ unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) +static inline unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, unsigned short type) { unsigned char *cur_ptr, *start_ptr; unsigned short tagLen, tagType; @@ -88,7 +88,7 @@ static __inline__ unsigned char *__nat25_find_pppoe_tag(struct pppoe_hdr *ph, un } -static __inline__ int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag) +static inline int __nat25_add_pppoe_tag(struct sk_buff *skb, struct pppoe_tag *tag) { struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); int data_len; @@ -128,7 +128,7 @@ static int skb_pull_and_merge(struct sk_buff *skb, unsigned char *src, int len) return 0; } -static __inline__ unsigned long __nat25_timeout(struct adapter *priv) +static inline unsigned long __nat25_timeout(struct adapter *priv) { unsigned long timeout; @@ -138,7 +138,7 @@ static __inline__ unsigned long __nat25_timeout(struct adapter *priv) } -static __inline__ int __nat25_has_expired(struct adapter *priv, +static inline int __nat25_has_expired(struct adapter *priv, struct nat25_network_db_entry *fdb) { if (time_before_eq(fdb->ageing_timer, __nat25_timeout(priv))) @@ -148,7 +148,7 @@ static __inline__ int __nat25_has_expired(struct adapter *priv, } -static __inline__ void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, +static inline void __nat25_generate_ipv4_network_addr(unsigned char *networkAddr, unsigned int *ipAddr) { memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); @@ -158,7 +158,7 @@ static __inline__ void __nat25_generate_ipv4_network_addr(unsigned char *network } -static __inline__ void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr, +static inline void __nat25_generate_ipx_network_addr_with_node(unsigned char *networkAddr, unsigned int *ipxNetAddr, unsigned char *ipxNodeAddr) { memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); @@ -169,7 +169,7 @@ static __inline__ void __nat25_generate_ipx_network_addr_with_node(unsigned char } -static __inline__ void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr, +static inline void __nat25_generate_ipx_network_addr_with_socket(unsigned char *networkAddr, unsigned int *ipxNetAddr, unsigned short *ipxSocketAddr) { memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); @@ -180,7 +180,7 @@ static __inline__ void __nat25_generate_ipx_network_addr_with_socket(unsigned ch } -static __inline__ void __nat25_generate_apple_network_addr(unsigned char *networkAddr, +static inline void __nat25_generate_apple_network_addr(unsigned char *networkAddr, unsigned short *network, unsigned char *node) { memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); @@ -190,8 +190,7 @@ static __inline__ void __nat25_generate_apple_network_addr(unsigned char *networ networkAddr[3] = *node; } - -static __inline__ void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, +static inline void __nat25_generate_pppoe_network_addr(unsigned char *networkAddr, unsigned char *ac_mac, unsigned short *sid) { memset(networkAddr, 0, MAX_NETWORK_ADDR_LEN); @@ -232,8 +231,8 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char mac = scan_tlv(&data[8], len-8, 1, 1); if (mac) { _DEBUG_INFO("Router Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], - replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); memcpy(mac, replace_mac, 6); return 1; } @@ -243,8 +242,8 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char mac = scan_tlv(&data[16], len-16, 1, 1); if (mac) { _DEBUG_INFO("Router Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], - replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); memcpy(mac, replace_mac, 6); return 1; } @@ -254,8 +253,8 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char mac = scan_tlv(&data[24], len-24, 1, 1); if (mac) { _DEBUG_INFO("Neighbor Solicitation, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], - replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); memcpy(mac, replace_mac, 6); return 1; } @@ -265,8 +264,8 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char mac = scan_tlv(&data[24], len-24, 2, 1); if (mac) { _DEBUG_INFO("Neighbor Advertisement, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], - replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); memcpy(mac, replace_mac, 6); return 1; } @@ -276,8 +275,8 @@ static int update_nd_link_layer_addr(unsigned char *data, int len, unsigned char mac = scan_tlv(&data[40], len-40, 2, 1); if (mac) { _DEBUG_INFO("Redirect, replace MAC From: %02x:%02x:%02x:%02x:%02x:%02x, To: %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0],mac[1],mac[2],mac[3],mac[4],mac[5], - replace_mac[0],replace_mac[1],replace_mac[2],replace_mac[3],replace_mac[4],replace_mac[5]); + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + replace_mac[0], replace_mac[1], replace_mac[2], replace_mac[3], replace_mac[4], replace_mac[5]); memcpy(mac, replace_mac, 6); return 1; } @@ -291,41 +290,34 @@ static void convert_ipv6_mac_to_mc(struct sk_buff *skb) struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); unsigned char *dst_mac = skb->data; - /*modified by qinjunjie,ipv6 multicast address ix 0x33-33-xx-xx-xx-xx*/ + /*modified by qinjunjie, ipv6 multicast address ix 0x33-33-xx-xx-xx-xx*/ dst_mac[0] = 0x33; dst_mac[1] = 0x33; memcpy(&dst_mac[2], &iph->daddr.s6_addr32[3], 4); } -static __inline__ int __nat25_network_hash(unsigned char *networkAddr) +static inline int __nat25_network_hash(unsigned char *networkAddr) { - if (networkAddr[0] == NAT25_IPV4) - { + if (networkAddr[0] == NAT25_IPV4) { unsigned long x; x = networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; return x & (NAT25_HASH_SIZE - 1); - } - else if (networkAddr[0] == NAT25_IPX) - { + } else if (networkAddr[0] == NAT25_IPX) { unsigned long x; x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8] ^ networkAddr[9] ^ networkAddr[10]; return x & (NAT25_HASH_SIZE - 1); - } - else if (networkAddr[0] == NAT25_APPLE) - { + } else if (networkAddr[0] == NAT25_APPLE) { unsigned long x; x = networkAddr[1] ^ networkAddr[2] ^ networkAddr[3]; return x & (NAT25_HASH_SIZE - 1); - } - else if (networkAddr[0] == NAT25_PPPOE) - { + } else if (networkAddr[0] == NAT25_PPPOE) { unsigned long x; x = networkAddr[0] ^ networkAddr[1] ^ networkAddr[2] ^ networkAddr[3] ^ networkAddr[4] ^ networkAddr[5] ^ networkAddr[6] ^ networkAddr[7] ^ networkAddr[8]; @@ -344,46 +336,34 @@ static __inline__ int __nat25_network_hash(unsigned char *networkAddr) unsigned long x = 0; int i; - for (i=0; ibr_ext_lock, &irqL); */ - ent->next_hash = priv->nethash[hash]; if (ent->next_hash != NULL) ent->next_hash->pprev_hash = &ent->next_hash; priv->nethash[hash] = ent; ent->pprev_hash = &priv->nethash[hash]; - - /* _exit_critical_bh(&priv->br_ext_lock, &irqL); */ } - -static __inline__ void __network_hash_unlink(struct nat25_network_db_entry *ent) +static inline void __network_hash_unlink(struct nat25_network_db_entry *ent) { /* Caller must _enter_critical_bh already! */ - /* unsigned long irqL; */ - /* _enter_critical_bh(&priv->br_ext_lock, &irqL); */ - *(ent->pprev_hash) = ent->next_hash; if (ent->next_hash != NULL) ent->next_hash->pprev_hash = ent->pprev_hash; ent->next_hash = NULL; ent->pprev_hash = NULL; - - /* _exit_critical_bh(&priv->br_ext_lock, &irqL); */ } - static int __nat25_db_network_lookup_and_replace(struct adapter *priv, struct sk_buff *skb, unsigned char *networkAddr) { @@ -392,12 +372,9 @@ static int __nat25_db_network_lookup_and_replace(struct adapter *priv, _enter_critical_bh(&priv->br_ext_lock, &irqL); db = priv->nethash[__nat25_network_hash(networkAddr)]; - while (db != NULL) - { - if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) - { - if (!__nat25_has_expired(priv, db)) - { + while (db != NULL) { + if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { + if (!__nat25_has_expired(priv, db)) { /* replace the destination mac address */ memcpy(skb->data, db->macAddr, ETH_ALEN); atomic_inc(&db->use_count); @@ -431,10 +408,8 @@ static int __nat25_db_network_lookup_and_replace(struct adapter *priv, _exit_critical_bh(&priv->br_ext_lock, &irqL); return 1; } - db = db->next_hash; } - _exit_critical_bh(&priv->br_ext_lock, &irqL); return 0; } @@ -445,29 +420,24 @@ static void __nat25_db_network_insert(struct adapter *priv, struct nat25_network_db_entry *db; int hash; unsigned long irqL; - _enter_critical_bh(&priv->br_ext_lock, &irqL); + _enter_critical_bh(&priv->br_ext_lock, &irqL); hash = __nat25_network_hash(networkAddr); db = priv->nethash[hash]; - while (db != NULL) - { - if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) - { + while (db != NULL) { + if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { memcpy(db->macAddr, macAddr, ETH_ALEN); db->ageing_timer = jiffies; _exit_critical_bh(&priv->br_ext_lock, &irqL); return; } - db = db->next_hash; } - db = (struct nat25_network_db_entry *) rtw_malloc(sizeof(*db)); if (db == NULL) { _exit_critical_bh(&priv->br_ext_lock, &irqL); return; } - memcpy(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN); memcpy(db->macAddr, macAddr, ETH_ALEN); atomic_set(&db->use_count, 1); @@ -478,7 +448,6 @@ static void __nat25_db_network_insert(struct adapter *priv, _exit_critical_bh(&priv->br_ext_lock, &irqL); } - static void __nat25_db_print(struct adapter *priv) { } @@ -493,65 +462,54 @@ void nat25_db_cleanup(struct adapter *priv) unsigned long irqL; _enter_critical_bh(&priv->br_ext_lock, &irqL); - for (i=0; inethash[i]; while (f != NULL) { struct nat25_network_db_entry *g; g = f->next_hash; - if (priv->scdb_entry == f) - { + if (priv->scdb_entry == f) { memset(priv->scdb_mac, 0, ETH_ALEN); memset(priv->scdb_ip, 0, 4); priv->scdb_entry = NULL; } __network_hash_unlink(f); rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry)); - f = g; } } - _exit_critical_bh(&priv->br_ext_lock, &irqL); } - void nat25_db_expire(struct adapter *priv) { int i; unsigned long irqL; _enter_critical_bh(&priv->br_ext_lock, &irqL); - /* if (!priv->ethBrExtInfo.nat25_disable) */ - { - for (i=0; inethash[i]; + for (i = 0; i < NAT25_HASH_SIZE; i++) { + struct nat25_network_db_entry *f; + f = priv->nethash[i]; - while (f != NULL) - { - struct nat25_network_db_entry *g; - g = f->next_hash; + while (f != NULL) { + struct nat25_network_db_entry *g; + g = f->next_hash; - if (__nat25_has_expired(priv, f)) { - if (atomic_dec_and_test(&f->use_count)) { - if (priv->scdb_entry == f) { - memset(priv->scdb_mac, 0, ETH_ALEN); - memset(priv->scdb_ip, 0, 4); - priv->scdb_entry = NULL; - } - __network_hash_unlink(f); - rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry)); + if (__nat25_has_expired(priv, f)) { + if (atomic_dec_and_test(&f->use_count)) { + if (priv->scdb_entry == f) { + memset(priv->scdb_mac, 0, ETH_ALEN); + memset(priv->scdb_ip, 0, 4); + priv->scdb_entry = NULL; } + __network_hash_unlink(f); + rtw_mfree((u8 *) f, sizeof(struct nat25_network_db_entry)); } - f = g; } + f = g; } } - _exit_critical_bh(&priv->br_ext_lock, &irqL); } @@ -572,672 +530,530 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) /*---------------------------------------------------*/ /* Handle IP frame */ /*---------------------------------------------------*/ - if (protocol == ETH_P_IP) - { - struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN); + if (protocol == ETH_P_IP) { + struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); - if (((unsigned char*)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) - { + if (((unsigned char *)(iph) + (iph->ihl<<2)) >= (skb->data + ETH_HLEN + skb->len)) { DEBUG_WARN("NAT25: malformed IP packet !\n"); return -1; } - switch (method) - { - case NAT25_CHECK: - return -1; - - case NAT25_INSERT: - { - /* some muticast with source IP is all zero, maybe other case is illegal */ - /* in class A, B, C, host address is all zero or all one is illegal */ - if (iph->saddr == 0) - return 0; - tmp = be32_to_cpu(iph->saddr); - DEBUG_INFO("NAT25: Insert IP, SA=%08x, DA=%08x\n", tmp, iph->daddr); - __nat25_generate_ipv4_network_addr(networkAddr, &tmp); - /* record source IP address and , source mac address into db */ - __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - - __nat25_db_print(priv); - } + switch (method) { + case NAT25_CHECK: + return -1; + case NAT25_INSERT: + /* some muticast with source IP is all zero, maybe other case is illegal */ + /* in class A, B, C, host address is all zero or all one is illegal */ + if (iph->saddr == 0) return 0; + tmp = be32_to_cpu(iph->saddr); + DEBUG_INFO("NAT25: Insert IP, SA =%08x, DA =%08x\n", tmp, iph->daddr); + __nat25_generate_ipv4_network_addr(networkAddr, &tmp); + /* record source IP address and , source mac address into db */ + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - case NAT25_LOOKUP: - { - DEBUG_INFO("NAT25: Lookup IP, SA=%08x, DA=%08x\n", iph->saddr, iph->daddr); - tmp = be32_to_cpu(iph->daddr); - __nat25_generate_ipv4_network_addr(networkAddr, &tmp); + __nat25_db_print(priv); + return 0; + case NAT25_LOOKUP: + DEBUG_INFO("NAT25: Lookup IP, SA =%08x, DA =%08x\n", iph->saddr, iph->daddr); + tmp = be32_to_cpu(iph->daddr); + __nat25_generate_ipv4_network_addr(networkAddr, &tmp); - if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) { - if (*((unsigned char *)&iph->daddr + 3) == 0xff) { - /* L2 is unicast but L3 is broadcast, make L2 bacome broadcast */ - DEBUG_INFO("NAT25: Set DA as boardcast\n"); - memset(skb->data, 0xff, ETH_ALEN); - } - else { - /* forward unknow IP packet to upper TCP/IP */ - DEBUG_INFO("NAT25: Replace DA with BR's MAC\n"); - if ( (*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac+4)) == 0 ) { - printk("Re-init netdev_br_init() due to br_mac==0!\n"); - netdev_br_init(priv->pnetdev); - } - memcpy(skb->data, priv->br_mac, ETH_ALEN); - } + if (!__nat25_db_network_lookup_and_replace(priv, skb, networkAddr)) { + if (*((unsigned char *)&iph->daddr + 3) == 0xff) { + /* L2 is unicast but L3 is broadcast, make L2 bacome broadcast */ + DEBUG_INFO("NAT25: Set DA as boardcast\n"); + memset(skb->data, 0xff, ETH_ALEN); + } else { + /* forward unknow IP packet to upper TCP/IP */ + DEBUG_INFO("NAT25: Replace DA with BR's MAC\n"); + if ((*(u32 *)priv->br_mac) == 0 && (*(u16 *)(priv->br_mac+4)) == 0) { + printk("Re-init netdev_br_init() due to br_mac == 0!\n"); + netdev_br_init(priv->pnetdev); } + memcpy(skb->data, priv->br_mac, ETH_ALEN); } - return 0; - - default: - return -1; + } + return 0; + default: + return -1; } - } - - /*---------------------------------------------------*/ - /* Handle ARP frame */ - /*---------------------------------------------------*/ - else if (protocol == ETH_P_ARP) - { + } else if (protocol == ETH_P_ARP) { + /*---------------------------------------------------*/ + /* Handle ARP frame */ + /*---------------------------------------------------*/ struct arphdr *arp = (struct arphdr *)(skb->data + ETH_HLEN); unsigned char *arp_ptr = (unsigned char *)(arp + 1); unsigned int *sender, *target; - if (arp->ar_pro != __constant_htons(ETH_P_IP)) - { + if (arp->ar_pro != __constant_htons(ETH_P_IP)) { DEBUG_WARN("NAT25: arp protocol unknown (%4x)!\n", be16_to_cpu(arp->ar_pro)); return -1; } - switch (method) - { - case NAT25_CHECK: - return 0; /* skb_copy for all ARP frame */ + switch (method) { + case NAT25_CHECK: + return 0; /* skb_copy for all ARP frame */ + case NAT25_INSERT: + DEBUG_INFO("NAT25: Insert ARP, MAC =%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], + arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]); - case NAT25_INSERT: - { - DEBUG_INFO("NAT25: Insert ARP, MAC=%02x%02x%02x%02x%02x%02x\n", arp_ptr[0], - arp_ptr[1], arp_ptr[2], arp_ptr[3], arp_ptr[4], arp_ptr[5]); + /* change to ARP sender mac address to wlan STA address */ + memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); + arp_ptr += arp->ar_hln; + sender = (unsigned int *)arp_ptr; + __nat25_generate_ipv4_network_addr(networkAddr, sender); + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + __nat25_db_print(priv); + return 0; + case NAT25_LOOKUP: + DEBUG_INFO("NAT25: Lookup ARP\n"); - /* change to ARP sender mac address to wlan STA address */ - memcpy(arp_ptr, GET_MY_HWADDR(priv), ETH_ALEN); - - arp_ptr += arp->ar_hln; - sender = (unsigned int *)arp_ptr; - - __nat25_generate_ipv4_network_addr(networkAddr, sender); - - __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - - __nat25_db_print(priv); - } - return 0; - - case NAT25_LOOKUP: - { - DEBUG_INFO("NAT25: Lookup ARP\n"); - - arp_ptr += arp->ar_hln; - sender = (unsigned int *)arp_ptr; - arp_ptr += (arp->ar_hln + arp->ar_pln); - target = (unsigned int *)arp_ptr; - - __nat25_generate_ipv4_network_addr(networkAddr, target); - - __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - - /* change to ARP target mac address to Lookup result */ - arp_ptr = (unsigned char *)(arp + 1); - arp_ptr += (arp->ar_hln + arp->ar_pln); - memcpy(arp_ptr, skb->data, ETH_ALEN); - } - return 0; - - default: - return -1; + arp_ptr += arp->ar_hln; + sender = (unsigned int *)arp_ptr; + arp_ptr += (arp->ar_hln + arp->ar_pln); + target = (unsigned int *)arp_ptr; + __nat25_generate_ipv4_network_addr(networkAddr, target); + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + /* change to ARP target mac address to Lookup result */ + arp_ptr = (unsigned char *)(arp + 1); + arp_ptr += (arp->ar_hln + arp->ar_pln); + memcpy(arp_ptr, skb->data, ETH_ALEN); + return 0; + default: + return -1; } - } - - /*---------------------------------------------------*/ - /* Handle IPX and Apple Talk frame */ - /*---------------------------------------------------*/ - else if ((protocol == ETH_P_IPX) || - (protocol <= ETH_FRAME_LEN)) - { + } else if ((protocol == ETH_P_IPX) || + (protocol <= ETH_FRAME_LEN)) { + /*---------------------------------------------------*/ + /* Handle IPX and Apple Talk frame */ + /*---------------------------------------------------*/ unsigned char ipx_header[2] = {0xFF, 0xFF}; struct ipxhdr *ipx = NULL; struct elapaarp *ea = NULL; struct ddpehdr *ddp = NULL; unsigned char *framePtr = skb->data + ETH_HLEN; - if (protocol == ETH_P_IPX) - { - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet II)\n"); + if (protocol == ETH_P_IPX) { + DEBUG_INFO("NAT25: Protocol = IPX (Ethernet II)\n"); ipx = (struct ipxhdr *)framePtr; - } - else if (protocol <= ETH_FRAME_LEN) - { - if (!memcmp(ipx_header, framePtr, 2)) - { - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.3)\n"); + } else if (protocol <= ETH_FRAME_LEN) { + if (!memcmp(ipx_header, framePtr, 2)) { + DEBUG_INFO("NAT25: Protocol = IPX (Ethernet 802.3)\n"); ipx = (struct ipxhdr *)framePtr; - } - else - { + } else { unsigned char ipx_8022_type = 0xE0; unsigned char snap_8022_type = 0xAA; - if (*framePtr == snap_8022_type) - { + if (*framePtr == snap_8022_type) { unsigned char ipx_snap_id[5] = {0x0, 0x0, 0x0, 0x81, 0x37}; /* IPX SNAP ID */ unsigned char aarp_snap_id[5] = {0x00, 0x00, 0x00, 0x80, 0xF3}; /* Apple Talk AARP SNAP ID */ unsigned char ddp_snap_id[5] = {0x08, 0x00, 0x07, 0x80, 0x9B}; /* Apple Talk DDP SNAP ID */ framePtr += 3; /* eliminate the 802.2 header */ - if (!memcmp(ipx_snap_id, framePtr, 5)) - { + if (!memcmp(ipx_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet SNAP)\n"); + DEBUG_INFO("NAT25: Protocol = IPX (Ethernet SNAP)\n"); ipx = (struct ipxhdr *)framePtr; - } - else if (!memcmp(aarp_snap_id, framePtr, 5)) - { + } else if (!memcmp(aarp_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ ea = (struct elapaarp *)framePtr; - } - else if (!memcmp(ddp_snap_id, framePtr, 5)) - { + } else if (!memcmp(ddp_snap_id, framePtr, 5)) { framePtr += 5; /* eliminate the SNAP header */ ddp = (struct ddpehdr *)framePtr; - } - else - { - DEBUG_WARN("NAT25: Protocol=Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0], + } else { + DEBUG_WARN("NAT25: Protocol = Ethernet SNAP %02x%02x%02x%02x%02x\n", framePtr[0], framePtr[1], framePtr[2], framePtr[3], framePtr[4]); return -1; } - } - else if (*framePtr == ipx_8022_type) - { + } else if (*framePtr == ipx_8022_type) { framePtr += 3; /* eliminate the 802.2 header */ - if (!memcmp(ipx_header, framePtr, 2)) - { - DEBUG_INFO("NAT25: Protocol=IPX (Ethernet 802.2)\n"); + if (!memcmp(ipx_header, framePtr, 2)) { + DEBUG_INFO("NAT25: Protocol = IPX (Ethernet 802.2)\n"); ipx = (struct ipxhdr *)framePtr; - } - else + } else { return -1; - } - else + } + } else { return -1; + } } - } - else + } else { return -1; + } /* IPX */ - if (ipx != NULL) - { - switch (method) - { - case NAT25_CHECK: - if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) - { - DEBUG_INFO("NAT25: Check IPX skb_copy\n"); - return 0; - } - return -1; + if (ipx != NULL) { + switch (method) { + case NAT25_CHECK: + if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) + DEBUG_INFO("NAT25: Check IPX skb_copy\n"); + return 0; + return -1; + case NAT25_INSERT: + DEBUG_INFO("NAT25: Insert IPX, Dest =%08x,%02x%02x%02x%02x%02x%02x,%04x Source =%08x,%02x%02x%02x%02x%02x%02x,%04x\n", + ipx->ipx_dest.net, + ipx->ipx_dest.node[0], + ipx->ipx_dest.node[1], + ipx->ipx_dest.node[2], + ipx->ipx_dest.node[3], + ipx->ipx_dest.node[4], + ipx->ipx_dest.node[5], + ipx->ipx_dest.sock, + ipx->ipx_source.net, + ipx->ipx_source.node[0], + ipx->ipx_source.node[1], + ipx->ipx_source.node[2], + ipx->ipx_source.node[3], + ipx->ipx_source.node[4], + ipx->ipx_source.node[5], + ipx->ipx_source.sock); - case NAT25_INSERT: - { - DEBUG_INFO("NAT25: Insert IPX, Dest=%08x,%02x%02x%02x%02x%02x%02x,%04x Source=%08x,%02x%02x%02x%02x%02x%02x,%04x\n", - ipx->ipx_dest.net, - ipx->ipx_dest.node[0], - ipx->ipx_dest.node[1], - ipx->ipx_dest.node[2], - ipx->ipx_dest.node[3], - ipx->ipx_dest.node[4], - ipx->ipx_dest.node[5], - ipx->ipx_dest.sock, - ipx->ipx_source.net, - ipx->ipx_source.node[0], - ipx->ipx_source.node[1], - ipx->ipx_source.node[2], - ipx->ipx_source.node[3], - ipx->ipx_source.node[4], - ipx->ipx_source.node[5], - ipx->ipx_source.sock); + if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) { + DEBUG_INFO("NAT25: Use IPX Net, and Socket as network addr\n"); - if (!memcmp(skb->data+ETH_ALEN, ipx->ipx_source.node, ETH_ALEN)) - { - DEBUG_INFO("NAT25: Use IPX Net, and Socket as network addr\n"); + __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock); - __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_source.net, &ipx->ipx_source.sock); + /* change IPX source node addr to wlan STA address */ + memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN); + } else { + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node); + } + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + __nat25_db_print(priv); + return 0; + case NAT25_LOOKUP: + if (!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) { + DEBUG_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n"); - /* change IPX source node addr to wlan STA address */ - memcpy(ipx->ipx_source.node, GET_MY_HWADDR(priv), ETH_ALEN); - } - else - { - __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_source.net, ipx->ipx_source.node); - } + __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock); - __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - __nat25_db_print(priv); - } - return 0; + /* replace IPX destination node addr with Lookup destination MAC addr */ + memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN); + } else { + __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node); - case NAT25_LOOKUP: - { - if (!memcmp(GET_MY_HWADDR(priv), ipx->ipx_dest.node, ETH_ALEN)) - { - DEBUG_INFO("NAT25: Lookup IPX, Modify Destination IPX Node addr\n"); - - __nat25_generate_ipx_network_addr_with_socket(networkAddr, &ipx->ipx_dest.net, &ipx->ipx_dest.sock); - - __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - - /* replace IPX destination node addr with Lookup destination MAC addr */ - memcpy(ipx->ipx_dest.node, skb->data, ETH_ALEN); - } - else - { - __nat25_generate_ipx_network_addr_with_node(networkAddr, &ipx->ipx_dest.net, ipx->ipx_dest.node); - - __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - } - } - return 0; - - default: - return -1; + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + } + return 0; + default: + return -1; } - } - - /* AARP */ - else if (ea != NULL) - { + } else if (ea != NULL) { /* Sanity check fields. */ - if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) - { + if (ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN) { DEBUG_WARN("NAT25: Appletalk AARP Sanity check fail!\n"); return -1; } - switch (method) - { - case NAT25_CHECK: - return 0; + switch (method) { + case NAT25_CHECK: + return 0; + case NAT25_INSERT: + /* change to AARP source mac address to wlan STA address */ + memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN); - case NAT25_INSERT: - { - /* change to AARP source mac address to wlan STA address */ - memcpy(ea->hw_src, GET_MY_HWADDR(priv), ETH_ALEN); + DEBUG_INFO("NAT25: Insert AARP, Source =%d,%d Destination =%d,%d\n", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); - DEBUG_INFO("NAT25: Insert AARP, Source=%d,%d Destination=%d,%d\n", - ea->pa_src_net, - ea->pa_src_node, - ea->pa_dst_net, - ea->pa_dst_node); + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node); - __nat25_generate_apple_network_addr(networkAddr, &ea->pa_src_net, &ea->pa_src_node); + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + __nat25_db_print(priv); + return 0; + case NAT25_LOOKUP: + DEBUG_INFO("NAT25: Lookup AARP, Source =%d,%d Destination =%d,%d\n", + ea->pa_src_net, + ea->pa_src_node, + ea->pa_dst_net, + ea->pa_dst_node); - __nat25_db_print(priv); - } - return 0; + __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node); - case NAT25_LOOKUP: - { - DEBUG_INFO("NAT25: Lookup AARP, Source=%d,%d Destination=%d,%d\n", - ea->pa_src_net, - ea->pa_src_node, - ea->pa_dst_net, - ea->pa_dst_node); + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - __nat25_generate_apple_network_addr(networkAddr, &ea->pa_dst_net, &ea->pa_dst_node); - - __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - - /* change to AARP destination mac address to Lookup result */ - memcpy(ea->hw_dst, skb->data, ETH_ALEN); - } - return 0; - - default: - return -1; + /* change to AARP destination mac address to Lookup result */ + memcpy(ea->hw_dst, skb->data, ETH_ALEN); + return 0; + default: + return -1; } - } + } else if (ddp != NULL) { + switch (method) { + case NAT25_CHECK: + return -1; + case NAT25_INSERT: + DEBUG_INFO("NAT25: Insert DDP, Source =%d,%d Destination =%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); - /* DDP */ - else if (ddp != NULL) - { - switch (method) - { - case NAT25_CHECK: - return -1; + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode); - case NAT25_INSERT: - { - DEBUG_INFO("NAT25: Insert DDP, Source=%d,%d Destination=%d,%d\n", - ddp->deh_snet, - ddp->deh_snode, - ddp->deh_dnet, - ddp->deh_dnode); + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_snet, &ddp->deh_snode); - - __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - - __nat25_db_print(priv); - } - return 0; - - case NAT25_LOOKUP: - { - DEBUG_INFO("NAT25: Lookup DDP, Source=%d,%d Destination=%d,%d\n", - ddp->deh_snet, - ddp->deh_snode, - ddp->deh_dnet, - ddp->deh_dnode); - - __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode); - - __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - } - return 0; - - default: - return -1; + __nat25_db_print(priv); + return 0; + case NAT25_LOOKUP: + DEBUG_INFO("NAT25: Lookup DDP, Source =%d,%d Destination =%d,%d\n", + ddp->deh_snet, + ddp->deh_snode, + ddp->deh_dnet, + ddp->deh_dnode); + __nat25_generate_apple_network_addr(networkAddr, &ddp->deh_dnet, &ddp->deh_dnode); + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + return 0; + default: + return -1; } } return -1; - } - - /*---------------------------------------------------*/ - /* Handle PPPoE frame */ - /*---------------------------------------------------*/ - else if ((protocol == ETH_P_PPP_DISC) || - (protocol == ETH_P_PPP_SES)) - { + } else if ((protocol == ETH_P_PPP_DISC) || + (protocol == ETH_P_PPP_SES)) { + /*---------------------------------------------------*/ + /* Handle PPPoE frame */ + /*---------------------------------------------------*/ struct pppoe_hdr *ph = (struct pppoe_hdr *)(skb->data + ETH_HLEN); unsigned short *pMagic; - switch (method) - { - case NAT25_CHECK: - if (ph->sid == 0) - return 0; - return 1; - - case NAT25_INSERT: - if (ph->sid == 0) /* Discovery phase according to tag */ - { - if (ph->code == PADI_CODE || ph->code == PADR_CODE) - { - if (priv->ethBrExtInfo.addPPPoETag) { - struct pppoe_tag *tag, *pOldTag; - unsigned char tag_buf[40]; - int old_tag_len=0; - - tag = (struct pppoe_tag *)tag_buf; - pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); - if (pOldTag) { /* if SID existed, copy old value and delete it */ - old_tag_len = ntohs(pOldTag->tag_len); - if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { - DEBUG_ERR("SID tag length too long!\n"); - return -1; - } - - memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN, - pOldTag->tag_data, old_tag_len); - - if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) { - DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n"); - return -1; - } - ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len); - } - - tag->tag_type = PTT_RELAY_SID; - tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len); - - /* insert the magic_code+client mac in relay tag */ - pMagic = (unsigned short *)tag->tag_data; - *pMagic = htons(MAGIC_CODE); - memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN); - - /* Add relay tag */ - if (__nat25_add_pppoe_tag(skb, tag) < 0) - return -1; - - DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n", - (ph->code == PADI_CODE ? "PADI" : "PADR")); - } - else { /* not add relay tag */ - if (priv->pppoe_connection_in_progress && - memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) { - DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); - return -2; - } - - if (priv->pppoe_connection_in_progress == 0) - memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN); - - priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; - } - } - else - return -1; - } - else /* session phase */ - { - DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); - - __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid)); - - __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - - __nat25_db_print(priv); - - if (!priv->ethBrExtInfo.addPPPoETag && - priv->pppoe_connection_in_progress && - !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) - priv->pppoe_connection_in_progress = 0; - } + switch (method) { + case NAT25_CHECK: + if (ph->sid == 0) return 0; - - case NAT25_LOOKUP: - if (ph->code == PADO_CODE || ph->code == PADS_CODE) - { + return 1; + case NAT25_INSERT: + if (ph->sid == 0) { /* Discovery phase according to tag */ + if (ph->code == PADI_CODE || ph->code == PADR_CODE) { if (priv->ethBrExtInfo.addPPPoETag) { - struct pppoe_tag *tag; - unsigned char *ptr; - unsigned short tagType, tagLen; - int offset=0; + struct pppoe_tag *tag, *pOldTag; + unsigned char tag_buf[40]; + int old_tag_len = 0; - if ((ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID))) == NULL) { - DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n"); - return -1; + tag = (struct pppoe_tag *)tag_buf; + pOldTag = (struct pppoe_tag *)__nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); + if (pOldTag) { /* if SID existed, copy old value and delete it */ + old_tag_len = ntohs(pOldTag->tag_len); + if (old_tag_len+TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN > sizeof(tag_buf)) { + DEBUG_ERR("SID tag length too long!\n"); + return -1; + } + + memcpy(tag->tag_data+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN, + pOldTag->tag_data, old_tag_len); + + if (skb_pull_and_merge(skb, (unsigned char *)pOldTag, TAG_HDR_LEN+old_tag_len) < 0) { + DEBUG_ERR("call skb_pull_and_merge() failed in PADI/R packet!\n"); + return -1; + } + ph->length = htons(ntohs(ph->length)-TAG_HDR_LEN-old_tag_len); } - tag = (struct pppoe_tag *)ptr; - tagType = (unsigned short)((ptr[0] << 8) + ptr[1]); - tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]); - - if ((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) { - DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen); - return -1; - } + tag->tag_type = PTT_RELAY_SID; + tag->tag_len = htons(MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN+old_tag_len); + /* insert the magic_code+client mac in relay tag */ pMagic = (unsigned short *)tag->tag_data; - if (ntohs(*pMagic) != MAGIC_CODE) { - DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n", - (ph->code == PADO_CODE ? "PADO" : "PADS")); + *pMagic = htons(MAGIC_CODE); + memcpy(tag->tag_data+MAGIC_CODE_LEN, skb->data+ETH_ALEN, ETH_ALEN); + + /* Add relay tag */ + if (__nat25_add_pppoe_tag(skb, tag) < 0) return -1; + + DEBUG_INFO("NAT25: Insert PPPoE, forward %s packet\n", + (ph->code == PADI_CODE ? "PADI" : "PADR")); + } else { /* not add relay tag */ + if (priv->pppoe_connection_in_progress && + memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) { + DEBUG_ERR("Discard PPPoE packet due to another PPPoE connection is in progress!\n"); + return -2; } - memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN); + if (priv->pppoe_connection_in_progress == 0) + memcpy(priv->pppoe_addr, skb->data+ETH_ALEN, ETH_ALEN); - if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN) - offset = TAG_HDR_LEN; - - if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) { - DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n"); - return -1; - } - ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset)); - if (offset > 0) - tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN); - - DEBUG_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n", - (ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name); - } - else { /* not add relay tag */ - if (!priv->pppoe_connection_in_progress) { - DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n"); - return -1; - } - memcpy(skb->data, priv->pppoe_addr, ETH_ALEN); priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; } + } else { + return -1; } - else { - if (ph->sid != 0) - { - DEBUG_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name); - __nat25_generate_pppoe_network_addr(networkAddr, skb->data+ETH_ALEN, &(ph->sid)); + } else { /* session phase */ + DEBUG_INFO("NAT25: Insert PPPoE, insert session packet to %s\n", skb->dev->name); - __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + __nat25_generate_pppoe_network_addr(networkAddr, skb->data, &(ph->sid)); - __nat25_db_print(priv); - } - else + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + + __nat25_db_print(priv); + + if (!priv->ethBrExtInfo.addPPPoETag && + priv->pppoe_connection_in_progress && + !memcmp(skb->data+ETH_ALEN, priv->pppoe_addr, ETH_ALEN)) + priv->pppoe_connection_in_progress = 0; + } + return 0; + case NAT25_LOOKUP: + if (ph->code == PADO_CODE || ph->code == PADS_CODE) { + if (priv->ethBrExtInfo.addPPPoETag) { + struct pppoe_tag *tag; + unsigned char *ptr; + unsigned short tagType, tagLen; + int offset = 0; + + ptr = __nat25_find_pppoe_tag(ph, ntohs(PTT_RELAY_SID)); + if (ptr == NULL) { + DEBUG_ERR("Fail to find PTT_RELAY_SID in FADO!\n"); return -1; + } + tag = (struct pppoe_tag *)ptr; + tagType = (unsigned short)((ptr[0] << 8) + ptr[1]); + tagLen = (unsigned short)((ptr[2] << 8) + ptr[3]); + + if ((tagType != ntohs(PTT_RELAY_SID)) || (tagLen < (MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN))) { + DEBUG_ERR("Invalid PTT_RELAY_SID tag length [%d]!\n", tagLen); + return -1; + } + + pMagic = (unsigned short *)tag->tag_data; + if (ntohs(*pMagic) != MAGIC_CODE) { + DEBUG_ERR("Can't find MAGIC_CODE in %s packet!\n", + (ph->code == PADO_CODE ? "PADO" : "PADS")); + return -1; + } + + memcpy(skb->data, tag->tag_data+MAGIC_CODE_LEN, ETH_ALEN); + + if (tagLen > MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN) + offset = TAG_HDR_LEN; + + if (skb_pull_and_merge(skb, ptr+offset, TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset) < 0) { + DEBUG_ERR("call skb_pull_and_merge() failed in PADO packet!\n"); + return -1; + } + ph->length = htons(ntohs(ph->length)-(TAG_HDR_LEN+MAGIC_CODE_LEN+RTL_RELAY_TAG_LEN-offset)); + if (offset > 0) + tag->tag_len = htons(tagLen-MAGIC_CODE_LEN-RTL_RELAY_TAG_LEN); + + DEBUG_INFO("NAT25: Lookup PPPoE, forward %s Packet from %s\n", + (ph->code == PADO_CODE ? "PADO" : "PADS"), skb->dev->name); + } else { /* not add relay tag */ + if (!priv->pppoe_connection_in_progress) { + DEBUG_ERR("Discard PPPoE packet due to no connection in progresss!\n"); + return -1; + } + memcpy(skb->data, priv->pppoe_addr, ETH_ALEN); + priv->pppoe_connection_in_progress = WAIT_TIME_PPPOE; } - return 0; - - default: - return -1; + } else { + if (ph->sid != 0) { + DEBUG_INFO("NAT25: Lookup PPPoE, lookup session packet from %s\n", skb->dev->name); + __nat25_generate_pppoe_network_addr(networkAddr, skb->data+ETH_ALEN, &(ph->sid)); + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + __nat25_db_print(priv); + } else { + return -1; + } + } + return 0; + default: + return -1; } - } - - /*---------------------------------------------------*/ - /* Handle EAP frame */ - /*---------------------------------------------------*/ - else if (protocol == 0x888e) - { - switch (method) - { - case NAT25_CHECK: - return -1; - - case NAT25_INSERT: - return 0; - - case NAT25_LOOKUP: - return 0; - - default: - return -1; + } else if (protocol == 0x888e) { + /*---------------------------------------------------*/ + /* Handle EAP frame */ + /*---------------------------------------------------*/ + switch (method) { + case NAT25_CHECK: + return -1; + case NAT25_INSERT: + return 0; + case NAT25_LOOKUP: + return 0; + default: + return -1; } - } - - /*---------------------------------------------------*/ - /* Handle C-Media proprietary frame */ - /*---------------------------------------------------*/ - else if ((protocol == 0xe2ae) || - (protocol == 0xe2af)) - { - switch (method) - { - case NAT25_CHECK: - return -1; - - case NAT25_INSERT: - return 0; - - case NAT25_LOOKUP: - return 0; - - default: - return -1; + } else if ((protocol == 0xe2ae) || (protocol == 0xe2af)) { + /*---------------------------------------------------*/ + /* Handle C-Media proprietary frame */ + /*---------------------------------------------------*/ + switch (method) { + case NAT25_CHECK: + return -1; + case NAT25_INSERT: + return 0; + case NAT25_LOOKUP: + return 0; + default: + return -1; } - } - - /*---------------------------------------------------*/ - /* Handle IPV6 frame */ - /*---------------------------------------------------*/ - else if (protocol == ETH_P_IPV6) - { + } else if (protocol == ETH_P_IPV6) { + /*------------------------------------------------*/ + /* Handle IPV6 frame */ + /*------------------------------------------------*/ struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN); - if (sizeof(*iph) >= (skb->len - ETH_HLEN)) - { + if (sizeof(*iph) >= (skb->len - ETH_HLEN)) { DEBUG_WARN("NAT25: malformed IPv6 packet !\n"); return -1; } - switch (method) - { - case NAT25_CHECK: - if (skb->data[0] & 1) - return 0; - return -1; + switch (method) { + case NAT25_CHECK: + if (skb->data[0] & 1) + return 0; + return -1; + case NAT25_INSERT: + DEBUG_INFO("NAT25: Insert IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," + " DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", + iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3], + iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7], + iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3], + iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]); - case NAT25_INSERT: - { - DEBUG_INFO("NAT25: Insert IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," - " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", - iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3], - iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7], - iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], - iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); + if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { + __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); + __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); + __nat25_db_print(priv); - if (memcmp(&iph->saddr, "\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0", 16)) { - __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->saddr); - __nat25_db_network_insert(priv, skb->data+ETH_ALEN, networkAddr); - __nat25_db_print(priv); - - if (iph->nexthdr == IPPROTO_ICMPV6 && - skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { - if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), - skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) { - struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); - hdr->icmp6_cksum = 0; - hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, - iph->payload_len, - IPPROTO_ICMPV6, - csum_partial((__u8 *)hdr, iph->payload_len, 0)); - } - } + if (iph->nexthdr == IPPROTO_ICMPV6 && + skb->len > (ETH_HLEN + sizeof(*iph) + 4)) { + if (update_nd_link_layer_addr(skb->data + ETH_HLEN + sizeof(*iph), + skb->len - ETH_HLEN - sizeof(*iph), GET_MY_HWADDR(priv))) { + struct icmp6hdr *hdr = (struct icmp6hdr *)(skb->data + ETH_HLEN + sizeof(*iph)); + hdr->icmp6_cksum = 0; + hdr->icmp6_cksum = csum_ipv6_magic(&iph->saddr, &iph->daddr, + iph->payload_len, + IPPROTO_ICMPV6, + csum_partial((__u8 *)hdr, iph->payload_len, 0)); } } - return 0; - - case NAT25_LOOKUP: - DEBUG_INFO("NAT25: Lookup IP, SA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x," - " DA=%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", - iph->saddr.s6_addr16[0],iph->saddr.s6_addr16[1],iph->saddr.s6_addr16[2],iph->saddr.s6_addr16[3], - iph->saddr.s6_addr16[4],iph->saddr.s6_addr16[5],iph->saddr.s6_addr16[6],iph->saddr.s6_addr16[7], - iph->daddr.s6_addr16[0],iph->daddr.s6_addr16[1],iph->daddr.s6_addr16[2],iph->daddr.s6_addr16[3], - iph->daddr.s6_addr16[4],iph->daddr.s6_addr16[5],iph->daddr.s6_addr16[6],iph->daddr.s6_addr16[7]); - - - __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr); - __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); - return 0; - - default: - return -1; + } + return 0; + case NAT25_LOOKUP: + DEBUG_INFO("NAT25: Lookup IP, SA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x, DA =%4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x\n", + iph->saddr.s6_addr16[0], iph->saddr.s6_addr16[1], iph->saddr.s6_addr16[2], iph->saddr.s6_addr16[3], + iph->saddr.s6_addr16[4], iph->saddr.s6_addr16[5], iph->saddr.s6_addr16[6], iph->saddr.s6_addr16[7], + iph->daddr.s6_addr16[0], iph->daddr.s6_addr16[1], iph->daddr.s6_addr16[2], iph->daddr.s6_addr16[3], + iph->daddr.s6_addr16[4], iph->daddr.s6_addr16[5], iph->daddr.s6_addr16[6], iph->daddr.s6_addr16[7]); + __nat25_generate_ipv6_network_addr(networkAddr, (unsigned int *)&iph->daddr); + __nat25_db_network_lookup_and_replace(priv, skb, networkAddr); + return 0; + default: + return -1; } } return -1; @@ -1246,21 +1062,20 @@ int nat25_db_handle(struct adapter *priv, struct sk_buff *skb, int method) int nat25_handle_frame(struct adapter *priv, struct sk_buff *skb) { if (!(skb->data[0] & 1)) { - int is_vlan_tag=0, i, retval=0; - unsigned short vlan_hdr=0; + int is_vlan_tag = 0, i, retval = 0; + unsigned short vlan_hdr = 0; unsigned short protocol; protocol = be16_to_cpu(*((__be16 *)(skb->data + 2 * ETH_ALEN))); if (protocol == ETH_P_8021Q) { is_vlan_tag = 1; vlan_hdr = *((unsigned short *)(skb->data+ETH_ALEN*2+2)); - for (i=0; i<6; i++) + for (i = 0; i < 6; i++) *((unsigned short *)(skb->data+ETH_ALEN*2+2-i*2)) = *((unsigned short *)(skb->data+ETH_ALEN*2-2-i*2)); skb_pull(skb, 4); } - if (!priv->ethBrExtInfo.nat25_disable) - { + if (!priv->ethBrExtInfo.nat25_disable) { unsigned long irqL; _enter_critical_bh(&priv->br_ext_lock, &irqL); /* @@ -1291,7 +1106,7 @@ int nat25_handle_frame(struct adapter *priv, struct sk_buff *skb) if (is_vlan_tag) { skb_push(skb, 4); - for (i=0; i<6; i++) + for (i = 0; i < 6; i++) *((unsigned short *)(skb->data+i*2)) = *((unsigned short *)(skb->data+4+i*2)); *((__be16 *)(skb->data+ETH_ALEN*2)) = __constant_htons(ETH_P_8021Q); *((unsigned short *)(skb->data+ETH_ALEN*2+2)) = vlan_hdr; @@ -1335,16 +1150,13 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) if (skb == NULL) return; - if (!priv->ethBrExtInfo.dhcp_bcst_disable) - { + if (!priv->ethBrExtInfo.dhcp_bcst_disable) { __be16 protocol = *((__be16 *)(skb->data + 2 * ETH_ALEN)); - if (protocol == __constant_htons(ETH_P_IP)) /* IP */ - { - struct iphdr* iph = (struct iphdr *)(skb->data + ETH_HLEN); + if (protocol == __constant_htons(ETH_P_IP)) { /* IP */ + struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN); - if (iph->protocol == IPPROTO_UDP) /* UDP */ - { + if (iph->protocol == IPPROTO_UDP) { /* UDP */ struct udphdr *udph = (struct udphdr *)((size_t)iph + (iph->ihl << 2)); if ((udph->source == __constant_htons(CLIENT_PORT)) && @@ -1354,8 +1166,8 @@ void dhcp_flag_bcast(struct adapter *priv, struct sk_buff *skb) u32 cookie = be32_to_cpu((__be32)dhcph->cookie); if (cookie == DHCP_MAGIC) { /* match magic word */ - if (!(dhcph->flags & htons(BROADCAST_FLAG))) /* if not broadcast */ - { + if (!(dhcph->flags & htons(BROADCAST_FLAG))) { + /* if not broadcast */ register int sum = 0; DEBUG_INFO("DHCP: change flag of DHCP request to broadcast.\n"); @@ -1388,8 +1200,7 @@ void *scdb_findEntry(struct adapter *priv, unsigned char *macAddr, __nat25_generate_ipv4_network_addr(networkAddr, (unsigned int *)ipAddr); hash = __nat25_network_hash(networkAddr); db = priv->nethash[hash]; - while (db != NULL) - { + while (db != NULL) { if (!memcmp(db->networkAddr, networkAddr, MAX_NETWORK_ADDR_LEN)) { /* _exit_critical_bh(&priv->br_ext_lock, &irqL); */ return (void *)db;