]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/kdp_udp.c
xnu-517.12.7.tar.gz
[apple/xnu.git] / osfmk / kdp / kdp_udp.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1982, 1986, 1993
24 * The Regents of the University of California. All rights reserved.
25 */
26
27 /*
28 * Kernel Debugging Protocol UDP implementation.
29 */
30
31 #include <mach_kdb.h>
32 #include <mach/boolean.h>
33 #include <mach/mach_types.h>
34 #include <mach/exception_types.h>
35 #include <kern/cpu_data.h>
36 #include <kern/debug.h>
37
38 #include <kdp/kdp_internal.h>
39 #include <kdp/kdp_en_debugger.h>
40 #include <kdp/kdp_udp.h>
41
42 #include <kdp/kdp_core.h>
43
44 #include <vm/vm_map.h>
45 #include <mach/memory_object_types.h>
46
47 #include <string.h>
48
49 #define DO_ALIGN 1 /* align all packet data accesses */
50
51 extern int kdp_getc(void);
52 extern int reattach_wait;
53
54 static u_short ip_id; /* ip packet ctr, for ids */
55
56 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
57
58 /*
59 * UDP protocol implementation.
60 * Per RFC 768, August, 1980.
61 */
62 #define UDP_TTL 60 /* deflt time to live for UDP packets */
63 int udp_ttl = UDP_TTL;
64 static unsigned char exception_seq;
65
66 static struct {
67 unsigned char data[KDP_MAXPACKET];
68 unsigned int off, len;
69 boolean_t input;
70 } pkt, saved_reply;
71
72 struct {
73 struct {
74 struct in_addr in;
75 struct ether_addr ea;
76 } loc;
77 struct {
78 struct in_addr in;
79 struct ether_addr ea;
80 } rmt;
81 } adr;
82
83 static char
84 *exception_message[] = {
85 "Unknown",
86 "Memory access", /* EXC_BAD_ACCESS */
87 "Failed instruction", /* EXC_BAD_INSTRUCTION */
88 "Arithmetic", /* EXC_ARITHMETIC */
89 "Emulation", /* EXC_EMULATION */
90 "Software", /* EXC_SOFTWARE */
91 "Breakpoint" /* EXC_BREAKPOINT */
92 };
93
94 int kdp_flag = 0;
95
96 static kdp_send_t kdp_en_send_pkt = 0;
97 static kdp_receive_t kdp_en_recv_pkt = 0;
98
99
100 static u_long kdp_current_ip_address = 0;
101 static struct ether_addr kdp_current_mac_address = {{0, 0, 0, 0, 0, 0}};
102 static void *kdp_current_ifp = 0;
103
104 static void kdp_handler( void *);
105
106 static unsigned int panic_server_ip = 0;
107 static unsigned int parsed_router_ip = 0;
108 static unsigned int router_ip = 0;
109 static unsigned int panicd_specified = 0;
110 static unsigned int router_specified = 0;
111
112 static struct ether_addr router_mac = {{0, 0, 0 , 0, 0, 0}};
113
114 static u_char flag_panic_dump_in_progress = 0;
115 static u_char flag_router_mac_initialized = 0;
116
117 static unsigned int panic_timeout = 100000;
118 static unsigned int last_panic_port = CORE_REMOTE_PORT;
119
120 unsigned int SEGSIZE = 512;
121
122 static unsigned int PANIC_PKTSIZE = 518;
123 static char panicd_ip_str[20];
124 static char router_ip_str[20];
125
126 static unsigned int panic_block = 0;
127 static volatile unsigned int kdp_trigger_core_dump = 0;
128
129 extern unsigned int not_in_kdp;
130
131 void
132 kdp_register_send_receive(
133 kdp_send_t send,
134 kdp_receive_t receive)
135 {
136 unsigned int debug;
137
138 kdp_en_send_pkt = send;
139 kdp_en_recv_pkt = receive;
140
141 debug_log_init();
142
143 PE_parse_boot_arg("debug", &debug);
144
145 if (debug & DB_KDP_BP_DIS)
146 kdp_flag |= KDP_BP_DIS;
147 if (debug & DB_KDP_GETC_ENA)
148 kdp_flag |= KDP_GETC_ENA;
149 if (debug & DB_ARP)
150 kdp_flag |= KDP_ARP;
151
152 if (debug & DB_KERN_DUMP_ON_PANIC)
153 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
154 if (debug & DB_KERN_DUMP_ON_NMI)
155 kdp_flag |= PANIC_CORE_ON_NMI;
156
157 if (debug & DB_DBG_POST_CORE)
158 kdp_flag |= DBG_POST_CORE;
159
160 if (debug & DB_PANICLOG_DUMP)
161 kdp_flag |= PANIC_LOG_DUMP;
162
163 if (PE_parse_boot_arg ("_panicd_ip", panicd_ip_str))
164 panicd_specified = 1;
165 /* For the future, currently non-functional */
166 if (PE_parse_boot_arg ("_router_ip", router_ip_str))
167 router_specified = 1;
168
169 kdp_flag |= KDP_READY;
170 if (current_debugger == NO_CUR_DB)
171 current_debugger = KDP_CUR_DB;
172 if (halt_in_debugger) {
173 kdp_call();
174 halt_in_debugger=0;
175 }
176 }
177
178 void
179 kdp_unregister_send_receive(
180 kdp_send_t send,
181 kdp_receive_t receive)
182 {
183 if (current_debugger == KDP_CUR_DB)
184 current_debugger = NO_CUR_DB;
185 kdp_flag &= ~KDP_READY;
186 kdp_en_send_pkt = NULL;
187 kdp_en_recv_pkt = NULL;
188 }
189
190 static void
191 enaddr_copy(
192 void *src,
193 void *dst
194 )
195 {
196 bcopy((char *)src, (char *)dst, sizeof (struct ether_addr));
197 }
198
199 static unsigned short
200 ip_sum(
201 unsigned char *c,
202 unsigned int hlen
203 )
204 {
205 unsigned int high, low, sum;
206
207 high = low = 0;
208 while (hlen-- > 0) {
209 low += c[1] + c[3];
210 high += c[0] + c[2];
211
212 c += sizeof (int);
213 }
214
215 sum = (high << 8) + low;
216 sum = (sum >> 16) + (sum & 65535);
217
218 return (sum > 65535 ? sum - 65535 : sum);
219 }
220
221 static void
222 kdp_reply(
223 unsigned short reply_port
224 )
225 {
226 struct udpiphdr aligned_ui, *ui = &aligned_ui;
227 struct ip aligned_ip, *ip = &aligned_ip;
228 struct in_addr tmp_ipaddr;
229 struct ether_addr tmp_enaddr;
230 struct ether_header *eh;
231
232 if (!pkt.input)
233 kdp_panic("kdp_reply");
234
235 pkt.off -= sizeof (struct udpiphdr);
236
237 #if DO_ALIGN
238 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
239 #else
240 ui = (struct udpiphdr *)&pkt.data[pkt.off];
241 #endif
242 ui->ui_next = ui->ui_prev = 0;
243 ui->ui_x1 = 0;
244 ui->ui_pr = IPPROTO_UDP;
245 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
246 tmp_ipaddr = ui->ui_src;
247 ui->ui_src = ui->ui_dst;
248 ui->ui_dst = tmp_ipaddr;
249 ui->ui_sport = htons(KDP_REMOTE_PORT);
250 ui->ui_dport = reply_port;
251 ui->ui_ulen = ui->ui_len;
252 ui->ui_sum = 0;
253 #if DO_ALIGN
254 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
255 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
256 #else
257 ip = (struct ip *)&pkt.data[pkt.off];
258 #endif
259 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
260 ip->ip_v = IPVERSION;
261 ip->ip_id = htons(ip_id++);
262 ip->ip_hl = sizeof (struct ip) >> 2;
263 ip->ip_ttl = udp_ttl;
264 ip->ip_sum = 0;
265 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
266 #if DO_ALIGN
267 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
268 #endif
269
270 pkt.len += sizeof (struct udpiphdr);
271
272 pkt.off -= sizeof (struct ether_header);
273
274 eh = (struct ether_header *)&pkt.data[pkt.off];
275 enaddr_copy(eh->ether_shost, &tmp_enaddr);
276 enaddr_copy(eh->ether_dhost, eh->ether_shost);
277 enaddr_copy(&tmp_enaddr, eh->ether_dhost);
278 eh->ether_type = htons(ETHERTYPE_IP);
279
280 pkt.len += sizeof (struct ether_header);
281
282 // save reply for possible retransmission
283 bcopy((char *)&pkt, (char *)&saved_reply, sizeof(pkt));
284
285 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
286
287 // increment expected sequence number
288 exception_seq++;
289 }
290
291 static void
292 kdp_send(
293 unsigned short remote_port
294 )
295 {
296 struct udpiphdr aligned_ui, *ui = &aligned_ui;
297 struct ip aligned_ip, *ip = &aligned_ip;
298 struct ether_header *eh;
299
300 if (pkt.input)
301 kdp_panic("kdp_send");
302
303 pkt.off -= sizeof (struct udpiphdr);
304
305 #if DO_ALIGN
306 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
307 #else
308 ui = (struct udpiphdr *)&pkt.data[pkt.off];
309 #endif
310 ui->ui_next = ui->ui_prev = 0;
311 ui->ui_x1 = 0;
312 ui->ui_pr = IPPROTO_UDP;
313 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
314 ui->ui_src = adr.loc.in;
315 ui->ui_dst = adr.rmt.in;
316 ui->ui_sport = htons(KDP_REMOTE_PORT);
317 ui->ui_dport = remote_port;
318 ui->ui_ulen = ui->ui_len;
319 ui->ui_sum = 0;
320 #if DO_ALIGN
321 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
322 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
323 #else
324 ip = (struct ip *)&pkt.data[pkt.off];
325 #endif
326 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
327 ip->ip_v = IPVERSION;
328 ip->ip_id = htons(ip_id++);
329 ip->ip_hl = sizeof (struct ip) >> 2;
330 ip->ip_ttl = udp_ttl;
331 ip->ip_sum = 0;
332 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
333 #if DO_ALIGN
334 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
335 #endif
336
337 pkt.len += sizeof (struct udpiphdr);
338
339 pkt.off -= sizeof (struct ether_header);
340
341 eh = (struct ether_header *)&pkt.data[pkt.off];
342 enaddr_copy(&adr.loc.ea, eh->ether_shost);
343 enaddr_copy(&adr.rmt.ea, eh->ether_dhost);
344 eh->ether_type = htons(ETHERTYPE_IP);
345
346 pkt.len += sizeof (struct ether_header);
347 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
348 }
349
350 /* We don't interpret this pointer, we just give it to the
351 bsd stack so it can decide when to set the MAC and IP info. */
352 void
353 kdp_set_interface(void *ifp)
354 {
355 kdp_current_ifp = ifp;
356 }
357
358 void *
359 kdp_get_interface()
360 {
361 return kdp_current_ifp;
362 }
363
364 void
365 kdp_set_ip_and_mac_addresses(
366 struct in_addr *ipaddr,
367 struct ether_addr *macaddr)
368 {
369 unsigned int debug = 0;
370
371 kdp_current_ip_address = ipaddr->s_addr;
372 kdp_current_mac_address = *macaddr;
373 }
374
375 void
376 kdp_set_gateway_mac(void *gatewaymac)
377 {
378 router_mac = *(struct ether_addr *)gatewaymac;
379 }
380
381 struct ether_addr
382 kdp_get_mac_addr(void)
383 {
384 return kdp_current_mac_address;
385 }
386
387 unsigned int
388 kdp_get_ip_address(void)
389 {
390 return kdp_current_ip_address;
391 }
392
393 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
394 is set. A workaround if you don't want to reboot is to set
395 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
396 interface!)
397 */
398 static void
399 kdp_arp_reply(void)
400 {
401 struct ether_header *eh;
402 struct ether_arp aligned_ea, *ea = &aligned_ea;
403
404 struct in_addr isaddr, itaddr, myaddr;
405 struct ether_addr my_enaddr;
406
407 eh = (struct ether_header *)&pkt.data[pkt.off];
408 pkt.off += sizeof(struct ether_header);
409
410 memcpy((void *)ea, (void *)&pkt.data[pkt.off],sizeof(*ea));
411
412 if(ntohs(ea->arp_op) != ARPOP_REQUEST)
413 return;
414
415 myaddr.s_addr = kdp_get_ip_address();
416 my_enaddr = kdp_get_mac_addr();
417
418 if (!(myaddr.s_addr) || !(my_enaddr.ether_addr_octet[1]))
419 return;
420
421 (void)memcpy((void *)&isaddr, (void *)ea->arp_spa, sizeof (isaddr));
422 (void)memcpy((void *)&itaddr, (void *)ea->arp_tpa, sizeof (itaddr));
423
424 if (itaddr.s_addr == myaddr.s_addr) {
425 (void)memcpy((void *)ea->arp_tha, (void *)ea->arp_sha, sizeof(ea->arp_sha));
426 (void)memcpy((void *)ea->arp_sha, (void *)&my_enaddr, sizeof(ea->arp_sha));
427
428 (void)memcpy((void *)ea->arp_tpa, (void *) ea->arp_spa, sizeof(ea->arp_spa));
429 (void)memcpy((void *)ea->arp_spa, (void *) &itaddr, sizeof(ea->arp_spa));
430
431 ea->arp_op = htons(ARPOP_REPLY);
432 ea->arp_pro = htons(ETHERTYPE_IP);
433 (void)memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
434 (void)memcpy(eh->ether_shost, &my_enaddr, sizeof(eh->ether_shost));
435 eh->ether_type = htons(ETHERTYPE_ARP);
436 (void)memcpy(&pkt.data[pkt.off], ea, sizeof(*ea));
437 pkt.off -= sizeof (struct ether_header);
438 /* pkt.len is still the length we want, ether_header+ether_arp */
439 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
440 }
441 }
442
443 static void
444 kdp_poll(void)
445 {
446 struct ether_header *eh;
447 struct udpiphdr aligned_ui, *ui = &aligned_ui;
448 struct ip aligned_ip, *ip = &aligned_ip;
449 static int msg_printed;
450
451
452 if (pkt.input)
453 kdp_panic("kdp_poll");
454
455 if (!kdp_en_recv_pkt || !kdp_en_send_pkt) {
456 if( msg_printed == 0) {
457 msg_printed = 1;
458 printf("kdp_poll: no debugger device\n");
459 }
460 return;
461 }
462
463 pkt.off = pkt.len = 0;
464 (*kdp_en_recv_pkt)(pkt.data, &pkt.len, 3/* ms */);
465
466 if (pkt.len == 0)
467 return;
468
469 if (pkt.len >= sizeof(struct ether_header))
470 {
471 eh = (struct ether_header *)&pkt.data[pkt.off];
472
473 if (kdp_flag & KDP_ARP)
474 {
475 if (ntohs(eh->ether_type) == ETHERTYPE_ARP)
476 {
477 kdp_arp_reply();
478 return;
479 }
480 }
481 }
482
483 if (pkt.len < (sizeof (struct ether_header) + sizeof (struct udpiphdr)))
484 return;
485
486 pkt.off += sizeof (struct ether_header);
487 if (ntohs(eh->ether_type) != ETHERTYPE_IP) {
488 return;
489 }
490
491 #if DO_ALIGN
492 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
493 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
494 #else
495 ui = (struct udpiphdr *)&pkt.data[pkt.off];
496 ip = (struct ip *)&pkt.data[pkt.off];
497 #endif
498
499 pkt.off += sizeof (struct udpiphdr);
500 if (ui->ui_pr != IPPROTO_UDP) {
501 return;
502 }
503
504 if (ip->ip_hl > (sizeof (struct ip) >> 2)) {
505 return;
506 }
507
508 if (ntohs(ui->ui_dport) != KDP_REMOTE_PORT) {
509 if (CORE_REMOTE_PORT == (ntohs(ui->ui_dport)) &&
510 flag_panic_dump_in_progress) {
511 last_panic_port = ui->ui_sport;
512 }
513 else
514 return;
515 }
516 /* If we receive a kernel debugging packet whilst a
517 * core dump is in progress, abort the transfer and
518 * enter the debugger.
519 */
520 else
521 if (flag_panic_dump_in_progress)
522 {
523 abort_panic_transfer();
524 return;
525 }
526
527 if (!kdp.is_conn && !flag_panic_dump_in_progress) {
528 enaddr_copy(eh->ether_dhost, &adr.loc.ea);
529 adr.loc.in = ui->ui_dst;
530
531 enaddr_copy(eh->ether_shost, &adr.rmt.ea);
532 adr.rmt.in = ui->ui_src;
533 }
534
535 /*
536 * Calculate kdp packet length.
537 */
538 pkt.len = ntohs((u_short)ui->ui_ulen) - sizeof (struct udphdr);
539 pkt.input = TRUE;
540 }
541
542 static void
543 kdp_handler(
544 void *saved_state
545 )
546 {
547 unsigned short reply_port;
548 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
549
550
551 kdp.saved_state = saved_state; // see comment in kdp_raise_exception
552
553 do {
554 while (!pkt.input)
555 kdp_poll();
556
557 #if DO_ALIGN
558 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
559 #else
560 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
561 #endif
562
563 // ignore replies -- we're not expecting them anyway.
564 if (hdr->is_reply) {
565 goto again;
566 }
567
568 if (hdr->request == KDP_REATTACH)
569 exception_seq = hdr->seq;
570
571 // check for retransmitted request
572 if (hdr->seq == (exception_seq - 1)) {
573 /* retransmit last reply */
574 (*kdp_en_send_pkt)(&saved_reply.data[saved_reply.off],
575 saved_reply.len);
576 goto again;
577 } else if (hdr->seq != exception_seq) {
578 printf("kdp: bad sequence %d (want %d)\n",
579 hdr->seq, exception_seq);
580 goto again;
581 }
582
583 if (kdp_packet((unsigned char*)&pkt.data[pkt.off],
584 (int *)&pkt.len,
585 (unsigned short *)&reply_port)) {
586 kdp_reply(reply_port);
587 }
588
589 again:
590 pkt.input = FALSE;
591 } while (kdp.is_halted);
592 }
593
594 static void
595 kdp_connection_wait(void)
596 {
597 unsigned short reply_port;
598 boolean_t kdp_call_kdb();
599 struct ether_addr kdp_mac_addr = kdp_get_mac_addr();
600 unsigned int ip_addr = ntohl(kdp_get_ip_address());
601
602 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
603 kdp_mac_addr.ether_addr_octet[0] & 0xff,
604 kdp_mac_addr.ether_addr_octet[1] & 0xff,
605 kdp_mac_addr.ether_addr_octet[2] & 0xff,
606 kdp_mac_addr.ether_addr_octet[3] & 0xff,
607 kdp_mac_addr.ether_addr_octet[4] & 0xff,
608 kdp_mac_addr.ether_addr_octet[5] & 0xff);
609
610 printf( "ip address: %d.%d.%d.%d\n",
611 (ip_addr & 0xff000000) >> 24,
612 (ip_addr & 0xff0000) >> 16,
613 (ip_addr & 0xff00) >> 8,
614 (ip_addr & 0xff));
615
616 printf("\nWaiting for remote debugger connection.\n");
617
618 if (reattach_wait == 0) {
619 if((kdp_flag & KDP_GETC_ENA) && (0 != kdp_getc()))
620 {
621 printf("Options..... Type\n");
622 printf("------------ ----\n");
623 printf("continue.... 'c'\n");
624 printf("reboot...... 'r'\n");
625 #if MACH_KDB
626 printf("enter kdb... 'k'\n");
627 #endif
628 }
629 } else
630 reattach_wait = 0;
631
632 exception_seq = 0;
633
634 do {
635 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
636
637 while (!pkt.input) {
638 if (kdp_flag & KDP_GETC_ENA) {
639 switch(kdp_getc()) {
640 case 'c':
641 printf("Continuing...\n");
642 return;
643 case 'r':
644 printf("Rebooting...\n");
645 kdp_reboot();
646 break;
647 #if MACH_KDB
648 case 'k':
649 printf("calling kdb...\n");
650 if (kdp_call_kdb())
651 return;
652 else
653 printf("not implemented...\n");
654 #endif
655 default:
656 break;
657 }
658 }
659 kdp_poll();
660 }
661
662 #if DO_ALIGN
663 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
664 #else
665 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
666 #endif
667 if (hdr->request == KDP_HOSTREBOOT) {
668 kdp_reboot();
669 /* should not return! */
670 }
671 if (((hdr->request == KDP_CONNECT) || (hdr->request == KDP_REATTACH)) &&
672 !hdr->is_reply && (hdr->seq == exception_seq)) {
673 if (kdp_packet((unsigned char *)&pkt.data[pkt.off],
674 (int *)&pkt.len,
675 (unsigned short *)&reply_port))
676 kdp_reply(reply_port);
677 if (hdr->request == KDP_REATTACH) {
678 reattach_wait = 0;
679 hdr->request=KDP_DISCONNECT;
680 exception_seq = 0;
681 }
682 }
683
684 pkt.input = FALSE;
685 } while (!kdp.is_conn);
686
687 if (current_debugger == KDP_CUR_DB)
688 active_debugger=1;
689 printf("Connected to remote debugger.\n");
690 }
691
692 static void
693 kdp_send_exception(
694 unsigned int exception,
695 unsigned int code,
696 unsigned int subcode
697 )
698 {
699 unsigned short remote_port;
700 unsigned int timeout_count = 100;
701 unsigned int poll_timeout;
702
703 do {
704 pkt.off = sizeof (struct ether_header) + sizeof (struct udpiphdr);
705 kdp_exception((unsigned char *)&pkt.data[pkt.off],
706 (int *)&pkt.len,
707 (unsigned short *)&remote_port,
708 (unsigned int)exception,
709 (unsigned int)code,
710 (unsigned int)subcode);
711
712 kdp_send(remote_port);
713
714 poll_timeout = 50;
715 while(!pkt.input && poll_timeout)
716 {
717 kdp_poll();
718 poll_timeout--;
719 }
720
721 if (pkt.input) {
722 if (!kdp_exception_ack(&pkt.data[pkt.off], pkt.len)) {
723 pkt.input = FALSE;
724 }
725 }
726
727 pkt.input = FALSE;
728
729 if (kdp.exception_ack_needed)
730 kdp_us_spin(250000);
731
732 } while (kdp.exception_ack_needed && timeout_count--);
733
734 if (kdp.exception_ack_needed) {
735 // give up & disconnect
736 printf("kdp: exception ack timeout\n");
737 if (current_debugger == KDP_CUR_DB)
738 active_debugger=0;
739 kdp_reset();
740 }
741 }
742
743 void
744 kdp_raise_exception(
745 unsigned int exception,
746 unsigned int code,
747 unsigned int subcode,
748 void *saved_state
749 )
750 {
751 int index;
752
753 extern unsigned int disableDebugOuput;
754 extern unsigned int disableConsoleOutput;
755
756 disable_preemption();
757
758 if (saved_state == 0)
759 printf("kdp_raise_exception with NULL state\n");
760
761 index = exception;
762 if (exception != EXC_BREAKPOINT) {
763 if (exception > EXC_BREAKPOINT || exception < EXC_BAD_ACCESS) {
764 index = 0;
765 }
766 printf("%s exception (%x,%x,%x)\n",
767 exception_message[index],
768 exception, code, subcode);
769 }
770
771 kdp_sync_cache();
772
773 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
774 * do this. I think the client and the host can get out of sync.
775 */
776 kdp.saved_state = saved_state;
777
778 if (pkt.input)
779 kdp_panic("kdp_raise_exception");
780
781 if (((kdp_flag & KDP_PANIC_DUMP_ENABLED) || (kdp_flag & PANIC_LOG_DUMP))
782 && (panicstr != (char *) 0)) {
783
784 kdp_panic_dump();
785
786 }
787 else
788 if ((kdp_flag & PANIC_CORE_ON_NMI) && (panicstr == (char *) 0) &&
789 !kdp.is_conn) {
790
791 disableDebugOuput = disableConsoleOutput = FALSE;
792 kdp_panic_dump();
793
794 if (!(kdp_flag & DBG_POST_CORE))
795 goto exit_raise_exception;
796 }
797
798 again:
799 if (!kdp.is_conn)
800 kdp_connection_wait();
801 else {
802 kdp_send_exception(exception, code, subcode);
803 if (kdp.exception_ack_needed) {
804 kdp.exception_ack_needed = FALSE;
805 kdp_remove_all_breakpoints();
806 printf("Remote debugger disconnected.\n");
807 }
808 }
809
810 if (kdp.is_conn) {
811 kdp.is_halted = TRUE; /* XXX */
812 kdp_handler(saved_state);
813 if (!kdp.is_conn)
814 {
815 kdp_remove_all_breakpoints();
816 printf("Remote debugger disconnected.\n");
817 }
818 }
819 /* Allow triggering a panic core dump when connected to the machine
820 * Continuing after setting kdp_trigger_core_dump should do the
821 * trick.
822 */
823 if (1 == kdp_trigger_core_dump) {
824 kdp_flag &= ~PANIC_LOG_DUMP;
825 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
826 kdp_panic_dump();
827 }
828
829 kdp_sync_cache();
830
831 if (reattach_wait == 1)
832 goto again;
833 exit_raise_exception:
834 enable_preemption();
835 }
836
837 void
838 kdp_reset(void)
839 {
840 kdp.reply_port = kdp.exception_port = 0;
841 kdp.is_halted = kdp.is_conn = FALSE;
842 kdp.exception_seq = kdp.conn_seq = 0;
843 }
844
845 struct corehdr *
846 create_panic_header(unsigned int request, const char *corename,
847 unsigned length, unsigned int block)
848 {
849 struct udpiphdr aligned_ui, *ui = &aligned_ui;
850 struct ip aligned_ip, *ip = &aligned_ip;
851 struct ether_header *eh;
852 struct corehdr *coreh;
853 const char *mode = "octet";
854 char modelen = strlen(mode);
855
856 pkt.off = sizeof (struct ether_header);
857 pkt.len = length + ((request == KDP_WRQ) ? modelen : 0) +
858 (corename ? strlen(corename): 0) + sizeof(struct corehdr);
859
860 #if DO_ALIGN
861 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
862 #else
863 ui = (struct udpiphdr *)&pkt.data[pkt.off];
864 #endif
865 ui->ui_next = ui->ui_prev = 0;
866 ui->ui_x1 = 0;
867 ui->ui_pr = IPPROTO_UDP;
868 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
869 ui->ui_src.s_addr = htonl(kdp_current_ip_address);
870 ui->ui_dst.s_addr = panic_server_ip;
871 ui->ui_sport = htons(CORE_REMOTE_PORT);
872 ui->ui_dport = ((request == KDP_WRQ) ? htons(CORE_REMOTE_PORT) : last_panic_port);
873 ui->ui_ulen = ui->ui_len;
874 ui->ui_sum = 0;
875 #if DO_ALIGN
876 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
877 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
878 #else
879 ip = (struct ip *)&pkt.data[pkt.off];
880 #endif
881 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
882 ip->ip_v = IPVERSION;
883 ip->ip_id = htons(ip_id++);
884 ip->ip_hl = sizeof (struct ip) >> 2;
885 ip->ip_ttl = udp_ttl;
886 ip->ip_sum = 0;
887 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
888 #if DO_ALIGN
889 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
890 #endif
891
892 pkt.len += sizeof (struct udpiphdr);
893
894 pkt.off += sizeof (struct udpiphdr);
895
896 coreh = (struct corehdr *) &pkt.data[pkt.off];
897 coreh->th_opcode = htons((u_short)request);
898
899 if (request == KDP_WRQ)
900 {
901 register char *cp;
902
903 cp = coreh->th_u.tu_rpl;
904 strcpy (cp, corename);
905 cp += strlen(corename);
906 *cp++ = '\0';
907 strcpy (cp, mode);
908 cp+= modelen;
909 *cp++ = '\0';
910 }
911 else
912 {
913 coreh->th_block = htonl((unsigned int) block);
914 }
915
916 pkt.off -= sizeof (struct udpiphdr);
917 pkt.off -= sizeof (struct ether_header);
918
919 eh = (struct ether_header *)&pkt.data[pkt.off];
920 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
921 enaddr_copy(&router_mac, eh->ether_dhost);
922 eh->ether_type = htons(ETHERTYPE_IP);
923
924 pkt.len += sizeof (struct ether_header);
925 return coreh;
926 }
927
928 int kdp_send_panic_packets (unsigned int request, char *corename,
929 unsigned int length, unsigned int txstart)
930 {
931 unsigned int txend = txstart + length;
932 int panic_error = 0;
933
934 if (length <= SEGSIZE) {
935 if ((panic_error = kdp_send_panic_pkt (request, corename, length, (caddr_t) txstart)) < 0) {
936 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error);
937 return panic_error ;
938 }
939 }
940 else
941 {
942 while (txstart <= (txend - SEGSIZE)) {
943 if ((panic_error = kdp_send_panic_pkt (KDP_DATA, NULL, SEGSIZE, (caddr_t) txstart)) < 0) {
944 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error);
945 return panic_error;
946 }
947 txstart += SEGSIZE;
948 if (!(panic_block % 2000))
949 printf(".");
950 }
951 if (txstart < txend) {
952 kdp_send_panic_pkt(request, corename, (txend - txstart), (caddr_t) txstart);
953 }
954 }
955 }
956
957 int
958 kdp_send_panic_pkt (unsigned int request, char *corename,
959 unsigned int length, void *panic_data)
960 {
961 struct corehdr *th = NULL;
962 int poll_count = 2500;
963
964 char rretries = 0, tretries = 0;
965 /*
966 extern signed long gIODebuggerSemaphore;
967 */
968 pkt.off = pkt.len = 0;
969
970 if (request == KDP_WRQ) /* longer timeout for initial request */
971 poll_count += 1000;
972
973 TRANSMIT_RETRY:
974 tretries++;
975
976 if (tretries > 2)
977 printf("TX retry #%d ", tretries );
978
979 if (tretries >=15) {
980 /* This iokit layer issue can potentially
981 *cause a hang, uncomment to check if it's happening.
982 */
983 /*
984 if (gIODebuggerSemaphore)
985 printf("The gIODebuggerSemaphore is raised, preventing packet transmission (2760413)\n");
986 */
987
988 printf ("Cannot contact panic server, timing out.\n");
989 return (-3);
990 }
991
992 th = create_panic_header(request, corename, length, panic_block);
993
994 if (request == KDP_DATA || request == KDP_SEEK) {
995 if (!kdp_vm_read ((caddr_t) panic_data, (caddr_t) th->th_data, length)) {
996 memset ((caddr_t) th->th_data, 'X', length);
997 }
998 }
999
1000 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
1001
1002 /* Now we have to listen for the ACK */
1003 RECEIVE_RETRY:
1004
1005 while (!pkt.input && flag_panic_dump_in_progress && poll_count) {
1006 kdp_poll();
1007 poll_count--;
1008 }
1009
1010 if (pkt.input) {
1011
1012 pkt.input = FALSE;
1013
1014 th = (struct corehdr *) &pkt.data[pkt.off];
1015 /* These will eventually have to be ntoh[ls]'ed as appropriate */
1016
1017 if (th->th_opcode == KDP_ACK && th->th_block == panic_block) {
1018 }
1019 else
1020 if (th->th_opcode == KDP_ERROR) {
1021 printf("Panic server returned error %d, retrying\n", th->th_code);
1022 poll_count = 1000;
1023 goto TRANSMIT_RETRY;
1024 }
1025 else
1026 if (th->th_block == (panic_block -1)) {
1027 printf("RX retry ");
1028 if (++rretries > 1)
1029 goto TRANSMIT_RETRY;
1030 else
1031 goto RECEIVE_RETRY;
1032 }
1033 }
1034 else
1035 if (!flag_panic_dump_in_progress) /* we received a debugging packet, bail*/
1036 {
1037 printf("Received a debugger packet,transferring control to debugger\n");
1038 /* Configure that if not set ..*/
1039 kdp_flag |= DBG_POST_CORE;
1040 return (-2);
1041 }
1042 else /* We timed out */
1043 if (0 == poll_count) {
1044 poll_count = 1000;
1045 kdp_us_spin ((tretries%4) * panic_timeout); /* capped linear backoff */
1046 goto TRANSMIT_RETRY;
1047 }
1048
1049 panic_block++;
1050
1051 if (request == KDP_EOF)
1052 printf ("\nTotal number of packets transmitted: %d\n", panic_block);
1053
1054 return 1;
1055 }
1056
1057 /* Since we don't seem to have an isdigit() .. */
1058 static int
1059 isdigit (char c)
1060 {
1061 return ((c > 47) && (c < 58));
1062 }
1063 /* From user mode Libc - this ought to be in a library */
1064 static char *
1065 strnstr(s, find, slen)
1066 const char *s;
1067 const char *find;
1068 size_t slen;
1069 {
1070 char c, sc;
1071 size_t len;
1072
1073 if ((c = *find++) != '\0') {
1074 len = strlen(find);
1075 do {
1076 do {
1077 if ((sc = *s++) == '\0' || slen-- < 1)
1078 return (NULL);
1079 } while (sc != c);
1080 if (len > slen)
1081 return (NULL);
1082 } while (strncmp(s, find, len) != 0);
1083 s--;
1084 }
1085 return ((char *)s);
1086 }
1087
1088 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1089 * would be to have the integrator run a script which would copy the
1090 * xnu version into a string or an int somewhere at project submission
1091 * time - makes assumptions about sizeof(version), but will not fail if
1092 * it changes, but may be incorrect.
1093 */
1094
1095 static int
1096 kdp_get_xnu_version(char *versionbuf)
1097 {
1098 extern const char version[];
1099 char *versionpos;
1100 char vstr[10];
1101 int retval = -1;
1102
1103 strcpy(vstr, "custom");
1104 if (version) {
1105 if (kdp_vm_read(version, versionbuf, 90)) {
1106
1107 versionbuf[89] = '\0';
1108
1109 versionpos = strnstr(versionbuf, "xnu-", 80);
1110
1111 if (versionpos) {
1112 strncpy (vstr, versionpos, (isdigit (versionpos[7]) ? 8 : 7));
1113 vstr[(isdigit (versionpos[7]) ? 8 : 7)] = '\0';
1114 retval = 0;
1115 }
1116 }
1117 }
1118 strcpy(versionbuf, vstr);
1119 return retval;
1120 }
1121 /* Primary dispatch routine for the system dump */
1122 void
1123 kdp_panic_dump()
1124 {
1125 char corename[50];
1126 char coreprefix[10];
1127 int panic_error;
1128 extern char *debug_buf;
1129 extern vm_map_t kernel_map;
1130
1131 extern char *inet_aton(const char *cp, struct in_addr *pin);
1132
1133 extern char *debug_buf;
1134 extern char *debug_buf_ptr;
1135 uint64_t abstime;
1136
1137 printf ("Entering system dump routine\n");
1138
1139 if (!panicd_specified) {
1140 printf ("A panic server was not specified in the boot-args, terminating kernel core dump.\n");
1141 goto panic_dump_exit;
1142 }
1143
1144 flag_panic_dump_in_progress = 1;
1145 not_in_kdp = 0;
1146
1147 if (pkt.input)
1148 kdp_panic("kdp_panic_dump");
1149
1150 kdp_get_xnu_version((char *) &pkt.data[0]);
1151
1152 /* Panic log bit takes precedence over core dump bit */
1153 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP))
1154 strncpy(coreprefix, "paniclog", sizeof(coreprefix));
1155 else
1156 strncpy(coreprefix, "core", sizeof(coreprefix));
1157
1158 abstime = mach_absolute_time();
1159 pkt.data[10] = '\0';
1160 snprintf (corename, sizeof(corename), "%s-%s-%d.%d.%d.%d-%x",
1161 coreprefix, &pkt.data[0],
1162 (kdp_current_ip_address & 0xff000000) >> 24,
1163 (kdp_current_ip_address & 0xff0000) >> 16,
1164 (kdp_current_ip_address & 0xff00) >> 8,
1165 (kdp_current_ip_address & 0xff),
1166 (unsigned int) (abstime & 0xffffffff));
1167
1168 if (0 == inet_aton(panicd_ip_str, (struct in_addr *) &panic_server_ip)) {
1169 printf("inet_aton() failed interpreting %s as a panic server IP\n",
1170 panicd_ip_str);
1171 }
1172 else
1173 printf("Attempting connection to panic server configured at IP %s\n",
1174 panicd_ip_str);
1175
1176 if (router_specified) {
1177 if (0 == inet_aton(router_ip_str, (struct in_addr *) &parsed_router_ip)){
1178 printf("inet_aton() failed interpreting %s as an IP\n", router_ip);
1179 }
1180 else {
1181 router_ip = parsed_router_ip;
1182 printf("Routing through specified router IP %s (%d)\n", router_ip_str, router_ip);
1183 /* We will eventually need to resolve the router's MAC ourselves,
1184 * if one is specified,rather than being set through the BSD callback
1185 * but the _router_ip option does not function currently
1186 */
1187 }
1188 }
1189 /* These & 0xffs aren't necessary,but cut&paste is ever so convenient */
1190 printf("Routing via router MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1191 router_mac.ether_addr_octet[0] & 0xff,
1192 router_mac.ether_addr_octet[1] & 0xff,
1193 router_mac.ether_addr_octet[2] & 0xff,
1194 router_mac.ether_addr_octet[3] & 0xff,
1195 router_mac.ether_addr_octet[4] & 0xff,
1196 router_mac.ether_addr_octet[5] & 0xff);
1197
1198 printf("Kernel map size is %d\n", get_vmmap_size(kernel_map));
1199 printf ("Sending write request for %s\n", corename);
1200
1201 if ((panic_error = kdp_send_panic_pkt (KDP_WRQ, corename, 0 , NULL) < 0)) {
1202 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error);
1203 goto panic_dump_exit;
1204 }
1205
1206 /* Just the panic log requested */
1207 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP)) {
1208 printf("Transmitting panic log, please wait: ");
1209 kdp_send_panic_packets (KDP_DATA, corename, (debug_buf_ptr - debug_buf), (unsigned int) debug_buf);
1210 kdp_send_panic_pkt (KDP_EOF, NULL, 0, ((void *) 0));
1211 printf("Please file a bug report on this panic, if possible.\n");
1212 goto panic_dump_exit;
1213 }
1214
1215 /* We want a core dump if we're here */
1216 kern_dump();
1217 panic_dump_exit:
1218 not_in_kdp = 1;
1219 flag_panic_dump_in_progress = 0;
1220 panic_block = 0;
1221 pkt.input = FALSE;
1222 pkt.len = 0;
1223 kdp_reset();
1224 return;
1225 }
1226
1227 void
1228 abort_panic_transfer()
1229 {
1230 flag_panic_dump_in_progress = 0;
1231 not_in_kdp = 1;
1232 panic_block = 0;
1233 }