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>