Add and use ethsock_for_each_ip
This commit is contained in:
parent
1b3bb6779b
commit
ae05a62666
3 changed files with 73 additions and 13 deletions
25
ethsock.c
25
ethsock.c
|
|
@ -544,18 +544,19 @@ int ethsock_list_all(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ethsock_is_same_subnet(struct ethsock *sock, struct in_addr *ipaddr,
|
int ethsock_for_each_ip(struct ethsock *sock, ethsock_ip_callback_t callback,
|
||||||
struct in_addr *ipmask)
|
void *arg)
|
||||||
{
|
{
|
||||||
|
struct ethsock_ip_callback_args args;
|
||||||
pcap_if_t *devs, *dev;
|
pcap_if_t *devs, *dev;
|
||||||
pcap_addr_t *addr;
|
pcap_addr_t *addr;
|
||||||
uint32_t ip, mask, net;
|
int status;
|
||||||
|
|
||||||
if (x_pcap_findalldevs(&devs) != 0) {
|
if (x_pcap_findalldevs(&devs) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
net = ipaddr->s_addr & ipmask->s_addr;
|
args.arg = arg;
|
||||||
|
|
||||||
for (dev = devs; dev; dev = dev->next) {
|
for (dev = devs; dev; dev = dev->next) {
|
||||||
if (strcmp(sock->intf, dev->name)) {
|
if (strcmp(sock->intf, dev->name)) {
|
||||||
|
|
@ -564,14 +565,20 @@ int ethsock_is_same_subnet(struct ethsock *sock, struct in_addr *ipaddr,
|
||||||
|
|
||||||
for (addr = dev->addresses; addr; addr = addr->next) {
|
for (addr = dev->addresses; addr; addr = addr->next) {
|
||||||
if (addr->addr->sa_family == AF_INET) {
|
if (addr->addr->sa_family == AF_INET) {
|
||||||
ip = ((struct sockaddr_in*)addr->addr)->sin_addr.s_addr;
|
args.ipaddr = &((struct sockaddr_in*)addr->addr)->sin_addr;
|
||||||
mask = ((struct sockaddr_in*)addr->netmask)->sin_addr.s_addr;
|
args.ipmask = &((struct sockaddr_in*)addr->netmask)->sin_addr;
|
||||||
if ((ip & mask) == net) {
|
|
||||||
return 1;
|
status = callback(&args);
|
||||||
|
if (status <= 0) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
pcap_freealldevs(devs);
|
||||||
|
|
||||||
|
return status <= 0 ? status : 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
50
nmrp.c
50
nmrp.c
|
|
@ -265,6 +265,40 @@ static int mac_parse(const char *str, uint8_t *hwaddr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct is_valid_ip_arg
|
||||||
|
{
|
||||||
|
struct in_addr *ipaddr;
|
||||||
|
struct in_addr *ipmask;
|
||||||
|
int result;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int is_valid_ip_cb(struct ethsock_ip_callback_args *args)
|
||||||
|
{
|
||||||
|
#define SUBNET(x) ((x)->ipaddr->s_addr & (x)->ipmask->s_addr)
|
||||||
|
struct is_valid_ip_arg *arg = args->arg;
|
||||||
|
if (SUBNET(args) == SUBNET(arg)) {
|
||||||
|
arg->result = args->ipaddr->s_addr != arg->ipaddr->s_addr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
#undef SUBNET
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_valid_ip(struct ethsock *sock, struct in_addr *ipaddr,
|
||||||
|
struct in_addr *ipmask)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
struct is_valid_ip_arg arg = {
|
||||||
|
.ipaddr = ipaddr,
|
||||||
|
.ipmask = ipmask,
|
||||||
|
.result = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
status = ethsock_for_each_ip(sock, is_valid_ip_cb, &arg);
|
||||||
|
return status < 0 ? status : arg.result;
|
||||||
|
}
|
||||||
|
|
||||||
static struct ethsock *gsock = NULL;
|
static struct ethsock *gsock = NULL;
|
||||||
|
|
||||||
static void sigh(int sig)
|
static void sigh(int sig)
|
||||||
|
|
@ -331,13 +365,13 @@ int nmrp_do(struct nmrpd_args *args)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ethsock_is_same_subnet(sock, &ipaddr, &ipmask);
|
status = is_valid_ip(sock, &ipaddr, &ipmask);
|
||||||
if (status <= 0) {
|
if (status <= 0) {
|
||||||
if (!status) {
|
if (!status) {
|
||||||
fprintf(stderr, "Address %s/%s invalid for interface %s.\n",
|
fprintf(stderr, "Address %s/%s cannot be used on interface %s.\n",
|
||||||
args->ipaddr, args->ipmask, args->intf);
|
args->ipaddr, args->ipmask, args->intf);
|
||||||
}
|
}
|
||||||
return 1;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
gsock = sock;
|
gsock = sock;
|
||||||
|
|
@ -494,6 +528,16 @@ int nmrp_do(struct nmrpd_args *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!status && args->file_local) {
|
if (!status && args->file_local) {
|
||||||
|
status = is_valid_ip(sock, &ipaddr, &ipmask);
|
||||||
|
if (status < 0) {
|
||||||
|
goto out;
|
||||||
|
} else if (!status) {
|
||||||
|
printf("IP address of %s has changed. Please assign a "
|
||||||
|
"static ip to the interface.\n", args->intf);
|
||||||
|
tx.msg.code = NMRP_C_CLOSE_REQ;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (verbosity) {
|
if (verbosity) {
|
||||||
printf("Using remote filename '%s'.\n",
|
printf("Using remote filename '%s'.\n",
|
||||||
args->file_remote);
|
args->file_remote);
|
||||||
|
|
|
||||||
11
nmrpd.h
11
nmrpd.h
|
|
@ -97,6 +97,15 @@ ssize_t ethsock_recv(struct ethsock *sock, void *buf, size_t len);
|
||||||
int ethsock_set_timeout(struct ethsock *sock, unsigned msec);
|
int ethsock_set_timeout(struct ethsock *sock, unsigned msec);
|
||||||
uint8_t *ethsock_get_hwaddr(struct ethsock *sock);
|
uint8_t *ethsock_get_hwaddr(struct ethsock *sock);
|
||||||
int ethsock_list_all(void);
|
int ethsock_list_all(void);
|
||||||
int ethsock_is_same_subnet(struct ethsock *sock, struct in_addr* ip, struct in_addr *mask);
|
|
||||||
|
|
||||||
|
struct ethsock_ip_callback_args
|
||||||
|
{
|
||||||
|
struct in_addr *ipaddr;
|
||||||
|
struct in_addr *ipmask;
|
||||||
|
void *arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (*ethsock_ip_callback_t)(struct ethsock_ip_callback_args *args);
|
||||||
|
int ethsock_for_each_ip(struct ethsock *sock, ethsock_ip_callback_t callback,
|
||||||
|
void *arg);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue