2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_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 License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1982, 1986, 1993
30 * The Regents of the University of California. All rights reserved.
34 * Kernel Debugging Protocol UDP implementation.
38 #include <mach/boolean.h>
39 #include <mach/mach_types.h>
40 #include <mach/exception_types.h>
41 #include <kern/cpu_data.h>
42 #include <kern/debug.h>
44 #include <kdp/kdp_internal.h>
45 #include <kdp/kdp_en_debugger.h>
46 #include <kdp/kdp_udp.h>
48 #include <kdp/kdp_core.h>
50 #include <vm/vm_map.h>
51 #include <vm/vm_protos.h>
53 #include <mach/memory_object_types.h>
57 #define DO_ALIGN 1 /* align all packet data accesses */
59 extern int kdp_getc(void);
60 extern int reattach_wait
;
62 static u_short ip_id
; /* ip packet ctr, for ids */
64 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
67 * UDP protocol implementation.
68 * Per RFC 768, August, 1980.
70 #define UDP_TTL 60 /* deflt time to live for UDP packets */
71 int udp_ttl
= UDP_TTL
;
72 static unsigned char exception_seq
;
75 unsigned char data
[KDP_MAXPACKET
];
76 unsigned int off
, len
;
92 *exception_message
[] = {
94 "Memory access", /* EXC_BAD_ACCESS */
95 "Failed instruction", /* EXC_BAD_INSTRUCTION */
96 "Arithmetic", /* EXC_ARITHMETIC */
97 "Emulation", /* EXC_EMULATION */
98 "Software", /* EXC_SOFTWARE */
99 "Breakpoint" /* EXC_BREAKPOINT */
104 static kdp_send_t kdp_en_send_pkt
= 0;
105 static kdp_receive_t kdp_en_recv_pkt
= 0;
108 static u_long kdp_current_ip_address
= 0;
109 static struct ether_addr kdp_current_mac_address
= {{0, 0, 0, 0, 0, 0}};
110 static void *kdp_current_ifp
= 0;
112 static void kdp_handler( void *);
114 static unsigned int panic_server_ip
= 0;
115 static unsigned int parsed_router_ip
= 0;
116 static unsigned int router_ip
= 0;
117 static unsigned int panicd_specified
= 0;
118 static unsigned int router_specified
= 0;
120 static struct ether_addr router_mac
= {{0, 0, 0 , 0, 0, 0}};
122 static u_char flag_panic_dump_in_progress
= 0;
123 static u_char flag_router_mac_initialized
= 0;
125 static unsigned int panic_timeout
= 100000;
126 static unsigned int last_panic_port
= CORE_REMOTE_PORT
;
128 unsigned int SEGSIZE
= 512;
130 static unsigned int PANIC_PKTSIZE
= 518;
131 static char panicd_ip_str
[20];
132 static char router_ip_str
[20];
134 static unsigned int panic_block
= 0;
135 static volatile unsigned int kdp_trigger_core_dump
= 0;
136 static volatile unsigned int flag_kdp_trigger_reboot
= 0;
138 extern unsigned int not_in_kdp
;
140 extern int kdp_vm_read( caddr_t
, caddr_t
, unsigned int);
143 kdp_register_send_receive(
145 kdp_receive_t receive
)
147 unsigned int debug
=0;
149 kdp_en_send_pkt
= send
;
150 kdp_en_recv_pkt
= receive
;
154 PE_parse_boot_arg("debug", &debug
);
156 if (debug
& DB_KDP_BP_DIS
)
157 kdp_flag
|= KDP_BP_DIS
;
158 if (debug
& DB_KDP_GETC_ENA
)
159 kdp_flag
|= KDP_GETC_ENA
;
163 if (debug
& DB_KERN_DUMP_ON_PANIC
)
164 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
165 if (debug
& DB_KERN_DUMP_ON_NMI
)
166 kdp_flag
|= PANIC_CORE_ON_NMI
;
168 if (debug
& DB_DBG_POST_CORE
)
169 kdp_flag
|= DBG_POST_CORE
;
171 if (debug
& DB_PANICLOG_DUMP
)
172 kdp_flag
|= PANIC_LOG_DUMP
;
174 if (PE_parse_boot_arg ("_panicd_ip", panicd_ip_str
))
175 panicd_specified
= 1;
176 /* For the future, currently non-functional */
177 if (PE_parse_boot_arg ("_router_ip", router_ip_str
))
178 router_specified
= 1;
180 kdp_flag
|= KDP_READY
;
181 if (current_debugger
== NO_CUR_DB
)
182 current_debugger
= KDP_CUR_DB
;
183 if (halt_in_debugger
) {
190 kdp_unregister_send_receive(
192 kdp_receive_t receive
)
194 if (current_debugger
== KDP_CUR_DB
)
195 current_debugger
= NO_CUR_DB
;
196 kdp_flag
&= ~KDP_READY
;
197 kdp_en_send_pkt
= NULL
;
198 kdp_en_recv_pkt
= NULL
;
207 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
210 static unsigned short
216 unsigned int high
, low
, sum
;
226 sum
= (high
<< 8) + low
;
227 sum
= (sum
>> 16) + (sum
& 65535);
229 return (sum
> 65535 ? sum
- 65535 : sum
);
234 unsigned short reply_port
237 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
238 struct ip aligned_ip
, *ip
= &aligned_ip
;
239 struct in_addr tmp_ipaddr
;
240 struct ether_addr tmp_enaddr
;
241 struct ether_header
*eh
;
244 kdp_panic("kdp_reply");
246 pkt
.off
-= sizeof (struct udpiphdr
);
249 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
251 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
253 ui
->ui_next
= ui
->ui_prev
= 0;
255 ui
->ui_pr
= IPPROTO_UDP
;
256 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
257 tmp_ipaddr
= ui
->ui_src
;
258 ui
->ui_src
= ui
->ui_dst
;
259 ui
->ui_dst
= tmp_ipaddr
;
260 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
261 ui
->ui_dport
= reply_port
;
262 ui
->ui_ulen
= ui
->ui_len
;
265 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
266 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
268 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
270 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
271 ip
->ip_v
= IPVERSION
;
272 ip
->ip_id
= htons(ip_id
++);
273 ip
->ip_hl
= sizeof (struct ip
) >> 2;
274 ip
->ip_ttl
= udp_ttl
;
276 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
278 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
281 pkt
.len
+= sizeof (struct udpiphdr
);
283 pkt
.off
-= sizeof (struct ether_header
);
285 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
286 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
287 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
288 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
289 eh
->ether_type
= htons(ETHERTYPE_IP
);
291 pkt
.len
+= sizeof (struct ether_header
);
293 // save reply for possible retransmission
294 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
296 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
298 // increment expected sequence number
304 unsigned short remote_port
307 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
308 struct ip aligned_ip
, *ip
= &aligned_ip
;
309 struct ether_header
*eh
;
312 kdp_panic("kdp_send");
314 pkt
.off
-= sizeof (struct udpiphdr
);
317 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
319 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
321 ui
->ui_next
= ui
->ui_prev
= 0;
323 ui
->ui_pr
= IPPROTO_UDP
;
324 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
325 ui
->ui_src
= adr
.loc
.in
;
326 ui
->ui_dst
= adr
.rmt
.in
;
327 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
328 ui
->ui_dport
= remote_port
;
329 ui
->ui_ulen
= ui
->ui_len
;
332 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
333 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
335 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
337 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
338 ip
->ip_v
= IPVERSION
;
339 ip
->ip_id
= htons(ip_id
++);
340 ip
->ip_hl
= sizeof (struct ip
) >> 2;
341 ip
->ip_ttl
= udp_ttl
;
343 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
345 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
348 pkt
.len
+= sizeof (struct udpiphdr
);
350 pkt
.off
-= sizeof (struct ether_header
);
352 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
353 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
354 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
355 eh
->ether_type
= htons(ETHERTYPE_IP
);
357 pkt
.len
+= sizeof (struct ether_header
);
358 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
361 /* We don't interpret this pointer, we just give it to the
362 bsd stack so it can decide when to set the MAC and IP info. */
364 kdp_set_interface(void *ifp
)
366 kdp_current_ifp
= ifp
;
372 return kdp_current_ifp
;
376 kdp_set_ip_and_mac_addresses(
377 struct in_addr
*ipaddr
,
378 struct ether_addr
*macaddr
)
380 kdp_current_ip_address
= ipaddr
->s_addr
;
381 kdp_current_mac_address
= *macaddr
;
385 kdp_set_gateway_mac(void *gatewaymac
)
387 router_mac
= *(struct ether_addr
*)gatewaymac
;
388 flag_router_mac_initialized
= 1;
392 kdp_get_mac_addr(void)
394 return kdp_current_mac_address
;
398 kdp_get_ip_address(void)
400 return kdp_current_ip_address
;
403 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
404 is set. A workaround if you don't want to reboot is to set
405 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
411 struct ether_header
*eh
;
412 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
414 struct in_addr isaddr
, itaddr
, myaddr
;
415 struct ether_addr my_enaddr
;
417 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
418 pkt
.off
+= sizeof(struct ether_header
);
420 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
422 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
425 myaddr
.s_addr
= kdp_get_ip_address();
426 my_enaddr
= kdp_get_mac_addr();
428 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
431 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
432 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
434 if (itaddr
.s_addr
== myaddr
.s_addr
) {
435 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
436 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
438 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
439 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
441 ea
->arp_op
= htons(ARPOP_REPLY
);
442 ea
->arp_pro
= htons(ETHERTYPE_IP
);
443 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
444 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
445 eh
->ether_type
= htons(ETHERTYPE_ARP
);
446 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
447 pkt
.off
-= sizeof (struct ether_header
);
448 /* pkt.len is still the length we want, ether_header+ether_arp */
449 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
456 struct ether_header
*eh
;
457 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
458 struct ip aligned_ip
, *ip
= &aligned_ip
;
459 static int msg_printed
;
463 kdp_panic("kdp_poll");
465 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
466 if( msg_printed
== 0) {
468 printf("kdp_poll: no debugger device\n");
473 pkt
.off
= pkt
.len
= 0;
474 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
479 if (pkt
.len
>= sizeof(struct ether_header
))
481 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
483 if (kdp_flag
& KDP_ARP
)
485 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
493 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
496 pkt
.off
+= sizeof (struct ether_header
);
497 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
502 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
503 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
505 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
506 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
509 pkt
.off
+= sizeof (struct udpiphdr
);
510 if (ui
->ui_pr
!= IPPROTO_UDP
) {
514 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
518 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
519 if (CORE_REMOTE_PORT
== (ntohs(ui
->ui_dport
)) &&
520 flag_panic_dump_in_progress
) {
521 last_panic_port
= ui
->ui_sport
;
526 /* If we receive a kernel debugging packet whilst a
527 * core dump is in progress, abort the transfer and
528 * enter the debugger.
531 if (flag_panic_dump_in_progress
)
533 abort_panic_transfer();
537 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
538 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
539 adr
.loc
.in
= ui
->ui_dst
;
541 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
542 adr
.rmt
.in
= ui
->ui_src
;
546 * Calculate kdp packet length.
548 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
557 unsigned short reply_port
;
558 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
561 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
568 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
570 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
573 // ignore replies -- we're not expecting them anyway.
578 if (hdr
->request
== KDP_REATTACH
)
579 exception_seq
= hdr
->seq
;
581 // check for retransmitted request
582 if (hdr
->seq
== (exception_seq
- 1)) {
583 /* retransmit last reply */
584 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
587 } else if (hdr
->seq
!= exception_seq
) {
588 printf("kdp: bad sequence %d (want %d)\n",
589 hdr
->seq
, exception_seq
);
593 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
595 (unsigned short *)&reply_port
)) {
596 kdp_reply(reply_port
);
601 } while (kdp
.is_halted
);
605 kdp_connection_wait(void)
607 unsigned short reply_port
;
608 boolean_t
kdp_call_kdb();
609 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
610 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
612 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
613 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
614 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
615 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
616 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
617 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
618 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
620 printf( "ip address: %d.%d.%d.%d\n",
621 (ip_addr
& 0xff000000) >> 24,
622 (ip_addr
& 0xff0000) >> 16,
623 (ip_addr
& 0xff00) >> 8,
626 printf("\nWaiting for remote debugger connection.\n");
628 if (reattach_wait
== 0) {
629 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
631 printf("Options..... Type\n");
632 printf("------------ ----\n");
633 printf("continue.... 'c'\n");
634 printf("reboot...... 'r'\n");
636 printf("enter kdb... 'k'\n");
645 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
648 if (kdp_flag
& KDP_GETC_ENA
) {
651 printf("Continuing...\n");
654 printf("Rebooting...\n");
659 printf("calling kdb...\n");
663 printf("not implemented...\n");
673 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
675 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
677 if (hdr
->request
== KDP_HOSTREBOOT
) {
679 /* should not return! */
681 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
682 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
683 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
685 (unsigned short *)&reply_port
))
686 kdp_reply(reply_port
);
687 if (hdr
->request
== KDP_REATTACH
) {
689 hdr
->request
=KDP_DISCONNECT
;
695 } while (!kdp
.is_conn
);
697 if (current_debugger
== KDP_CUR_DB
)
699 printf("Connected to remote debugger.\n");
704 unsigned int exception
,
709 unsigned short remote_port
;
710 unsigned int timeout_count
= 100;
711 unsigned int poll_timeout
;
714 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
715 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
717 (unsigned short *)&remote_port
,
718 (unsigned int)exception
,
720 (unsigned int)subcode
);
722 kdp_send(remote_port
);
725 while(!pkt
.input
&& poll_timeout
)
732 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
739 if (kdp
.exception_ack_needed
)
742 } while (kdp
.exception_ack_needed
&& timeout_count
--);
744 if (kdp
.exception_ack_needed
) {
745 // give up & disconnect
746 printf("kdp: exception ack timeout\n");
747 if (current_debugger
== KDP_CUR_DB
)
755 unsigned int exception
,
757 unsigned int subcode
,
763 extern unsigned int disableConsoleOutput
;
765 disable_preemption();
767 if (saved_state
== 0)
768 printf("kdp_raise_exception with NULL state\n");
771 if (exception
!= EXC_BREAKPOINT
) {
772 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
775 printf("%s exception (%x,%x,%x)\n",
776 exception_message
[index
],
777 exception
, code
, subcode
);
782 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
783 * do this. I think the client and the host can get out of sync.
785 kdp
.saved_state
= saved_state
;
788 kdp_panic("kdp_raise_exception");
790 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
) || (kdp_flag
& PANIC_LOG_DUMP
))
791 && (panicstr
!= (char *) 0)) {
797 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && (panicstr
== (char *) 0) &&
800 disableDebugOuput
= disableConsoleOutput
= FALSE
;
803 if (!(kdp_flag
& DBG_POST_CORE
))
804 goto exit_raise_exception
;
809 kdp_connection_wait();
811 kdp_send_exception(exception
, code
, subcode
);
812 if (kdp
.exception_ack_needed
) {
813 kdp
.exception_ack_needed
= FALSE
;
814 kdp_remove_all_breakpoints();
815 printf("Remote debugger disconnected.\n");
820 kdp
.is_halted
= TRUE
; /* XXX */
821 kdp_handler(saved_state
);
824 kdp_remove_all_breakpoints();
825 printf("Remote debugger disconnected.\n");
828 /* Allow triggering a panic core dump when connected to the machine
829 * Continuing after setting kdp_trigger_core_dump should do the
833 if (1 == kdp_trigger_core_dump
) {
834 kdp_flag
&= ~PANIC_LOG_DUMP
;
835 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
839 /* Trigger a reboot if the user has set this flag through the
840 * debugger.Ideally, this would be done through the HOSTREBOOT packet
841 * in the protocol,but that will need gdb support,and when it's
842 * available, it should work automatically.
844 if (1 == flag_kdp_trigger_reboot
) {
846 /* If we're still around, reset the flag */
847 flag_kdp_trigger_reboot
= 0;
852 if (reattach_wait
== 1)
855 exit_raise_exception
:
862 kdp
.reply_port
= kdp
.exception_port
= 0;
863 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
864 kdp
.exception_seq
= kdp
.conn_seq
= 0;
868 create_panic_header(unsigned int request
, const char *corename
,
869 unsigned length
, unsigned int block
)
871 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
872 struct ip aligned_ip
, *ip
= &aligned_ip
;
873 struct ether_header
*eh
;
874 struct corehdr
*coreh
;
875 const char *mode
= "octet";
876 char modelen
= strlen(mode
);
878 pkt
.off
= sizeof (struct ether_header
);
879 pkt
.len
= length
+ ((request
== KDP_WRQ
) ? modelen
: 0) +
880 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
);
883 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
885 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
887 ui
->ui_next
= ui
->ui_prev
= 0;
889 ui
->ui_pr
= IPPROTO_UDP
;
890 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
891 ui
->ui_src
.s_addr
= htonl(kdp_current_ip_address
);
892 ui
->ui_dst
.s_addr
= panic_server_ip
;
893 ui
->ui_sport
= htons(CORE_REMOTE_PORT
);
894 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(CORE_REMOTE_PORT
) : last_panic_port
);
895 ui
->ui_ulen
= ui
->ui_len
;
898 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
899 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
901 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
903 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
904 ip
->ip_v
= IPVERSION
;
905 ip
->ip_id
= htons(ip_id
++);
906 ip
->ip_hl
= sizeof (struct ip
) >> 2;
907 ip
->ip_ttl
= udp_ttl
;
909 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
911 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
914 pkt
.len
+= sizeof (struct udpiphdr
);
916 pkt
.off
+= sizeof (struct udpiphdr
);
918 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
919 coreh
->th_opcode
= htons((u_short
)request
);
921 if (request
== KDP_WRQ
)
925 cp
= coreh
->th_u
.tu_rpl
;
926 strcpy (cp
, corename
);
927 cp
+= strlen(corename
);
935 coreh
->th_block
= htonl((unsigned int) block
);
938 pkt
.off
-= sizeof (struct udpiphdr
);
939 pkt
.off
-= sizeof (struct ether_header
);
941 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
942 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
943 enaddr_copy(&router_mac
, eh
->ether_dhost
);
944 eh
->ether_type
= htons(ETHERTYPE_IP
);
946 pkt
.len
+= sizeof (struct ether_header
);
950 int kdp_send_panic_packets (unsigned int request
, char *corename
,
951 unsigned int length
, unsigned int txstart
)
953 unsigned int txend
= txstart
+ length
;
956 if (length
<= SEGSIZE
) {
957 if ((panic_error
= kdp_send_panic_pkt (request
, corename
, length
, (caddr_t
) txstart
)) < 0) {
958 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
964 while (txstart
<= (txend
- SEGSIZE
)) {
965 if ((panic_error
= kdp_send_panic_pkt (KDP_DATA
, NULL
, SEGSIZE
, (caddr_t
) txstart
)) < 0) {
966 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
970 if (!(panic_block
% 2000))
973 if (txstart
< txend
) {
974 kdp_send_panic_pkt(request
, corename
, (txend
- txstart
), (caddr_t
) txstart
);
981 kdp_send_panic_pkt (unsigned int request
, char *corename
,
982 unsigned int length
, void *panic_data
)
984 struct corehdr
*th
= NULL
;
985 int poll_count
= 2500;
987 char rretries
= 0, tretries
= 0;
989 extern signed long gIODebuggerSemaphore;
991 pkt
.off
= pkt
.len
= 0;
993 if (request
== KDP_WRQ
) /* longer timeout for initial request */
1000 printf("TX retry #%d ", tretries
);
1002 if (tretries
>=15) {
1003 /* This iokit layer issue can potentially
1004 *cause a hang, uncomment to check if it's happening.
1007 if (gIODebuggerSemaphore)
1008 printf("The gIODebuggerSemaphore is raised, preventing packet transmission (2760413)\n");
1011 printf ("Cannot contact panic server, timing out.\n");
1015 th
= create_panic_header(request
, corename
, length
, panic_block
);
1017 if (request
== KDP_DATA
|| request
== KDP_SEEK
) {
1018 if (!kdp_vm_read ((caddr_t
) panic_data
, (caddr_t
) th
->th_data
, length
)) {
1019 memset ((caddr_t
) th
->th_data
, 'X', length
);
1023 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
1025 /* Now we have to listen for the ACK */
1028 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1037 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1038 /* These will eventually have to be ntoh[ls]'ed as appropriate */
1040 if (th
->th_opcode
== KDP_ACK
&& th
->th_block
== panic_block
) {
1043 if (th
->th_opcode
== KDP_ERROR
) {
1044 printf("Panic server returned error %d, retrying\n", th
->th_code
);
1046 goto TRANSMIT_RETRY
;
1049 if (th
->th_block
== (panic_block
-1)) {
1050 printf("RX retry ");
1052 goto TRANSMIT_RETRY
;
1058 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1060 printf("Received a debugger packet,transferring control to debugger\n");
1061 /* Configure that if not set ..*/
1062 kdp_flag
|= DBG_POST_CORE
;
1065 else /* We timed out */
1066 if (0 == poll_count
) {
1068 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1069 goto TRANSMIT_RETRY
;
1074 if (request
== KDP_EOF
)
1075 printf ("\nTotal number of packets transmitted: %d\n", panic_block
);
1080 /* Since we don't seem to have an isdigit() .. */
1084 return ((c
> 47) && (c
< 58));
1086 /* From user mode Libc - this ought to be in a library */
1088 strnstr(s
, find
, slen
)
1096 if ((c
= *find
++) != '\0') {
1100 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1105 } while (strncmp(s
, find
, len
) != 0);
1111 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1112 * would be to have the integrator run a script which would copy the
1113 * xnu version into a string or an int somewhere at project submission
1114 * time - makes assumptions about sizeof(version), but will not fail if
1115 * it changes, but may be incorrect.
1119 kdp_get_xnu_version(char *versionbuf
)
1121 extern const char version
[];
1126 strcpy(vstr
, "custom");
1128 if (kdp_vm_read(version
, versionbuf
, 90)) {
1130 versionbuf
[89] = '\0';
1132 versionpos
= strnstr(versionbuf
, "xnu-", 80);
1135 strncpy (vstr
, versionpos
, (isdigit (versionpos
[7]) ? 8 : 7));
1136 vstr
[(isdigit (versionpos
[7]) ? 8 : 7)] = '\0';
1141 strcpy(versionbuf
, vstr
);
1145 /* Primary dispatch routine for the system dump */
1150 char coreprefix
[10];
1153 extern vm_map_t kernel_map
;
1155 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1159 printf ("Entering system dump routine\n");
1161 if (!panicd_specified
) {
1162 printf ("A panic server was not specified in the boot-args, terminating kernel core dump.\n");
1163 goto panic_dump_exit
;
1166 flag_panic_dump_in_progress
= 1;
1170 kdp_panic("kdp_panic_dump");
1172 kdp_get_xnu_version((char *) &pkt
.data
[0]);
1174 /* Panic log bit takes precedence over core dump bit */
1175 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
))
1176 strncpy(coreprefix
, "paniclog", sizeof(coreprefix
));
1178 strncpy(coreprefix
, "core", sizeof(coreprefix
));
1180 abstime
= mach_absolute_time();
1181 pkt
.data
[10] = '\0';
1182 snprintf (corename
, sizeof(corename
), "%s-%s-%d.%d.%d.%d-%x",
1183 coreprefix
, &pkt
.data
[0],
1184 (kdp_current_ip_address
& 0xff000000) >> 24,
1185 (kdp_current_ip_address
& 0xff0000) >> 16,
1186 (kdp_current_ip_address
& 0xff00) >> 8,
1187 (kdp_current_ip_address
& 0xff),
1188 (unsigned int) (abstime
& 0xffffffff));
1190 if (0 == inet_aton(panicd_ip_str
, (struct in_addr
*) &panic_server_ip
)) {
1191 printf("inet_aton() failed interpreting %s as a panic server IP\n",
1195 printf("Attempting connection to panic server configured at IP %s\n",
1198 if (router_specified
) {
1199 if (0 == inet_aton(router_ip_str
, (struct in_addr
*) &parsed_router_ip
)){
1200 printf("inet_aton() failed interpreting %s as an IP\n", router_ip
);
1203 router_ip
= parsed_router_ip
;
1204 printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
1205 /* We will eventually need to resolve the router's MAC ourselves,
1206 * if one is specified,rather than being set through the BSD callback
1207 * but the _router_ip option does not function currently
1212 printf("Routing via router MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1213 router_mac
.ether_addr_octet
[0] & 0xff,
1214 router_mac
.ether_addr_octet
[1] & 0xff,
1215 router_mac
.ether_addr_octet
[2] & 0xff,
1216 router_mac
.ether_addr_octet
[3] & 0xff,
1217 router_mac
.ether_addr_octet
[4] & 0xff,
1218 router_mac
.ether_addr_octet
[5] & 0xff);
1220 printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map
));
1221 printf ("Sending write request for %s\n", corename
);
1223 if ((panic_error
= kdp_send_panic_pkt (KDP_WRQ
, corename
, 0 , NULL
)) < 0) {
1224 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
1225 goto panic_dump_exit
;
1228 /* Just the panic log requested */
1229 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
1230 printf("Transmitting panic log, please wait: ");
1231 kdp_send_panic_packets (KDP_DATA
, corename
, (debug_buf_ptr
- debug_buf
), (unsigned int) debug_buf
);
1232 kdp_send_panic_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1233 printf("Please file a bug report on this panic, if possible.\n");
1234 goto panic_dump_exit
;
1237 /* We want a core dump if we're here */
1241 flag_panic_dump_in_progress
= 0;
1250 abort_panic_transfer()
1252 flag_panic_dump_in_progress
= 0;