#ifndef lint static char *RCSid = "$Header: /proj/freeware1.0/nfswatch/nfswatch4.1/RCS/netaddr.c,v 1.1 1995/08/08 04:40:30 rck Exp $"; #endif #include "os.h" /* * netaddr.c - routines for working with network addresses. * * David A. Curry Jeffrey C. Mogul * Purdue University Digital Equipment Corporation * Engineering Computer Network Western Research Laboratory * 1285 Electrical Engineering Building 250 University Avenue * West Lafayette, IN 47907-1285 Palo Alto, CA 94301 * davy@ecn.purdue.edu mogul@decwrl.dec.com * * $Log: netaddr.c,v $ * Revision 1.1 1995/08/08 04:40:30 rck * initial checkin * * Revision 4.3 93/10/11 15:36:33 mogul * Bugfix for SUNOS5 * * Revision 4.2 1993/10/04 18:31:07 mogul * Added code to discover if a given IP address is local to this host. * * Revision 4.1 93/09/28 21:24:42 mogul * Explicit data type for IP addresses. * * Revision 4.0 93/03/01 19:59:00 davy * NFSWATCH Version 4.0. * * Revision 3.4 1993/02/24 17:44:45 davy * Added -auth mode, changes to -proc mode, -map option, -server option. * * Revision 3.3 1993/01/16 19:08:59 davy * Corrected Jeff's address. * * Revision 3.2 1993/01/15 19:33:39 davy * Miscellaneous cleanups. * * Revision 3.1 1993/01/13 20:18:17 davy * Put in OS-specific define scheme, and merged in Tim Hudson's code for * SGI systems (as yet untested). * * Revision 3.0 1991/01/23 08:23:06 davy * NFSWATCH Version 3.0. * * Revision 1.2 90/08/17 15:47:24 davy * NFSWATCH Version 2.0. * * Revision 1.1 88/11/29 11:20:35 davy * NFSWATCH Release 1.0 * */ #include #include #include #include #ifdef SUNOS5 #include #endif /* SUNOS5 */ #include #include #include #include "nfswatch.h" #include "externs.h" #define MAXOURADDRS 32 ipaddrt ouraddrs[MAXOURADDRS]; /* * get_net_addrs - get network addresses of source and destination * hosts, along with official host names. */ void get_net_addrs() { register int n; char *inet_ntoa(); register char **cp; struct hostent *hp; /* * Look up the local host. */ if ((hp = gethostbyname(myhost)) == NULL) { (void) fprintf(stderr, "%s: %s: unknown host.\n", pname, myhost); finish(-1); } setup_ouraddrs(); /* * Save the official host name. */ (void) strcpy(myhost, hp->h_name); /* * If one was specified, look up the destination host. * Otherwise, we can use what we have. */ if (allflag) { (void) sprintf(dsthost, "all hosts"); } else if (dstflag) { if ((hp = gethostbyname(dsthost)) == NULL) { (void) fprintf(stderr, "%s: %s: unknown host.\n", pname, dsthost); finish(-1); } /* * Save the official host name. */ (void) strcpy(dsthost, hp->h_name); } else { /* * Host name is the same as the local * host. */ (void) strcpy(dsthost, myhost); } /* * Copy destination host's network addresses. */ n = 0; (void) bzero((char *) dstaddrs, MAXHOSTADDR * sizeof(ipaddrt)); for (cp = hp->h_addr_list; *cp != NULL; cp++) { if (n >= MAXHOSTADDR) break; (void) bcopy(*cp, (char *) &dstaddrs[n], hp->h_length); n++; } /* * If they specified a server host, get its addresses. */ if (serverflag) { if ((hp = gethostbyname(serverhost)) == NULL) { fprintf(stderr, "%s: %s: unknown host.\n", pname, serverhost); finish(-1); } /* * Save the official host name. */ (void) strcpy(serverhost, hp->h_name); /* * Copy the server's network addresses. */ n = 0; (void) bzero((char *) serveraddrs, MAXHOSTADDR * sizeof(ipaddrt)); for (cp = hp->h_addr_list; *cp != NULL; cp++) { if (n >= MAXHOSTADDR) break; (void) bcopy(*cp, (char *) &serveraddrs[n], hp->h_length); n++; } } /* * If they didn't specify a source host, * we're done. */ if (!srcflag) return; /* * Look up the source host. */ if ((hp = gethostbyname(srchost)) == NULL) { (void) fprintf(stderr, "%s: %s: unknown host.\n", pname, srchost); finish(-1); } /* * Save the official host name. */ (void) strcpy(srchost, hp->h_name); /* * Copy source host's network addresses. */ n = 0; (void) bzero((char *) srcaddrs, MAXHOSTADDR * sizeof(ipaddrt)); for (cp = hp->h_addr_list; *cp != NULL; cp++) { if (n >= MAXHOSTADDR) break; (void) bcopy(*cp, (char *) &srcaddrs[n], hp->h_length); n++; } } /* * want_packet - determine if we're interested in a packet by examining * its source and destination addresses. */ int want_packet(src, dst) ipaddrt src, dst; { register int i, want; want = FALSE; thisdst = dst; /* * Check that the source or destination is the server. */ if (serverflag) { for (i=0; (serveraddrs[i] != 0) && (i < MAXHOSTADDR); i++) { if (!bcmp((char *) &src, (char *) &serveraddrs[i], sizeof(ipaddrt)) || !bcmp((char *) &dst, (char *) &serveraddrs[i], sizeof(ipaddrt))) { want = TRUE; break; } } return(want); } /* * Any source or destination is okay. */ if (allflag) { return(TRUE); } /* * Check source address first. */ if (srcflag) { for (i = 0; (srcaddrs[i] != 0) && (i < MAXHOSTADDR); i++) { if (!bcmp((char *) &src, (char *) &srcaddrs[i], sizeof(ipaddrt))) { want = TRUE; break; } } /* * If it's not from our source, we * don't even need to check the destination. */ if (!want) return(FALSE); } want = FALSE; /* * Check destination address. */ for (i = 0; (dstaddrs[i] != 0) && (i < MAXHOSTADDR); i++) { if (!bcmp((char *) &dst, (char *) &dstaddrs[i], sizeof(ipaddrt))) { want = TRUE; break; } } return(want); } /* * to_self - determine if packet destination is the local host */ int to_self(dst) ipaddrt dst; { register int i; /* * Check if the destination is one of our addresses */ for (i=0; (ouraddrs[i] != 0) && (i < MAXOURADDRS); i++) { if (ouraddrs[i] == dst) { return(1); } } return(0); } /* Not all systems have IFF_LOOPBACK */ #ifdef IFF_LOOPBACK #define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK) #else #define ISLOOPBACK(p) (strcmp((p)->ifr_name, "lo0") == 0) #endif /* * Make a list of our possible IP addresses * A lot of the code in setup_ouraddrs() was borrowed from tcpdump/ */ setup_ouraddrs() { struct ifreq ibuf[MAXOURADDRS], *ifrp, *ifend; struct ifconf ifc; int n; int fd; n = 0; (void) bzero((char *) ouraddrs, MAXOURADDRS * sizeof(ipaddrt)); fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { perror("socket"); finish(-1); } ifc.ifc_len = sizeof ibuf; ifc.ifc_buf = (caddr_t)ibuf; if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 || ifc.ifc_len < sizeof(struct ifreq)) { perror("SIOCGIFCONF"); finish(-1); } ifrp = ibuf; ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len); while (ifrp < ifend) { struct ifreq ifr; struct sockaddr_in *sin = (struct sockaddr_in *)&ifrp->ifr_addr; /* * Need a temporary to preserve address info that is * used below to locate the next entry. (Otherwise, * SIOCGIFFLAGS stomps over it because the requests * are returned in a union.) */ bcopy(ifrp->ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { (void)fprintf(stderr, "SIOCGIFFLAGS: "); perror(ifrp->ifr_name); finish(-1); } if ((ifr.ifr_flags & IFF_UP) && !ISLOOPBACK(&ifr)) { if (n >= MAXOURADDRS) break; ouraddrs[n] = sin->sin_addr.s_addr; n++; } #if BSD >= 199006 n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name); if (n < sizeof(*ifrp)) ++ifrp; else ifrp = (struct ifreq *)((char *)ifrp + n); #else ++ifrp; #endif } close(fd); }