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