Annotation of embedaddon/dhcp/common/raw.c, revision 1.1.1.1

1.1       misho       1: /* raw.c
                      2: 
                      3:    BSD raw socket interface code... */
                      4: 
                      5: /* XXX
                      6: 
                      7:    It's not clear how this should work, and that lack of clarity is
                      8:    terribly detrimental to the NetBSD 1.1 kernel - it crashes and
                      9:    burns.
                     10: 
                     11:    Using raw sockets ought to be a big win over using BPF or something
                     12:    like it, because you don't need to deal with the complexities of
                     13:    the physical layer, but it appears not to be possible with existing
                     14:    raw socket implementations.  This may be worth revisiting in the
                     15:    future.  For now, this code can probably be considered a curiosity.
                     16:    Sigh. */
                     17: 
                     18: /*
                     19:  * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
                     20:  * Copyright (c) 1995-2003 by Internet Software Consortium
                     21:  *
                     22:  * Permission to use, copy, modify, and distribute this software for any
                     23:  * purpose with or without fee is hereby granted, provided that the above
                     24:  * copyright notice and this permission notice appear in all copies.
                     25:  *
                     26:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     27:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     28:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     29:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     30:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     31:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     32:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     33:  *
                     34:  *   Internet Systems Consortium, Inc.
                     35:  *   950 Charter Street
                     36:  *   Redwood City, CA 94063
                     37:  *   <info@isc.org>
                     38:  *   https://www.isc.org/
                     39:  *
                     40:  * This software has been written for Internet Systems Consortium
                     41:  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
                     42:  * To learn more about Internet Systems Consortium, see
                     43:  * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
                     44:  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
                     45:  * ``http://www.nominum.com''.
                     46:  */
                     47: 
                     48: #include "dhcpd.h"
                     49: 
                     50: #if defined (USE_RAW_SEND)
                     51: #include <sys/uio.h>
                     52: 
                     53: /* Generic interface registration routine... */
                     54: void if_register_send (info)
                     55:        struct interface_info *info;
                     56: {
                     57:        struct sockaddr_in name;
                     58:        int sock;
                     59:        struct socklist *tmp;
                     60:        int flag;
                     61: 
                     62:        /* Set up the address we're going to connect to. */
                     63:        name.sin_family = AF_INET;
                     64:        name.sin_port = local_port;
                     65:        name.sin_addr.s_addr = htonl (INADDR_BROADCAST);
                     66:        memset (name.sin_zero, 0, sizeof (name.sin_zero));
                     67: 
                     68:        /* List addresses on which we're listening. */
                     69:         if (!quiet_interface_discovery)
                     70:                log_info ("Sending on %s, port %d",
                     71:                      piaddr (info -> address), htons (local_port));
                     72:        if ((sock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
                     73:                log_fatal ("Can't create dhcp socket: %m");
                     74: 
                     75:        /* Set the BROADCAST option so that we can broadcast DHCP responses. */
                     76:        flag = 1;
                     77:        if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST,
                     78:                        &flag, sizeof flag) < 0)
                     79:                log_fatal ("Can't set SO_BROADCAST option on dhcp socket: %m");
                     80: 
                     81:        /* Set the IP_HDRINCL flag so that we can supply our own IP
                     82:           headers... */
                     83:        if (setsockopt (sock, IPPROTO_IP, IP_HDRINCL, &flag, sizeof flag) < 0)
                     84:                log_fatal ("Can't set IP_HDRINCL flag: %m");
                     85: 
                     86:        info -> wfdesc = sock;
                     87:         if (!quiet_interface_discovery)
                     88:                log_info ("Sending on   Raw/%s%s%s",
                     89:                      info -> name,
                     90:                      (info -> shared_network ? "/" : ""),
                     91:                      (info -> shared_network ?
                     92:                       info -> shared_network -> name : ""));
                     93: }
                     94: 
                     95: void if_deregister_send (info)
                     96:        struct interface_info *info;
                     97: {
                     98:        close (info -> wfdesc);
                     99:        info -> wfdesc = -1;
                    100: 
                    101:         if (!quiet_interface_discovery)
                    102:                log_info ("Disabling output on Raw/%s%s%s",
                    103:                      info -> name,
                    104:                      (info -> shared_network ? "/" : ""),
                    105:                      (info -> shared_network ?
                    106:                       info -> shared_network -> name : ""));
                    107: }
                    108: 
                    109: size_t send_packet (interface, packet, raw, len, from, to, hto)
                    110:        struct interface_info *interface;
                    111:        struct packet *packet;
                    112:        struct dhcp_packet *raw;
                    113:        size_t len;
                    114:        struct in_addr from;
                    115:        struct sockaddr_in *to;
                    116:        struct hardware *hto;
                    117: {
                    118:        unsigned char buf [256];
                    119:        int bufp = 0;
                    120:        struct iovec iov [2];
                    121:        int result;
                    122: 
                    123:        /* Assemble the headers... */
                    124:        assemble_udp_ip_header (interface, buf, &bufp, from.s_addr,
                    125:                                to -> sin_addr.s_addr, to -> sin_port,
                    126:                                (unsigned char *)raw, len);
                    127: 
                    128:        /* Fire it off */
                    129:        iov [0].iov_base = (char *)buf;
                    130:        iov [0].iov_len = bufp;
                    131:        iov [1].iov_base = (char *)raw;
                    132:        iov [1].iov_len = len;
                    133: 
                    134:        result = writev(interface -> wfdesc, iov, 2);
                    135:        if (result < 0)
                    136:                log_error ("send_packet: %m");
                    137:        return result;
                    138: }
                    139: #endif /* USE_SOCKET_SEND */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>