Unify ethsock IP/ARP API
authorJoseph C. Lehner <joseph.c.lehner@gmail.com>
Sat, 19 Nov 2016 10:08:41 +0000 (11:08 +0100)
committerJoseph C. Lehner <joseph.c.lehner@gmail.com>
Sat, 19 Nov 2016 10:14:47 +0000 (11:14 +0100)
ethsock.c
nmrp.c
nmrpd.h

index 1c6a039c665fcbd34157fe6636a5c462495b9935..f8fdf236884a398934ec8af5ccd02534106e3deb 100644 (file)
--- a/ethsock.c
+++ b/ethsock.c
@@ -38,6 +38,12 @@ struct ethsock
        uint8_t hwaddr[6];
 };
 
+struct ethsock_arp_undo
+{
+       uint32_t ipaddr;
+       uint8_t hwaddr[6];
+};
+
 struct ethsock_ip_undo
 {
 #ifndef NMRPFLASH_WINDOWS
@@ -455,50 +461,66 @@ inline int ethsock_set_timeout(struct ethsock *sock, unsigned msec)
 }
 
 #ifndef NMRPFLASH_WINDOWS
-int ethsock_arp_add(struct ethsock *sock, uint8_t *hwaddr, struct in_addr *ipaddr)
+int ethsock_arp_add(struct ethsock *sock, uint8_t *hwaddr, uint32_t ipaddr, struct ethsock_arp_undo **undo)
 {
        return 0;
 }
 
-int ethsock_arp_del(struct ethsock *sock, uint8_t *hwaddr, struct in_addr *ipaddr)
+int ethsock_arp_del(struct ethsock *sock, struct ethsock_arp_undo **undo)
 {
        return 0;
 }
 #else
