version 1.14, 2007/08/02 02:10:07 |
version 1.15, 2007/08/15 14:22:39 |
|
|
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
#include <sys/param.h> |
|
#include <sys/socket.h> |
#include <sys/stat.h> |
#include <sys/stat.h> |
#include <stdio.h> |
#include <stdio.h> |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
|
|
#endif /* HAVE_EXTENDED_GLOB */ |
#endif /* HAVE_EXTENDED_GLOB */ |
|
|
#ifndef lint |
#ifndef lint |
__unused static const char rcsid[] = "$Sudo: parse.c,v 1.160.2.11 2007/08/02 02:09:10 millert Exp $"; |
__unused static const char rcsid[] = "$Sudo: parse.c,v 1.160.2.12 2007/08/13 16:30:02 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
/* |
/* |
|
|
} |
} |
} |
} |
|
|
/* |
static int |
* Returns TRUE if "n" is one of our ip addresses or if |
addr_matches_if(n) |
* "n" is a network that we are on, else returns FALSE. |
|
*/ |
|
int |
|
addr_matches(n) |
|
char *n; |
char *n; |
{ |
{ |
int i; |
int i; |
|
struct in_addr addr; |
|
struct interface *ifp; |
|
#ifdef AF_INET6 |
|
struct in6_addr addr6; |
|
int j; |
|
#endif |
|
int family = AF_UNSPEC; |
|
|
|
#ifdef AF_INET6 |
|
if (inet_pton(AF_INET6, n, &addr6) > 0) { |
|
family = AF_INET6; |
|
} else |
|
#else |
|
{ |
|
family = AF_INET; |
|
addr.s_addr = inet_addr(n); |
|
} |
|
#endif |
|
|
|
for (i = 0; i < num_interfaces; i++) { |
|
ifp = &interfaces[i]; |
|
if (ifp->family != family) |
|
continue; |
|
switch(family) { |
|
case AF_INET: |
|
if (ifp->addr.ip4.s_addr == addr.s_addr || |
|
(ifp->addr.ip4.s_addr & ifp->netmask.ip4.s_addr) |
|
== addr.s_addr) |
|
return(TRUE); |
|
break; |
|
#ifdef AF_INET6 |
|
case AF_INET6: |
|
if (memcmp(ifp->addr.ip6.s6_addr, addr6.s6_addr, |
|
sizeof(addr6.s6_addr)) == 0) |
|
return(TRUE); |
|
for (j = 0; j < sizeof(addr6.s6_addr); j++) { |
|
if ((ifp->addr.ip6.s6_addr[j] & ifp->netmask.ip6.s6_addr[j]) != addr6.s6_addr[j]) |
|
break; |
|
} |
|
if (j == sizeof(addr6.s6_addr)) |
|
return(TRUE); |
|
#endif /* AF_INET6 */ |
|
} |
|
} |
|
|
|
return(FALSE); |
|
} |
|
|
|
static int |
|
addr_matches_if_netmask(n, m) |
|
char *n; |
char *m; |
char *m; |
|
{ |
|
int i; |
struct in_addr addr, mask; |
struct in_addr addr, mask; |
|
struct interface *ifp; |
|
#ifdef AF_INET6 |
|
struct in6_addr addr6, mask6; |
|
int j; |
|
#endif |
|
int family = AF_UNSPEC; |
|
|
/* If there's an explicit netmask, use it. */ |
#ifdef AF_INET6 |
if ((m = strchr(n, '/'))) { |
if (inet_pton(AF_INET6, n, &addr6) > 0) |
*m++ = '\0'; |
family = AF_INET6; |
|
else |
|
#else |
|
{ |
|
family = AF_INET; |
addr.s_addr = inet_addr(n); |
addr.s_addr = inet_addr(n); |
|
} |
|
#endif |
|
|
|
if (family == AF_INET) { |
if (strchr(m, '.')) |
if (strchr(m, '.')) |
mask.s_addr = inet_addr(m); |
mask.s_addr = inet_addr(m); |
else { |
else { |
|
|
mask.s_addr <<= i; |
mask.s_addr <<= i; |
mask.s_addr = htonl(mask.s_addr); |
mask.s_addr = htonl(mask.s_addr); |
} |
} |
*(m - 1) = '/'; |
} |
|
#ifdef AF_INET6 |
|
else { |
|
if (inet_pton(AF_INET6, m, &mask6) <= 0) { |
|
j = atoi(m); |
|
for (i = 0; i < 16; i++) { |
|
if (j < i * 8) |
|
mask6.s6_addr[i] = 0; |
|
else if (i * 8 + 8 <= j) |
|
mask6.s6_addr[i] = 0xff; |
|
else |
|
mask6.s6_addr[i] = 0xff00 >> (j - i * 8); |
|
} |
|
} |
|
} |
|
#endif /* AF_INET6 */ |
|
|
for (i = 0; i < num_interfaces; i++) |
for (i = 0; i < num_interfaces; i++) { |
if ((interfaces[i].addr.s_addr & mask.s_addr) == addr.s_addr) |
ifp = &interfaces[i]; |
return(TRUE); |
if (ifp->family != family) |
} else { |
continue; |
addr.s_addr = inet_addr(n); |
switch(family) { |
|
case AF_INET: |
for (i = 0; i < num_interfaces; i++) |
if ((ifp->addr.ip4.s_addr & mask.s_addr) == addr.s_addr) |
if (interfaces[i].addr.s_addr == addr.s_addr || |
return(TRUE); |
(interfaces[i].addr.s_addr & interfaces[i].netmask.s_addr) |
#ifdef AF_INET6 |
== addr.s_addr) |
case AF_INET6: |
return(TRUE); |
for (j = 0; j < sizeof(addr6.s6_addr); j++) { |
|
if ((ifp->addr.ip6.s6_addr[j] & mask6.s6_addr[j]) != addr6.s6_addr[j]) |
|
break; |
|
} |
|
if (j == sizeof(addr6.s6_addr)) |
|
return(TRUE); |
|
#endif /* AF_INET6 */ |
|
} |
} |
} |
|
|
return(FALSE); |
return(FALSE); |
|
} |
|
|
|
/* |
|
* Returns TRUE if "n" is one of our ip addresses or if |
|
* "n" is a network that we are on, else returns FALSE. |
|
*/ |
|
int |
|
addr_matches(n) |
|
char *n; |
|
{ |
|
char *m; |
|
int retval; |
|
|
|
/* If there's an explicit netmask, use it. */ |
|
if ((m = strchr(n, '/'))) { |
|
*m++ = '\0'; |
|
retval = addr_matches_if_netmask(n, m); |
|
*(m - 1) = '/'; |
|
} else |
|
retval = addr_matches_if(n); |
|
|
|
return(retval); |
} |
} |
|
|
/* |
/* |