ISC DHCP  4.3.6
A reference DHCPv4 and DHCPv6 implementation
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  if (!ip->addresses) {
88  dfree(ip->ifp, MDL);
89  ip->ifp = NULL;
90  interface_dereference (&ip, MDL);
91  status = ISC_R_NOMEMORY;
92  goto foo;
93  }
94  memcpy(ip->addresses, &tipkt->primary_address, sizeof(*ip->addresses));
95  memcpy (ip -> name, tipkt -> name, sizeof ip -> name);
96  ip -> index = ntohl (tipkt -> index);
97 
98  interface_snorf (ip, 0);
100  (*dhcp_interface_discovery_hook) (ip);
101 
102  /* Fake up an ifp. */
103  memcpy (ip -> ifp -> ifr_name, ip -> name, sizeof ip -> name);
104 #ifdef HAVE_SA_LEN
105  ip -> ifp -> ifr_addr.sa_len = sizeof (struct sockaddr_in);
106 #endif
107  sin = (struct sockaddr_in *)&ip -> ifp -> ifr_addr;
108  sin->sin_addr = ip->addresses[0];
109 
110  addr.len = 4;
111  memcpy (addr.iabuf, &sin -> sin_addr.s_addr, addr.len);
113  (*dhcp_interface_setup_hook) (ip, &addr);
114  interface_stash (ip);
115 
117  log_info ("Listening on Trace/%s/%s%s%s",
118  ip -> name,
119  print_hw_addr (ip -> hw_address.hbuf [0],
120  ip -> hw_address.hlen - 1,
121  &ip -> hw_address.hbuf [1]),
122  (ip -> shared_network ? "/" : ""),
123  (ip -> shared_network ?
124  ip -> shared_network -> name : ""));
125  if (strcmp (ip -> name, "fallback")) {
126  log_info ("Sending on Trace/%s/%s%s%s",
127  ip -> name,
128  print_hw_addr (ip -> hw_address.hbuf [0],
129  ip -> hw_address.hlen - 1,
130  &ip -> hw_address.hbuf [1]),
131  (ip -> shared_network ? "/" : ""),
132  (ip -> shared_network ?
133  ip -> shared_network -> name : ""));
134  }
135  }
136  interface_dereference (&ip, MDL);
137 }
138 
139 void trace_interface_stop (trace_type_t *ttype) {
140  /* XXX */
141 }
142 
143 void trace_inpacket_stash (struct interface_info *interface,
144  struct dhcp_packet *packet,
145  unsigned len,
146  unsigned int from_port,
147  struct iaddr from,
148  struct hardware *hfrom)
149 {
150  trace_inpacket_t tip;
151  trace_iov_t iov [2];
152 
153  if (!trace_record ())
154  return;
155  tip.from_port = from_port;
156  tip.from = from;
157  tip.from.len = htonl (tip.from.len);
158  if (hfrom) {
159  tip.hfrom = *hfrom;
160  tip.havehfrom = 1;
161  } else {
162  memset (&tip.hfrom, 0, sizeof tip.hfrom);
163  tip.havehfrom = 0;
164  }
165  tip.index = htonl (interface -> index);
166 
167  iov [0].buf = (char *)&tip;
168  iov [0].len = sizeof tip;
169  iov [1].buf = (char *)packet;
170  iov [1].len = len;
172 }
173 
174 void trace_inpacket_input (trace_type_t *ttype, unsigned len, char *buf)
175 {
176  trace_inpacket_t *tip;
177  int index;
178 
179  if (len < sizeof *tip) {
180  log_error ("trace_input_packet: too short - %d", len);
181  return;
182  }
183  tip = (trace_inpacket_t *)buf;
184  index = ntohl (tip -> index);
185  tip -> from.len = ntohl (tip -> from.len);
186 
187  if (index > interface_count ||
188  index < 0 ||
189  !interface_vector [index]) {
190  log_error ("trace_input_packet: unknown interface index %d",
191  index);
192  return;
193  }
194 
195  if (!bootp_packet_handler) {
196  log_error ("trace_input_packet: no bootp packet handler.");
197  return;
198  }
199 
200  (*bootp_packet_handler) (interface_vector [index],
201  (struct dhcp_packet *)(tip + 1),
202  len - sizeof *tip,
203  tip -> from_port,
204  tip -> from,
205  (tip -> havehfrom ?
206  &tip -> hfrom
207  : (struct hardware *)0));
208 }
209 
210 void trace_inpacket_stop (trace_type_t *ttype) { }
211 
212 ssize_t trace_packet_send (struct interface_info *interface,
213  struct packet *packet,
214  struct dhcp_packet *raw,
215  size_t len,
216  struct in_addr from,
217  struct sockaddr_in *to,
218  struct hardware *hto)
219 {
220  trace_outpacket_t tip;
221  trace_iov_t iov [2];
222 
223  if (trace_record ()) {
224  if (hto) {
225  tip.hto = *hto;
226  tip.havehto = 1;
227  } else {
228  memset (&tip.hto, 0, sizeof tip.hto);
229  tip.havehto = 0;
230  }
231  tip.from.len = 4;
232  memcpy (tip.from.iabuf, &from, 4);
233  tip.to.len = 4;
234  memcpy (tip.to.iabuf, &to -> sin_addr, 4);
235  tip.to_port = to -> sin_port;
236  tip.index = htonl (interface -> index);
237 
238  iov [0].buf = (char *)&tip;
239  iov [0].len = sizeof tip;
240  iov [1].buf = (char *)raw;
241  iov [1].len = len;
243  }
244  if (!trace_playback ()) {
245  return send_packet (interface, packet, raw, len,
246  from, to, hto);
247  }
248  return len;
249 }
250 
251 void trace_outpacket_input (trace_type_t *ttype, unsigned len, char *buf)
252 {
253  trace_outpacket_t *tip;
254  int index;
255 
256  if (len < sizeof *tip) {
257  log_error ("trace_input_packet: too short - %d", len);
258  return;
259  }
260  tip = (trace_outpacket_t *)buf;
261  index = ntohl (tip -> index);
262 
263  if (index > interface_count ||
264  index < 0 ||
265  !interface_vector [index]) {
266  log_error ("trace_input_packet: unknown interface index %d",
267  index);
268  return;
269  }
270 
271  /* XXX would be nice to somehow take notice of these. */
272 }
273 
274 void trace_outpacket_stop (trace_type_t *ttype) { }
275 
276 void trace_seed_stash (trace_type_t *ttype, unsigned seed)
277 {
278  u_int32_t outseed;
279  if (!trace_record ())
280  return;
281  outseed = htonl (seed);
282  trace_write_packet (ttype, sizeof outseed, (char *)&outseed, MDL);
283  return;
284 }
285 
286 void trace_seed_input (trace_type_t *ttype, unsigned length, char *buf)
287 {
288  u_int32_t *seed;
289 
290  if (length != sizeof seed) {
291  log_error ("trace_seed_input: wrong size (%d)", length);
292  }
293  seed = (u_int32_t *)buf;
294  srandom (ntohl (*seed));
295 }
296 
297 void trace_seed_stop (trace_type_t *ttype) { }
298 #endif /* TRACING */
const char * buf
Definition: trace.h:75
char name[IFNAMSIZ]
Definition: dhcpd.h:1375
void(* bootp_packet_handler)(struct interface_info *, struct dhcp_packet *, unsigned, unsigned int, struct iaddr, struct hardware *)
Definition: discover.c:58
struct iaddr from
Definition: ctrace.h:38
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 *)
struct in_addr * addresses
Definition: dhcpd.h:1355
int trace_playback(void)
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
Definition: dhcpd.h:405
isc_result_t trace_write_packet_iov(trace_type_t *, int, trace_iov_t *, const char *, int)
u_int16_t to_port
Definition: ctrace.h:48
Definition: ip.h:47
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
void dfree(void *, const char *, int)
Definition: alloc.c:145
u_int8_t havehto
Definition: ctrace.h:50
struct hardware hw_address
Definition: dhcpd.h:1353
int trace_record(void)
int int log_info(const char *,...) __attribute__((__format__(__printf__
void trace_seed_stash(trace_type_t *, unsigned)
void * dmalloc(size_t, const char *, int)
Definition: alloc.c:57
void interface_snorf(struct interface_info *tmp, int ir)
Definition: discover.c:1520
int address_max
Definition: dhcpd.h:1359
int(* dhcp_interface_setup_hook)(struct interface_info *, struct iaddr *)
Definition: discover.c:48
Definition: inet.h:31
int quiet_interface_discovery
Definition: discover.c:44
u_int32_t index
Definition: ctrace.h:45
int address_count
Definition: dhcpd.h:1358
int(* dhcp_interface_discovery_hook)(struct interface_info *)
Definition: discover.c:49
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 *)
isc_result_t trace_write_packet(trace_type_t *, unsigned, const char *, const char *, int)
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:1477
trace_type_t * outpacket_trace
void trace_seed_input(trace_type_t *, unsigned, char *)
struct ifreq * ifp
Definition: dhcpd.h:1385
void trace_interface_stop(trace_type_t *)
struct iaddr to
Definition: ctrace.h:47