Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

arp-win32.c

Go to the documentation of this file.
00001 /*
00002  * arp-win32.c
00003  *
00004  * Copyright (c) 2002 Dug Song <dugsong@monkey.org>
00005  *
00006  * $Id: arp-win32.c,v 1.12 2005/01/23 07:36:54 dugsong Exp $
00007  */
00008 
00009 #include "config.h"
00010 
00011 #include <ws2tcpip.h>
00012 #include <iphlpapi.h>
00013 
00014 #include <errno.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 
00018 #include "dnet.h"
00019 
00020 struct arp_handle {
00021         MIB_IPNETTABLE *iptable;
00022 };
00023 
00024 arp_t *
00025 arp_open(void)
00026 {
00027         return (calloc(1, sizeof(arp_t)));
00028 }
00029 
00030 int
00031 arp_add(arp_t *arp, const struct arp_entry *entry)
00032 {
00033         MIB_IPFORWARDROW ipfrow;
00034         MIB_IPNETROW iprow;
00035         
00036         if (GetBestRoute(entry->arp_pa.addr_ip,
00037             IP_ADDR_ANY, &ipfrow) != NO_ERROR)
00038                 return (-1);
00039 
00040         iprow.dwIndex = ipfrow.dwForwardIfIndex;
00041         iprow.dwPhysAddrLen = ETH_ADDR_LEN;
00042         memcpy(iprow.bPhysAddr, &entry->arp_ha.addr_eth, ETH_ADDR_LEN);
00043         iprow.dwAddr = entry->arp_pa.addr_ip;
00044         iprow.dwType = 4;       /* XXX - static */
00045 
00046         if (CreateIpNetEntry(&iprow) != NO_ERROR)
00047                 return (-1);
00048 
00049         return (0);
00050 }
00051 
00052 int
00053 arp_delete(arp_t *arp, const struct arp_entry *entry)
00054 {
00055         MIB_IPFORWARDROW ipfrow;
00056         MIB_IPNETROW iprow;
00057 
00058         if (GetBestRoute(entry->arp_pa.addr_ip,
00059             IP_ADDR_ANY, &ipfrow) != NO_ERROR)
00060                 return (-1);
00061 
00062         memset(&iprow, 0, sizeof(iprow));
00063         iprow.dwIndex = ipfrow.dwForwardIfIndex;
00064         iprow.dwAddr = entry->arp_pa.addr_ip;
00065 
00066         if (DeleteIpNetEntry(&iprow) != NO_ERROR) {
00067                 errno = ENXIO;
00068                 return (-1);
00069         }
00070         return (0);
00071 }
00072 
00073 static int
00074 _arp_get_entry(const struct arp_entry *entry, void *arg)
00075 {
00076         struct arp_entry *e = (struct arp_entry *)arg;
00077         
00078         if (addr_cmp(&entry->arp_pa, &e->arp_pa) == 0) {
00079                 memcpy(&e->arp_ha, &entry->arp_ha, sizeof(e->arp_ha));
00080                 return (1);
00081         }
00082         return (0);
00083 }
00084 
00085 int
00086 arp_get(arp_t *arp, struct arp_entry *entry)
00087 {
00088         if (arp_loop(arp, _arp_get_entry, entry) != 1) {
00089                 errno = ENXIO;
00090                 SetLastError(ERROR_NO_DATA);
00091                 return (-1);
00092         }
00093         return (0);
00094 }
00095 
00096 int
00097 arp_loop(arp_t *arp, arp_handler callback, void *arg)
00098 {
00099         struct arp_entry entry;
00100         ULONG len;
00101         int i, ret;
00102 
00103         for (len = sizeof(arp->iptable[0]); ; ) {
00104                 if (arp->iptable)
00105                         free(arp->iptable);
00106                 arp->iptable = malloc(len);
00107                 ret = GetIpNetTable(arp->iptable, &len, FALSE);
00108                 if (ret == NO_ERROR)
00109                         break;
00110                 else if (ret != ERROR_INSUFFICIENT_BUFFER)
00111                         return (-1);
00112         }
00113         entry.arp_pa.addr_type = ADDR_TYPE_IP;
00114         entry.arp_pa.addr_bits = IP_ADDR_BITS;
00115         
00116         entry.arp_ha.addr_type = ADDR_TYPE_ETH;
00117         entry.arp_ha.addr_bits = ETH_ADDR_BITS;
00118         
00119         for (i = 0; i < (int)arp->iptable->dwNumEntries; i++) {
00120                 if (arp->iptable->table[i].dwPhysAddrLen != ETH_ADDR_LEN)
00121                         continue;
00122                 entry.arp_pa.addr_ip = arp->iptable->table[i].dwAddr;
00123                 memcpy(&entry.arp_ha.addr_eth,
00124                     arp->iptable->table[i].bPhysAddr, ETH_ADDR_LEN);
00125                 
00126                 if ((ret = (*callback)(&entry, arg)) != 0)
00127                         return (ret);
00128         }
00129         return (0);
00130 }
00131 
00132 arp_t *
00133 arp_close(arp_t *arp)
00134 {
00135         if (arp != NULL) {
00136                 if (arp->iptable != NULL)
00137                         free(arp->iptable);
00138                 free(arp);
00139         }
00140         return (NULL);
00141 }

Generated on Sun May 14 14:51:11 2006 by  doxygen 1.4.2