File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dhcp / common / ctrace.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:06:54 2012 UTC (12 years ago) by misho
Branches: dhcp, MAIN
CVS tags: v4_1_R7p0, v4_1_R7, v4_1_R4, HEAD
dhcp 4.1 r7

    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>