]> git.ipfire.org Git - thirdparty/dhcp.git/blobdiff - common/upf.c
copy rights update
[thirdparty/dhcp.git] / common / upf.c
index 535e3b4d83ca8b63025de78b520daccfe85745a3..37e5cb2879f14e19f4cd9c2a6b7dcf0e67d38da5 100644 (file)
@@ -3,28 +3,29 @@
    Ultrix PacketFilter interface code. */
 
 /*
- * Copyright (c) 1996-1999 Internet Software Consortium.
- * Use is subject to license terms which appear in the file named
- * ISC-LICENSE that should have accompanied this file when you
- * received it.   If a file named ISC-LICENSE did not accompany this
- * file, or you are not sure the one you have is correct, you may
- * obtain an applicable copy of the license at:
+ * Copyright (C) 2004-2022 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-2003 by Internet Software Consortium
  *
- *             http://www.isc.org/isc-license-1.0.html. 
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  *
- * This file is part of the ISC DHCP distribution.   The documentation
- * associated with this file is listed in the file DOCUMENTATION,
- * included in the top-level directory of this release.
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ *   Internet Systems Consortium, Inc.
+ *   PO Box 360
+ *   Newmarket, NH 03857 USA
+ *   <info@isc.org>
+ *   https://www.isc.org/
  *
- * Support and other services are available for ISC products - see
- * http://www.isc.org for more information.
  */
 
-#ifndef lint
-static char copyright[] =
-"$Id: upf.c,v 1.14 1999/10/07 06:47:49 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium.  All rights reserved.\n";
-#endif /* not lint */
-
 #include "dhcpd.h"
 #if defined (USE_UPF_SEND) || defined (USE_UPF_RECEIVE)
 #include <sys/ioctl.h>
