Annotation of embedaddon/dhcp/common/ctrace.c, revision 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>