Browse Source

Detect unplugged Ethernet cable on Windows

Joseph C. Lehner 3 years ago
parent
commit
35fd6f41df
3 changed files with 43 additions and 4 deletions
  1. 23 4
      ethsock.c
  2. 19 0
      nmrp.c
  3. 1 0
      nmrpd.h

+ 23 - 4
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
 
-inline uint8_t *ethsock_get_hwaddr(struct ethsock *sock)
-{
-	return sock->hwaddr;
+
+
 }
 
 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) {

+ 19 - 0
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) {

+ 1 - 0
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);