diff --git a/ethsock.c b/ethsock.c index 1c6a039..f8fdf23 100644 --- 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 0d39259..da665cf 100644 --- 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 2e85012..e061155 100644 --- 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