uint8_t hwaddr[6];
};
+struct ethsock_arp_undo
+{
+ uint32_t ipaddr;
+ uint8_t hwaddr[6];
+};
+
struct ethsock_ip_undo
{
#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;
}
-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
}
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;
}
}
gsock = sock;
- garp = 0;
sigh_orig = signal(SIGINT, sigh);
if (!autoip) {
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;
}
}
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) {
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;
}
extern int verbosity;
struct ethsock;
+struct ethsock_arp_undo;
struct ethsock_ip_undo;
struct ethsock *ethsock_create(const char *intf, uint16_t protocol);
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