]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Move discover_interfaces and relate goop to discover.c
authorTed Lemon <source@isc.org>
Sat, 17 Oct 1998 13:35:24 +0000 (13:35 +0000)
committerTed Lemon <source@isc.org>
Sat, 17 Oct 1998 13:35:24 +0000 (13:35 +0000)
common/dispatch.c

index cea517ee82aaee70a814713aca51d0936255120b..ee1f170f2f7adcba8cc26f7866f7e92dac707a1a 100644 (file)
@@ -3,7 +3,7 @@
    Network input dispatcher... */
 
 /*
- * Copyright (c) 1995, 1996 The Internet Software Consortium.
+ * Copyright (c) 1995, 1996, 1998 The Internet Software Consortium.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #ifndef lint
 static char copyright[] =
-"$Id: dispatch.c,v 1.50 1998/06/25 02:55:16 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
+"$Id: dispatch.c,v 1.51 1998/10/17 13:35:24 mellon Exp $ Copyright (c) 1995, 1996 The Internet Software Consortium.  All rights reserved.\n";
 #endif /* not lint */
 
 #include "dhcpd.h"
-#include <sys/ioctl.h>
 
-struct interface_info *interfaces, *dummy_interfaces;
 struct protocol *protocols;
 struct timeout *timeouts;
 static struct timeout *free_timeouts;
-static int interfaces_invalidated;
-void (*bootp_packet_handler) PROTO ((struct interface_info *,
-                                    struct dhcp_packet *, int, unsigned int,
-                                    struct iaddr, struct hardware *));
 