@@ -67,11 +68,9 @@ int if_register_upf (info)
 
        /* Open a UPF device */
        for (b = 0; 1; b++) {
-#ifndef NO_SNPRINTF
-               snprintf(filename, sizeof(filename), "/dev/pf/pfilt%d", b);
-#else
+               /* %Audit% Cannot exceed 36 bytes. %2004.06.17,Safe% */
                sprintf(filename, "/dev/pf/pfilt%d", b);
-#endif
+
                sock = open (filename, O_RDWR, 0);
                if (sock < 0) {
                        if (errno == EBUSY) {
@@ -95,7 +94,7 @@ int if_register_upf (info)
                       info -> name);
 
        /* We only know how to do ethernet. */
-       if (param.end_dev_type != ENDT_10MB)    
+       if (param.end_dev_type != ENDT_10MB)
                log_fatal ("Invalid device type on network interface %s: %d",
                       info -> name, param.end_dev_type);
 
@@ -103,9 +102,9 @@ int if_register_upf (info)
                log_fatal ("Invalid hardware address length on %s: %d",
                       info -> name, param.end_addr_len);
 
-       info -> hw_address.hlen = 6;
-       info -> hw_address.htype = ARPHRD_ETHER;
-       memcpy (&info -> hw_address.haddr [0], param.end_addr, 6);
+       info -> hw_address.hlen = 7;
+       info -> hw_address.hbuf [0] = ARPHRD_ETHER;
+       memcpy (&info -> hw_address.hbuf [1], param.end_addr, 6);
 
        return sock;
 }
@@ -125,9 +124,27 @@ void if_register_send (info)
         if (!quiet_interface_discovery)
                log_info ("Sending on   UPF/%s/%s%s%s",
                      info -> name,
-                     print_hw_addr (info -> hw_address.htype,
-                                    info -> hw_address.hlen,
-                                    info -> hw_address.haddr),
+                     print_hw_addr (info -> hw_address.hbuf [0],
+                                    info -> hw_address.hlen - 1,
+                                    &info -> hw_address.hbuf [1]),
+                     (info -> shared_network ? "/" : ""),
+                     (info -> shared_network ?
+                      info -> shared_network -> name : ""));
+}
+
+void if_deregister_send (info)
+       struct interface_info *info;
+{
+#ifndef USE_UPF_RECEIVE
+       close (info -> wfdesc);
+#endif
+       info -> wfdesc = -1;
+        if (!quiet_interface_discovery)
+               log_info ("Disabling output on UPF/%s/%s%s%s",
+                     info -> name,
+                     print_hw_addr (info -> hw_address.hbuf [0],
+                                    info -> hw_address.hlen - 1,
+                                    &info -> hw_address.hbuf [1]),
                      (info -> shared_network ? "/" : ""),
                      (info -> shared_network ?
                       info -> shared_network -> name : ""));
@@ -139,6 +156,9 @@ void if_register_send (info)
    XXX Changes to the filter program may require changes to the constant
    offsets used in if_register_send to patch the UPF program! XXX */
 
+#if defined(RELAY_PORT)
+#error "Relay port is not yet supported for UPF"
+#endif
 
 void if_register_receive (info)
        struct interface_info *info;
@@ -191,9 +211,25 @@ void if_register_receive (info)
         if (!quiet_interface_discovery)
                log_info ("Listening on UPF/%s/%s%s%s",
                      info -> name,
-                     print_hw_addr (info -> hw_address.htype,
-                                    info -> hw_address.hlen,
-                                    info -> hw_address.haddr),
+                     print_hw_addr (info -> hw_address.hbuf [0],
+                                    info -> hw_address.hlen - 1,
+                                    &info -> hw_address.hbuf [1]),
+                     (info -> shared_network ? "/" : ""),
+                     (info -> shared_network ?
+                      info -> shared_network -> name : ""));
+}
+
+void if_deregister_receive (info)
+       struct interface_info *info;
+{
+       close (info -> rfdesc);
+       info -> rfdesc = -1;
+        if (!quiet_interface_discovery)
+               log_info ("Disabling input on UPF/%s/%s%s%s",
+                     info -> name,
+                     print_hw_addr (info -> hw_address.hbuf [0],
+                                    info -> hw_address.hlen - 1,
+                                    &info -> hw_address.hbuf [1]),
                      (info -> shared_network ? "/" : ""),
                      (info -> shared_network ?
                       info -> shared_network -> name : ""));
@@ -210,28 +246,36 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
        struct sockaddr_in *to;
        struct hardware *hto;
 {
-       unsigned bufp = 0;
-       unsigned char buf [256];
-       struct iovec iov [2];
+       unsigned hbufp = 0, ibufp = 0;
+       double hw [4];
+       double ip [32];
+       struct iovec iov [3];
        int result;
+       int fudge;
 
        if (!strcmp (interface -> name, "fallback"))
                return send_fallback (interface, packet, raw,
                                      len, from, to, hto);
 
+       if (hto == NULL && interface->anycast_mac_addr.hlen)
+               hto = &interface->anycast_mac_addr;
+
        /* Assemble the headers... */
-       assemble_hw_header (interface, buf, &bufp, hto);
-       assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
+       assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);
+       assemble_udp_ip_header (interface,
+                               (unsigned char *)ip, &ibufp, from.s_addr,
                                to -> sin_addr.s_addr, to -> sin_port,
                                (unsigned char *)raw, len);
 
        /* Fire it off */
-       iov [0].iov_base = (char *)buf;
-       iov [0].iov_len = bufp;
-       iov [1].iov_base = (char *)raw;
-       iov [1].iov_len = len;
-
-       result = writev(interface -> wfdesc, iov, 2);
+       iov [0].iov_base = ((char *)hw);
+       iov [0].iov_len = hbufp;
+       iov [1].iov_base = ((char *)ip);
+       iov [1].iov_len = ibufp;
+       iov [2].iov_base = (char *)raw;
+       iov [2].iov_len = len;
+
+       result = writev(interface -> wfdesc, iov, 3);
        if (result < 0)
                log_error ("send_packet: %m");
        return result;
@@ -251,6 +295,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
        int offset = 0;
        unsigned char ibuf [1500 + sizeof (struct enstamp)];
        int bufix = 0;
+       unsigned paylen;
 
        length = read (interface -> rfdesc, ibuf, sizeof ibuf);
        if (length <= 0)
@@ -272,7 +317,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
 
        /* Decode the IP and UDP headers... */
        offset = decode_udp_ip_header (interface, ibuf, bufix,
-                                      from, (unsigned char *)0, length);
+                                      from, length, &paylen, 1);
 
        /* If the IP or UDP checksum was bad, skip the packet... */
        if (offset < 0)
@@ -281,9 +326,12 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
        bufix += offset;
        length -= offset;
 
+       if (length < paylen)
+               log_fatal("Internal inconsistency at %s:%d.", MDL);
+
        /* Copy out the data in the packet... */
-       memcpy (buf, &ibuf [bufix], length);
-       return length;
+       memcpy (buf, &ibuf[bufix], paylen);
+       return paylen;
 }
 
 int can_unicast_without_arp (ip)
@@ -298,21 +346,25 @@ int can_receive_unicast_unconfigured (ip)
        return 1;
 }
 
+int supports_multiple_interfaces (ip)
+       struct interface_info *ip;
+{
+       return 1;
+}
+
 void maybe_setup_fallback ()
 {
        isc_result_t status;
-       struct interface_info *fbi;
-       fbi = setup_fallback ();
-       if (fbi) {
+       struct interface_info *fbi = (struct interface_info *)0;
+       if (setup_fallback (&fbi, MDL)) {
                if_register_fallback (fbi);
-               fbi -> refcnt = 1;
-               fbi -> type = dhcp_type_interface;
                status = omapi_register_io_object ((omapi_object_t *)fbi,
                                                   if_readsocket, 0,
                                                   fallback_discard, 0, 0);
                if (status != ISC_R_SUCCESS)
                        log_fatal ("Can't register I/O handle for %s: %s",
                                   fbi -> name, isc_result_totext (status));
+               interface_dereference (&fbi, MDL);
        }
 }
 #endif