[pisa-src] r1004 - trunk/libpisa

  • From: Thomas Jansen <mithi@xxxxxxxxx>
  • To: pisa-src@xxxxxxxxxxxxx
  • Date: Wed, 30 Sep 2009 16:01:07 +0200

Author: tjansen
Date: Wed Sep 30 16:01:07 2009
New Revision: 1004

Log:
Added caching for ARP addresses. Hopefully speeds up legacy connections. Note
that this is work in progress, especially the malloc has no free counterpart
yet.

Modified:
   trunk/libpisa/arp.c

Modified: trunk/libpisa/arp.c
==============================================================================
--- trunk/libpisa/arp.c Wed Sep 30 15:30:10 2009        (r1003)
+++ trunk/libpisa/arp.c Wed Sep 30 16:01:07 2009        (r1004)
@@ -12,9 +12,20 @@
 
 #include <arpa/inet.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "arp.h"
+#include "global.h"
+#include "uthash.h"
+
+struct pisa_arp_cache_entry {
+       pisa_mac mac;
+       struct in_addr ip;
+       UT_hash_handle hh;
+};
+
+static struct pisa_arp_cache_entry *arp_cache = NULL;
 
 /**
  * Convert a string to an ARP entry.
@@ -42,16 +53,63 @@
 }
 
 /**
- * Search the ARP table for an entry.
- * @param ip IPv4 address to search for
- * @param arp destination buffer for the ARP
+ * Find an entry in the ARP cache.
+ * @param ip IPv4 address we are looking for
+ * @return pointer to the cache entry or NULL, if none was found
+ */
+static inline struct pisa_arp_cache_entry *pisa_arp_cache_find(struct in_addr 
*ip)
+{
+       struct pisa_arp_cache_entry *e = NULL;
+       HASH_FIND(hh, arp_cache, ip, sizeof(struct in_addr), e);
+       return e;
+}
+
+/**
+ * Set the MAC address for the IPv4 address. If a previous mapping existed,
+ * the old MAC is overwritten by the new MAC. If no previous mapping for that
+ * IPv4 existed, a new entry will be created.
+ * @param ip IPv4 address
+ * @param mac destination buffer for the MAC address
+ */
+static void pisa_arp_cache_set(struct in_addr *ip, pisa_mac *mac)
+{
+       struct pisa_arp_cache_entry *e = pisa_arp_cache_find(ip);
+
+       if (e == NULL) {
+               e = malloc(sizeof(struct pisa_arp_cache_entry));
+               pisa_ipv4_copy(&e->ip, ip);
+               HASH_ADD(hh, arp_cache, ip, sizeof(struct in_addr), e);
+       }
+       memcpy(&e->mac, mac, sizeof(pisa_mac));
+}
+
+/**
+ * Retrieve the MAC for a given IPv4 address from the ARP cache.
+ * @param ip IPv4 address we are looking for
+ * @param mac destination buffer for the MAC address
+ */
+static int pisa_arp_cache_lookup(struct in_addr *ip, pisa_mac *mac)
+{
+       struct pisa_arp_cache_entry *e = pisa_arp_cache_find(ip);
+
+       if (e == NULL)
+               return -1;
+
+       memcpy(mac, &e->mac, sizeof(pisa_mac));
+       return 0;
+}
+
+/**
+ * Update or create an entry in the ARP cache for a given IPv4 address.
+ * @param ip IPv4 address that will be updated
  * @return 0 on success, -1 otherwise
  */
-int pisa_arp_from_ipv4(struct in_addr *ip, pisa_mac *mac)
+static int pisa_arp_cache_update(struct in_addr *ip)
 {
        char ip_str[INET_ADDRSTRLEN+1];
        char line[1024];
        int result = -1;
+       pisa_mac mac;
        FILE *f = fopen("/proc/net/arp", "r");
 
        inet_ntop(AF_INET, ip, ip_str, sizeof(ip_str));
@@ -61,12 +119,32 @@
        while (!feof(f)) {
                fgets(line, sizeof(line), f);
                if (!strncmp(ip_str, line, strlen(ip_str))) {
-                       pisa_mac_parse_string(mac, line + 41);
+                       pisa_mac_parse_string(&mac, line + 41);
                        result = 0;
                        break;
                }
        }
 
        fclose(f);
+
+       if (result == 0)
+               pisa_arp_cache_set(ip, &mac);
        return result;
 }
+
+/**
+ * Search the ARP table for an entry.
+ * @param ip IPv4 address to search for
+ * @param mac destination buffer for the MAC address
+ * @return 0 on success, -1 otherwise
+ */
+int pisa_arp_from_ipv4(struct in_addr *ip, pisa_mac *mac)
+{
+       if (pisa_arp_cache_lookup(ip, mac) == 0)
+               return 0;
+
+       if (pisa_arp_cache_update(ip) == 0)
+               return pisa_arp_cache_lookup(ip, mac);
+
+       return -1;
+}

Other related posts:

  • » [pisa-src] r1004 - trunk/libpisa - Thomas Jansen