Unify ethsock IP/ARP API

This commit is contained in:
Joseph C. Lehner 2016-11-19 11:08:41 +01:00
parent fd02c7dfa9
commit fba7aab1bd
3 changed files with 46 additions and 33 deletions

View file

@ -38,6 +38,12 @@ struct ethsock
uint8_t hwaddr[6]; uint8_t hwaddr[6];
}; };
struct ethsock_arp_undo
{
uint32_t ipaddr;
uint8_t hwaddr[6];
};
struct ethsock_ip_undo struct ethsock_ip_undo
{ {
#ifndef NMRPFLASH_WINDOWS #ifndef NMRPFLASH_WINDOWS
@ -455,50 +461,66 @@ inline int ethsock_set_timeout(struct ethsock *sock, unsigned msec)
} }
#ifndef NMRPFLASH_WINDOWS #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; 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; return 0;
} }
#else #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; DWORD ret;
MIB_IPNETROW arp = { MIB_IPNETROW arp = {
.dwIndex = sock->index, .dwIndex = sock->index,
.dwPhysAddrLen = 6, .dwPhysAddrLen = 6,
.dwAddr = ipaddr->s_addr, .dwAddr = ipaddr,
.dwType = MIB_IPNET_TYPE_STATIC .dwType = MIB_IPNET_TYPE_STATIC
}; };
memcpy(arp.bPhysAddr, hwaddr, 6); memcpy(arp.bPhysAddr, hwaddr, 6);
if (add) { if (undo) {
ret = CreateIpNetEntry(&arp); ret = CreateIpNetEntry(&arp);
if (ret != NO_ERROR) { if (ret != NO_ERROR) {
win_perror2("CreateIpNetEntry", ret); win_perror2("CreateIpNetEntry", ret);
return -1; return -1;
} }
*undo = malloc(sizeof(struct ethsock_arp_undo));
if (!*undo) {
perror("malloc");
return -1;
}
(*undo)->ipaddr = ipaddr;
memcpy((*undo)->hwaddr, hwaddr, 6);
} else { } else {
DeleteIpNetEntry(&arp); DeleteIpNetEntry(&arp);
} }
return 0; 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); ethsock_arp(sock, hwaddr, ipaddr, NULL);
return ethsock_arp(sock, hwaddr, ipaddr, 1); 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 #endif

26
nmrp.c
View file

@ -386,19 +386,15 @@ static int is_valid_ip(struct ethsock *sock, struct in_addr *ipaddr,
} }
static struct ethsock *gsock = NULL; static struct ethsock *gsock = NULL;
static struct ethsock_ip_undo *gundo = NULL; static struct ethsock_ip_undo *g_ip_undo = NULL;
static int garp = 0; static struct ethsock_arp_undo *g_arp_undo = NULL;
static struct in_addr arpip = { 0 };
static uint8_t arpmac[6] = { 0 };
static void sigh(int sig) static void sigh(int sig)
{ {
printf("\n"); printf("\n");
if (gsock) { if (gsock) {
if (garp) { ethsock_arp_del(gsock, &g_arp_undo);
ethsock_arp_del(gsock, arpmac, &arpip); ethsock_ip_del(gsock, &g_ip_undo);
}
ethsock_ip_del(gsock, &gundo);
ethsock_close(gsock); ethsock_close(gsock);
gsock = NULL; gsock = NULL;
} }
@ -496,7 +492,6 @@ int nmrp_do(struct nmrpd_args *args)
} }
gsock = sock; gsock = sock;
garp = 0;
sigh_orig = signal(SIGINT, sigh); sigh_orig = signal(SIGINT, sigh);
if (!autoip) { 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); 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; goto out;
} }
} }
@ -609,15 +604,10 @@ int nmrp_do(struct nmrpd_args *args)
printf("Sending configuration: %s, netmask %s.\n", printf("Sending configuration: %s, netmask %s.\n",
args->ipaddr, args->ipmask); args->ipaddr, args->ipmask);
memcpy(arpmac, rx.eh.ether_shost, 6); if (ethsock_arp_add(sock, rx.eh.ether_shost, ipconf.addr.s_addr, &g_arp_undo) != 0) {
memcpy(&arpip, &ipconf.addr, sizeof(ipconf.addr));
if (ethsock_arp_add(sock, arpmac, &arpip) != 0) {
goto out; goto out;
} }
garp = 1;
break; break;
case NMRP_C_TFTP_UL_REQ: case NMRP_C_TFTP_UL_REQ:
if (!upload_ok) { if (!upload_ok) {
@ -760,8 +750,8 @@ int nmrp_do(struct nmrpd_args *args)
out: out:
signal(SIGINT, sigh_orig); signal(SIGINT, sigh_orig);
gsock = NULL; gsock = NULL;
ethsock_arp_del(sock, arpmac, &arpip); ethsock_arp_del(sock, &g_arp_undo);
ethsock_ip_del(sock, &gundo); ethsock_ip_del(sock, &g_ip_undo);
ethsock_close(sock); ethsock_close(sock);
return status; return status;
} }

View file

@ -104,6 +104,7 @@ void sock_perror(const char *msg);
extern int verbosity; extern int verbosity;
struct ethsock; struct ethsock;
struct ethsock_arp_undo;
struct ethsock_ip_undo; struct ethsock_ip_undo;
struct ethsock *ethsock_create(const char *intf, uint16_t protocol); 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); ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len);
int ethsock_set_timeout(struct ethsock *sock, unsigned msec); int ethsock_set_timeout(struct ethsock *sock, unsigned msec);
uint8_t *ethsock_get_hwaddr(struct ethsock *sock); 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_add(struct ethsock *sock, uint8_t *hwaddr, uint32_t ipaddr, struct ethsock_arp_undo **undo);
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);
int ethsock_list_all(void); int ethsock_list_all(void);
struct ethsock_ip_callback_args struct ethsock_ip_callback_args