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

1.1       misho       1: /* trace.c
                      2: 
                      3:    Subroutines that support dhcp tracing... */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2004,2007,2009 by Internet Systems Consortium, Inc. ("ISC")
                      7:  * Copyright (c) 2001-2003 by Internet Software Consortium
                      8:  *
                      9:  * Permission to use, copy, modify, and distribute this software for any
                     10:  * purpose with or without fee is hereby granted, provided that the above
                     11:  * copyright notice and this permission notice appear in all copies.
                     12:  *
                     13:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     14:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     15:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     16:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     17:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     18:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     19:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     20:  *
                     21:  *   Internet Systems Consortium, Inc.
                     22:  *   950 Charter Street
                     23:  *   Redwood City, CA 94063
                     24:  *   <info@isc.org>
                     25:  *   https://www.isc.org/
                     26:  *
                     27:  * This software has been written for Internet Systems Consortium
                     28:  * by Ted Lemon, as part of a project for Nominum, Inc.   To learn more
                     29:  * about Internet Systems Consortium, see https://www.isc.org/.  To
                     30:  * learn more about Nominum, Inc., see ``http://www.nominum.com''.
                     31:  */
                     32: 
                     33: #include "dhcpd.h"
                     34: 
                     35: #if defined (TRACING)
                     36: void trace_interface_register (trace_type_t *ttype, struct interface_info *ip)
                     37: {
                     38:        trace_interface_packet_t tipkt;
                     39: 
                     40:        if (trace_record ()) {
                     41:                memset (&tipkt, 0, sizeof tipkt);
                     42:                memcpy (&tipkt.hw_address,
                     43:                        &ip -> hw_address, sizeof ip -> hw_address);
                     44:                if (ip->address_count)
                     45:                        memcpy(&tipkt.primary_address,
                     46:                               ip->addresses, sizeof(*ip->addresses));
                     47:                memcpy (tipkt.name, ip -> name, sizeof ip -> name);
                     48:                tipkt.index = htonl (ip -> index);
                     49: 
                     50:                trace_write_packet (ttype, sizeof tipkt, (char *)&tipkt, MDL);
                     51:        }       
                     52: }
                     53: 
                     54: void trace_interface_input (trace_type_t *ttype, unsigned len, char *buf)
                     55: {
                     56:        trace_interface_packet_t *tipkt;
                     57:        struct interface_info *ip;
                     58:        struct sockaddr_in *sin;
                     59:        struct iaddr addr;
                     60:        isc_result_t status;
                     61: 
                     62:        if (len != sizeof *tipkt) {
                     63:                log_error ("trace interface packet size mismatch: %ld != %d",
                     64:                           (long)(sizeof *tipkt), len);
                     65:                return;
                     66:        }
                     67:        tipkt = (trace_interface_packet_t *)buf;
                     68:        
                     69:        ip = (struct interface_info *)0;
                     70:        status = interface_allocate (&ip, MDL);
                     71:        if (status != ISC_R_SUCCESS) {
                     72:              foo:
                     73:                log_error ("trace_interface_input: %s.",
                     74:                           isc_result_totext (status));
                     75:                return;
                     76:        }
                     77:        ip -> ifp = dmalloc (sizeof *(ip -> ifp), MDL);
                     78:        if (!ip -> ifp) {
                     79:                interface_dereference (&ip, MDL);
                     80:                status = ISC_R_NOMEMORY;
                     81:                goto foo;
                     82:        }
                     83: 
                     84:        memcpy (&ip -> hw_address, &tipkt -> hw_address,
                     85:                sizeof ip -> hw_address);
                     86:        /* XXX: Without the full addresses state it's not quite a full
                     87:         * trace.
                     88:         */
                     89:        ip->address_count = ip->address_max = 1;
                     90:        ip->addresses = dmalloc(sizeof(*ip->addresses), MDL);
                     91:        memcpy(ip->addresses, &tipkt->primary_address, sizeof(*ip->addresses));
                     92:        memcpy (ip -> name, tipkt -> name, sizeof ip -> name);
                     93:        ip -> index = ntohl (tipkt -> index);
                     94: 
                     95:        interface_snorf (ip, 0);
                     96:        if (dhcp_interface_discovery_hook)
                     97:                (*dhcp_interface_discovery_hook) (ip);
                     98: 
                     99:        /* Fake up an ifp. */
                    100:        memcpy (ip -> ifp -> ifr_name, ip -> name, sizeof ip -> name);
                    101: #ifdef HAVE_SA_LEN
                    102:        ip -> ifp -> ifr_addr.sa_len = sizeof (struct sockaddr_in);
                    103: #endif
                    104:        sin = (struct sockaddr_in *)&ip -> ifp -> ifr_addr;
                    105:        sin->sin_addr = ip->addresses[0];
                    106: 
                    107:        addr.len = 4;
                    108:        memcpy (addr.iabuf, &sin -> sin_addr.s_addr, addr.len);
                    109:        if (dhcp_interface_setup_hook)
                    110:                (*dhcp_interface_setup_hook) (ip, &addr);
                    111:        interface_stash (ip);
                    112: 
                    113:        if (!quiet_interface_discovery) {
                    114:                log_info ("Listening on Trace/%s/%s%s%s",
                    115:                          ip -> name,
                    116:                          print_hw_addr (ip -> hw_address.hbuf [0],
                    117:                                         ip -> hw_address.hlen - 1,
                    118:                                         &ip -> hw_address.hbuf [1]),
                    119:                          (ip -> shared_network ? "/" : ""),
                    120:                          (ip -> shared_network ?
                    121:                           ip -> shared_network -> name : ""));
                    122:                if (strcmp (ip -> name, "fallback")) {
                    123:                        log_info ("Sending   on Trace/%s/%s%s%s",
                    124:                                  ip -> name,
                    125:                                  print_hw_addr (ip -> hw_address.hbuf [0],
                    126:                                                 ip -> hw_address.hlen - 1,
                    127:                                                 &ip -> hw_address.hbuf [1]),
                    128:                                  (ip -> shared_network ? "/" : ""),
                    129:                                  (ip -> shared_network ?
                    130:                                   ip -> shared_network -> name : ""));
                    131:                }
                    132:        }
                    133:        interface_dereference (&ip, MDL);
                    134: }
                    135: 
                    136: void trace_interface_stop (trace_type_t *ttype) {
                    137:        /* XXX */
                    138: }
                    139: 
                    140: void trace_inpacket_stash (struct interface_info *interface,
                    141:                           struct dhcp_packet *packet,
                    142:                           unsigned len,
                    143:                           unsigned int from_port,
                    144:                           struct iaddr from,
                    145:                           struct hardware *hfrom)
                    146: {
                    147:        trace_inpacket_t tip;
                    148:        trace_iov_t iov [2];
                    149: 
                    150:        if (!trace_record ())
                    151:                return;
                    152:        tip.from_port = from_port;
                    153:        tip.from = from;
                    154:        tip.from.len = htonl (tip.from.len);
                    155:        if (hfrom) {
                    156:                tip.hfrom = *hfrom;
                    157:                tip.havehfrom = 1;
                    158:        } else {
                    159:                memset (&tip.hfrom, 0, sizeof tip.hfrom);
                    160:                tip.havehfrom = 0;
                    161:        }
                    162:        tip.index = htonl (interface -> index);
                    163: 
                    164:        iov [0].buf = (char *)&tip;
                    165:        iov [0].len = sizeof tip;
                    166:        iov [1].buf = (char *)packet;
                    167:        iov [1].len = len;
                    168:        trace_write_packet_iov (inpacket_trace, 2, iov, MDL);
                    169: }
                    170: 
                    171: void trace_inpacket_input (trace_type_t *ttype, unsigned len, char *buf)
                    172: {
                    173:        trace_inpacket_t *tip;
                    174:        int index;
                    175: 
                    176:        if (len < sizeof *tip) {
                    177:                log_error ("trace_input_packet: too short - %d", len);
                    178:                return;
                    179:        }
                    180:        tip = (trace_inpacket_t *)buf;
                    181:        index = ntohl (tip -> index);
                    182:        tip -> from.len = ntohl (tip -> from.len);
                    183:        
                    184:        if (index > interface_count ||
                    185:            index < 0 ||
                    186:            !interface_vector [index]) {
                    187:                log_error ("trace_input_packet: unknown interface index %d",
                    188:                           index);
                    189:                return;
                    190:        }
                    191: 
                    192:        if (!bootp_packet_handler) {
                    193:                log_error ("trace_input_packet: no bootp packet handler.");
                    194:                return;
                    195:        }
                    196: 
                    197:        (*bootp_packet_handler) (interface_vector [index],
                    198:                                 (struct dhcp_packet *)(tip + 1),
                    199:                                 len - sizeof *tip,
                    200:                                 tip -> from_port,
                    201:                                 tip -> from,
                    202:                                 (tip -> havehfrom ?
                    203:                                  &tip -> hfrom
                    204:                                  : (struct hardware *)0));
                    205: }
                    206: 
                    207: void trace_inpacket_stop (trace_type_t *ttype) { }
                    208: 
                    209: ssize_t trace_packet_send (struct interface_info *interface,
                    210:                           struct packet *packet,
                    211:                           struct dhcp_packet *raw,
                    212:                           size_t len,
                    213:                           struct in_addr from,
                    214:                           struct sockaddr_in *to,
                    215:                           struct hardware *hto)
                    216: {
                    217:        trace_outpacket_t tip;
                    218:        trace_iov_t iov [2];
                    219: 
                    220:        if (trace_record ()) {
                    221:                if (hto) {
                    222:                        tip.hto = *hto;
                    223:                        tip.havehto = 1;
                    224:                } else {
                    225:                        memset (&tip.hto, 0, sizeof tip.hto);
                    226:                        tip.havehto = 0;
                    227:                }
                    228:                tip.from.len = 4;
                    229:                memcpy (tip.from.iabuf, &from, 4);
                    230:                tip.to.len = 4;
                    231:                memcpy (tip.to.iabuf, &to -> sin_addr, 4);
                    232:                tip.to_port = to -> sin_port;
                    233:                tip.index = htonl (interface -> index);
                    234: 
                    235:                iov [0].buf = (char *)&tip;
                    236:                iov [0].len = sizeof tip;
                    237:                iov [1].buf = (char *)raw;
                    238:                iov [1].len = len;
                    239:                trace_write_packet_iov (outpacket_trace, 2, iov, MDL);
                    240:        }
                    241:        if (!trace_playback ()) {
                    242:                return send_packet (interface, packet, raw, len,
                    243:                                    from, to, hto);
                    244:        }
                    245:        return len;
                    246: }
                    247: 
                    248: void trace_outpacket_input (trace_type_t *ttype, unsigned len, char *buf)
                    249: {
                    250:        trace_outpacket_t *tip;
                    251:        int index;
                    252: 
                    253:        if (len < sizeof *tip) {
                    254:                log_error ("trace_input_packet: too short - %d", len);
                    255:                return;
                    256:        }
                    257:        tip = (trace_outpacket_t *)buf;
                    258:        index = ntohl (tip -> index);
                    259:        
                    260:        if (index > interface_count ||
                    261:            index < 0 ||
                    262:            !interface_vector [index]) {
                    263:                log_error ("trace_input_packet: unknown interface index %d",
                    264:                           index);
                    265:                return;
                    266:        }
                    267: 
                    268:        /* XXX would be nice to somehow take notice of these. */
                    269: }
                    270: 
                    271: void trace_outpacket_stop (trace_type_t *ttype) { }
                    272: 
                    273: void trace_seed_stash (trace_type_t *ttype, unsigned seed)
                    274: {
                    275:        u_int32_t outseed;
                    276:        if (!trace_record ())
                    277:                return;
                    278:        outseed = htonl (seed);
                    279:        trace_write_packet (ttype, sizeof outseed, (char *)&outseed, MDL);
                    280:        return;
                    281: }
                    282: 
                    283: void trace_seed_input (trace_type_t *ttype, unsigned length, char *buf)
                    284: {
                    285:        u_int32_t *seed;
                    286: 
                    287:        if (length != sizeof seed) {
                    288:                log_error ("trace_seed_input: wrong size (%d)", length);
                    289:        }
                    290:        seed = (u_int32_t *)buf;
                    291:        srandom (ntohl (*seed));
                    292: }
                    293: 
                    294: void trace_seed_stop (trace_type_t *ttype) { }
                    295: #endif /* TRACING */

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