Check if ip address is valid for given interface
authorJoseph C. Lehner <joseph.c.lehner@gmail.com>
Sat, 13 Feb 2016 13:16:35 +0000 (14:16 +0100)
committerJoseph C. Lehner <joseph.c.lehner@gmail.com>
Sat, 13 Feb 2016 15:14:59 +0000 (16:14 +0100)
ethsock.c
nmrp.c
nmrpd.h

index 36ffeb6de0f948a53f5a8a0bd2df513339e38bfc..d0c192ef07749cc7299afee27a1d33564cb38bce 100644 (file)
--- a/ethsock.c
+++ b/ethsock.c
@@ -28,6 +28,7 @@
 
 struct ethsock
 {
+       const char *intf;
        pcap_t *pcap;
 #ifndef NMRPFLASH_WINDOWS
        int fd;
@@ -276,7 +277,8 @@ struct ethsock *ethsock_create(const char *intf, uint16_t protocol)
 
        buf[0] = '\0';
 
-       sock->pcap = pcap_open_live(intf, BUFSIZ, 1, 1, buf);
+       sock->intf = intf;
+       sock->pcap = pcap_open_live(sock->intf, BUFSIZ, 1, 1, buf);
        if (!sock->pcap) {
                fprintf(stderr, "%s.\n", buf);
                goto cleanup_malloc;
@@ -541,3 +543,35 @@ int ethsock_list_all(void)
 
        return 0;
 }
+
+int ethsock_is_same_subnet(struct ethsock *sock, struct in_addr *ipaddr,
+               struct in_addr *ipmask)
+{
+       pcap_if_t *devs, *dev;
+       pcap_addr_t *addr;
+       uint32_t ip, mask, net;
+
+       if (x_pcap_findalldevs(&devs) != 0) {
+               return -1;
+       }
+
+       net = ipaddr->s_addr & ipmask->s_addr;
+
+       for (dev = devs; dev; dev = dev->next) {
+               if (strcmp(sock->intf, dev->name)) {
+                       continue;
+               }
+
+               for (addr = dev->addresses; addr; addr = addr->next) {
+                       if (addr->addr->sa_family == AF_INET) {
+                               ip = ((struct sockaddr_in*)addr->addr)->sin_addr.s_addr;
+                               mask = ((struct sockaddr_in*)addr->netmask)->sin_addr.s_addr;
+                               if ((ip & mask) == net) {
+                                       return 1;
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
diff --git a/nmrp.c b/nmrp.c
index 1ff5b9e16972df872bd7605b1d87052fc4c40757..c9cf6c204745fc747e29265ff2677f557ab4a727 100644 (file)
--- a/nmrp.c
+++ b/nmrp.c
@@ -287,7 +287,7 @@ int nmrp_do(struct nmrpd_args *args)
        char *filename;
        struct in_addr ipaddr, ipmask;
        time_t beg;
-       int i, err, ulreqs, expect;
+       int i, status, ulreqs, expect;
        struct ethsock *sock;
        void (*sigh_orig)(int);
 
@@ -324,13 +324,22 @@ int nmrp_do(struct nmrpd_args *args)
                }
        }
 
-       err = 1;
+       status = 1;
 
        sock = ethsock_create(args->intf, ETH_P_NMRP);
        if (!sock) {
                return 1;
        }
 
+       status = ethsock_is_same_subnet(sock, &ipaddr, &ipmask);
+       if (status <= 0) {
+               if (!status) {
+                       fprintf(stderr, "Address %s/%s invalid for interface %s.\n",
+                                       args->ipaddr, args->ipmask, args->intf);
+               }
+               return 1;
+       }
+
        gsock = sock;
        sigh_orig = signal(SIGINT, sigh);
 
@@ -375,10 +384,10 @@ int nmrp_do(struct nmrpd_args *args)
                        goto out;
                }
 
-               err = pkt_recv(sock, &rx);
-               if (err == 0 && memcmp(rx.eh.ether_dhost, src, 6) == 0) {
+               status = pkt_recv(sock, &rx);
+               if (status == 0 && memcmp(rx.eh.ether_dhost, src, 6) == 0) {
                        break;
-               } else if (err == 1) {
+               } else if (status == 1) {
                        printf("ERR\n");
                        goto out;
                } else {
@@ -406,13 +415,13 @@ int nmrp_do(struct nmrpd_args *args)
                tx.msg.num_opts = 0;
                tx.msg.len = 0;
 
-               err = 1;
+               status = 1;
 
                switch (rx.msg.code) {
                        case NMRP_C_ADVERTISE:
                                printf("Received NMRP advertisement from %s.\n",
                                                mac_to_str(rx.eh.ether_shost));
-                               err = 1;
+                               status = 1;
                                goto out;
                        case NMRP_C_CONF_REQ:
                                tx.msg.code = NMRP_C_CONF_ACK;
@@ -471,20 +480,20 @@ int nmrp_do(struct nmrpd_args *args)
                                        printf("Received upload request with empty filename.");
                                }
 
-                               err = 0;
+                               status = 0;
 
                                if (args->tftpcmd) {
                                        printf("Executing '%s' ... ", args->tftpcmd);
                                        fflush(stdout);
-                                       err = system(args->tftpcmd);
-                                       if (!err) {
+                                       status = system(args->tftpcmd);
+                                       if (!status) {
                                                printf("OK\n");
                                        } else {
                                                printf("ERR\n");
                                        }
                                }
 
-                               if (!err && args->file_local) {
+                               if (!status && args->file_local) {
                                        if (verbosity) {
                                                printf("Using remote filename '%s'.\n",
                                                                args->file_remote);
@@ -496,14 +505,14 @@ int nmrp_do(struct nmrpd_args *args)
                                                printf("Uploading %s ... ", args->file_local);
                                        }
                                        fflush(stdout);
-                                       err = tftp_put(args);
+                                       status = tftp_put(args);
                                }
 
-                               if (!err) {
+                               if (!status) {
                                        printf("OK\nWaiting for remote to respond.\n");
                                        ethsock_set_timeout(sock, args->ul_timeout);
                                        expect = NMRP_C_CLOSE_REQ;
-                               } else if (err == -2) {
+                               } else if (status == -2) {
                                        expect = NMRP_C_TFTP_UL_REQ;
                                } else {
                                        goto out;
@@ -517,7 +526,7 @@ int nmrp_do(struct nmrpd_args *args)
                                tx.msg.code = NMRP_C_CLOSE_ACK;
                                break;
                        case NMRP_C_CLOSE_ACK:
-                               err = 0;
+                               status = 0;
                                goto out;
                        default:
                                fprintf(stderr, "Unknown message code 0x%02x!\n",
@@ -540,9 +549,9 @@ int nmrp_do(struct nmrpd_args *args)
                        break;
                }
 
-               err = pkt_recv(sock, &rx);
-               if (err) {
-                       if (err == 2) {
+               status = pkt_recv(sock, &rx);
+               if (status) {
+                       if (status == 2) {
                                fprintf(stderr, "Timeout while waiting for 0x%02x.\n", expect);
                        }
                        goto out;
@@ -552,7 +561,7 @@ int nmrp_do(struct nmrpd_args *args)
 
        } while (1);
 
-       err = 0;
+       status = 0;
 
        printf("Reboot your device now.\n");
 
@@ -560,5 +569,5 @@ out:
        signal(SIGINT, sigh_orig);
        gsock = NULL;
        ethsock_close(sock);
-       return err;
+       return status;
 }
diff --git a/nmrpd.h b/nmrpd.h
index 125dc557c43b681916f49e36253561ca5bc86277..f6b776540e7b92ba5a803602555e68f0ad97f383 100644 (file)
--- a/nmrpd.h
+++ b/nmrpd.h
@@ -97,5 +97,6 @@ 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_list_all(void);
+int ethsock_is_same_subnet(struct ethsock *sock, struct in_addr* ip, struct in_addr *mask);
 
 #endif