Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / staging / bcm / Arp.c
1
2 /*
3  * File Name: Arp.c
4  * Abstract: This file contains the routines for handling ARP PACKETS
5  */
6 #include "headers.h"
7 #define ARP_PKT_SIZE    60
8
9 /* =========================================================================
10  * Function    - reply_to_arp_request()
11  *
12  * Description - When this host tries to broadcast ARP request packet through
13  *                               the virtual interface (veth0), reply directly to upper layer.
14  *                               This function allocates a new skb for ARP reply packet,
15  *                               fills in the fields of the packet and then sends it to
16  *                               upper layer.
17  *
18  * Parameters  - skb:   Pointer to sk_buff structure of the ARP request pkt.
19  *
20  * Returns     - None
21  * =========================================================================*/
22
23 VOID
24 reply_to_arp_request(struct sk_buff *skb)
25 {
26         PMINI_ADAPTER           Adapter;
27         struct ArpHeader        *pArpHdr = NULL;
28         struct ethhdr           *pethhdr = NULL;
29         UCHAR                           uiIPHdr[4];
30         /* Check for valid skb */
31         if(skb == NULL)
32         {
33                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n");
34                 return;
35         }
36
37
38         Adapter = GET_BCM_ADAPTER(skb->dev);
39         /* Print the ARP Request Packet */
40         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :");
41         BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
42
43         /*
44          * Extract the Ethernet Header and Arp Payload including Header
45      */
46         pethhdr = (struct ethhdr *)skb->data;
47         pArpHdr  = (struct ArpHeader *)(skb->data+ETH_HLEN);
48
49         if(Adapter->bETHCSEnabled)
50         {
51                 if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
52                 {
53                         bcm_kfree_skb(skb);
54                         return;
55                 }
56         }
57
58         // Set the Ethernet Header First.
59         memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN);
60         if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
61         {
62                 pethhdr->h_source[5]++;
63         }
64
65         /* Set the reply to ARP Reply */
66         pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY);
67
68         /* Set the HW Address properly */
69         memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN);
70         memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN);
71
72         // Swapping the IP Adddress
73         memcpy(uiIPHdr,pArpHdr->ar_sip,4);
74         memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4);
75         memcpy(pArpHdr->ar_tip,uiIPHdr,4);
76
77         /* Print the ARP Reply Packet */
78
79         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: ");
80
81         /* Send the Packet to upper layer */
82         BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
83
84         skb->protocol = eth_type_trans(skb,skb->dev);
85         skb->pkt_type = PACKET_HOST;
86
87 //      skb->mac.raw=skb->data+LEADER_SIZE;
88         skb_set_mac_header (skb, LEADER_SIZE);
89         netif_rx(skb);
90         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n");
91         return;
92 }
93
94