struct ethsock
{
+ const char *intf;
pcap_t *pcap;
#ifndef NMRPFLASH_WINDOWS
int fd;
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;
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;
+}
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);
}
}
- 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);
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 {
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;
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);
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;
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",
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;
} while (1);
- err = 0;
+ status = 0;
printf("Reboot your device now.\n");
signal(SIGINT, sigh_orig);
gsock = NULL;
ethsock_close(sock);
- return err;
+ return status;
}