From 35fd6f41df25b2ac8071f7388c7016cfa723c157 Mon Sep 17 00:00:00 2001 From: "Joseph C. Lehner" Date: Mon, 17 Aug 2020 16:58:11 +0200 Subject: [PATCH] Detect unplugged Ethernet cable on Windows --- ethsock.c | 29 ++++++++++++++++++++++++----- nmrp.c | 19 +++++++++++++++++++ nmrpd.h | 1 + 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/ethsock.c b/ethsock.c index c5aedd0..db63322 100644 --- a/ethsock.c +++ b/ethsock.c @@ -505,16 +505,33 @@ static const char *intf_get_pretty_name(const char *intf) return intf; } -void init_unicast_row(MIB_UNICASTIPADDRESS_ROW* row, DWORD index, uint32_t ipaddr, uint32_t ipmask) -{ -} - - #endif inline uint8_t *ethsock_get_hwaddr(struct ethsock *sock) { return sock->hwaddr; +} + +bool ethsock_is_unplugged(struct ethsock *sock) +{ +#ifdef NMRPFLASH_WINDOWS + MIB_IF_ROW2 row; + memset(&row, 0, sizeof(row)); + row.InterfaceIndex = sock->index; + + DWORD err = GetIfEntry2(&row); + if (err != NO_ERROR) { + win_perror2("GetIfEntry2", err); + return false; + } + + return row.InterfaceAndOperStatusFlags.NotMediaConnected; +#else + return false; +#endif + + + } struct ethsock *ethsock_create(const char *intf, uint16_t protocol) @@ -1049,6 +1066,7 @@ static int ethsock_ip_add_del(struct ethsock *sock, uint32_t ipaddr, uint32_t ip /* Wait until the new IP has actually been added */ + /* while (bind(fd, (struct sockaddr*)&row.Address.Ipv4, sizeof(row.Address.Ipv4)) != 0) { if ((time_monotonic() - beg) >= 5) { fprintf(stderr, "Failed to bind after 5 seconds: "); @@ -1057,6 +1075,7 @@ static int ethsock_ip_add_del(struct ethsock *sock, uint32_t ipaddr, uint32_t ip goto out; } } + */ } else { err = DeleteUnicastIpAddressEntry(&row); if (err != NO_ERROR) { diff --git a/nmrp.c b/nmrp.c index d6c866e..5f9e670 100644 --- a/nmrp.c +++ b/nmrp.c @@ -446,6 +446,25 @@ int nmrp_do(struct nmrpd_args *args) sigh_orig = signal(SIGINT, sigh); + if (ethsock_is_unplugged(sock)) { + printf("Waiting for Ethernet cable to be plugged in.\n"); + + bool unplugged = true; + time_t beg = time_monotonic(); + + while (!g_interrupted && (time_monotonic() - beg) < 20) { + if (!ethsock_is_unplugged(sock)) { + unplugged = false; + break; + } + } + + if (unplugged) { + fprintf(stderr, "Error: Ethernet cable is unplugged."); + goto out; + } + } + if (!autoip) { status = is_valid_ip(sock, &ipaddr, &ipmask); if (status <= 0) { diff --git a/nmrpd.h b/nmrpd.h index 3bd6487..7429d86 100644 --- a/nmrpd.h +++ b/nmrpd.h @@ -125,6 +125,7 @@ struct ethsock_arp_undo; struct ethsock_ip_undo; struct ethsock *ethsock_create(const char *intf, uint16_t protocol); +bool ethsock_is_unplugged(struct ethsock *sock); int ethsock_close(struct ethsock *sock); int ethsock_send(struct ethsock *sock, void *buf, size_t len); ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len);