]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/kdp_udp.c
xnu-1228.15.4.tar.gz
[apple/xnu.git] / osfmk / kdp / kdp_udp.c
1 /*
2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 /*
30 * Copyright (c) 1982, 1986, 1993
31 * The Regents of the University of California. All rights reserved.
32 */
33
34 /*
35 * Kernel Debugging Protocol UDP implementation.
36 */
37
38 #include <mach_kdb.h>
39 #include <mach/boolean.h>
40 #include <mach/mach_types.h>
41 #include <mach/exception_types.h>
42 #include <kern/cpu_data.h>
43 #include <kern/debug.h>
44 #include <kern/clock.h>
45
46 #include <kdp/kdp_core.h>
47 #include <kdp/kdp_internal.h>
48 #include <kdp/kdp_en_debugger.h>
49 #include <kdp/kdp_callout.h>
50 #include <kdp/kdp_udp.h>
51 #if CONFIG_SERIAL_KDP
52 #include <kdp/kdp_serial.h>
53 #endif
54
55 #include <vm/vm_map.h>
56 #include <vm/vm_protos.h>
57 #include <vm/vm_kern.h> /* kernel_map */
58
59 #include <mach/memory_object_types.h>
60
61 #include <string.h>
62
63 #define DO_ALIGN 1 /* align all packet data accesses */
64
65 extern int kdp_getc(void);
66 extern int reattach_wait;
67
68 extern int serial_getc(void);
69 extern void serial_putc(char);
70 extern int serial_init(void);
71
72 static u_short ip_id; /* ip packet ctr, for ids */
73
74 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
75
76 /*
77 * UDP protocol implementation.
78 * Per RFC 768, August, 1980.
79 */
80 #define UDP_TTL 60 /* deflt time to live for UDP packets */
81 int udp_ttl = UDP_TTL;
82 static unsigned char exception_seq;
83
84 static struct {
85 unsigned char data[KDP_MAXPACKET];
86 unsigned int off, len;
87 boolean_t input;
88 } pkt, saved_reply;
89
90 struct {
91 struct {
92 struct in_addr in;
93 struct ether_addr ea;
94 } loc;
95 struct {
96 struct in_addr in;
97 struct ether_addr ea;
98 } rmt;
99 } adr;
100
101 static const char
102 *exception_message[] = {
103 "Unknown",
104 "Memory access", /* EXC_BAD_ACCESS */
105 "Failed instruction", /* EXC_BAD_INSTRUCTION */
106 "Arithmetic", /* EXC_ARITHMETIC */
107 "Emulation", /* EXC_EMULATION */
108 "Software", /* EXC_SOFTWARE */
109 "Breakpoint" /* EXC_BREAKPOINT */
110 };
111
112 volatile int kdp_flag = 0;
113
114 static kdp_send_t kdp_en_send_pkt;
115 static kdp_receive_t kdp_en_recv_pkt;
116
117
118 static u_long kdp_current_ip_address = 0;
119 static struct ether_addr kdp_current_mac_address = {{0, 0, 0, 0, 0, 0}};
120 static void *kdp_current_ifp;
121
122 static void kdp_handler( void *);
123
124 static uint32_t panic_server_ip = 0;
125 static uint32_t parsed_router_ip = 0;
126 static uint32_t router_ip = 0;
127 static uint32_t target_ip = 0;
128
129 static volatile boolean_t panicd_specified = FALSE;
130 static boolean_t router_specified = FALSE;
131 static unsigned int panicd_port = CORE_REMOTE_PORT;
132
133 static struct ether_addr etherbroadcastaddr = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
134
135 static struct ether_addr router_mac = {{0, 0, 0 , 0, 0, 0}};
136 static struct ether_addr destination_mac = {{0, 0, 0 , 0, 0, 0}};
137 static struct ether_addr temp_mac = {{0, 0, 0 , 0, 0, 0}};
138 static struct ether_addr current_resolved_MAC = {{0, 0, 0 , 0, 0, 0}};
139
140 static boolean_t flag_panic_dump_in_progress = FALSE;
141 static boolean_t flag_router_mac_initialized = FALSE;
142
143 static boolean_t flag_arp_resolved = FALSE;
144
145 static unsigned int panic_timeout = 100000;
146 static unsigned int last_panic_port = CORE_REMOTE_PORT;
147
148 unsigned int SEGSIZE = 512;
149
150 __unused static unsigned int PANIC_PKTSIZE = 518;
151 static char panicd_ip_str[20];
152 static char router_ip_str[20];
153
154 static unsigned int panic_block = 0;
155 volatile unsigned int kdp_trigger_core_dump = 0;
156 __private_extern__ volatile unsigned int flag_kdp_trigger_reboot = 0;
157
158 extern unsigned int not_in_kdp;
159
160 extern unsigned int disableConsoleOutput;
161
162 extern int kdp_vm_read( caddr_t, caddr_t, unsigned int);
163 extern void kdp_call(void);
164 extern boolean_t kdp_call_kdb(void);
165 extern int kern_dump(void);
166
167 void * kdp_get_interface(void);
168 void kdp_set_gateway_mac(void *);
169 void kdp_set_ip_and_mac_addresses(struct in_addr *, struct ether_addr *);
170 void kdp_set_interface(void *);
171
172 void kdp_disable_arp(void);
173 static void kdp_arp_reply(struct ether_arp *);
174 static void kdp_process_arp_reply(struct ether_arp *);
175 static boolean_t kdp_arp_resolve(uint32_t, struct ether_addr *);
176
177 static volatile unsigned kdp_reentry_deadline;
178
179 static boolean_t gKDPDebug = FALSE;
180 #define KDP_DEBUG(...) if (gKDPDebug) printf(__VA_ARGS__);
181
182 int kdp_snapshot = 0;
183 static int stack_snapshot_ret = 0;
184 static unsigned stack_snapshot_bytes_traced = 0;
185
186 static void *stack_snapshot_buf;
187 static uint32_t stack_snapshot_bufsize;
188 static int stack_snapshot_pid;
189 static uint32_t stack_snapshot_options;
190
191 static unsigned int old_debugger;
192
193 void
194 kdp_snapshot_preflight(int pid, void * tracebuf, uint32_t tracebuf_size,
195 uint32_t options);
196
197 void
198 kdp_snapshot_postflight(void);
199
200 extern int
201 kdp_stackshot(int pid, void *tracebuf, uint32_t tracebuf_size,
202 unsigned trace_options, uint32_t *pbytesTraced);
203
204 int
205 kdp_stack_snapshot_geterror(void);
206
207 int
208 kdp_stack_snapshot_bytes_traced(void);
209
210 static thread_call_t
211 kdp_timer_call;
212
213 static void
214 kdp_ml_enter_debugger_wrapper(__unused void *param0, __unused void *param1) {
215 kdp_ml_enter_debugger();
216 }
217
218 static void
219 kdp_timer_callout_init(void) {
220 kdp_timer_call = thread_call_allocate(kdp_ml_enter_debugger_wrapper, NULL);
221 }
222
223
224 void
225 kdp_register_send_receive(
226 kdp_send_t send,
227 kdp_receive_t receive)
228 {
229 unsigned int debug = 0;
230
231 debug_log_init();
232
233 kdp_timer_callout_init();
234
235 PE_parse_boot_argn("debug", &debug, sizeof (debug));
236
237
238 if (!debug)
239 return;
240
241 kdp_en_send_pkt = send;
242 kdp_en_recv_pkt = receive;
243
244 if (debug & DB_KDP_BP_DIS)
245 kdp_flag |= KDP_BP_DIS;
246 if (debug & DB_KDP_GETC_ENA)
247 kdp_flag |= KDP_GETC_ENA;
248 if (debug & DB_ARP)
249 kdp_flag |= KDP_ARP;
250
251 if (debug & DB_KERN_DUMP_ON_PANIC)
252 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
253 if (debug & DB_KERN_DUMP_ON_NMI)
254 kdp_flag |= PANIC_CORE_ON_NMI;
255
256 if (debug & DB_DBG_POST_CORE)
257 kdp_flag |= DBG_POST_CORE;
258
259 if (debug & DB_PANICLOG_DUMP)
260 kdp_flag |= PANIC_LOG_DUMP;
261
262 if (PE_parse_boot_argn("_panicd_ip", panicd_ip_str, sizeof (panicd_ip_str)))
263 panicd_specified = TRUE;
264
265 if (PE_parse_boot_argn("_router_ip", router_ip_str, sizeof (router_ip_str)))
266 router_specified = TRUE;
267
268 if (!PE_parse_boot_argn("panicd_port", &panicd_port, sizeof (panicd_port)))
269 panicd_port = CORE_REMOTE_PORT;
270
271 kdp_flag |= KDP_READY;
272 if (current_debugger == NO_CUR_DB)
273 current_debugger = KDP_CUR_DB;
274 if ((kdp_current_ip_address != 0) && halt_in_debugger) {
275 kdp_call();
276 halt_in_debugger=0;
277 }
278 }
279
280 void
281 kdp_unregister_send_receive(
282 __unused kdp_send_t send,
283 __unused kdp_receive_t receive)
284 {
285 if (current_debugger == KDP_CUR_DB)
286 current_debugger = NO_CUR_DB;
287 kdp_flag &= ~KDP_READY;
288 kdp_en_send_pkt = NULL;
289 kdp_en_recv_pkt = NULL;
290 }
291
292 /* Cache stack snapshot parameters in preparation for a trace */
293 void
294 kdp_snapshot_preflight(int pid, void * tracebuf, uint32_t tracebuf_size, uint32_t options)
295 {
296 stack_snapshot_pid = pid;
297 stack_snapshot_buf = tracebuf;
298 stack_snapshot_bufsize = tracebuf_size;
299 stack_snapshot_options = options;
300 kdp_snapshot++;
301 /* Mark this debugger as active, since the polled mode driver that
302 * ordinarily does this may not be enabled (yet), or since KDB may be
303 * the primary debugger.
304 */
305 old_debugger = current_debugger;
306 if (old_debugger != KDP_CUR_DB) {
307 current_debugger = KDP_CUR_DB;
308 }
309 }
310
311 void
312 kdp_snapshot_postflight(void)
313 {
314 kdp_snapshot--;
315 if ((kdp_en_send_pkt == NULL) || (old_debugger == KDB_CUR_DB))
316 current_debugger = old_debugger;
317 }
318
319 int
320 kdp_stack_snapshot_geterror(void)
321 {
322 return stack_snapshot_ret;
323 }
324
325 int
326 kdp_stack_snapshot_bytes_traced(void)
327 {
328 return stack_snapshot_bytes_traced;
329 }
330
331 static void
332 kdp_schedule_debugger_reentry(unsigned interval) {
333 uint64_t deadline;;
334
335 clock_interval_to_deadline(interval, 1000 * 1000, &deadline);
336 thread_call_enter_delayed(kdp_timer_call, deadline);
337 }
338
339 static void
340 enaddr_copy(
341 void *src,
342 void *dst
343 )
344 {
345 bcopy((char *)src, (char *)dst, sizeof (struct ether_addr));
346 }
347
348 static unsigned short
349 ip_sum(
350 unsigned char *c,
351 unsigned int hlen
352 )
353 {
354 unsigned int high, low, sum;
355
356 high = low = 0;
357 while (hlen-- > 0) {
358 low += c[1] + c[3];
359 high += c[0] + c[2];
360
361 c += sizeof (int);
362 }
363
364 sum = (high << 8) + low;
365 sum = (sum >> 16) + (sum & 65535);
366
367 return (sum > 65535 ? sum - 65535 : sum);
368 }
369
370 static void
371 kdp_reply(
372 unsigned short reply_port
373 )
374 {
375 struct udpiphdr aligned_ui, *ui = &aligned_ui;
376 struct ip aligned_ip, *ip = &aligned_ip;
377 struct in_addr tmp_ipaddr;
378 struct ether_addr tmp_enaddr;
379 struct ether_header *eh = NULL;
380
381 if (!pkt.input)
382 kdp_panic("kdp_reply");
383
384 pkt.off -= sizeof (struct udpiphdr);
385
386 #if DO_ALIGN
387 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
388 #else
389 ui = (struct udpiphdr *)&pkt.data[pkt.off];
390 #endif
391 ui->ui_next = ui->ui_prev = NULL;
392 ui->ui_x1 = 0;
393 ui->ui_pr = IPPROTO_UDP;
394 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
395 tmp_ipaddr = ui->ui_src;
396 ui->ui_src = ui->ui_dst;
397 ui->ui_dst = tmp_ipaddr;
398 ui->ui_sport = htons(KDP_REMOTE_PORT);
399 ui->ui_dport = reply_port;
400 ui->ui_ulen = ui->ui_len;
401 ui->ui_sum = 0;
402 #if DO_ALIGN
403 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
404 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
405 #else
406 ip = (struct ip *)&pkt.data[pkt.off];
407 #endif
408 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
409 ip->ip_v = IPVERSION;
410 ip->ip_id = htons(ip_id++);
411 ip->ip_hl = sizeof (struct ip) >> 2;
412 ip->ip_ttl = udp_ttl;
413 ip->ip_sum = 0;
414 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
415 #if DO_ALIGN
416 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
417 #endif
418
419 pkt.len += sizeof (struct udpiphdr);
420
421 pkt.off -= sizeof (struct ether_header);
422
423 eh = (struct ether_header *)&pkt.data[pkt.off];
424 enaddr_copy(eh->ether_shost, &tmp_enaddr);
425 enaddr_copy(eh->ether_dhost, eh->ether_shost);
426 enaddr_copy(&tmp_enaddr, eh->ether_dhost);
427 eh->ether_type = htons(ETHERTYPE_IP);
428
429 pkt.len += sizeof (struct ether_header);
430
431 // save reply for possible retransmission
432 bcopy((char *)&pkt, (char *)&saved_reply, sizeof(pkt));
433
434 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
435
436 // increment expected sequence number
437 exception_seq++;
438 }
439
440 static void
441 kdp_send(
442 unsigned short remote_port
443 )
444 {
445 struct udpiphdr aligned_ui, *ui = &aligned_ui;
446 struct ip aligned_ip, *ip = &aligned_ip;
447 struct ether_header *eh;
448
449 if (pkt.input)
450 kdp_panic("kdp_send");
451
452 pkt.off -= sizeof (struct udpiphdr);
453
454 #if DO_ALIGN
455 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
456 #else
457 ui = (struct udpiphdr *)&pkt.data[pkt.off];
458 #endif
459 ui->ui_next = ui->ui_prev = NULL;
460 ui->ui_x1 = 0;
461 ui->ui_pr = IPPROTO_UDP;
462 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
463 ui->ui_src = adr.loc.in;
464 ui->ui_dst = adr.rmt.in;
465 ui->ui_sport = htons(KDP_REMOTE_PORT);
466 ui->ui_dport = remote_port;
467 ui->ui_ulen = ui->ui_len;
468 ui->ui_sum = 0;
469 #if DO_ALIGN
470 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
471 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
472 #else
473 ip = (struct ip *)&pkt.data[pkt.off];
474 #endif
475 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
476 ip->ip_v = IPVERSION;
477 ip->ip_id = htons(ip_id++);
478 ip->ip_hl = sizeof (struct ip) >> 2;
479 ip->ip_ttl = udp_ttl;
480 ip->ip_sum = 0;
481 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
482 #if DO_ALIGN
483 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
484 #endif
485
486 pkt.len += sizeof (struct udpiphdr);
487
488 pkt.off -= sizeof (struct ether_header);
489
490 eh = (struct ether_header *)&pkt.data[pkt.off];
491 enaddr_copy(&adr.loc.ea, eh->ether_shost);
492 enaddr_copy(&adr.rmt.ea, eh->ether_dhost);
493 eh->ether_type = htons(ETHERTYPE_IP);
494
495 pkt.len += sizeof (struct ether_header);
496 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
497 }
498
499 /* We don't interpret this pointer, we just give it to the
500 bsd stack so it can decide when to set the MAC and IP info. */
501 void
502 kdp_set_interface(void *ifp)
503 {
504 kdp_current_ifp = ifp;
505 }
506
507 void *
508 kdp_get_interface(void)
509 {
510 return kdp_current_ifp;
511 }
512
513 void
514 kdp_set_ip_and_mac_addresses(
515 struct in_addr *ipaddr,
516 struct ether_addr *macaddr)
517 {
518 kdp_current_ip_address = ipaddr->s_addr;
519 kdp_current_mac_address = *macaddr;
520 if ((current_debugger == KDP_CUR_DB) && halt_in_debugger) {
521 kdp_call();
522 halt_in_debugger=0;
523 }
524 }
525
526 void
527 kdp_set_gateway_mac(void *gatewaymac)
528 {
529 router_mac = *(struct ether_addr *)gatewaymac;
530 flag_router_mac_initialized = TRUE;
531 }
532
533 struct ether_addr
534 kdp_get_mac_addr(void)
535 {
536 return kdp_current_mac_address;
537 }
538
539 unsigned int
540 kdp_get_ip_address(void)
541 {
542 return kdp_current_ip_address;
543 }
544
545 void
546 kdp_disable_arp(void)
547 {
548 kdp_flag &= ~(DB_ARP);
549 }
550
551 static void
552 kdp_arp_dispatch(void)
553 {
554 struct ether_arp aligned_ea, *ea = &aligned_ea;
555 unsigned arp_header_offset;
556
557 arp_header_offset = sizeof(struct ether_header) + pkt.off;
558 memcpy((void *)ea, (void *)&pkt.data[arp_header_offset], sizeof(*ea));
559
560 switch(ntohs(ea->arp_op)) {
561 case ARPOP_REQUEST:
562 kdp_arp_reply(ea);
563 break;
564 case ARPOP_REPLY:
565 kdp_process_arp_reply(ea);
566 break;
567 default:
568 return;
569 }
570 }
571
572 static void
573 kdp_process_arp_reply(struct ether_arp *ea)
574 {
575 /* Are we interested in ARP replies? */
576 if (flag_arp_resolved == TRUE)
577 return;
578
579 /* Did we receive a reply from the right source? */
580 if (((struct in_addr *)(ea->arp_spa))->s_addr != target_ip)
581 return;
582
583 flag_arp_resolved = TRUE;
584 current_resolved_MAC = *(struct ether_addr *) (ea->arp_sha);
585
586 return;
587 }
588
589 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
590 * is set.
591 */
592
593 static void
594 kdp_arp_reply(struct ether_arp *ea)
595 {
596 struct ether_header *eh;
597
598 struct in_addr isaddr, itaddr, myaddr;
599 struct ether_addr my_enaddr;
600
601 eh = (struct ether_header *)&pkt.data[pkt.off];
602 pkt.off += sizeof(struct ether_header);
603
604 if(ntohs(ea->arp_op) != ARPOP_REQUEST)
605 return;
606
607 myaddr.s_addr = kdp_get_ip_address();
608 my_enaddr = kdp_get_mac_addr();
609
610 if ((ntohl(myaddr.s_addr) == 0) ||
611 ((my_enaddr.ether_addr_octet[0] & 0xff) == 0
612 && (my_enaddr.ether_addr_octet[1] & 0xff) == 0
613 && (my_enaddr.ether_addr_octet[2] & 0xff) == 0
614 && (my_enaddr.ether_addr_octet[3] & 0xff) == 0
615 && (my_enaddr.ether_addr_octet[4] & 0xff) == 0
616 && (my_enaddr.ether_addr_octet[5] & 0xff) == 0
617 ))
618 return;
619
620 (void)memcpy((void *)&isaddr, (void *)ea->arp_spa, sizeof (isaddr));
621 (void)memcpy((void *)&itaddr, (void *)ea->arp_tpa, sizeof (itaddr));
622
623 if (itaddr.s_addr == myaddr.s_addr) {
624 (void)memcpy((void *)ea->arp_tha, (void *)ea->arp_sha, sizeof(ea->arp_sha));
625 (void)memcpy((void *)ea->arp_sha, (void *)&my_enaddr, sizeof(ea->arp_sha));
626
627 (void)memcpy((void *)ea->arp_tpa, (void *) ea->arp_spa, sizeof(ea->arp_spa));
628 (void)memcpy((void *)ea->arp_spa, (void *) &itaddr, sizeof(ea->arp_spa));
629
630 ea->arp_op = htons(ARPOP_REPLY);
631 ea->arp_pro = htons(ETHERTYPE_IP);
632 (void)memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
633 (void)memcpy(eh->ether_shost, &my_enaddr, sizeof(eh->ether_shost));
634 eh->ether_type = htons(ETHERTYPE_ARP);
635 (void)memcpy(&pkt.data[pkt.off], ea, sizeof(*ea));
636 pkt.off -= sizeof (struct ether_header);
637 /* pkt.len is still the length we want, ether_header+ether_arp */
638 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
639 }
640 }
641
642 static void
643 kdp_poll(void)
644 {
645 struct ether_header *eh = NULL;
646 struct udpiphdr aligned_ui, *ui = &aligned_ui;
647 struct ip aligned_ip, *ip = &aligned_ip;
648 static int msg_printed;
649
650 if (pkt.input)
651 kdp_panic("kdp_poll");
652
653 if (!kdp_en_recv_pkt || !kdp_en_send_pkt) {
654 if( msg_printed == 0) {
655 msg_printed = 1;
656 printf("kdp_poll: no debugger device\n");
657 }
658 return;
659 }
660
661 pkt.off = pkt.len = 0;
662 (*kdp_en_recv_pkt)(pkt.data, &pkt.len, 3/* ms */);
663
664 if (pkt.len == 0)
665 return;
666
667 if (pkt.len >= sizeof(struct ether_header))
668 {
669 eh = (struct ether_header *)&pkt.data[pkt.off];
670
671 if (kdp_flag & KDP_ARP)
672 {
673 if (ntohs(eh->ether_type) == ETHERTYPE_ARP)
674 {
675 kdp_arp_dispatch();
676 return;
677 }
678 }
679 }
680
681 if (pkt.len < (sizeof (struct ether_header) + sizeof (struct udpiphdr)))
682 return;
683
684 pkt.off += sizeof (struct ether_header);
685 if (ntohs(eh->ether_type) != ETHERTYPE_IP) {
686 return;
687 }
688
689 #if DO_ALIGN
690 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
691 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
692 #else
693 ui = (struct udpiphdr *)&pkt.data[pkt.off];
694 ip = (struct ip *)&pkt.data[pkt.off];
695 #endif
696
697 pkt.off += sizeof (struct udpiphdr);
698 if (ui->ui_pr != IPPROTO_UDP) {
699 return;
700 }
701
702 if (ip->ip_hl > (sizeof (struct ip) >> 2)) {
703 return;
704 }
705
706 if (ntohs(ui->ui_dport) != KDP_REMOTE_PORT) {
707 if (panicd_port == (ntohs(ui->ui_dport)) &&
708 flag_panic_dump_in_progress) {
709 last_panic_port = ui->ui_sport;
710 }
711 else
712 return;
713 }
714 /* If we receive a kernel debugging packet whilst a
715 * core dump is in progress, abort the transfer and
716 * enter the debugger.
717 */
718 else
719 if (flag_panic_dump_in_progress)
720 {
721 abort_panic_transfer();
722 return;
723 }
724
725 if (!kdp.is_conn && !flag_panic_dump_in_progress) {
726 enaddr_copy(eh->ether_dhost, &adr.loc.ea);
727 adr.loc.in = ui->ui_dst;
728
729 enaddr_copy(eh->ether_shost, &adr.rmt.ea);
730 adr.rmt.in = ui->ui_src;
731 }
732
733 /*
734 * Calculate kdp packet length.
735 */
736 pkt.len = ntohs((u_short)ui->ui_ulen) - sizeof (struct udphdr);
737 pkt.input = TRUE;
738 }
739
740 /* Create and transmit an ARP resolution request for the target IP address.
741 * This is modeled on ether_inet_arp()/RFC 826.
742 */
743
744 static void
745 transmit_ARP_request(uint32_t ip_addr)
746 {
747 struct ether_header *eh = (struct ether_header *) &pkt.data[0];
748 struct ether_arp *ea = (struct ether_arp *) &pkt.data[sizeof(struct ether_header)];
749
750 KDP_DEBUG("Transmitting ARP request\n");
751 /* Populate the ether_header */
752 eh->ether_type = htons(ETHERTYPE_ARP);
753 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
754 enaddr_copy(&etherbroadcastaddr, eh->ether_dhost);
755
756 /* Populate the ARP header */
757 ea->arp_pro = htons(ETHERTYPE_IP);
758 ea->arp_hln = sizeof(ea->arp_sha);
759 ea->arp_pln = sizeof(ea->arp_spa);
760 ea->arp_hrd = htons(ARPHRD_ETHER);
761 ea->arp_op = htons(ARPOP_REQUEST);
762
763 /* Target fields */
764 enaddr_copy(&etherbroadcastaddr, ea->arp_tha);
765 memcpy(ea->arp_tpa, (void *) &ip_addr, sizeof(ip_addr));
766
767 /* Source fields */
768 enaddr_copy(&kdp_current_mac_address, ea->arp_sha);
769 memcpy(ea->arp_spa, (void *) &kdp_current_ip_address, sizeof(kdp_current_ip_address));
770
771 pkt.off = 0;
772 pkt.len = sizeof(struct ether_header) + sizeof(struct ether_arp);
773 /* Transmit */
774 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
775 }
776
777 static boolean_t
778 kdp_arp_resolve(uint32_t arp_target_ip, struct ether_addr *resolved_MAC)
779 {
780 int poll_count = 256; /* ~770 ms modulo broadcast/delayed traffic? */
781 char tretries = 0;
782
783 #define NUM_ARP_TX_RETRIES 5
784
785 target_ip = arp_target_ip;
786 flag_arp_resolved = FALSE;
787
788 TRANSMIT_RETRY:
789 pkt.off = pkt.len = 0;
790
791 tretries++;
792
793 if (tretries >= NUM_ARP_TX_RETRIES) {
794 return FALSE;
795 }
796
797 KDP_DEBUG("ARP TX attempt #%d \n", tretries);
798
799 transmit_ARP_request(arp_target_ip);
800
801 while (!pkt.input && !flag_arp_resolved && flag_panic_dump_in_progress && --poll_count) {
802 kdp_poll();
803 }
804
805 if (flag_arp_resolved) {
806 *resolved_MAC = current_resolved_MAC;
807 return TRUE;
808 }
809
810 if (!flag_panic_dump_in_progress || pkt.input) /* we received a debugging packet, bail*/
811 {
812 printf("Received a debugger packet,transferring control to debugger\n");
813 /* Indicate that we should wait in the debugger when we return */
814 kdp_flag |= DBG_POST_CORE;
815 pkt.input = FALSE;
816 return FALSE;
817 }
818 else /* We timed out */
819 if (0 == poll_count) {
820 poll_count = 256;
821 goto TRANSMIT_RETRY;
822 }
823 return FALSE;
824 }
825
826 static void
827 kdp_handler(
828 void *saved_state
829 )
830 {
831 unsigned short reply_port;
832 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
833
834 kdp.saved_state = saved_state; // see comment in kdp_raise_exception
835
836 do {
837 while (!pkt.input)
838 kdp_poll();
839
840 #if DO_ALIGN
841 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
842 #else
843 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
844 #endif
845
846 // ignore replies -- we're not expecting them anyway.
847 if (hdr->is_reply) {
848 goto again;
849 }
850
851 if (hdr->request == KDP_REATTACH)
852 exception_seq = hdr->seq;
853
854 // check for retransmitted request
855 if (hdr->seq == (exception_seq - 1)) {
856 /* retransmit last reply */
857 (*kdp_en_send_pkt)(&saved_reply.data[saved_reply.off],
858 saved_reply.len);
859 goto again;
860 } else if (hdr->seq != exception_seq) {
861 printf("kdp: bad sequence %d (want %d)\n",
862 hdr->seq, exception_seq);
863 goto again;
864 }
865
866 if (kdp_packet((unsigned char*)&pkt.data[pkt.off],
867 (int *)&pkt.len,
868 (unsigned short *)&reply_port)) {
869 kdp_reply(reply_port);
870 }
871
872 again:
873 pkt.input = FALSE;
874 } while (kdp.is_halted);
875 }
876
877 static void
878 kdp_connection_wait(void)
879 {
880 unsigned short reply_port;
881 struct ether_addr kdp_mac_addr = kdp_get_mac_addr();
882 unsigned int ip_addr = ntohl(kdp_get_ip_address());
883
884 /*
885 * Do both a printf() and a kprintf() of the MAC and IP so that
886 * they will print out on headless machines but not be added to
887 * the panic.log
888 */
889
890 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
891 kdp_mac_addr.ether_addr_octet[0] & 0xff,
892 kdp_mac_addr.ether_addr_octet[1] & 0xff,
893 kdp_mac_addr.ether_addr_octet[2] & 0xff,
894 kdp_mac_addr.ether_addr_octet[3] & 0xff,
895 kdp_mac_addr.ether_addr_octet[4] & 0xff,
896 kdp_mac_addr.ether_addr_octet[5] & 0xff);
897
898 kprintf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
899 kdp_mac_addr.ether_addr_octet[0] & 0xff,
900 kdp_mac_addr.ether_addr_octet[1] & 0xff,
901 kdp_mac_addr.ether_addr_octet[2] & 0xff,
902 kdp_mac_addr.ether_addr_octet[3] & 0xff,
903 kdp_mac_addr.ether_addr_octet[4] & 0xff,
904 kdp_mac_addr.ether_addr_octet[5] & 0xff);
905
906 printf( "ip address: %d.%d.%d.%d\n",
907 (ip_addr & 0xff000000) >> 24,
908 (ip_addr & 0xff0000) >> 16,
909 (ip_addr & 0xff00) >> 8,
910 (ip_addr & 0xff));
911
912 kprintf( "ip address: %d.%d.%d.%d\n",
913 (ip_addr & 0xff000000) >> 24,
914 (ip_addr & 0xff0000) >> 16,
915 (ip_addr & 0xff00) >> 8,
916 (ip_addr & 0xff));
917
918 printf("\nWaiting for remote debugger connection.\n");
919
920
921 if (reattach_wait == 0) {
922 if((kdp_flag & KDP_GETC_ENA) && (0 != kdp_getc()))
923 {
924 printf("Options..... Type\n");
925 printf("------------ ----\n");
926 printf("continue.... 'c'\n");
927 printf("reboot...... 'r'\n");
928 #if MACH_KDB
929 printf("enter kdb... 'k'\n");
930 #endif
931 }
932 } else
933 reattach_wait = 0;
934
935 exception_seq = 0;
936
937 do {
938 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
939
940 while (!pkt.input) {
941 if (kdp_flag & KDP_GETC_ENA) {
942 switch(kdp_getc()) {
943 case 'c':
944 printf("Continuing...\n");
945 return;
946 case 'r':
947 printf("Rebooting...\n");
948 kdp_reboot();
949 break;
950 #if MACH_KDB
951 case 'k':
952 printf("calling kdb...\n");
953 if (kdp_call_kdb())
954 return;
955 else
956 printf("not implemented...\n");
957 #endif
958 default:
959 break;
960 }
961 }
962 kdp_poll();
963 }
964
965 #if DO_ALIGN
966 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
967 #else
968 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
969 #endif
970 if (hdr->request == KDP_HOSTREBOOT) {
971 kdp_reboot();
972 /* should not return! */
973 }
974 if (((hdr->request == KDP_CONNECT) || (hdr->request == KDP_REATTACH)) &&
975 !hdr->is_reply && (hdr->seq == exception_seq)) {
976 if (kdp_packet((unsigned char *)&pkt.data[pkt.off],
977 (int *)&pkt.len,
978 (unsigned short *)&reply_port))
979 kdp_reply(reply_port);
980 if (hdr->request == KDP_REATTACH) {
981 reattach_wait = 0;
982 hdr->request=KDP_DISCONNECT;
983 exception_seq = 0;
984 }
985 }
986
987 pkt.input = FALSE;
988 } while (!kdp.is_conn);
989
990 if (current_debugger == KDP_CUR_DB)
991 active_debugger=1;
992 printf("Connected to remote debugger.\n");
993 }
994
995 static void
996 kdp_send_exception(
997 unsigned int exception,
998 unsigned int code,
999 unsigned int subcode
1000 )
1001 {
1002 unsigned short remote_port;
1003 unsigned int timeout_count = 100;
1004 unsigned int poll_timeout;
1005
1006 do {
1007 pkt.off = sizeof (struct ether_header) + sizeof (struct udpiphdr);
1008 kdp_exception((unsigned char *)&pkt.data[pkt.off],
1009 (int *)&pkt.len,
1010 (unsigned short *)&remote_port,
1011 (unsigned int)exception,
1012 (unsigned int)code,
1013 (unsigned int)subcode);
1014
1015 kdp_send(remote_port);
1016
1017 poll_timeout = 50;
1018 while(!pkt.input && poll_timeout)
1019 {
1020 kdp_poll();
1021 poll_timeout--;
1022 }
1023
1024 if (pkt.input) {
1025 if (!kdp_exception_ack(&pkt.data[pkt.off], pkt.len)) {
1026 pkt.input = FALSE;
1027 }
1028 }
1029
1030 pkt.input = FALSE;
1031
1032 if (kdp.exception_ack_needed)
1033 kdp_us_spin(250000);
1034
1035 } while (kdp.exception_ack_needed && timeout_count--);
1036
1037 if (kdp.exception_ack_needed) {
1038 // give up & disconnect
1039 printf("kdp: exception ack timeout\n");
1040 if (current_debugger == KDP_CUR_DB)
1041 active_debugger=0;
1042 kdp_reset();
1043 }
1044 }
1045
1046 void
1047 kdp_raise_exception(
1048 unsigned int exception,
1049 unsigned int code,
1050 unsigned int subcode,
1051 void *saved_state
1052 )
1053 {
1054 int index;
1055
1056 /* Was a system trace requested ? */
1057 if (kdp_snapshot && (!panic_active()) && (panic_caller == 0)) {
1058 stack_snapshot_ret = kdp_stackshot(stack_snapshot_pid,
1059 stack_snapshot_buf, stack_snapshot_bufsize,
1060 stack_snapshot_options, &stack_snapshot_bytes_traced);
1061 return;
1062 }
1063
1064 disable_preemption();
1065
1066 if (saved_state == 0)
1067 printf("kdp_raise_exception with NULL state\n");
1068
1069 index = exception;
1070 if (exception != EXC_BREAKPOINT) {
1071 if (exception > EXC_BREAKPOINT || exception < EXC_BAD_ACCESS) {
1072 index = 0;
1073 }
1074 printf("%s exception (%x,%x,%x)\n",
1075 exception_message[index],
1076 exception, code, subcode);
1077 }
1078
1079 kdp_sync_cache();
1080
1081 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
1082 * do this. I think the client and the host can get out of sync.
1083 */
1084 kdp.saved_state = saved_state;
1085 kdp.kdp_cpu = cpu_number();
1086 kdp.kdp_thread = current_thread();
1087
1088 if (pkt.input)
1089 kdp_panic("kdp_raise_exception");
1090
1091
1092 if (((kdp_flag & KDP_PANIC_DUMP_ENABLED) || (kdp_flag & PANIC_LOG_DUMP))
1093 && (panicstr != (char *) 0)) {
1094
1095 kdp_panic_dump();
1096 }
1097 else
1098 if ((kdp_flag & PANIC_CORE_ON_NMI) && (panicstr == (char *) 0) &&
1099 !kdp.is_conn) {
1100
1101 disable_debug_output = disableConsoleOutput = FALSE;
1102 kdp_panic_dump();
1103
1104 if (!(kdp_flag & DBG_POST_CORE))
1105 goto exit_raise_exception;
1106 }
1107
1108 again:
1109 if (!kdp.is_conn)
1110 kdp_connection_wait();
1111 else {
1112 kdp_send_exception(exception, code, subcode);
1113 if (kdp.exception_ack_needed) {
1114 kdp.exception_ack_needed = FALSE;
1115 kdp_remove_all_breakpoints();
1116 printf("Remote debugger disconnected.\n");
1117 }
1118 }
1119
1120 if (kdp.is_conn) {
1121 kdp.is_halted = TRUE; /* XXX */
1122 kdp_handler(saved_state);
1123 if (!kdp.is_conn)
1124 {
1125 kdp_remove_all_breakpoints();
1126 printf("Remote debugger disconnected.\n");
1127 }
1128 }
1129 /* Allow triggering a panic core dump when connected to the machine
1130 * Continuing after setting kdp_trigger_core_dump should do the
1131 * trick.
1132 */
1133
1134 if (1 == kdp_trigger_core_dump) {
1135 kdp_flag &= ~PANIC_LOG_DUMP;
1136 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
1137 kdp_panic_dump();
1138 kdp_trigger_core_dump = 0;
1139 }
1140
1141 /* Trigger a reboot if the user has set this flag through the
1142 * debugger.Ideally, this would be done through the HOSTREBOOT packet
1143 * in the protocol,but that will need gdb support,and when it's
1144 * available, it should work automatically.
1145 */
1146 if (1 == flag_kdp_trigger_reboot) {
1147 kdp_reboot();
1148 /* If we're still around, reset the flag */
1149 flag_kdp_trigger_reboot = 0;
1150 }
1151
1152 if (kdp_reentry_deadline) {
1153 kdp_schedule_debugger_reentry(kdp_reentry_deadline);
1154 printf("Debugger re-entry scheduled in %d milliseconds\n", kdp_reentry_deadline);
1155 kdp_reentry_deadline = 0;
1156 }
1157
1158 kdp_sync_cache();
1159
1160 if (reattach_wait == 1)
1161 goto again;
1162
1163 exit_raise_exception:
1164 enable_preemption();
1165 }
1166
1167 void
1168 kdp_reset(void)
1169 {
1170 kdp.reply_port = kdp.exception_port = 0;
1171 kdp.is_halted = kdp.is_conn = FALSE;
1172 kdp.exception_seq = kdp.conn_seq = 0;
1173 }
1174
1175 struct corehdr *
1176 create_panic_header(unsigned int request, const char *corename,
1177 unsigned length, unsigned int block)
1178 {
1179 struct udpiphdr aligned_ui, *ui = &aligned_ui;
1180 struct ip aligned_ip, *ip = &aligned_ip;
1181 struct ether_header *eh;
1182 struct corehdr *coreh;
1183 const char *mode = "octet";
1184 char modelen = strlen(mode);
1185
1186 pkt.off = sizeof (struct ether_header);
1187 pkt.len = length + ((request == KDP_WRQ) ? modelen : 0) +
1188 (corename ? strlen(corename): 0) + sizeof(struct corehdr);
1189
1190 #if DO_ALIGN
1191 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
1192 #else
1193 ui = (struct udpiphdr *)&pkt.data[pkt.off];
1194 #endif
1195 ui->ui_next = ui->ui_prev = NULL;
1196 ui->ui_x1 = 0;
1197 ui->ui_pr = IPPROTO_UDP;
1198 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
1199 ui->ui_src.s_addr = kdp_current_ip_address;
1200 /* Already in network byte order via inet_aton() */
1201 ui->ui_dst.s_addr = panic_server_ip;
1202 ui->ui_sport = htons(panicd_port);
1203 ui->ui_dport = ((request == KDP_WRQ) ? htons(panicd_port) : last_panic_port);
1204 ui->ui_ulen = ui->ui_len;
1205 ui->ui_sum = 0;
1206 #if DO_ALIGN
1207 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
1208 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
1209 #else
1210 ip = (struct ip *)&pkt.data[pkt.off];
1211 #endif
1212 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
1213 ip->ip_v = IPVERSION;
1214 ip->ip_id = htons(ip_id++);
1215 ip->ip_hl = sizeof (struct ip) >> 2;
1216 ip->ip_ttl = udp_ttl;
1217 ip->ip_sum = 0;
1218 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
1219 #if DO_ALIGN
1220 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
1221 #endif
1222
1223 pkt.len += sizeof (struct udpiphdr);
1224
1225 pkt.off += sizeof (struct udpiphdr);
1226
1227 coreh = (struct corehdr *) &pkt.data[pkt.off];
1228 coreh->th_opcode = htons((u_short)request);
1229
1230 if (request == KDP_WRQ)
1231 {
1232 char *cp;
1233
1234 cp = coreh->th_u.tu_rpl;
1235 cp += strlcpy (cp, corename, KDP_MAXPACKET);
1236 *cp++ = '\0';
1237 cp += strlcpy (cp, mode, KDP_MAXPACKET - strlen(corename));
1238 *cp++ = '\0';
1239 }
1240 else
1241 {
1242 coreh->th_block = htonl((unsigned int) block);
1243 }
1244
1245 pkt.off -= sizeof (struct udpiphdr);
1246 pkt.off -= sizeof (struct ether_header);
1247
1248 eh = (struct ether_header *)&pkt.data[pkt.off];
1249 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
1250 enaddr_copy(&destination_mac, eh->ether_dhost);
1251 eh->ether_type = htons(ETHERTYPE_IP);
1252
1253 pkt.len += sizeof (struct ether_header);
1254 return coreh;
1255 }
1256
1257 int kdp_send_crashdump_data(unsigned int request, char *corename,
1258 unsigned int length, caddr_t txstart)
1259 {
1260 caddr_t txend = txstart + length;
1261 int panic_error = 0;
1262
1263 if (length <= SEGSIZE) {
1264 if ((panic_error = kdp_send_crashdump_pkt(request, corename, length, (caddr_t) txstart)) < 0) {
1265 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
1266 return panic_error ;
1267 }
1268 }
1269 else
1270 {
1271 while (txstart <= (txend - SEGSIZE)) {
1272 if ((panic_error = kdp_send_crashdump_pkt(KDP_DATA, NULL, SEGSIZE, txstart)) < 0) {
1273 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
1274 return panic_error;
1275 }
1276 txstart += SEGSIZE;
1277 if (!(panic_block % 2000))
1278 printf(".");
1279 }
1280 if (txstart < txend) {
1281 kdp_send_crashdump_pkt(request, corename, (txend - txstart), txstart);
1282 }
1283 }
1284 return 0;
1285 }
1286
1287 int
1288 kdp_send_crashdump_pkt(unsigned int request, char *corename,
1289 unsigned int length, void *panic_data)
1290 {
1291 struct corehdr *th = NULL;
1292 int poll_count = 2500;
1293
1294 char rretries = 0, tretries = 0;
1295
1296 pkt.off = pkt.len = 0;
1297
1298 if (request == KDP_WRQ) /* longer timeout for initial request */
1299 poll_count += 1000;
1300
1301 TRANSMIT_RETRY:
1302 tretries++;
1303
1304 if (tretries >=15) {
1305 /* The crashdump server is unreachable for some reason. This could be a network
1306 * issue or, if we've been especially unfortunate, we've hit Radar 2760413,
1307 * which is a long standing problem with the IOKit polled mode network driver
1308 * shim which can prevent transmits/receives completely.
1309 */
1310 printf ("Cannot contact panic server, timing out.\n");
1311 return (-3);
1312 }
1313
1314 if (tretries > 2)
1315 printf("TX retry #%d ", tretries );
1316
1317 th = create_panic_header(request, corename, length, panic_block);
1318
1319 if (request == KDP_DATA) {
1320 if (!kdp_vm_read((caddr_t) panic_data, (caddr_t) th->th_data, length)) {
1321 memset ((caddr_t) th->th_data, 'X', length);
1322 }
1323 }
1324 else if (request == KDP_SEEK) {
1325 *(unsigned int *) th->th_data = htonl(*(unsigned int *) panic_data);
1326 }
1327
1328 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
1329
1330 /* Listen for the ACK */
1331 RECEIVE_RETRY:
1332 while (!pkt.input && flag_panic_dump_in_progress && poll_count) {
1333 kdp_poll();
1334 poll_count--;
1335 }
1336
1337 if (pkt.input) {
1338
1339 pkt.input = FALSE;
1340
1341 th = (struct corehdr *) &pkt.data[pkt.off];
1342
1343 if (ntohs(th->th_opcode) == KDP_ACK && ntohl(th->th_block) == panic_block) {
1344 }
1345 else
1346 if (ntohs(th->th_opcode) == KDP_ERROR) {
1347 printf("Panic server returned error %d, retrying\n", ntohl(th->th_code));
1348 poll_count = 1000;
1349 goto TRANSMIT_RETRY;
1350 }
1351 else
1352 if (ntohl(th->th_block) == (panic_block - 1)) {
1353 printf("RX retry ");
1354 if (++rretries > 1)
1355 goto TRANSMIT_RETRY;
1356 else
1357 goto RECEIVE_RETRY;
1358 }
1359 }
1360 else
1361 if (!flag_panic_dump_in_progress) /* we received a debugging packet, bail*/
1362 {
1363 printf("Received a debugger packet,transferring control to debugger\n");
1364 /* Configure that if not set ..*/
1365 kdp_flag |= DBG_POST_CORE;
1366 return (-2);
1367 }
1368 else /* We timed out */
1369 if (0 == poll_count) {
1370 poll_count = 1000;
1371 kdp_us_spin ((tretries%4) * panic_timeout); /* capped linear backoff */
1372 goto TRANSMIT_RETRY;
1373 }
1374
1375 panic_block++;
1376
1377 if (request == KDP_EOF)
1378 printf("\nTotal number of packets transmitted: %d\n", panic_block);
1379
1380 return 1;
1381 }
1382
1383 static int
1384 isdigit (char c)
1385 {
1386 return ((c > 47) && (c < 58));
1387 }
1388 /* From user mode Libc - this ought to be in a library */
1389 static char *
1390 strnstr(char *s, const char *find, size_t slen)
1391 {
1392 char c, sc;
1393 size_t len;
1394
1395 if ((c = *find++) != '\0') {
1396 len = strlen(find);
1397 do {
1398 do {
1399 if ((sc = *s++) == '\0' || slen-- < 1)
1400 return (NULL);
1401 } while (sc != c);
1402 if (len > slen)
1403 return (NULL);
1404 } while (strncmp(s, find, len) != 0);
1405 s--;
1406 }
1407 return (s);
1408 }
1409
1410 extern char version[];
1411
1412 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1413 * would be to have the integrator run a script which would copy the
1414 * xnu version into a string or an int somewhere at project submission
1415 * time - makes assumptions about sizeof(version), but will not fail if
1416 * it changes, but may be incorrect.
1417 */
1418 /* 2006: Incorporated a change from Darwin user P. Lovell to extract
1419 * the minor kernel version numbers from the version string.
1420 */
1421 static int
1422 kdp_get_xnu_version(char *versionbuf)
1423 {
1424 char *versionpos;
1425 char vstr[20];
1426 int retval = -1;
1427 char *vptr;
1428
1429 strlcpy(vstr, "custom", 10);
1430 if (strlcpy(versionbuf, version, 95) < 95) {
1431 versionpos = strnstr(versionbuf, "xnu-", 90);
1432 if (versionpos) {
1433 strncpy(vstr, versionpos, sizeof(vstr));
1434 vstr[sizeof(vstr)-1] = '\0';
1435 vptr = vstr + 4; /* Begin after "xnu-" */
1436 while (*vptr && (isdigit(*vptr) || *vptr == '.'))
1437 vptr++;
1438 *vptr = '\0';
1439 /* Remove trailing period, if any */
1440 if (*(--vptr) == '.')
1441 *vptr = '\0';
1442 retval = 0;
1443 }
1444 }
1445 strlcpy(versionbuf, vstr, KDP_MAXPACKET);
1446 return retval;
1447 }
1448
1449 extern char *inet_aton(const char *cp, struct in_addr *pin);
1450
1451 /* Primary dispatch routine for the system dump */
1452 void
1453 kdp_panic_dump(void)
1454 {
1455 char corename[50];
1456 char coreprefix[10];
1457 int panic_error;
1458
1459 uint64_t abstime;
1460 uint32_t current_ip = ntohl(kdp_current_ip_address);
1461
1462 if (flag_panic_dump_in_progress) {
1463 printf("System dump aborted.\n");
1464 goto panic_dump_exit;
1465 }
1466
1467 printf("Entering system dump routine\n");
1468
1469 if (!panicd_specified) {
1470 printf("A dump server was not specified in the boot-args, terminating kernel core dump.\n");
1471 goto panic_dump_exit;
1472 }
1473
1474 flag_panic_dump_in_progress = TRUE;
1475 not_in_kdp = 0;
1476
1477 if (pkt.input)
1478 kdp_panic("kdp_panic_dump: unexpected pending input packet");
1479
1480 kdp_get_xnu_version((char *) &pkt.data[0]);
1481
1482 /* Panic log bit takes precedence over core dump bit */
1483 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP))
1484 strncpy(coreprefix, "paniclog", sizeof(coreprefix));
1485 else
1486 strncpy(coreprefix, "core", sizeof(coreprefix));
1487
1488 abstime = mach_absolute_time();
1489 pkt.data[20] = '\0';
1490 snprintf (corename, sizeof(corename), "%s-%s-%d.%d.%d.%d-%x",
1491 coreprefix, &pkt.data[0],
1492 (current_ip & 0xff000000) >> 24,
1493 (current_ip & 0xff0000) >> 16,
1494 (current_ip & 0xff00) >> 8,
1495 (current_ip & 0xff),
1496 (unsigned int) (abstime & 0xffffffff));
1497
1498 if (0 == inet_aton(panicd_ip_str, (struct in_addr *) &panic_server_ip)) {
1499 printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str);
1500 }
1501 else
1502 printf("Attempting connection to panic server configured at IP %s, port %d\n", panicd_ip_str, panicd_port);
1503
1504 destination_mac = router_mac;
1505
1506 if (kdp_arp_resolve(panic_server_ip, &temp_mac)) {
1507 printf("Resolved %s's (or proxy's) link level address\n", panicd_ip_str);
1508 destination_mac = temp_mac;
1509 }
1510 else {
1511 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
1512 if (router_specified) {
1513 if (0 == inet_aton(router_ip_str, (struct in_addr *) &parsed_router_ip))
1514 printf("inet_aton() failed interpreting %s as an IP\n", router_ip_str);
1515 else {
1516 router_ip = parsed_router_ip;
1517 if (kdp_arp_resolve(router_ip, &temp_mac)) {
1518 destination_mac = temp_mac;
1519 printf("Routing through specified router IP %s (%d)\n", router_ip_str, router_ip);
1520 }
1521 }
1522 }
1523 }
1524
1525 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
1526
1527 printf("Transmitting packets to link level address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1528 destination_mac.ether_addr_octet[0] & 0xff,
1529 destination_mac.ether_addr_octet[1] & 0xff,
1530 destination_mac.ether_addr_octet[2] & 0xff,
1531 destination_mac.ether_addr_octet[3] & 0xff,
1532 destination_mac.ether_addr_octet[4] & 0xff,
1533 destination_mac.ether_addr_octet[5] & 0xff);
1534
1535 printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map));
1536 printf("Sending write request for %s\n", corename);
1537
1538 if ((panic_error = kdp_send_crashdump_pkt(KDP_WRQ, corename, 0 , NULL)) < 0) {
1539 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
1540 goto panic_dump_exit;
1541 }
1542
1543 /* Just the panic log requested */
1544 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP)) {
1545 printf("Transmitting panic log, please wait: ");
1546 kdp_send_crashdump_data(KDP_DATA, corename, (debug_buf_ptr - debug_buf), debug_buf);
1547 kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
1548 printf("Please file a bug report on this panic, if possible.\n");
1549 goto panic_dump_exit;
1550 }
1551
1552 /* We want a core dump if we're here */
1553 kern_dump();
1554 panic_dump_exit:
1555 abort_panic_transfer();
1556 pkt.input = FALSE;
1557 pkt.len = 0;
1558 kdp_reset();
1559 return;
1560 }
1561
1562 void
1563 abort_panic_transfer(void)
1564 {
1565 flag_panic_dump_in_progress = FALSE;
1566 not_in_kdp = 1;
1567 panic_block = 0;
1568 }
1569
1570 #if CONFIG_SERIAL_KDP
1571
1572 static boolean_t needs_serial_init = TRUE;
1573
1574 static void
1575 kdp_serial_send(void *rpkt, unsigned int rpkt_len)
1576 {
1577 if (needs_serial_init)
1578 {
1579 serial_init();
1580 needs_serial_init = FALSE;
1581 }
1582
1583 // printf("tx\n");
1584 kdp_serialize_packet((unsigned char *)rpkt, rpkt_len, serial_putc);
1585 }
1586
1587 static void
1588 kdp_serial_receive(void *rpkt, unsigned int *rpkt_len, unsigned int timeout)
1589 {
1590 int readkar;
1591 uint64_t now, deadline;
1592
1593 if (needs_serial_init)
1594 {
1595 serial_init();
1596 needs_serial_init = FALSE;
1597 }
1598
1599 clock_interval_to_deadline(timeout, 1000 * 1000 /* milliseconds */, &deadline);
1600
1601 // printf("rx\n");
1602 for(clock_get_uptime(&now); now < deadline; clock_get_uptime(&now))
1603 {
1604 readkar = serial_getc();
1605 if(readkar >= 0)
1606 {
1607 unsigned char *packet;
1608 // printf("got char %02x\n", readkar);
1609 if((packet = kdp_unserialize_packet(readkar,rpkt_len)))
1610 {
1611 memcpy(rpkt, packet, *rpkt_len);
1612 return;
1613 }
1614 }
1615 }
1616 *rpkt_len = 0;
1617 }
1618
1619 static void kdp_serial_callout(__unused void *arg, kdp_event_t event)
1620 {
1621 /* When we stop KDP, set the bit to re-initialize the console serial port
1622 * the next time we send/receive a KDP packet. We don't do it on
1623 * KDP_EVENT_ENTER directly because it also gets called when we trap to KDP
1624 * for non-external debugging, i.e., stackshot or core dumps.
1625 *
1626 * Set needs_serial_init on exit (and initialization, see above) and not
1627 * enter because enter is sent multiple times and causes excess reinitialization.
1628 */
1629
1630 switch (event)
1631 {
1632 case KDP_EVENT_PANICLOG:
1633 case KDP_EVENT_ENTER:
1634 break;
1635 case KDP_EVENT_EXIT:
1636 needs_serial_init = TRUE;
1637 break;
1638 }
1639 }
1640
1641 #endif /* CONFIG_SERIAL_KDP */
1642
1643 void
1644 kdp_init(void)
1645 {
1646 #if CONFIG_SERIAL_KDP
1647 char kdpname[80];
1648 struct in_addr ipaddr;
1649 struct ether_addr macaddr;
1650
1651 #if CONFIG_EMBEDDED
1652 //serial will be the debugger, unless match name is explicitly provided, and it's not "serial"
1653 if(PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname)) && strncmp(kdpname, "serial", sizeof(kdpname)) != 0)
1654 return;
1655 #else
1656 // serial must be explicitly requested
1657 if(!PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname)) || strncmp(kdpname, "serial", sizeof(kdpname)) != 0)
1658 return;
1659 #endif
1660
1661 kprintf("Intializing serial KDP\n");
1662
1663 kdp_register_callout(kdp_serial_callout, NULL);
1664 kdp_register_send_receive(kdp_serial_send, kdp_serial_receive);
1665
1666 /* fake up an ip and mac for early serial debugging */
1667 macaddr.ether_addr_octet[0] = 's';
1668 macaddr.ether_addr_octet[1] = 'e';
1669 macaddr.ether_addr_octet[2] = 'r';
1670 macaddr.ether_addr_octet[3] = 'i';
1671 macaddr.ether_addr_octet[4] = 'a';
1672 macaddr.ether_addr_octet[5] = 'l';
1673 ipaddr.s_addr = 0xABADBABE;
1674 kdp_set_ip_and_mac_addresses(&ipaddr, &macaddr);
1675 #endif /* CONFIG_SERIAL_KDP */
1676 }