📄 discover.c
字号:
*sep = '\0'; while (*name == ' ') name++; /* See if we've seen an interface that matches this one. */ for (tmp = interfaces; tmp; tmp = tmp -> next) if (!strcmp (tmp -> name, name)) break; /* If we found one, nothing more to do.. */ if (tmp) continue; /* Otherwise, allocate one. */ tmp = (struct interface_info *)0; status = interface_allocate (&tmp, MDL); if (status != ISC_R_SUCCESS) log_fatal ("Can't allocate interface %s: %s", name, isc_result_totext (status)); tmp -> flags = ir; strncpy (tmp -> name, name, IFNAMSIZ); if (interfaces) { interface_reference (&tmp -> next, interfaces, MDL); interface_dereference (&interfaces, MDL); } interface_reference (&interfaces, tmp, MDL); interface_dereference (&tmp, MDL); tmp = interfaces; if (dhcp_interface_discovery_hook) (*dhcp_interface_discovery_hook) (tmp); } fclose (proc_dev); }#endif /* Now cycle through all the interfaces we found, looking for hardware addresses. */#if defined (HAVE_SIOCGIFHWADDR) && !defined (HAVE_AF_LINK) for (tmp = interfaces; tmp; tmp = tmp -> next) { struct ifreq ifr; struct sockaddr sa; int b, sk; if (!tmp -> ifp) { /* Make up an ifreq structure. */ tif = (struct ifreq *)dmalloc (sizeof (struct ifreq), MDL); if (!tif) log_fatal ("no space to remember ifp."); memset (tif, 0, sizeof (struct ifreq)); strcpy (tif -> ifr_name, tmp -> name); tmp -> ifp = tif; } /* Read the hardware address from this interface. */ ifr = *tmp -> ifp; if (ioctl (sock, SIOCGIFHWADDR, &ifr) < 0) continue; sa = *(struct sockaddr *)&ifr.ifr_hwaddr; switch (sa.sa_family) {#ifdef HAVE_ARPHRD_TUNNEL case ARPHRD_TUNNEL: /* ignore tunnel interfaces. */#endif#ifdef HAVE_ARPHRD_ROSE case ARPHRD_ROSE:#endif#ifdef HAVE_ARPHRD_LOOPBACK case ARPHRD_LOOPBACK: /* ignore loopback interface */ break;#endif case ARPHRD_ETHER: tmp -> hw_address.hlen = 7; tmp -> hw_address.hbuf [0] = ARPHRD_ETHER; memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6); break;#ifndef HAVE_ARPHRD_IEEE802# define ARPHRD_IEEE802 HTYPE_IEEE802#endif#if defined (HAVE_ARPHRD_IEEE802_TR) case ARPHRD_IEEE802_TR:#endif case ARPHRD_IEEE802: tmp -> hw_address.hlen = 7; tmp -> hw_address.hbuf [0] = ARPHRD_IEEE802; memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6); break;#ifndef HAVE_ARPHRD_FDDI# define ARPHRD_FDDI HTYPE_FDDI#endif case ARPHRD_FDDI: tmp -> hw_address.hlen = 17; tmp -> hw_address.hbuf [0] = HTYPE_FDDI; /* XXX */ memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 16); break;#ifdef HAVE_ARPHRD_METRICOM case ARPHRD_METRICOM: tmp -> hw_address.hlen = 7; tmp -> hw_address.hbuf [0] = ARPHRD_METRICOM; memcpy (&tmp -> hw_address.hbuf [0], sa.sa_data, 6); break;#endif#ifdef HAVE_ARPHRD_AX25 case ARPHRD_AX25: tmp -> hw_address.hlen = 7; tmp -> hw_address.hbuf [0] = ARPHRD_AX25; memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6); break;#endif#ifdef HAVE_ARPHRD_NETROM case ARPHRD_NETROM: tmp -> hw_address.hlen = 7; tmp -> hw_address.hbuf [0] = ARPHRD_NETROM; memcpy (&tmp -> hw_address.hbuf [1], sa.sa_data, 6); break;#endif default: log_error ("%s: unknown hardware address type %d", ifr.ifr_name, sa.sa_family); break; } }#endif /* defined (HAVE_SIOCGIFHWADDR) && !defined (HAVE_AF_LINK) */ /* 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) { close (sock); return; } /* Weed out the interfaces that did not have IP addresses. */ tmp = last = next = (struct interface_info *)0; if (interfaces) interface_reference (&tmp, interfaces, MDL); while (tmp) { if (next) interface_dereference (&next, MDL); if (tmp -> next) interface_reference (&next, tmp -> next, MDL); /* skip interfaces that are running already */ if (tmp -> flags & INTERFACE_RUNNING) { interface_dereference(&tmp, MDL); if(next) interface_reference(&tmp, next, MDL); continue; } 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) log_fatal ("%s: not found", tmp -> name); if (!last) { if (interfaces) interface_dereference (&interfaces, MDL); if (next) interface_reference (&interfaces, next, MDL); } else { interface_dereference (&last -> next, MDL); if (next) interface_reference (&last -> next, next, MDL); } if (tmp -> next) interface_dereference (&tmp -> next, MDL); /* Remember the interface in case we need to know about it later. */ if (dummy_interfaces) { interface_reference (&tmp -> next, dummy_interfaces, MDL); interface_dereference (&dummy_interfaces, MDL); } interface_reference (&dummy_interfaces, tmp, MDL); interface_dereference (&tmp, MDL); if (next) interface_reference (&tmp, next, MDL); 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)) { log_error ("%s", ""); log_error ("No subnet declaration for %s (%s).", tmp -> name, inet_ntoa (foo.sin_addr)); if (supports_multiple_interfaces (tmp)) { log_error ("** Ignoring requests on %s. %s", tmp -> name, "If this is not what"); log_error (" you want, please write %s", "a subnet declaration"); log_error (" in your dhcpd.conf file %s", "for the network segment"); log_error (" to %s %s %s", "which interface", tmp -> name, "is attached. **"); log_error ("%s", ""); goto next; } else { log_error ("You must write a subnet %s", " declaration for this"); log_error ("subnet. You cannot prevent %s", "the DHCP server"); log_error ("from listening on this subnet %s", "because your"); log_fatal ("operating system does not %s.", "support this capability"); } } /* 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); } } /* Flag the index as not having been set, so that the interface registerer can set it or not as it chooses. */ tmp -> index = -1; /* Register the interface... */ if_register_receive (tmp); if_register_send (tmp); interface_stash (tmp); wifcount++;#if defined (HAVE_SETFD) if (fcntl (tmp -> rfdesc, F_SETFD, 1) < 0) log_error ("Can't set close-on-exec on %s: %m", tmp -> name); if (tmp -> rfdesc != tmp -> wfdesc) { if (fcntl (tmp -> wfdesc, F_SETFD, 1) < 0) log_error ("Can't set close-on-exec on %s: %m", tmp -> name); }#endif next: interface_dereference (&tmp, MDL); if (next) interface_reference (&tmp, next, MDL); } /* Now register all the remaining interfaces as protocols. */ for (tmp = interfaces; tmp; tmp = tmp -> next) { /* not if it's been registered before */ if (tmp -> flags & INTERFACE_RUNNING) continue; if (tmp -> rfdesc == -1) continue; status = omapi_register_io_object ((omapi_object_t *)tmp, if_readsocket, 0, got_one, 0, 0); if (status != ISC_R_SUCCESS) log_fatal ("Can't register I/O handle for %s: %s", tmp -> name, isc_result_totext (status)); } close (sock); if (state == DISCOVER_SERVER && wifcount == 0) { log_info ("%s", ""); log_fatal ("Not configured to listen on any interfaces!"); } if (!setup_fallback) { setup_fallback = 1; maybe_setup_fallback (); }#if defined (HAVE_SETFD) if (fallback_interface) { if (fcntl (fallback_interface -> rfdesc, F_SETFD, 1) < 0) log_error ("Can't set close-on-exec on fallback: %m"); if (fallback_interface -> rfdesc != fallback_interface -> wfdesc) { if (fcntl (fallback_interface -> wfdesc, F_SETFD, 1) < 0) log_error ("Can't set close-on-exec on fallback: %m"); } }#endif}int if_readsocket (h) omapi_object_t *h;{ struct interface_info *ip; if (h -> type != dhcp_type_interface) return -1; ip = (struct interface_info *)h; return ip -> rfdesc;}int setup_fallback (struct interface_info **fp, const char *file, int line){ isc_result_t status; status = interface_allocate (&fallback_interface, file, line); if (status != ISC_R_SUCCESS) log_fatal ("Error allocating fallback interface: %s", isc_result_totext (status)); strcpy (fallback_interface -> name, "fallback"); if (dhcp_interface_setup_hook) (*dhcp_interface_setup_hook) (fallback_interface, (struct iaddr *)0); status = interface_reference (fp, fallback_interface, file, line); fallback_interface -> index = -1; interface_stash (fallback_interface); return status == ISC_R_SUCCESS;}void reinitialize_interfaces (){ struct interface_info *ip; for (ip = interfaces; ip; ip = ip -> next) { if_reinitialize_receive (ip); if_reinitialize_send (ip); } if (fallback_interface) if_reinitialize_send (fallback_interface); interfaces_invalidated = 1;}isc_result_t got_one (h) omapi_object_t *h;{ 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; if (h -> type != dhcp_type_interface) return ISC_R_INVALIDARG; ip = (struct interface_info *)h; again: if ((result = receive_packet (ip, u.packbuf, sizeof u, &from, &hfrom)) < 0) { log_error ("receive_packet failed on %s: %m", ip -> name); return ISC_R_UNEXPECTED; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -