2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
31 * Copyright (c) 1982, 1986, 1993
32 * The Regents of the University of California. All rights reserved.
36 * Kernel Debugging Protocol UDP implementation.
40 #include <mach/boolean.h>
41 #include <mach/mach_types.h>
42 #include <mach/exception_types.h>
43 #include <kern/cpu_data.h>
44 #include <kern/debug.h>
46 #include <kdp/kdp_internal.h>
47 #include <kdp/kdp_en_debugger.h>
48 #include <kdp/kdp_udp.h>
50 #include <kdp/kdp_core.h>
52 #include <vm/vm_map.h>
53 #include <vm/vm_protos.h>
55 #include <mach/memory_object_types.h>
59 #define DO_ALIGN 1 /* align all packet data accesses */
61 extern int kdp_getc(void);
62 extern int reattach_wait
;
64 static u_short ip_id
; /* ip packet ctr, for ids */
66 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
69 * UDP protocol implementation.
70 * Per RFC 768, August, 1980.
72 #define UDP_TTL 60 /* deflt time to live for UDP packets */
73 int udp_ttl
= UDP_TTL
;
74 static unsigned char exception_seq
;
77 unsigned char data
[KDP_MAXPACKET
];
78 unsigned int off
, len
;
94 *exception_message
[] = {
96 "Memory access", /* EXC_BAD_ACCESS */
97 "Failed instruction", /* EXC_BAD_INSTRUCTION */
98 "Arithmetic", /* EXC_ARITHMETIC */
99 "Emulation", /* EXC_EMULATION */
100 "Software", /* EXC_SOFTWARE */
101 "Breakpoint" /* EXC_BREAKPOINT */
106 static kdp_send_t kdp_en_send_pkt
= 0;
107 static kdp_receive_t kdp_en_recv_pkt
= 0;
110 static u_long kdp_current_ip_address
= 0;
111 static struct ether_addr kdp_current_mac_address
= {{0, 0, 0, 0, 0, 0}};
112 static void *kdp_current_ifp
= 0;
114 static void kdp_handler( void *);
116 static unsigned int panic_server_ip
= 0;
117 static unsigned int parsed_router_ip
= 0;
118 static unsigned int router_ip
= 0;
119 static unsigned int panicd_specified
= 0;
120 static unsigned int router_specified
= 0;
122 static struct ether_addr router_mac
= {{0, 0, 0 , 0, 0, 0}};
124 static u_char flag_panic_dump_in_progress
= 0;
125 static u_char flag_router_mac_initialized
= 0;
127 static unsigned int panic_timeout
= 100000;
128 static unsigned int last_panic_port
= CORE_REMOTE_PORT
;
130 unsigned int SEGSIZE
= 512;
132 static unsigned int PANIC_PKTSIZE
= 518;
133 static char panicd_ip_str
[20];
134 static char router_ip_str
[20];
136 static unsigned int panic_block
= 0;
137 static volatile unsigned int kdp_trigger_core_dump
= 0;
138 static volatile unsigned int flag_kdp_trigger_reboot
= 0;
140 extern unsigned int not_in_kdp
;
142 extern int kdp_vm_read( caddr_t
, caddr_t
, unsigned int);
145 kdp_register_send_receive(
147 kdp_receive_t receive
)
149 unsigned int debug
=0;
151 kdp_en_send_pkt
= send
;
152 kdp_en_recv_pkt
= receive
;
156 PE_parse_boot_arg("debug", &debug
);
158 if (debug
& DB_KDP_BP_DIS
)
159 kdp_flag
|= KDP_BP_DIS
;
160 if (debug
& DB_KDP_GETC_ENA
)
161 kdp_flag
|= KDP_GETC_ENA
;
165 if (debug
& DB_KERN_DUMP_ON_PANIC
)
166 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
167 if (debug
& DB_KERN_DUMP_ON_NMI
)
168 kdp_flag
|= PANIC_CORE_ON_NMI
;
170 if (debug
& DB_DBG_POST_CORE
)
171 kdp_flag
|= DBG_POST_CORE
;
173 if (debug
& DB_PANICLOG_DUMP
)
174 kdp_flag
|= PANIC_LOG_DUMP
;
176 if (PE_parse_boot_arg ("_panicd_ip", panicd_ip_str
))
177 panicd_specified
= 1;
178 /* For the future, currently non-functional */
179 if (PE_parse_boot_arg ("_router_ip", router_ip_str
))
180 router_specified
= 1;
182 kdp_flag
|= KDP_READY
;
183 if (current_debugger
== NO_CUR_DB
)
184 current_debugger
= KDP_CUR_DB
;
185 if (halt_in_debugger
) {
192 kdp_unregister_send_receive(
194 kdp_receive_t receive
)
196 if (current_debugger
== KDP_CUR_DB
)
197 current_debugger
= NO_CUR_DB
;
198 kdp_flag
&= ~KDP_READY
;
199 kdp_en_send_pkt
= NULL
;
200 kdp_en_recv_pkt
= NULL
;
209 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
212 static unsigned short
218 unsigned int high
, low
, sum
;
228 sum
= (high
<< 8) + low
;
229 sum
= (sum
>> 16) + (sum
& 65535);
231 return (sum
> 65535 ? sum
- 65535 : sum
);
236 unsigned short reply_port
239 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
240 struct ip aligned_ip
, *ip
= &aligned_ip
;
241 struct in_addr tmp_ipaddr
;
242 struct ether_addr tmp_enaddr
;
243 struct ether_header
*eh
;
246 kdp_panic("kdp_reply");
248 pkt
.off
-= sizeof (struct udpiphdr
);
251 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
253 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
255 ui
->ui_next
= ui
->ui_prev
= 0;
257 ui
->ui_pr
= IPPROTO_UDP
;
258 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
259 tmp_ipaddr
= ui
->ui_src
;
260 ui
->ui_src
= ui
->ui_dst
;
261 ui
->ui_dst
= tmp_ipaddr
;
262 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
263 ui
->ui_dport
= reply_port
;
264 ui
->ui_ulen
= ui
->ui_len
;
267 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
268 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
270 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
272 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
273 ip
->ip_v
= IPVERSION
;
274 ip
->ip_id
= htons(ip_id
++);
275 ip
->ip_hl
= sizeof (struct ip
) >> 2;
276 ip
->ip_ttl
= udp_ttl
;
278 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
280 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
283 pkt
.len
+= sizeof (struct udpiphdr
);
285 pkt
.off
-= sizeof (struct ether_header
);
287 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
288 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
289 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
290 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
291 eh
->ether_type
= htons(ETHERTYPE_IP
);
293 pkt
.len
+= sizeof (struct ether_header
);
295 // save reply for possible retransmission
296 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
298 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
300 // increment expected sequence number
306 unsigned short remote_port
309 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
310 struct ip aligned_ip
, *ip
= &aligned_ip
;
311 struct ether_header
*eh
;
314 kdp_panic("kdp_send");
316 pkt
.off
-= sizeof (struct udpiphdr
);
319 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
321 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
323 ui
->ui_next
= ui
->ui_prev
= 0;
325 ui
->ui_pr
= IPPROTO_UDP
;
326 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
327 ui
->ui_src
= adr
.loc
.in
;
328 ui
->ui_dst
= adr
.rmt
.in
;
329 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
330 ui
->ui_dport
= remote_port
;
331 ui
->ui_ulen
= ui
->ui_len
;
334 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
335 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
337 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
339 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
340 ip
->ip_v
= IPVERSION
;
341 ip
->ip_id
= htons(ip_id
++);
342 ip
->ip_hl
= sizeof (struct ip
) >> 2;
343 ip
->ip_ttl
= udp_ttl
;
345 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
347 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
350 pkt
.len
+= sizeof (struct udpiphdr
);
352 pkt
.off
-= sizeof (struct ether_header
);
354 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
355 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
356 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
357 eh
->ether_type
= htons(ETHERTYPE_IP
);
359 pkt
.len
+= sizeof (struct ether_header
);
360 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
363 /* We don't interpret this pointer, we just give it to the
364 bsd stack so it can decide when to set the MAC and IP info. */
366 kdp_set_interface(void *ifp
)
368 kdp_current_ifp
= ifp
;
374 return kdp_current_ifp
;
378 kdp_set_ip_and_mac_addresses(
379 struct in_addr
*ipaddr
,
380 struct ether_addr
*macaddr
)
382 kdp_current_ip_address
= ipaddr
->s_addr
;
383 kdp_current_mac_address
= *macaddr
;
387 kdp_set_gateway_mac(void *gatewaymac
)
389 router_mac
= *(struct ether_addr
*)gatewaymac
;
390 flag_router_mac_initialized
= 1;
394 kdp_get_mac_addr(void)
396 return kdp_current_mac_address
;
400 kdp_get_ip_address(void)
402 return kdp_current_ip_address
;
405 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
406 is set. A workaround if you don't want to reboot is to set
407 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
413 struct ether_header
*eh
;
414 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
416 struct in_addr isaddr
, itaddr
, myaddr
;
417 struct ether_addr my_enaddr
;
419 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
420 pkt
.off
+= sizeof(struct ether_header
);
422 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
424 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
427 myaddr
.s_addr
= kdp_get_ip_address();
428 my_enaddr
= kdp_get_mac_addr();
430 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
433 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
434 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
436 if (itaddr
.s_addr
== myaddr
.s_addr
) {
437 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
438 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
440 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
441 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
443 ea
->arp_op
= htons(ARPOP_REPLY
);
444 ea
->arp_pro
= htons(ETHERTYPE_IP
);
445 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
446 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
447 eh
->ether_type
= htons(ETHERTYPE_ARP
);
448 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
449 pkt
.off
-= sizeof (struct ether_header
);
450 /* pkt.len is still the length we want, ether_header+ether_arp */
451 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
458 struct ether_header
*eh
;
459 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
460 struct ip aligned_ip
, *ip
= &aligned_ip
;
461 static int msg_printed
;
465 kdp_panic("kdp_poll");
467 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
468 if( msg_printed
== 0) {
470 printf("kdp_poll: no debugger device\n");
475 pkt
.off
= pkt
.len
= 0;
476 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
481 if (pkt
.len
>= sizeof(struct ether_header
))
483 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
485 if (kdp_flag
& KDP_ARP
)
487 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
495 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
498 pkt
.off
+= sizeof (struct ether_header
);
499 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
504 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
505 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
507 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
508 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
511 pkt
.off
+= sizeof (struct udpiphdr
);
512 if (ui
->ui_pr
!= IPPROTO_UDP
) {
516 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
520 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
521 if (CORE_REMOTE_PORT
== (ntohs(ui
->ui_dport
)) &&
522 flag_panic_dump_in_progress
) {
523 last_panic_port
= ui
->ui_sport
;
528 /* If we receive a kernel debugging packet whilst a
529 * core dump is in progress, abort the transfer and
530 * enter the debugger.
533 if (flag_panic_dump_in_progress
)
535 abort_panic_transfer();
539 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
540 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
541 adr
.loc
.in
= ui
->ui_dst
;
543 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
544 adr
.rmt
.in
= ui
->ui_src
;
548 * Calculate kdp packet length.
550 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
559 unsigned short reply_port
;
560 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
563 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
570 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
572 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
575 // ignore replies -- we're not expecting them anyway.
580 if (hdr
->request
== KDP_REATTACH
)
581 exception_seq
= hdr
->seq
;
583 // check for retransmitted request
584 if (hdr
->seq
== (exception_seq
- 1)) {
585 /* retransmit last reply */
586 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
589 } else if (hdr
->seq
!= exception_seq
) {
590 printf("kdp: bad sequence %d (want %d)\n",
591 hdr
->seq
, exception_seq
);
595 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
597 (unsigned short *)&reply_port
)) {
598 kdp_reply(reply_port
);
603 } while (kdp
.is_halted
);
607 kdp_connection_wait(void)
609 unsigned short reply_port
;
610 boolean_t
kdp_call_kdb();
611 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
612 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
614 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
615 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
616 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
617 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
618 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
619 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
620 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
622 printf( "ip address: %d.%d.%d.%d\n",
623 (ip_addr
& 0xff000000) >> 24,
624 (ip_addr
& 0xff0000) >> 16,
625 (ip_addr
& 0xff00) >> 8,
628 printf("\nWaiting for remote debugger connection.\n");
630 if (reattach_wait
== 0) {
631 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
633 printf("Options..... Type\n");
634 printf("------------ ----\n");
635 printf("continue.... 'c'\n");
636 printf("reboot...... 'r'\n");
638 printf("enter kdb... 'k'\n");
647 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
650 if (kdp_flag
& KDP_GETC_ENA
) {
653 printf("Continuing...\n");
656 printf("Rebooting...\n");
661 printf("calling kdb...\n");
665 printf("not implemented...\n");
675 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
677 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
679 if (hdr
->request
== KDP_HOSTREBOOT
) {
681 /* should not return! */
683 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
684 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
685 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
687 (unsigned short *)&reply_port
))
688 kdp_reply(reply_port
);
689 if (hdr
->request
== KDP_REATTACH
) {
691 hdr
->request
=KDP_DISCONNECT
;
697 } while (!kdp
.is_conn
);
699 if (current_debugger
== KDP_CUR_DB
)
701 printf("Connected to remote debugger.\n");
706 unsigned int exception
,
711 unsigned short remote_port
;
712 unsigned int timeout_count
= 100;
713 unsigned int poll_timeout
;
716 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
717 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
719 (unsigned short *)&remote_port
,
720 (unsigned int)exception
,
722 (unsigned int)subcode
);
724 kdp_send(remote_port
);
727 while(!pkt
.input
&& poll_timeout
)
734 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
741 if (kdp
.exception_ack_needed
)
744 } while (kdp
.exception_ack_needed
&& timeout_count
--);
746 if (kdp
.exception_ack_needed
) {
747 // give up & disconnect
748 printf("kdp: exception ack timeout\n");
749 if (current_debugger
== KDP_CUR_DB
)
757 unsigned int exception
,
759 unsigned int subcode
,
765 extern unsigned int disableConsoleOutput
;
767 disable_preemption();
769 if (saved_state
== 0)
770 printf("kdp_raise_exception with NULL state\n");
773 if (exception
!= EXC_BREAKPOINT
) {
774 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
777 printf("%s exception (%x,%x,%x)\n",
778 exception_message
[index
],
779 exception
, code
, subcode
);
784 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
785 * do this. I think the client and the host can get out of sync.
787 kdp
.saved_state
= saved_state
;
790 kdp_panic("kdp_raise_exception");
792 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
) || (kdp_flag
& PANIC_LOG_DUMP
))
793 && (panicstr
!= (char *) 0)) {
799 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && (panicstr
== (char *) 0) &&
802 disableDebugOuput
= disableConsoleOutput
= FALSE
;
805 if (!(kdp_flag
& DBG_POST_CORE
))
806 goto exit_raise_exception
;
811 kdp_connection_wait();
813 kdp_send_exception(exception
, code
, subcode
);
814 if (kdp
.exception_ack_needed
) {
815 kdp
.exception_ack_needed
= FALSE
;
816 kdp_remove_all_breakpoints();
817 printf("Remote debugger disconnected.\n");
822 kdp
.is_halted
= TRUE
; /* XXX */
823 kdp_handler(saved_state
);
826 kdp_remove_all_breakpoints();
827 printf("Remote debugger disconnected.\n");
830 /* Allow triggering a panic core dump when connected to the machine
831 * Continuing after setting kdp_trigger_core_dump should do the
835 if (1 == kdp_trigger_core_dump
) {
836 kdp_flag
&= ~PANIC_LOG_DUMP
;
837 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
841 /* Trigger a reboot if the user has set this flag through the
842 * debugger.Ideally, this would be done through the HOSTREBOOT packet
843 * in the protocol,but that will need gdb support,and when it's
844 * available, it should work automatically.
846 if (1 == flag_kdp_trigger_reboot
) {
848 /* If we're still around, reset the flag */
849 flag_kdp_trigger_reboot
= 0;
854 if (reattach_wait
== 1)
857 exit_raise_exception
:
864 kdp
.reply_port
= kdp
.exception_port
= 0;
865 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
866 kdp
.exception_seq
= kdp
.conn_seq
= 0;
870 create_panic_header(unsigned int request
, const char *corename
,
871 unsigned length
, unsigned int block
)
873 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
874 struct ip aligned_ip
, *ip
= &aligned_ip
;
875 struct ether_header
*eh
;
876 struct corehdr
*coreh
;
877 const char *mode
= "octet";
878 char modelen
= strlen(mode
);
880 pkt
.off
= sizeof (struct ether_header
);
881 pkt
.len
= length
+ ((request
== KDP_WRQ
) ? modelen
: 0) +
882 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
);
885 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
887 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
889 ui
->ui_next
= ui
->ui_prev
= 0;
891 ui
->ui_pr
= IPPROTO_UDP
;
892 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
893 ui
->ui_src
.s_addr
= htonl(kdp_current_ip_address
);
894 ui
->ui_dst
.s_addr
= panic_server_ip
;
895 ui
->ui_sport
= htons(CORE_REMOTE_PORT
);
896 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(CORE_REMOTE_PORT
) : last_panic_port
);
897 ui
->ui_ulen
= ui
->ui_len
;
900 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
901 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
903 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
905 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
906 ip
->ip_v
= IPVERSION
;
907 ip
->ip_id
= htons(ip_id
++);
908 ip
->ip_hl
= sizeof (struct ip
) >> 2;
909 ip
->ip_ttl
= udp_ttl
;
911 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
913 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
916 pkt
.len
+= sizeof (struct udpiphdr
);
918 pkt
.off
+= sizeof (struct udpiphdr
);
920 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
921 coreh
->th_opcode
= htons((u_short
)request
);
923 if (request
== KDP_WRQ
)
927 cp
= coreh
->th_u
.tu_rpl
;
928 strcpy (cp
, corename
);
929 cp
+= strlen(corename
);
937 coreh
->th_block
= htonl((unsigned int) block
);
940 pkt
.off
-= sizeof (struct udpiphdr
);
941 pkt
.off
-= sizeof (struct ether_header
);
943 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
944 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
945 enaddr_copy(&router_mac
, eh
->ether_dhost
);
946 eh
->ether_type
= htons(ETHERTYPE_IP
);
948 pkt
.len
+= sizeof (struct ether_header
);
952 int kdp_send_panic_packets (unsigned int request
, char *corename
,
953 unsigned int length
, unsigned int txstart
)
955 unsigned int txend
= txstart
+ length
;
958 if (length
<= SEGSIZE
) {
959 if ((panic_error
= kdp_send_panic_pkt (request
, corename
, length
, (caddr_t
) txstart
)) < 0) {
960 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
966 while (txstart
<= (txend
- SEGSIZE
)) {
967 if ((panic_error
= kdp_send_panic_pkt (KDP_DATA
, NULL
, SEGSIZE
, (caddr_t
) txstart
)) < 0) {
968 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
972 if (!(panic_block
% 2000))
975 if (txstart
< txend
) {
976 kdp_send_panic_pkt(request
, corename
, (txend
- txstart
), (caddr_t
) txstart
);
983 kdp_send_panic_pkt (unsigned int request
, char *corename
,
984 unsigned int length
, void *panic_data
)
986 struct corehdr
*th
= NULL
;
987 int poll_count
= 2500;
989 char rretries
= 0, tretries
= 0;
991 extern signed long gIODebuggerSemaphore;
993 pkt
.off
= pkt
.len
= 0;
995 if (request
== KDP_WRQ
) /* longer timeout for initial request */
1002 printf("TX retry #%d ", tretries
);
1004 if (tretries
>=15) {
1005 /* This iokit layer issue can potentially
1006 *cause a hang, uncomment to check if it's happening.
1009 if (gIODebuggerSemaphore)
1010 printf("The gIODebuggerSemaphore is raised, preventing packet transmission (2760413)\n");
1013 printf ("Cannot contact panic server, timing out.\n");
1017 th
= create_panic_header(request
, corename
, length
, panic_block
);
1019 if (request
== KDP_DATA
|| request
== KDP_SEEK
) {
1020 if (!kdp_vm_read ((caddr_t
) panic_data
, (caddr_t
) th
->th_data
, length
)) {
1021 memset ((caddr_t
) th
->th_data
, 'X', length
);
1025 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
1027 /* Now we have to listen for the ACK */
1030 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1039 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1040 /* These will eventually have to be ntoh[ls]'ed as appropriate */
1042 if (th
->th_opcode
== KDP_ACK
&& th
->th_block
== panic_block
) {
1045 if (th
->th_opcode
== KDP_ERROR
) {
1046 printf("Panic server returned error %d, retrying\n", th
->th_code
);
1048 goto TRANSMIT_RETRY
;
1051 if (th
->th_block
== (panic_block
-1)) {
1052 printf("RX retry ");
1054 goto TRANSMIT_RETRY
;
1060 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1062 printf("Received a debugger packet,transferring control to debugger\n");
1063 /* Configure that if not set ..*/
1064 kdp_flag
|= DBG_POST_CORE
;
1067 else /* We timed out */
1068 if (0 == poll_count
) {
1070 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1071 goto TRANSMIT_RETRY
;
1076 if (request
== KDP_EOF
)
1077 printf ("\nTotal number of packets transmitted: %d\n", panic_block
);
1082 /* Since we don't seem to have an isdigit() .. */
1086 return ((c
> 47) && (c
< 58));
1088 /* From user mode Libc - this ought to be in a library */
1090 strnstr(s
, find
, slen
)
1098 if ((c
= *find
++) != '\0') {
1102 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1107 } while (strncmp(s
, find
, len
) != 0);
1113 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1114 * would be to have the integrator run a script which would copy the
1115 * xnu version into a string or an int somewhere at project submission
1116 * time - makes assumptions about sizeof(version), but will not fail if
1117 * it changes, but may be incorrect.
1121 kdp_get_xnu_version(char *versionbuf
)
1123 extern const char version
[];
1128 strcpy(vstr
, "custom");
1130 if (kdp_vm_read(version
, versionbuf
, 90)) {
1132 versionbuf
[89] = '\0';
1134 versionpos
= strnstr(versionbuf
, "xnu-", 80);
1137 strncpy (vstr
, versionpos
, (isdigit (versionpos
[7]) ? 8 : 7));
1138 vstr
[(isdigit (versionpos
[7]) ? 8 : 7)] = '\0';
1143 strcpy(versionbuf
, vstr
);
1147 /* Primary dispatch routine for the system dump */
1152 char coreprefix
[10];
1155 extern vm_map_t kernel_map
;
1157 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1161 printf ("Entering system dump routine\n");
1163 if (!panicd_specified
) {
1164 printf ("A panic server was not specified in the boot-args, terminating kernel core dump.\n");
1165 goto panic_dump_exit
;
1168 flag_panic_dump_in_progress
= 1;
1172 kdp_panic("kdp_panic_dump");
1174 kdp_get_xnu_version((char *) &pkt
.data
[0]);
1176 /* Panic log bit takes precedence over core dump bit */
1177 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
))
1178 strncpy(coreprefix
, "paniclog", sizeof(coreprefix
));
1180 strncpy(coreprefix
, "core", sizeof(coreprefix
));
1182 abstime
= mach_absolute_time();
1183 pkt
.data
[10] = '\0';
1184 snprintf (corename
, sizeof(corename
), "%s-%s-%d.%d.%d.%d-%x",
1185 coreprefix
, &pkt
.data
[0],
1186 (kdp_current_ip_address
& 0xff000000) >> 24,
1187 (kdp_current_ip_address
& 0xff0000) >> 16,
1188 (kdp_current_ip_address
& 0xff00) >> 8,
1189 (kdp_current_ip_address
& 0xff),
1190 (unsigned int) (abstime
& 0xffffffff));
1192 if (0 == inet_aton(panicd_ip_str
, (struct in_addr
*) &panic_server_ip
)) {
1193 printf("inet_aton() failed interpreting %s as a panic server IP\n",
1197 printf("Attempting connection to panic server configured at IP %s\n",
1200 if (router_specified
) {
1201 if (0 == inet_aton(router_ip_str
, (struct in_addr
*) &parsed_router_ip
)){
1202 printf("inet_aton() failed interpreting %s as an IP\n", router_ip
);
1205 router_ip
= parsed_router_ip
;
1206 printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
1207 /* We will eventually need to resolve the router's MAC ourselves,
1208 * if one is specified,rather than being set through the BSD callback
1209 * but the _router_ip option does not function currently
1214 printf("Routing via router MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1215 router_mac
.ether_addr_octet
[0] & 0xff,
1216 router_mac
.ether_addr_octet
[1] & 0xff,
1217 router_mac
.ether_addr_octet
[2] & 0xff,
1218 router_mac
.ether_addr_octet
[3] & 0xff,
1219 router_mac
.ether_addr_octet
[4] & 0xff,
1220 router_mac
.ether_addr_octet
[5] & 0xff);
1222 printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map
));
1223 printf ("Sending write request for %s\n", corename
);
1225 if ((panic_error
= kdp_send_panic_pkt (KDP_WRQ
, corename
, 0 , NULL
)) < 0) {
1226 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
1227 goto panic_dump_exit
;
1230 /* Just the panic log requested */
1231 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
1232 printf("Transmitting panic log, please wait: ");
1233 kdp_send_panic_packets (KDP_DATA
, corename
, (debug_buf_ptr
- debug_buf
), (unsigned int) debug_buf
);
1234 kdp_send_panic_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1235 printf("Please file a bug report on this panic, if possible.\n");
1236 goto panic_dump_exit
;
1239 /* We want a core dump if we're here */
1243 flag_panic_dump_in_progress
= 0;
1252 abort_panic_transfer()
1254 flag_panic_dump_in_progress
= 0;