From 1b3bb6779bb9eda8510075e6b2f47652196fcf54 Mon Sep 17 00:00:00 2001 From: "Joseph C. Lehner" Date: Sat, 13 Feb 2016 14:16:35 +0100 Subject: [PATCH] Check if ip address is valid for given interface --- ethsock.c | 36 +++++++++++++++++++++++++++++++++++- nmrp.c | 49 +++++++++++++++++++++++++++++-------------------- nmrpd.h | 1 + 3 files changed, 65 insertions(+), 21 deletions(-) diff --git a/ethsock.c b/ethsock.c index 36ffeb6..d0c192e 100644 --- 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 1ff5b9e..c9cf6c2 100644 --- 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 125dc55..f6b7765 100644 --- 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 -- 2.25.1