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;
|
||||
}
|
||||
|
||||
int ethsock_is_same_subnet(struct ethsock *sock, struct in_addr *ipaddr,
|
||||
struct in_addr *ipmask)
|
||||
int ethsock_for_each_ip(struct ethsock *sock, ethsock_ip_callback_t callback,
|
||||
void *arg)
|
||||
{
|
||||
struct ethsock_ip_callback_args args;
|
||||
pcap_if_t *devs, *dev;
|
||||
pcap_addr_t *addr;
|
||||
uint32_t ip, mask, net;
|
||||
int status;
|
||||
|
||||
if (x_pcap_findalldevs(&devs) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
net = ipaddr->s_addr & ipmask->s_addr;
|
||||
args.arg = arg;
|
||||
|
||||
for (dev = devs; dev; dev = dev->next) {
|
||||
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) {
|
||||
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;
|
||||
args.ipaddr = &((struct sockaddr_in*)addr->addr)->sin_addr;
|
||||
args.ipmask = &((struct sockaddr_in*)addr->netmask)->sin_addr;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 void sigh(int sig)
|
||||
|
@ -331,13 +365,13 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
return 1;
|
||||
}
|
||||
|
||||
status = ethsock_is_same_subnet(sock, &ipaddr, &ipmask);
|
||||
status = is_valid_ip(sock, &ipaddr, &ipmask);
|
||||
if (status <= 0) {
|
||||
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);
|
||||
}
|
||||
return 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
gsock = sock;
|
||||
|
@ -494,6 +528,16 @@ int nmrp_do(struct nmrpd_args *args)
|
|||
}
|
||||
|
||||
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) {
|
||||
printf("Using remote filename '%s'.\n",
|
||||
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);
|
||||
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);
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue