summaryrefslogtreecommitdiffstats
path: root/usr.sbin/portmap
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2000-08-09 09:24:31 +0000
committerbrian <brian@FreeBSD.org>2000-08-09 09:24:31 +0000
commit3193d19dd6ec8ef532d49d49bc46e829bca516cc (patch)
treebb585a6fee69d41b7356dedf77967004107b8888 /usr.sbin/portmap
parentf67f88e23938af1d9e3e65d426081e1534e3703f (diff)
downloadFreeBSD-src-3193d19dd6ec8ef532d49d49bc46e829bca516cc.zip
FreeBSD-src-3193d19dd6ec8ef532d49d49bc46e829bca516cc.tar.gz
Treat all interface aliases as local addresses.
The new rtiparse() function should really be in libc IMHO.... I'm sick of writing this code :-( PR: 20381
Diffstat (limited to 'usr.sbin/portmap')
-rw-r--r--usr.sbin/portmap/from_local.c55
1 files changed, 40 insertions, 15 deletions
diff --git a/usr.sbin/portmap/from_local.c b/usr.sbin/portmap/from_local.c
index 80948f3..9886f12 100644
--- a/usr.sbin/portmap/from_local.c
+++ b/usr.sbin/portmap/from_local.c
@@ -63,6 +63,7 @@ static const char rcsid[] =
#include <net/if.h>
#include <net/if_dl.h>
+#include <net/route.h>
#include <netinet/in.h>
#include "pmap_check.h"
@@ -72,12 +73,31 @@ static const char rcsid[] =
#define FALSE 0
#endif
+#define ROUNDUP(x) ((x) ? (1 + (((x) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
/* How many interfaces could there be on a computer? */
#define ESTIMATED_LOCAL 20
static int num_local = -1;
static struct in_addr *addrs;
+static void
+rtiparse(struct ifa_msghdr *ifam, struct rt_addrinfo *ai)
+{
+ char *wp;
+ int rtax;
+
+ wp = (char *)(ifam + 1);
+
+ ai->rti_addrs = ifam->ifam_addrs;
+ for (rtax = 0; rtax < sizeof ai->rti_info / sizeof *ai->rti_info; rtax++)
+ if (ifam->ifam_addrs & (1 << rtax)) {
+ ai->rti_info[rtax] = (struct sockaddr *)wp;
+ wp += ROUNDUP(ai->rti_info[rtax]->sa_len);
+ } else
+ ai->rti_info[rtax] = NULL;
+}
+
/* find_local - find all IP addresses for this host */
static int
@@ -87,6 +107,8 @@ find_local()
size_t needed;
char *buf, *end, *ptr;
struct if_msghdr *ifm;
+ struct ifa_msghdr *ifam;
+ struct rt_addrinfo ai;
struct ifreq ifr;
struct sockaddr_dl *dl;
@@ -129,7 +151,7 @@ find_local()
dl = (struct sockaddr_dl *)(ifm + 1);
if (ifm->ifm_index != dl->sdl_index || dl->sdl_nlen == 0)
- /* We only want to see each interface once */
+ /* Skip over remaining ifa_msghdrs */
continue;
n = dl->sdl_nlen > sizeof ifr.ifr_name ?
@@ -143,23 +165,26 @@ find_local()
fprintf(stderr, "%.*s: SIOCGIFFLAGS: %s\n", n, ifr.ifr_name,
strerror(errno));
else if (ifr.ifr_flags & IFF_UP) { /* active interface */
- if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
- fprintf(stderr, "%.*s: SIOCGIFADDR: %s\n", n, ifr.ifr_name,
- strerror(errno));
- else {
- if (alloced < num_local + 1) {
- alloced += ESTIMATED_LOCAL;
- if (addrs)
+ ifam = (struct ifa_msghdr *)(ptr + ifm->ifm_msglen);
+ while ((char *)ifam < end && ifam->ifam_type == RTM_NEWADDR) {
+ rtiparse(ifam, &ai);
+
+ if (ai.rti_info[RTAX_IFA] != NULL &&
+ ai.rti_info[RTAX_IFA]->sa_family == AF_INET) {
+ if (alloced < num_local + 1) {
+ alloced += ESTIMATED_LOCAL;
addrs = (struct in_addr *)realloc(addrs, alloced * sizeof addrs[0]);
- else
- addrs = (struct in_addr *)malloc(alloced * sizeof addrs[0]);
- if (addrs == NULL) {
- perror("malloc/realloc");
- num_local = 0;
- break;
+ if (addrs == NULL) {
+ perror("malloc/realloc");
+ num_local = 0;
+ break;
+ }
}
+ addrs[num_local++] = ((struct sockaddr_in *)
+ ai.rti_info[RTAX_IFA])->sin_addr;
+
}
- addrs[num_local++] = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
+ ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
}
}
}
OpenPOWER on IntegriCloud