-static int ethsock_arp(struct ethsock *sock, uint8_t *hwaddr, struct in_addr *ipaddr, int add)
+static int ethsock_arp(struct ethsock *sock, uint8_t *hwaddr, uint32_t ipaddr, struct ethsock_arp_undo **undo)
 {
        DWORD ret;
        MIB_IPNETROW arp = {
                .dwIndex = sock->index,
                .dwPhysAddrLen = 6,
-               .dwAddr = ipaddr->s_addr,
+               .dwAddr = ipaddr,
                .dwType = MIB_IPNET_TYPE_STATIC
        };
-       
+
        memcpy(arp.bPhysAddr, hwaddr, 6);
-       
-       if (add) {
+
+       if (undo) {
                ret = CreateIpNetEntry(&arp);
                if (ret != NO_ERROR) {
                        win_perror2("CreateIpNetEntry", ret);
                        return -1;
                }
+
+               *undo = malloc(sizeof(struct ethsock_arp_undo));
+               if (!*undo) {
+                       perror("malloc");
+                       return -1;
+               }
+
+               (*undo)->ipaddr = ipaddr;
+               memcpy((*undo)->hwaddr, hwaddr, 6);
        } else {
                DeleteIpNetEntry(&arp);
        }
-       
+
        return 0;
 }
 
-int ethsock_arp_add(struct ethsock *sock, uint8_t *hwaddr, struct in_addr *ipaddr)
+int ethsock_arp_add(struct ethsock *sock, uint8_t *hwaddr, uint32_t ipaddr, struct ethsock_arp_undo **undo)
 {
-       ethsock_arp_del(sock, hwaddr, ipaddr);
-       return ethsock_arp(sock, hwaddr, ipaddr, 1);
+       ethsock_arp(sock, hwaddr, ipaddr, NULL);
+       return undo ? ethsock_arp(sock, hwaddr, ipaddr, undo) : -1;
 }
 
-int ethsock_arp_del(struct ethsock *sock, uint8_t *hwaddr, struct in_addr *ipaddr)
+int ethsock_arp_del(struct ethsock *sock, struct ethsock_arp_undo **undo)
 {
-       return ethsock_arp(sock, hwaddr, ipaddr, 0);
+       if (!*undo) {
+               return 0;
+       }
+
+       int ret = ethsock_arp(sock, (*undo)->hwaddr, (*undo)->ipaddr, NULL);
+       free(*undo);
+       *undo = NULL;
+       return ret;
 }
 #endif
 
diff --git a/nmrp.c b/nmrp.c
index 0d392592e05c02c52d0e54e16b29f2b554af7e5b..da665cfa856aa892e89f3350ed53799bf010205a 100644 (file)
--- a/nmrp.c
+++ b/nmrp.c
@@ -386,19 +386,15 @@ static int is_valid_ip(struct ethsock *sock, struct in_addr *ipaddr,
 }
 
 static struct ethsock *gsock = NULL;
-static struct ethsock_ip_undo *gundo = NULL;
-static int garp = 0;
-static struct in_addr arpip = { 0 };
-static uint8_t arpmac[6] = { 0 };
+static struct ethsock_ip_undo *g_ip_undo = NULL;
+static struct ethsock_arp_undo *g_arp_undo = NULL;
 
 static void sigh(int sig)
 {
        printf("\n");
        if (gsock) {
-               if (garp) {
-                       ethsock_arp_del(gsock, arpmac, &arpip);
-               }
-               ethsock_ip_del(gsock, &gundo);
+               ethsock_arp_del(gsock, &g_arp_undo);
+               ethsock_ip_del(gsock, &g_ip_undo);
                ethsock_close(gsock);
                gsock = NULL;
        }
@@ -496,7 +492,6 @@ int nmrp_do(struct nmrpd_args *args)
        }
 
        gsock = sock;
-       garp = 0;
        sigh_orig = signal(SIGINT, sigh);
 
        if (!autoip) {
@@ -513,7 +508,7 @@ int nmrp_do(struct nmrpd_args *args)
                        printf("Adding %s to interface %s.\n", args->ipaddr_intf, args->intf);
                }
 
-               if (ethsock_ip_add(sock, intf_addr, ipconf.mask.s_addr, &gundo) != 0) {
+               if (ethsock_ip_add(sock, intf_addr, ipconf.mask.s_addr, &g_ip_undo) != 0) {
                        goto out;
                }
        }
@@ -609,15 +604,10 @@ int nmrp_do(struct nmrpd_args *args)
                                printf("Sending configuration: %s, netmask %s.\n",
                                                args->ipaddr, args->ipmask);
 
-                               memcpy(arpmac, rx.eh.ether_shost, 6);
-                               memcpy(&arpip, &ipconf.addr, sizeof(ipconf.addr));
-
-                               if (ethsock_arp_add(sock, arpmac, &arpip) != 0) {
+                               if (ethsock_arp_add(sock, rx.eh.ether_shost, ipconf.addr.s_addr, &g_arp_undo) != 0) {
                                        goto out;
                                }
 
-                               garp = 1;
-
                                break;
                        case NMRP_C_TFTP_UL_REQ:
                                if (!upload_ok) {
@@ -760,8 +750,8 @@ int nmrp_do(struct nmrpd_args *args)
 out:
        signal(SIGINT, sigh_orig);
        gsock = NULL;
-       ethsock_arp_del(sock, arpmac, &arpip);
-       ethsock_ip_del(sock, &gundo);
+       ethsock_arp_del(sock, &g_arp_undo);
+       ethsock_ip_del(sock, &g_ip_undo);
        ethsock_close(sock);
        return status;
 }
diff --git a/nmrpd.h b/nmrpd.h
index 2e85012694658b9329410cf5ad8a5f6b1fe0d216..e061155b83dc1370bab3dc8cfbb9bd4d09c8a1fe 100644 (file)
--- a/nmrpd.h
+++ b/nmrpd.h
@@ -104,6 +104,7 @@ void sock_perror(const char *msg);
 extern int verbosity;
 
 struct ethsock;
+struct ethsock_arp_undo;
 struct ethsock_ip_undo;
 
 struct ethsock *ethsock_create(const char *intf, uint16_t protocol);
@@ -112,8 +113,8 @@ int ethsock_send(struct ethsock *sock, void *buf, size_t len);
 ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len);
 int ethsock_set_timeout(struct ethsock *sock, unsigned msec);
 uint8_t *ethsock_get_hwaddr(struct ethsock *sock);
-int ethsock_arp_add(struct ethsock *sock, uint8_t *hwaddr, struct in_addr *ipaddr);
-int ethsock_arp_del(struct ethsock *sock, uint8_t *hwaddr, struct in_addr *ipaddr);
+int ethsock_arp_add(struct ethsock *sock, uint8_t *hwaddr, uint32_t ipaddr, struct ethsock_arp_undo **undo);
+int ethsock_arp_del(struct ethsock *sock, struct ethsock_arp_undo **undo);
 int ethsock_list_all(void);
 
 struct ethsock_ip_callback_args