-static void got_one PROTO ((struct protocol *));
-int quiet_interface_discovery;
-
-/* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
-   For each interface that's of type INET and not the loopback interface,
-   register that interface with the network I/O software, figure out what
-   subnet it's on, and add it to the list of interfaces. */
-
-void discover_interfaces (state)
-       int state;
-{
-       struct interface_info *tmp;
-       struct interface_info *last, *next;
-       char buf [8192];
-       struct ifconf ic;
-       struct ifreq ifr;
-       int i;
-       int sock;
-       int address_count = 0;
-       struct subnet *subnet;
-       struct shared_network *share;
-       struct sockaddr_in foo;
-       int ir;
-#ifdef ALIAS_NAMES_PERMUTED
-       char *s;
-#endif
-#ifdef USE_FALLBACK
-       static struct shared_network fallback_network;
-#endif
-
-       /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
-       if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
-               error ("Can't create addrlist socket");
-
-       /* Get the interface configuration information... */
-       ic.ifc_len = sizeof buf;
-       ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
-       i = ioctl(sock, SIOCGIFCONF, &ic);
-
-       if (i < 0)
-               error ("ioctl: SIOCGIFCONF: %m");
-
-       /* If we already have a list of interfaces, and we're running as
-          a DHCP server, the interfaces were requested. */
-       if (interfaces && (state == DISCOVER_SERVER ||
-                          state == DISCOVER_RELAY ||
-                          state == DISCOVER_REQUESTED))
-               ir = 0;
-       else if (state == DISCOVER_UNCONFIGURED)
-               ir = INTERFACE_REQUESTED | INTERFACE_AUTOMATIC;
-       else
-               ir = INTERFACE_REQUESTED;
-
-       /* Cycle through the list of interfaces looking for IP addresses.
-          Go through twice; once to count the number of addresses, and a
-          second time to copy them into an array of addresses. */
-       for (i = 0; i < ic.ifc_len;) {
-               struct ifreq *ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);
-#ifdef HAVE_SA_LEN
-               if (ifp -> ifr_addr.sa_len)
-                       i += (sizeof ifp -> ifr_name) + ifp -> ifr_addr.sa_len;
-               else
-#endif
-                       i += sizeof *ifp;
-
-#ifdef ALIAS_NAMES_PERMUTED
-               if ((s = strrchr (ifp -> ifr_name, ':'))) {
-                       *s = 0;
-               }
-#endif
-
-#ifdef SKIP_DUMMY_INTERFACES
-               if (!strncmp (ifp -> ifr_name, "dummy", 5))
-                       continue;
-#endif
-
-
-               /* See if this is the sort of interface we want to
-                  deal with. */
-               strcpy (ifr.ifr_name, ifp -> ifr_name);
-               if (ioctl (sock, SIOCGIFFLAGS, &ifr) < 0)
-                       error ("Can't get interface flags for %s: %m",
-                              ifr.ifr_name);
-
-               /* Skip loopback, point-to-point and down interfaces,
-                  except don't skip down interfaces if we're trying to
-                  get a list of configurable interfaces. */
-               if ((ifr.ifr_flags & IFF_LOOPBACK) ||
-#ifdef IFF_POINTOPOINT
-                   (ifr.ifr_flags & IFF_POINTOPOINT) ||
-#endif
-                   (!(ifr.ifr_flags & IFF_UP) &&
-                    state != DISCOVER_UNCONFIGURED))
-                       continue;
-               
-               /* See if we've seen an interface that matches this one. */
-               for (tmp = interfaces; tmp; tmp = tmp -> next)
-                       if (!strcmp (tmp -> name, ifp -> ifr_name))
-                               break;
-
-               /* If there isn't already an interface by this name,
-                  allocate one. */
-               if (!tmp) {
-                       tmp = ((struct interface_info *)
-                              dmalloc (sizeof *tmp, "discover_interfaces"));
-                       if (!tmp)
-                               error ("Insufficient memory to %s %s",
-                                      "record interface", ifp -> ifr_name);
-                       strcpy (tmp -> name, ifp -> ifr_name);
-                       tmp -> next = interfaces;
-                       tmp -> flags = ir;
-                       interfaces = tmp;
-               }
-
-               /* If we have the capability, extract link information
-                  and record it in a linked list. */
-#ifdef AF_LINK
-               if (ifp -> ifr_addr.sa_family == AF_LINK) {
-                       struct sockaddr_dl *foo = ((struct sockaddr_dl *)
-                                                  (&ifp -> ifr_addr));
-#if defined (HAVE_SIN_LEN)
-                       tmp -> hw_address.hlen = foo -> sdl_alen;
-#else
-                       tmp -> hw_address.hlen = 6; /* XXX!!! */
-#endif
-                       tmp -> hw_address.htype = HTYPE_ETHER; /* XXX */
-                       memcpy (tmp -> hw_address.haddr,
-                               LLADDR (foo), tmp -> hw_address.hlen);
-               } else
-#endif /* AF_LINK */
-
-               if (ifp -> ifr_addr.sa_family == AF_INET) {
-                       struct iaddr addr;
-
-#if defined (SIOCGIFHWADDR) && !defined (AF_LINK)
-                       struct ifreq ifr;
-                       struct sockaddr sa;
-                       int b, sk;
-                       
-                       /* Read the hardware address from this interface. */
-                       ifr = *ifp;
-                       if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0)
-                               error ("Can't get hardware address for %s: %m",
-                                      ifr.ifr_name);
-
-                       sa = *(struct sockaddr *)&ifr.ifr_hwaddr;
-                                       
-                       switch (sa.sa_family) {
-#ifdef ARPHRD_LOOPBACK
-                             case ARPHRD_LOOPBACK:
-                               /* ignore loopback interface */
-                               break;
-#endif
-
-                             case ARPHRD_ETHER:
-                               tmp -> hw_address.hlen = 6;
-                               tmp -> hw_address.htype = ARPHRD_ETHER;
-                               memcpy (tmp -> hw_address.haddr,
-                                       sa.sa_data, 6);
-                               break;
-
-#ifndef ARPHRD_IEEE802
-# define ARPHRD_IEEE802 HTYPE_IEEE802
-#endif
-                             case ARPHRD_IEEE802:
-                               tmp -> hw_address.hlen = 6;
-                               tmp -> hw_address.htype = ARPHRD_IEEE802;
-                               memcpy (tmp -> hw_address.haddr,
-                                       sa.sa_data, 6);
-                               break;
-
-#ifdef ARPHRD_METRICOM
-                             case ARPHRD_METRICOM:
-                               tmp -> hw_address.hlen = 6;
-                               tmp -> hw_address.htype = ARPHRD_METRICOM;
-                               memcpy (tmp -> hw_address.haddr,
-                                       sa.sa_data, 6);
-
-                               break;
-#endif
-
-                             default:
-                               error ("%s: unknown hardware address type %d",
-                                      ifr.ifr_name, sa.sa_family);
-                       }
-#endif /* defined (SIOCGIFHWADDR) && !defined (AF_LINK) */
-
-                       /* Get a pointer to the address... */
-                       memcpy (&foo, &ifp -> ifr_addr,
-                               sizeof ifp -> ifr_addr);
-
-                       /* We don't want the loopback interface. */
-                       if (foo.sin_addr.s_addr == htonl (INADDR_LOOPBACK))
-                               continue;
-
-
-                       /* If this is the first real IP address we've
-                          found, keep a pointer to ifreq structure in
-                          which we found it. */
-                       if (!tmp -> ifp) {
-                               struct ifreq *tif;
-#ifdef HAVE_SA_LEN
-                               int len = ((sizeof ifp -> ifr_name) +
-                                          ifp -> ifr_addr.sa_len);
-#else
-                               int len = sizeof *ifp;
-#endif
-                               tif = (struct ifreq *)malloc (len);
-                               if (!tif)
-                                       error ("no space to remember ifp.");
-                               memcpy (tif, ifp, len);
-                               tmp -> ifp = tif;
-                               tmp -> primary_address = foo.sin_addr;
-                       }
-
-                       /* Grab the address... */
-                       addr.len = 4;
-                       memcpy (addr.iabuf, &foo.sin_addr.s_addr,
-                               addr.len);
-
-                       /* If there's a registered subnet for this address,
-                          connect it together... */
-                       if ((subnet = find_subnet (addr))) {
-                               /* If this interface has multiple aliases
-                                  on the same subnet, ignore all but the
-                                  first we encounter. */
-                               if (!subnet -> interface) {
-                                       subnet -> interface = tmp;
-                                       subnet -> interface_address = addr;
-                               } else if (subnet -> interface != tmp) {
-                                       warn ("Multiple %s %s: %s %s", 
-                                             "interfaces match the",
-                                             "same subnet",
-                                             subnet -> interface -> name,
-                                             tmp -> name);
-                               }
-                               share = subnet -> shared_network;
-                               if (tmp -> shared_network &&
-                                   tmp -> shared_network != share) {
-                                       warn ("Interface %s matches %s",
-                                             tmp -> name,
-                                             "multiple shared networks");
-                               } else {
-                                       tmp -> shared_network = share;
-                               }
-
-                               if (!share -> interface) {
-                                       share -> interface = tmp;
-                               } else if (share -> interface != tmp) {
-                                       warn ("Multiple %s %s: %s %s", 
-                                             "interfaces match the",
-                                             "same shared network",
-                                             share -> interface -> name,
-                                             tmp -> name);
-                               }
-                       }
-               }
-       }
-
-       /* If we're just trying to get a list of interfaces that we might
-          be able to configure, we can quit now. */
-       if (state == DISCOVER_UNCONFIGURED)
-               return;
-
-       /* Weed out the interfaces that did not have IP addresses. */
-       last = (struct interface_info *)0;
-       for (tmp = interfaces; tmp; tmp = next) {
-               next = tmp -> next;
-               if ((tmp -> flags & INTERFACE_AUTOMATIC) &&
-                   state == DISCOVER_REQUESTED)
-                       tmp -> flags &= ~(INTERFACE_AUTOMATIC |
-                                         INTERFACE_REQUESTED);
-               if (!tmp -> ifp || !(tmp -> flags & INTERFACE_REQUESTED)) {
-                       if ((tmp -> flags & INTERFACE_REQUESTED) != ir)
-                               error ("%s: not found", tmp -> name);
-                       if (!last)
-                               interfaces = interfaces -> next;
-                       else
-                               last -> next = tmp -> next;
-
-                       /* Remember the interface in case we need to know
-                          about it later. */
-                       tmp -> next = dummy_interfaces;
-                       dummy_interfaces = tmp;
-                       continue;
-               }
-               last = tmp;
-
-               memcpy (&foo, &tmp -> ifp -> ifr_addr,
-                       sizeof tmp -> ifp -> ifr_addr);
-
-               /* We must have a subnet declaration for each interface. */
-               if (!tmp -> shared_network && (state == DISCOVER_SERVER))
-                       error ("No subnet declaration for %s (%s).",
-                              tmp -> name, inet_ntoa (foo.sin_addr));
-
-               /* Find subnets that don't have valid interface
-                  addresses... */
-               for (subnet = (tmp -> shared_network
-                              ? tmp -> shared_network -> subnets
-                              : (struct subnet *)0);
-                    subnet; subnet = subnet -> next_sibling) {
-                       if (!subnet -> interface_address.len) {
-                               /* Set the interface address for this subnet
-                                  to the first address we found. */
-                               subnet -> interface_address.len = 4;
-                               memcpy (subnet -> interface_address.iabuf,
-                                       &foo.sin_addr.s_addr, 4);
-                       }
-               }
-
-               /* Register the interface... */
-               if_register_receive (tmp);
-               if_register_send (tmp);
-       }
-
-       /* Now register all the remaining interfaces as protocols. */
-       for (tmp = interfaces; tmp; tmp = tmp -> next)
-               add_protocol (tmp -> name, tmp -> rfdesc, got_one, tmp);
-
-       close (sock);
-
-#ifdef USE_FALLBACK
-       strcpy (fallback_interface.name, "fallback");   
-       fallback_interface.shared_network = &fallback_network;
-       fallback_network.name = "fallback-net";
-       if_register_fallback (&fallback_interface);
-       add_protocol ("fallback", fallback_interface.wfdesc,
-                     fallback_discard, &fallback_interface);
-#endif
-}
-
-void reinitialize_interfaces ()
-{
-       struct interface_info *ip;
-
-       for (ip = interfaces; ip; ip = ip -> next) {
-               if_reinitialize_receive (ip);
-               if_reinitialize_send (ip);
-       }
-
-#ifdef USE_FALLBACK
-       if_reinitialize_fallback (&fallback_interface);
-#endif
-
-       interfaces_invalidated = 1;
-}
+int interfaces_invalidated;
 
 #ifdef USE_POLL
 /* Wait for packets to come in using poll().  Anyway, when a packet
@@ -570,38 +218,6 @@ void dispatch ()
 }
 #endif /* USE_POLL */
 
-static void got_one (l)
-       struct protocol *l;
-{
-       struct sockaddr_in from;
-       struct hardware hfrom;
-       struct iaddr ifrom;
-       int result;
-       union {
-               unsigned char packbuf [4095]; /* Packet input buffer.
-                                                Must be as large as largest
-                                                possible MTU. */
-               struct dhcp_packet packet;
-       } u;
-       struct interface_info *ip = l -> local;
-
-       if ((result =
-            receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)) < 0) {
-               warn ("receive_packet failed on %s: %m", ip -> name);
-               return;
-       }
-       if (result == 0)
-               return;
-
-       if (bootp_packet_handler) {
-               ifrom.len = 4;
-               memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
-
-               (*bootp_packet_handler) (ip, &u.packet, result,
-                                        from.sin_port, ifrom, &hfrom);
-       }
-}
-
 int locate_network (packet)
        struct packet *packet;
 {