home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / trace / tcpdump-2.2.1 / inet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-29  |  4.4 KB  |  173 lines

  1. /*
  2.  * Copyright (c) 1990 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static  char rcsid[] =
  24.     "@(#)$Header: inet.c,v 1.12 92/01/29 12:46:18 mccanne Exp $ (LBL)";
  25. #endif
  26.  
  27. #include <stdio.h>
  28. #include <ctype.h>
  29. #include <strings.h>
  30. #include <sys/types.h>
  31. #include <sys/socket.h>
  32. #include <sys/file.h>
  33. #include <sys/ioctl.h>
  34.  
  35. #include <net/if.h>
  36. #include <netinet/in.h>
  37.  
  38. #include "interface.h"
  39.  
  40. /* Not all systems have IFF_LOOPBACK */
  41. #ifdef IFF_LOOPBACK
  42. #define ISLOOPBACK(p) ((p)->ifr_flags & IFF_LOOPBACK)
  43. #else
  44. #define ISLOOPBACK(p) (strcmp((p)->ifr_name, "lo0") == 0)
  45. #endif
  46.  
  47. /*
  48.  * Return the name of a network interface attached to the system, or 0
  49.  * if none can be found.  The interface must be configured up; the
  50.  * lowest unit number is preferred; loopback is ignored.
  51.  */
  52. char *
  53. lookup_device()
  54. {
  55.     struct ifreq ibuf[16], *ifrp, *ifend, *mp;
  56.     struct ifconf ifc;
  57.     int fd;
  58.     int minunit, n;
  59.     char *cp;
  60.     static char device[sizeof(ifrp->ifr_name)];
  61.  
  62.     fd = socket(AF_INET, SOCK_DGRAM, 0);
  63.     if (fd < 0) {
  64.         perror("tcpdump: socket");
  65.         exit(1);
  66.     }
  67.     ifc.ifc_len = sizeof ibuf;
  68.     ifc.ifc_buf = (caddr_t)ibuf;
  69.  
  70.     if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 ||
  71.         ifc.ifc_len < sizeof(struct ifreq)) {
  72.         perror("tcpdump: SIOCGIFCONF: ");
  73.         exit(1);
  74.     }
  75.     ifrp = ibuf;
  76.     ifend = (struct ifreq *)((char *)ibuf + ifc.ifc_len);
  77.     
  78.     mp = 0;
  79.     minunit = 666;
  80.     while (ifrp < ifend) {
  81.         struct ifreq ifr;
  82.         /*
  83.          * Need a template to preserve address info that is
  84.          * used below to locate the next entry.  (Otherwise,
  85.          * SIOCGIFFLAGS stomps over it because the requests
  86.          * are returned in a union.)
  87.          */
  88.         bcopy(ifrp->ifr_name, ifr.ifr_name, sizeof(ifr.ifr_name));
  89.         if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
  90.             fprintf(stderr, "tcpdump: SIOCGIFFLAGS: ");
  91.             perror(ifrp->ifr_name);
  92.             exit(1);
  93.         }
  94.         if ((ifr.ifr_flags & IFF_UP) && !ISLOOPBACK(&ifr)) {
  95.             for (cp = ifrp->ifr_name; !isdigit(*cp); ++cp)
  96.                 ;
  97.             n = atoi(cp);
  98.             if (n < minunit) {
  99.                 minunit = n;
  100.                 mp = ifrp;
  101.             }
  102.         }
  103. #if BSD >= 199006
  104.         n = ifrp->ifr_addr.sa_len + sizeof(ifrp->ifr_name);
  105.         if (n < sizeof(*ifrp))
  106.             ++ifrp;
  107.         else
  108.             ifrp = (struct ifreq *)((char *)ifrp + n);
  109. #else
  110.         ++ifrp;
  111. #endif
  112.     }
  113.     close(fd);
  114.     if (mp == 0)
  115.         return (0);
  116.     
  117.     (void)strcpy(device, mp->ifr_name);
  118.     return (device);
  119. }
  120.  
  121. /*
  122.  * Get the netmask of an IP address.  This routine is used if
  123.  * SIOCGIFNETMASK doesn't work.
  124.  */
  125. static u_long
  126. ipaddrtonetmask(addr)
  127.     u_long addr;
  128. {
  129.     if (IN_CLASSA(addr))
  130.         return (IN_CLASSA_NET);
  131.     if (IN_CLASSB(addr))
  132.         return (IN_CLASSB_NET);
  133.     if (IN_CLASSC(addr))
  134.         return (IN_CLASSC_NET);
  135.     error("unknown IP address class: %08X", addr);
  136.     /* NOTREACHED */
  137. }
  138.  
  139. void
  140. lookup_net(device, netp, maskp)
  141.     char *device;
  142.     u_long *netp;
  143.     u_long *maskp;
  144. {
  145.     int fd;
  146.     struct ifreq ifr;
  147.     struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr;
  148.  
  149.     /* Use data gram socket to get IP address. */
  150.     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  151.         perror("tcpdump: socket");
  152.         exit(1);
  153.     }
  154.     (void)strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name);
  155.     if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
  156.         /*
  157.          * This will fail if an IP address hasn't been assigned.
  158.          */
  159.         *netp = 0;
  160.         *maskp = 0;
  161.         return;
  162.     }
  163.     *netp = sin->sin_addr.s_addr;
  164.     if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0)
  165.         *maskp = 0;
  166.     else
  167.         *maskp = sin->sin_addr.s_addr;
  168.     if (*maskp == 0)
  169.         *maskp = ipaddrtonetmask(*netp);
  170.     *netp &= *maskp;
  171.     (void)close(fd);
  172. }
  173.