summaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/Arp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/bcm/Arp.c')
-rw-r--r--drivers/staging/bcm/Arp.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/drivers/staging/bcm/Arp.c b/drivers/staging/bcm/Arp.c
new file mode 100644
index 0000000..d60d859
--- /dev/null
+++ b/drivers/staging/bcm/Arp.c
@@ -0,0 +1,94 @@
+
+/*
+ * File Name: Arp.c
+ * Abstract: This file contains the routines for handling ARP PACKETS
+ */
+#include "headers.h"
+#define ARP_PKT_SIZE 60
+
+/* =========================================================================
+ * Function - reply_to_arp_request()
+ *
+ * Description - When this host tries to broadcast ARP request packet through
+ * the virtual interface (veth0), reply directly to upper layer.
+ * This function allocates a new skb for ARP reply packet,
+ * fills in the fields of the packet and then sends it to
+ * upper layer.
+ *
+ * Parameters - skb: Pointer to sk_buff structure of the ARP request pkt.
+ *
+ * Returns - None
+ * =========================================================================*/
+
+VOID
+reply_to_arp_request(struct sk_buff *skb)
+{
+ PMINI_ADAPTER Adapter;
+ struct ArpHeader *pArpHdr = NULL;
+ struct ethhdr *pethhdr = NULL;
+ UCHAR uiIPHdr[4];
+ /* Check for valid skb */
+ if(skb == NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n");
+ return;
+ }
+
+
+ Adapter = GET_BCM_ADAPTER(skb->dev);
+ /* Print the ARP Request Packet */
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :");
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
+
+ /*
+ * Extract the Ethernet Header and Arp Payload including Header
+ */
+ pethhdr = (struct ethhdr *)skb->data;
+ pArpHdr = (struct ArpHeader *)(skb->data+ETH_HLEN);
+
+ if(Adapter->bETHCSEnabled)
+ {
+ if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
+ {
+ bcm_kfree_skb(skb);
+ return;
+ }
+ }
+
+ // Set the Ethernet Header First.
+ memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN);
+ if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN))
+ {
+ pethhdr->h_source[5]++;
+ }
+
+ /* Set the reply to ARP Reply */
+ pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY);
+
+ /* Set the HW Address properly */
+ memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN);
+ memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN);
+
+ // Swapping the IP Adddress
+ memcpy(uiIPHdr,pArpHdr->ar_sip,4);
+ memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4);
+ memcpy(pArpHdr->ar_tip,uiIPHdr,4);
+
+ /* Print the ARP Reply Packet */
+
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: ");
+
+ /* Send the Packet to upper layer */
+ BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len);
+
+ skb->protocol = eth_type_trans(skb,skb->dev);
+ skb->pkt_type = PACKET_HOST;
+
+// skb->mac.raw=skb->data+LEADER_SIZE;
+ skb_set_mac_header (skb, LEADER_SIZE);
+ netif_rx(skb);
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n");
+ return;
+}
+
+
OpenPOWER on IntegriCloud