ISC DHCP  4.3.1
A reference DHCPv4 and DHCPv6 implementation
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ctrace.c
Go to the documentation of this file.
1 /* trace.c
2 
3  Subroutines that support dhcp tracing... */
4 
5 /*
6  * Copyright (c) 2004,2007,2009,2014 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  */
28 
29 #include "dhcpd.h"
30 
31 #if defined (TRACING)
33 {
35 
36  if (trace_record ()) {
37  memset (&tipkt, 0, sizeof tipkt);
38  memcpy (&tipkt.hw_address,
39  &ip -> hw_address, sizeof ip -> hw_address);
40  if (ip->address_count)
41  memcpy(&tipkt.primary_address,
42  ip->addresses, sizeof(*ip->addresses));
43  memcpy (tipkt.name, ip -> name, sizeof ip -> name);
44  tipkt.index = htonl (ip -> index);
45 
46  trace_write_packet (ttype, sizeof tipkt, (char *)&tipkt, MDL);
47  }
48 }
49 
50 void trace_interface_input (trace_type_t *ttype, unsigned len, char *buf)
51 {
53  struct interface_info *ip;
54  struct sockaddr_in *sin;
55  struct iaddr addr;
56  isc_result_t status;
57 
58  if (len != sizeof *tipkt) {
59  log_error ("trace interface packet size mismatch: %ld != %d",
60  (long)(sizeof *tipkt), len);
61  return;
62  }
63  tipkt = (trace_interface_packet_t *)buf;
64 
65  ip = (struct interface_info *)0;
66  status = interface_allocate (&ip, MDL);
67  if (status != ISC_R_SUCCESS) {
68  foo:
69  log_error ("trace_interface_input: %s.",
70  isc_result_totext (status));
71  return;
72  }
73  ip -> ifp = dmalloc (sizeof *(ip -> ifp), MDL);
74  if (!ip -> ifp) {
75  interface_dereference (&ip, MDL);
76  status = ISC_R_NOMEMORY;
77  goto foo;
78  }
79 
80  memcpy (&ip -> hw_address, &tipkt -> hw_address,
81  sizeof ip -> hw_address);
82  /* XXX: Without the full addresses state it's not quite a full
83  * trace.
84  */
85  ip->address_count = ip->address_max = 1;
86  ip->addresses = dmalloc(sizeof(*ip->addresses), MDL);
87  memcpy(ip->addresses, &tipkt->primary_address, sizeof(*ip->addresses));
88  memcpy (ip -> name, tipkt -> name, sizeof ip -> name);
89  ip -> index = ntohl (tipkt -> index);
90 
91  interface_snorf (ip, 0);
93  (*dhcp_interface_discovery_hook) (ip);
94 
95  /* Fake up an ifp. */
96  memcpy (ip -> ifp -> ifr_name, ip -> name, sizeof ip -> name);
97 #ifdef HAVE_SA_LEN
98  ip -> ifp -> ifr_addr.sa_len = sizeof (struct sockaddr_in);
99 #endif
100  sin = (struct sockaddr_in *)&ip -> ifp -> ifr_addr;
101  sin->sin_addr = ip->addresses[0];
102 
103  addr.len = 4;
104  memcpy (addr.iabuf, &sin -> sin_addr.s_addr, addr.len);
106  (*dhcp_interface_setup_hook) (ip, &addr);
107  interface_stash (ip);
108 
110  log_info ("Listening on Trace/%s/%s%s%s",
111  ip -> name,
112  print_hw_addr (ip -> hw_address.hbuf [0],
113  ip -> hw_address.hlen - 1,
114  &ip -> hw_address.hbuf [1]),
115  (ip -> shared_network ? "/" : ""),
116  (ip -> shared_network ?
117  ip -> shared_network -> name : ""));
118  if (strcmp (ip -> name, "fallback")) {
119  log_info ("Sending on Trace/%s/%s%s%s",
120  ip -> name,
121  print_hw_addr (ip -> hw_address.hbuf [0],
122  ip -> hw_address.hlen - 1,
123  &ip -> hw_address.hbuf [1]),
124  (ip -> shared_network ? "/" : ""),
125  (ip -> shared_network ?
126  ip -> shared_network -> name : ""));
127  }
128  }
129  interface_dereference (&ip, MDL);
130 }
131 
132 void trace_interface_stop (trace_type_t *ttype) {
133  /* XXX */
134 }
135 
136 void trace_inpacket_stash (struct interface_info *interface,
137  struct dhcp_packet *packet,
138  unsigned len,
139  unsigned int from_port,
140  struct iaddr from,
141  struct hardware *hfrom)
142 {
143  trace_inpacket_t tip;
144  trace_iov_t iov [2];
145 
146  if (!trace_record ())
147  return;
148  tip.from_port = from_port;
149  tip.from = from;
150  tip.from.len = htonl (tip.from.len);
151  if (hfrom) {
152  tip.hfrom = *hfrom;
153  tip.havehfrom = 1;
154  } else {
155  memset (&tip.hfrom, 0, sizeof tip.hfrom);
156  tip.havehfrom = 0;
157  }
158  tip.index = htonl (interface -> index);
159 
160  iov [0].buf = (char *)&tip;
161  iov [0].len = sizeof tip;
162  iov [1].buf = (char *)packet;
163  iov [1].len = len;
165 }
166 
167 void trace_inpacket_input (trace_type_t *ttype, unsigned len, char *buf)
168 {
169  trace_inpacket_t *tip;
170  int index;
171 
172  if (len < sizeof *tip) {
173  log_error ("trace_input_packet: too short - %d", len);
174  return;
175  }
176  tip = (trace_inpacket_t *)buf;
177  index = ntohl (tip -> index);
178  tip -> from.len = ntohl (tip -> from.len);
179 
180  if (index > interface_count ||
181  index < 0 ||
182  !interface_vector [index]) {
183  log_error ("trace_input_packet: unknown interface index %d",
184  index);
185  return;
186  }
187 
188  if (!bootp_packet_handler) {
189  log_error ("trace_input_packet: no bootp packet handler.");
190  return;
191  }
192 
193  (*bootp_packet_handler) (interface_vector [index],
194  (struct dhcp_packet *)(tip + 1),
195  len - sizeof *tip,
196  tip -> from_port,
197  tip -> from,
198  (tip -> havehfrom ?
199  &tip -> hfrom
200  : (struct hardware *)0));
201 }
202 
203 void trace_inpacket_stop (trace_type_t *ttype) { }
204 
205 ssize_t trace_packet_send (struct interface_info *interface,
206  struct packet *packet,
207  struct dhcp_packet *raw,
208  size_t len,
209  struct in_addr from,
210  struct sockaddr_in *to,
211  struct hardware *hto)
212 {
213  trace_outpacket_t tip;
214  trace_iov_t iov [2];
215 
216  if (trace_record ()) {
217  if (hto) {
218  tip.hto = *hto;
219  tip.havehto = 1;
220  } else {
221  memset (&tip.hto, 0, sizeof tip.hto);
222  tip.havehto = 0;
223  }
224  tip.from.len = 4;
225  memcpy (tip.from.iabuf, &from, 4);
226  tip.to.len = 4;
227  memcpy (tip.to.iabuf, &to -> sin_addr, 4);
228  tip.to_port = to -> sin_port;
229  tip.index = htonl (interface -> index);
230 
231  iov [0].buf = (char *)&tip;
232  iov [0].len = sizeof tip;
233  iov [1].buf = (char *)raw;
234  iov [1].len = len;
236  }
237  if (!trace_playback ()) {
238  return send_packet (interface, packet, raw, len,
239  from, to, hto);
240  }
241  return len;
242 }
243 
244 void trace_outpacket_input (trace_type_t *ttype, unsigned len, char *buf)
245 {
246  trace_outpacket_t *tip;
247  int index;
248 
249  if (len < sizeof *tip) {
250  log_error ("trace_input_packet: too short - %d", len);
251  return;
252  }
253  tip = (trace_outpacket_t *)buf;
254  index = ntohl (tip -> index);
255 
256  if (index > interface_count ||
257  index < 0 ||
258  !interface_vector [index]) {
259  log_error ("trace_input_packet: unknown interface index %d",
260  index);
261  return;
262  }
263 
264  /* XXX would be nice to somehow take notice of these. */
265 }
266 
267 void trace_outpacket_stop (trace_type_t *ttype) { }
268 
269 void trace_seed_stash (trace_type_t *ttype, unsigned seed)
270 {
271  u_int32_t outseed;
272  if (!trace_record ())
273  return;
274  outseed = htonl (seed);
275  trace_write_packet (ttype, sizeof outseed, (char *)&outseed, MDL);
276  return;
277 }
278 
279 void trace_seed_input (trace_type_t *ttype, unsigned length, char *buf)
280 {
281  u_int32_t *seed;
282 
283  if (length != sizeof seed) {
284  log_error ("trace_seed_input: wrong size (%d)", length);
285  }
286  seed = (u_int32_t *)buf;
287  srandom (ntohl (*seed));
288 }
289 
290 void trace_seed_stop (trace_type_t *ttype) { }
291 #endif /* TRACING */
const char * buf
Definition: trace.h:75
int trace_playback(void)
char name[IFNAMSIZ]
Definition: dhcpd.h:1272
struct iaddr from
Definition: ctrace.h:38
void * dmalloc(unsigned, const char *, int)
Definition: alloc.c:56
void trace_interface_register(trace_type_t *, struct interface_info *)
#define MDL
Definition: omapip.h:568
unsigned char iabuf[16]
Definition: inet.h:33
struct hardware hfrom
Definition: ctrace.h:40
struct iaddr from
Definition: ctrace.h:46
void trace_outpacket_input(trace_type_t *, unsigned, char *)
isc_result_t trace_write_packet_iov(trace_type_t *, int, trace_iov_t *, const char *, int)
struct in_addr * addresses
Definition: dhcpd.h:1252
int log_error(const char *,...) __attribute__((__format__(__printf__
struct hardware hto
Definition: ctrace.h:49
unsigned len
Definition: inet.h:32
u_int16_t from_port
Definition: ctrace.h:39
char name[IFNAMSIZ]
Definition: ctrace.h:33
struct in_addr primary_address
Definition: ctrace.h:30
int interface_count
Definition: discover.c:78
void trace_outpacket_stop(trace_type_t *)
void trace_inpacket_stop(trace_type_t *)
void trace_seed_stop(trace_type_t *)
u_int8_t havehfrom
Definition: ctrace.h:41
ssize_t trace_packet_send(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
void trace_inpacket_input(trace_type_t *, unsigned, char *)
unsigned len
Definition: trace.h:76
trace_type_t * inpacket_trace
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
Definition: discover.c:58
Definition: dhcpd.h:369
int(* dhcp_interface_discovery_hook)(struct interface_info *)
Definition: discover.c:49
u_int16_t to_port
Definition: ctrace.h:48
Definition: ip.h:47
int trace_record(void)
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
u_int8_t havehto
Definition: ctrace.h:50
struct hardware hw_address
Definition: dhcpd.h:1250
int int log_info(const char *,...) __attribute__((__format__(__printf__
void trace_seed_stash(trace_type_t *, unsigned)
void interface_snorf(struct interface_info *tmp, int ir)
Definition: discover.c:1485
int address_max
Definition: dhcpd.h:1256
Definition: inet.h:31
int quiet_interface_discovery
Definition: discover.c:45
int(* dhcp_interface_setup_hook)(struct interface_info *, struct iaddr *)
Definition: discover.c:48
u_int32_t index
Definition: ctrace.h:45
isc_result_t trace_write_packet(trace_type_t *, unsigned, const char *, const char *, int)
int address_count
Definition: dhcpd.h:1255
void trace_interface_input(trace_type_t *, unsigned, char *)
u_int32_t index
Definition: ctrace.h:37
void trace_inpacket_stash(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
struct hardware hw_address
Definition: ctrace.h:32
struct interface_info ** interface_vector
Definition: discover.c:77
void interface_stash(struct interface_info *tptr)
Definition: discover.c:1447
trace_type_t * outpacket_trace
void trace_seed_input(trace_type_t *, unsigned, char *)
struct ifreq * ifp
Definition: dhcpd.h:1282
void trace_interface_stop(trace_type_t *)
struct iaddr to
Definition: ctrace.h:47