2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1982, 1986, 1993
27 * The Regents of the University of California. All rights reserved.
31 * Kernel Debugging Protocol UDP implementation.
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>
41 #include <kdp/kdp_internal.h>
42 #include <kdp/kdp_en_debugger.h>
43 #include <kdp/kdp_udp.h>
45 #include <kdp/kdp_core.h>
47 #include <vm/vm_map.h>
48 #include <mach/memory_object_types.h>
52 #define DO_ALIGN 1 /* align all packet data accesses */
54 extern int kdp_getc(void);
55 extern int reattach_wait
;
57 static u_short ip_id
; /* ip packet ctr, for ids */
59 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
62 * UDP protocol implementation.
63 * Per RFC 768, August, 1980.
65 #define UDP_TTL 60 /* deflt time to live for UDP packets */
66 int udp_ttl
= UDP_TTL
;
67 static unsigned char exception_seq
;
70 unsigned char data
[KDP_MAXPACKET
];
71 unsigned int off
, len
;
87 *exception_message
[] = {
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 */
99 static kdp_send_t kdp_en_send_pkt
= 0;
100 static kdp_receive_t kdp_en_recv_pkt
= 0;
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;
107 static void kdp_handler( void *);
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;
115 static struct ether_addr router_mac
= {{0, 0, 0 , 0, 0, 0}};
117 static u_char flag_panic_dump_in_progress
= 0;
118 static u_char flag_router_mac_initialized
= 0;
120 static unsigned int panic_timeout
= 100000;
121 static unsigned int last_panic_port
= CORE_REMOTE_PORT
;
123 unsigned int SEGSIZE
= 512;
125 static unsigned int PANIC_PKTSIZE
= 518;
126 static char panicd_ip_str
[20];
127 static char router_ip_str
[20];
129 static unsigned int panic_block
= 0;
130 static volatile unsigned int kdp_trigger_core_dump
= 0;
132 extern unsigned int not_in_kdp
;
135 kdp_register_send_receive(
137 kdp_receive_t receive
)
141 kdp_en_send_pkt
= send
;
142 kdp_en_recv_pkt
= receive
;
146 PE_parse_boot_arg("debug", &debug
);
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
;
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
;
160 if (debug
& DB_DBG_POST_CORE
)
161 kdp_flag
|= DBG_POST_CORE
;
163 if (debug
& DB_PANICLOG_DUMP
)
164 kdp_flag
|= PANIC_LOG_DUMP
;
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;
172 kdp_flag
|= KDP_READY
;
173 if (current_debugger
== NO_CUR_DB
)
174 current_debugger
= KDP_CUR_DB
;
175 if (halt_in_debugger
) {
182 kdp_unregister_send_receive(
184 kdp_receive_t receive
)
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
;
199 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
202 static unsigned short
208 unsigned int high
, low
, sum
;
218 sum
= (high
<< 8) + low
;
219 sum
= (sum
>> 16) + (sum
& 65535);
221 return (sum
> 65535 ? sum
- 65535 : sum
);
226 unsigned short reply_port
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
;
236 kdp_panic("kdp_reply");
238 pkt
.off
-= sizeof (struct udpiphdr
);
241 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
243 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
245 ui
->ui_next
= ui
->ui_prev
= 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
;
257 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
258 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
260 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
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
;
268 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
270 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
273 pkt
.len
+= sizeof (struct udpiphdr
);
275 pkt
.off
-= sizeof (struct ether_header
);
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
);
283 pkt
.len
+= sizeof (struct ether_header
);
285 // save reply for possible retransmission
286 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
288 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
290 // increment expected sequence number
296 unsigned short remote_port
299 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
300 struct ip aligned_ip
, *ip
= &aligned_ip
;
301 struct ether_header
*eh
;
304 kdp_panic("kdp_send");
306 pkt
.off
-= sizeof (struct udpiphdr
);
309 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
311 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
313 ui
->ui_next
= ui
->ui_prev
= 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
;
324 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
325 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
327 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
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
;
335 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
337 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
340 pkt
.len
+= sizeof (struct udpiphdr
);
342 pkt
.off
-= sizeof (struct ether_header
);
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
);
349 pkt
.len
+= sizeof (struct ether_header
);
350 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
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. */
356 kdp_set_interface(void *ifp
)
358 kdp_current_ifp
= ifp
;
364 return kdp_current_ifp
;
368 kdp_set_ip_and_mac_addresses(
369 struct in_addr
*ipaddr
,
370 struct ether_addr
*macaddr
)
372 unsigned int debug
= 0;
374 kdp_current_ip_address
= ipaddr
->s_addr
;
375 kdp_current_mac_address
= *macaddr
;
379 kdp_set_gateway_mac(void *gatewaymac
)
381 router_mac
= *(struct ether_addr
*)gatewaymac
;
385 kdp_get_mac_addr(void)
387 return kdp_current_mac_address
;
391 kdp_get_ip_address(void)
393 return kdp_current_ip_address
;
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
404 struct ether_header
*eh
;
405 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
407 struct in_addr isaddr
, itaddr
, myaddr
;
408 struct ether_addr my_enaddr
;
410 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
411 pkt
.off
+= sizeof(struct ether_header
);
413 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
415 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
418 myaddr
.s_addr
= kdp_get_ip_address();
419 my_enaddr
= kdp_get_mac_addr();
421 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
424 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
425 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
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
));
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
));
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
);
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
;
456 kdp_panic("kdp_poll");
458 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
459 if( msg_printed
== 0) {
461 printf("kdp_poll: no debugger device\n");
466 pkt
.off
= pkt
.len
= 0;
467 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
472 if (pkt
.len
>= sizeof(struct ether_header
))
474 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
476 if (kdp_flag
& KDP_ARP
)
478 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
486 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
489 pkt
.off
+= sizeof (struct ether_header
);
490 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
495 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
496 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
498 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
499 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
502 pkt
.off
+= sizeof (struct udpiphdr
);
503 if (ui
->ui_pr
!= IPPROTO_UDP
) {
507 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
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
;
519 /* If we receive a kernel debugging packet whilst a
520 * core dump is in progress, abort the transfer and
521 * enter the debugger.
524 if (flag_panic_dump_in_progress
)
526 abort_panic_transfer();
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
;
534 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
535 adr
.rmt
.in
= ui
->ui_src
;
539 * Calculate kdp packet length.
541 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
550 unsigned short reply_port
;
551 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
554 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
561 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
563 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
566 // ignore replies -- we're not expecting them anyway.
571 if (hdr
->request
== KDP_REATTACH
)
572 exception_seq
= hdr
->seq
;
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
],
580 } else if (hdr
->seq
!= exception_seq
) {
581 printf("kdp: bad sequence %d (want %d)\n",
582 hdr
->seq
, exception_seq
);
586 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
588 (unsigned short *)&reply_port
)) {
589 kdp_reply(reply_port
);
594 } while (kdp
.is_halted
);
598 kdp_connection_wait(void)
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());
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);
613 printf( "ip address: %d.%d.%d.%d\n",
614 (ip_addr
& 0xff000000) >> 24,
615 (ip_addr
& 0xff0000) >> 16,
616 (ip_addr
& 0xff00) >> 8,
619 printf("\nWaiting for remote debugger connection.\n");
621 if (reattach_wait
== 0) {
622 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
624 printf("Options..... Type\n");
625 printf("------------ ----\n");
626 printf("continue.... 'c'\n");
627 printf("reboot...... 'r'\n");
629 printf("enter kdb... 'k'\n");
638 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
641 if (kdp_flag
& KDP_GETC_ENA
) {
644 printf("Continuing...\n");
647 printf("Rebooting...\n");
652 printf("calling kdb...\n");
656 printf("not implemented...\n");
666 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
668 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
670 if (hdr
->request
== KDP_HOSTREBOOT
) {
672 /* should not return! */
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
],
678 (unsigned short *)&reply_port
))
679 kdp_reply(reply_port
);
680 if (hdr
->request
== KDP_REATTACH
) {
682 hdr
->request
=KDP_DISCONNECT
;
688 } while (!kdp
.is_conn
);
690 if (current_debugger
== KDP_CUR_DB
)
692 printf("Connected to remote debugger.\n");
697 unsigned int exception
,
702 unsigned short remote_port
;
703 unsigned int timeout_count
= 100;
704 unsigned int poll_timeout
;
707 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
708 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
710 (unsigned short *)&remote_port
,
711 (unsigned int)exception
,
713 (unsigned int)subcode
);
715 kdp_send(remote_port
);
718 while(!pkt
.input
&& poll_timeout
)
725 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
732 if (kdp
.exception_ack_needed
)
735 } while (kdp
.exception_ack_needed
&& timeout_count
--);
737 if (kdp
.exception_ack_needed
) {
738 // give up & disconnect
739 printf("kdp: exception ack timeout\n");
740 if (current_debugger
== KDP_CUR_DB
)
748 unsigned int exception
,
750 unsigned int subcode
,
756 extern unsigned int disableDebugOuput
;
757 extern unsigned int disableConsoleOutput
;
759 disable_preemption();
761 if (saved_state
== 0)
762 printf("kdp_raise_exception with NULL state\n");
765 if (exception
!= EXC_BREAKPOINT
) {
766 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
769 printf("%s exception (%x,%x,%x)\n",
770 exception_message
[index
],
771 exception
, code
, subcode
);
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.
779 kdp
.saved_state
= saved_state
;
782 kdp_panic("kdp_raise_exception");
784 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
) || (kdp_flag
& PANIC_LOG_DUMP
))
785 && (panicstr
!= (char *) 0)) {
791 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && (panicstr
== (char *) 0) &&
794 disableDebugOuput
= disableConsoleOutput
= FALSE
;
797 if (!(kdp_flag
& DBG_POST_CORE
))
798 goto exit_raise_exception
;
803 kdp_connection_wait();
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");
814 kdp
.is_halted
= TRUE
; /* XXX */
815 kdp_handler(saved_state
);
818 kdp_remove_all_breakpoints();
819 printf("Remote debugger disconnected.\n");
822 /* Allow triggering a panic core dump when connected to the machine
823 * Continuing after setting kdp_trigger_core_dump should do the
826 if (1 == kdp_trigger_core_dump
) {
827 kdp_flag
&= ~PANIC_LOG_DUMP
;
828 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
834 if (reattach_wait
== 1)
836 exit_raise_exception
:
843 kdp
.reply_port
= kdp
.exception_port
= 0;
844 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
845 kdp
.exception_seq
= kdp
.conn_seq
= 0;
849 create_panic_header(unsigned int request
, const char *corename
,
850 unsigned length
, unsigned int block
)
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
);
859 pkt
.off
= sizeof (struct ether_header
);
860 pkt
.len
= length
+ ((request
== KDP_WRQ
) ? modelen
: 0) +
861 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
);
864 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
866 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
868 ui
->ui_next
= ui
->ui_prev
= 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
;
879 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
880 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
882 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
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
;
890 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
892 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
895 pkt
.len
+= sizeof (struct udpiphdr
);
897 pkt
.off
+= sizeof (struct udpiphdr
);
899 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
900 coreh
->th_opcode
= htons((u_short
)request
);
902 if (request
== KDP_WRQ
)
906 cp
= coreh
->th_u
.tu_rpl
;
907 strcpy (cp
, corename
);
908 cp
+= strlen(corename
);
916 coreh
->th_block
= htonl((unsigned int) block
);
919 pkt
.off
-= sizeof (struct udpiphdr
);
920 pkt
.off
-= sizeof (struct ether_header
);
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
);
927 pkt
.len
+= sizeof (struct ether_header
);
931 int kdp_send_panic_packets (unsigned int request
, char *corename
,
932 unsigned int length
, unsigned int txstart
)
934 unsigned int txend
= txstart
+ length
;
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
);
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
);
951 if (!(panic_block
% 2000))
954 if (txstart
< txend
) {
955 kdp_send_panic_pkt(request
, corename
, (txend
- txstart
), (caddr_t
) txstart
);
961 kdp_send_panic_pkt (unsigned int request
, char *corename
,
962 unsigned int length
, void *panic_data
)
964 struct corehdr
*th
= NULL
;
965 int poll_count
= 2500;
967 char rretries
= 0, tretries
= 0;
969 extern signed long gIODebuggerSemaphore;
971 pkt
.off
= pkt
.len
= 0;
973 if (request
== KDP_WRQ
) /* longer timeout for initial request */
980 printf("TX retry #%d ", tretries
);
983 /* This iokit layer issue can potentially
984 *cause a hang, uncomment to check if it's happening.
987 if (gIODebuggerSemaphore)
988 printf("The gIODebuggerSemaphore is raised, preventing packet transmission (2760413)\n");
991 printf ("Cannot contact panic server, timing out.\n");
995 th
= create_panic_header(request
, corename
, length
, panic_block
);
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
);
1003 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
1005 /* Now we have to listen for the ACK */
1008 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1017 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1018 /* These will eventually have to be ntoh[ls]'ed as appropriate */
1020 if (th
->th_opcode
== KDP_ACK
&& th
->th_block
== panic_block
) {
1023 if (th
->th_opcode
== KDP_ERROR
) {
1024 printf("Panic server returned error %d, retrying\n", th
->th_code
);
1026 goto TRANSMIT_RETRY
;
1029 if (th
->th_block
== (panic_block
-1)) {
1030 printf("RX retry ");
1032 goto TRANSMIT_RETRY
;
1038 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1040 printf("Received a debugger packet,transferring control to debugger\n");
1041 /* Configure that if not set ..*/
1042 kdp_flag
|= DBG_POST_CORE
;
1045 else /* We timed out */
1046 if (0 == poll_count
) {
1048 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1049 goto TRANSMIT_RETRY
;
1054 if (request
== KDP_EOF
)
1055 printf ("\nTotal number of packets transmitted: %d\n", panic_block
);
1060 /* Since we don't seem to have an isdigit() .. */
1064 return ((c
> 47) && (c
< 58));
1066 /* From user mode Libc - this ought to be in a library */
1068 strnstr(s
, find
, slen
)
1076 if ((c
= *find
++) != '\0') {
1080 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1085 } while (strncmp(s
, find
, len
) != 0);
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.
1099 kdp_get_xnu_version(char *versionbuf
)
1101 extern const char version
[];
1106 strcpy(vstr
, "custom");
1108 if (kdp_vm_read(version
, versionbuf
, 90)) {
1110 versionbuf
[89] = '\0';
1112 versionpos
= strnstr(versionbuf
, "xnu-", 80);
1115 strncpy (vstr
, versionpos
, (isdigit (versionpos
[7]) ? 8 : 7));
1116 vstr
[(isdigit (versionpos
[7]) ? 8 : 7)] = '\0';
1121 strcpy(versionbuf
, vstr
);
1124 /* Primary dispatch routine for the system dump */
1129 char coreprefix
[10];
1131 extern char *debug_buf
;
1132 extern vm_map_t kernel_map
;
1134 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1136 extern char *debug_buf
;
1137 extern char *debug_buf_ptr
;
1140 printf ("Entering system dump routine\n");
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
;
1147 flag_panic_dump_in_progress
= 1;
1151 kdp_panic("kdp_panic_dump");
1153 kdp_get_xnu_version((char *) &pkt
.data
[0]);
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
));
1159 strncpy(coreprefix
, "core", sizeof(coreprefix
));
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));
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",
1176 printf("Attempting connection to panic server configured at IP %s\n",
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
);
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
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);
1201 printf("Kernel map size is %d\n", get_vmmap_size(kernel_map
));
1202 printf ("Sending write request for %s\n", corename
);
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
;
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
;
1218 /* We want a core dump if we're here */
1222 flag_panic_dump_in_progress
= 0;
1231 abort_panic_transfer()
1233 flag_panic_dump_in_progress
= 0;