2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1982, 1986, 1993
24 * The Regents of the University of California. All rights reserved.
28 * Kernel Debugging Protocol UDP implementation.
32 #include <mach/boolean.h>
33 #include <mach/mach_types.h>
34 #include <mach/exception_types.h>
35 #include <kern/cpu_data.h>
36 #include <kern/debug.h>
38 #include <kdp/kdp_internal.h>
39 #include <kdp/kdp_en_debugger.h>
40 #include <kdp/kdp_udp.h>
42 #include <kdp/kdp_core.h>
44 #include <vm/vm_map.h>
45 #include <mach/memory_object_types.h>
49 #define DO_ALIGN 1 /* align all packet data accesses */
51 extern int kdp_getc(void);
52 extern int reattach_wait
;
54 static u_short ip_id
; /* ip packet ctr, for ids */
56 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
59 * UDP protocol implementation.
60 * Per RFC 768, August, 1980.
62 #define UDP_TTL 60 /* deflt time to live for UDP packets */
63 int udp_ttl
= UDP_TTL
;
64 static unsigned char exception_seq
;
67 unsigned char data
[KDP_MAXPACKET
];
68 unsigned int off
, len
;
84 *exception_message
[] = {
86 "Memory access", /* EXC_BAD_ACCESS */
87 "Failed instruction", /* EXC_BAD_INSTRUCTION */
88 "Arithmetic", /* EXC_ARITHMETIC */
89 "Emulation", /* EXC_EMULATION */
90 "Software", /* EXC_SOFTWARE */
91 "Breakpoint" /* EXC_BREAKPOINT */
96 static kdp_send_t kdp_en_send_pkt
= 0;
97 static kdp_receive_t kdp_en_recv_pkt
= 0;
100 static u_long kdp_current_ip_address
= 0;
101 static struct ether_addr kdp_current_mac_address
= {{0, 0, 0, 0, 0, 0}};
102 static void *kdp_current_ifp
= 0;
104 static void kdp_handler( void *);
106 static unsigned int panic_server_ip
= 0;
107 static unsigned int parsed_router_ip
= 0;
108 static unsigned int router_ip
= 0;
109 static unsigned int panicd_specified
= 0;
110 static unsigned int router_specified
= 0;
112 static struct ether_addr router_mac
= {{0, 0, 0 , 0, 0, 0}};
114 static u_char flag_panic_dump_in_progress
= 0;
115 static u_char flag_router_mac_initialized
= 0;
117 static unsigned int panic_timeout
= 100000;
118 static unsigned int last_panic_port
= CORE_REMOTE_PORT
;
120 unsigned int SEGSIZE
= 512;
122 static unsigned int PANIC_PKTSIZE
= 518;
123 static char panicd_ip_str
[20];
124 static char router_ip_str
[20];
126 static unsigned int panic_block
= 0;
127 static volatile unsigned int kdp_trigger_core_dump
= 0;
129 extern unsigned int not_in_kdp
;
132 kdp_register_send_receive(
134 kdp_receive_t receive
)
138 kdp_en_send_pkt
= send
;
139 kdp_en_recv_pkt
= receive
;
143 PE_parse_boot_arg("debug", &debug
);
145 if (debug
& DB_KDP_BP_DIS
)
146 kdp_flag
|= KDP_BP_DIS
;
147 if (debug
& DB_KDP_GETC_ENA
)
148 kdp_flag
|= KDP_GETC_ENA
;
152 if (debug
& DB_KERN_DUMP_ON_PANIC
)
153 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
154 if (debug
& DB_KERN_DUMP_ON_NMI
)
155 kdp_flag
|= PANIC_CORE_ON_NMI
;
157 if (debug
& DB_DBG_POST_CORE
)
158 kdp_flag
|= DBG_POST_CORE
;
160 if (debug
& DB_PANICLOG_DUMP
)
161 kdp_flag
|= PANIC_LOG_DUMP
;
163 if (PE_parse_boot_arg ("_panicd_ip", panicd_ip_str
))
164 panicd_specified
= 1;
165 /* For the future, currently non-functional */
166 if (PE_parse_boot_arg ("_router_ip", router_ip_str
))
167 router_specified
= 1;
169 kdp_flag
|= KDP_READY
;
170 if (current_debugger
== NO_CUR_DB
)
171 current_debugger
= KDP_CUR_DB
;
172 if (halt_in_debugger
) {
179 kdp_unregister_send_receive(
181 kdp_receive_t receive
)
183 if (current_debugger
== KDP_CUR_DB
)
184 current_debugger
= NO_CUR_DB
;
185 kdp_flag
&= ~KDP_READY
;
186 kdp_en_send_pkt
= NULL
;
187 kdp_en_recv_pkt
= NULL
;
196 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
199 static unsigned short
205 unsigned int high
, low
, sum
;
215 sum
= (high
<< 8) + low
;
216 sum
= (sum
>> 16) + (sum
& 65535);
218 return (sum
> 65535 ? sum
- 65535 : sum
);
223 unsigned short reply_port
226 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
227 struct ip aligned_ip
, *ip
= &aligned_ip
;
228 struct in_addr tmp_ipaddr
;
229 struct ether_addr tmp_enaddr
;
230 struct ether_header
*eh
;
233 kdp_panic("kdp_reply");
235 pkt
.off
-= sizeof (struct udpiphdr
);
238 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
240 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
242 ui
->ui_next
= ui
->ui_prev
= 0;
244 ui
->ui_pr
= IPPROTO_UDP
;
245 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
246 tmp_ipaddr
= ui
->ui_src
;
247 ui
->ui_src
= ui
->ui_dst
;
248 ui
->ui_dst
= tmp_ipaddr
;
249 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
250 ui
->ui_dport
= reply_port
;
251 ui
->ui_ulen
= ui
->ui_len
;
254 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
255 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
257 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
259 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
260 ip
->ip_v
= IPVERSION
;
261 ip
->ip_id
= htons(ip_id
++);
262 ip
->ip_hl
= sizeof (struct ip
) >> 2;
263 ip
->ip_ttl
= udp_ttl
;
265 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
267 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
270 pkt
.len
+= sizeof (struct udpiphdr
);
272 pkt
.off
-= sizeof (struct ether_header
);
274 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
275 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
276 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
277 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
278 eh
->ether_type
= htons(ETHERTYPE_IP
);
280 pkt
.len
+= sizeof (struct ether_header
);
282 // save reply for possible retransmission
283 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
285 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
287 // increment expected sequence number
293 unsigned short remote_port
296 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
297 struct ip aligned_ip
, *ip
= &aligned_ip
;
298 struct ether_header
*eh
;
301 kdp_panic("kdp_send");
303 pkt
.off
-= sizeof (struct udpiphdr
);
306 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
308 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
310 ui
->ui_next
= ui
->ui_prev
= 0;
312 ui
->ui_pr
= IPPROTO_UDP
;
313 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
314 ui
->ui_src
= adr
.loc
.in
;
315 ui
->ui_dst
= adr
.rmt
.in
;
316 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
317 ui
->ui_dport
= remote_port
;
318 ui
->ui_ulen
= ui
->ui_len
;
321 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
322 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
324 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
326 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
327 ip
->ip_v
= IPVERSION
;
328 ip
->ip_id
= htons(ip_id
++);
329 ip
->ip_hl
= sizeof (struct ip
) >> 2;
330 ip
->ip_ttl
= udp_ttl
;
332 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
334 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
337 pkt
.len
+= sizeof (struct udpiphdr
);
339 pkt
.off
-= sizeof (struct ether_header
);
341 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
342 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
343 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
344 eh
->ether_type
= htons(ETHERTYPE_IP
);
346 pkt
.len
+= sizeof (struct ether_header
);
347 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
350 /* We don't interpret this pointer, we just give it to the
351 bsd stack so it can decide when to set the MAC and IP info. */
353 kdp_set_interface(void *ifp
)
355 kdp_current_ifp
= ifp
;
361 return kdp_current_ifp
;
365 kdp_set_ip_and_mac_addresses(
366 struct in_addr
*ipaddr
,
367 struct ether_addr
*macaddr
)
369 unsigned int debug
= 0;
371 kdp_current_ip_address
= ipaddr
->s_addr
;
372 kdp_current_mac_address
= *macaddr
;
376 kdp_set_gateway_mac(void *gatewaymac
)
378 router_mac
= *(struct ether_addr
*)gatewaymac
;
382 kdp_get_mac_addr(void)
384 return kdp_current_mac_address
;
388 kdp_get_ip_address(void)
390 return kdp_current_ip_address
;
393 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
394 is set. A workaround if you don't want to reboot is to set
395 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
401 struct ether_header
*eh
;
402 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
404 struct in_addr isaddr
, itaddr
, myaddr
;
405 struct ether_addr my_enaddr
;
407 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
408 pkt
.off
+= sizeof(struct ether_header
);
410 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
412 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
415 myaddr
.s_addr
= kdp_get_ip_address();
416 my_enaddr
= kdp_get_mac_addr();
418 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
421 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
422 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
424 if (itaddr
.s_addr
== myaddr
.s_addr
) {
425 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
426 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
428 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
429 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
431 ea
->arp_op
= htons(ARPOP_REPLY
);
432 ea
->arp_pro
= htons(ETHERTYPE_IP
);
433 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
434 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
435 eh
->ether_type
= htons(ETHERTYPE_ARP
);
436 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
437 pkt
.off
-= sizeof (struct ether_header
);
438 /* pkt.len is still the length we want, ether_header+ether_arp */
439 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
446 struct ether_header
*eh
;
447 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
448 struct ip aligned_ip
, *ip
= &aligned_ip
;
449 static int msg_printed
;
453 kdp_panic("kdp_poll");
455 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
456 if( msg_printed
== 0) {
458 printf("kdp_poll: no debugger device\n");
463 pkt
.off
= pkt
.len
= 0;
464 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
469 if (pkt
.len
>= sizeof(struct ether_header
))
471 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
473 if (kdp_flag
& KDP_ARP
)
475 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
483 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
486 pkt
.off
+= sizeof (struct ether_header
);
487 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
492 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
493 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
495 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
496 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
499 pkt
.off
+= sizeof (struct udpiphdr
);
500 if (ui
->ui_pr
!= IPPROTO_UDP
) {
504 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
508 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
509 if (CORE_REMOTE_PORT
== (ntohs(ui
->ui_dport
)) &&
510 flag_panic_dump_in_progress
) {
511 last_panic_port
= ui
->ui_sport
;
516 /* If we receive a kernel debugging packet whilst a
517 * core dump is in progress, abort the transfer and
518 * enter the debugger.
521 if (flag_panic_dump_in_progress
)
523 abort_panic_transfer();
527 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
528 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
529 adr
.loc
.in
= ui
->ui_dst
;
531 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
532 adr
.rmt
.in
= ui
->ui_src
;
536 * Calculate kdp packet length.
538 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
547 unsigned short reply_port
;
548 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
551 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
558 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
560 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
563 // ignore replies -- we're not expecting them anyway.
568 if (hdr
->request
== KDP_REATTACH
)
569 exception_seq
= hdr
->seq
;
571 // check for retransmitted request
572 if (hdr
->seq
== (exception_seq
- 1)) {
573 /* retransmit last reply */
574 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
577 } else if (hdr
->seq
!= exception_seq
) {
578 printf("kdp: bad sequence %d (want %d)\n",
579 hdr
->seq
, exception_seq
);
583 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
585 (unsigned short *)&reply_port
)) {
586 kdp_reply(reply_port
);
591 } while (kdp
.is_halted
);
595 kdp_connection_wait(void)
597 unsigned short reply_port
;
598 boolean_t
kdp_call_kdb();
599 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
600 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
602 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
603 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
604 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
605 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
606 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
607 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
608 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
610 printf( "ip address: %d.%d.%d.%d\n",
611 (ip_addr
& 0xff000000) >> 24,
612 (ip_addr
& 0xff0000) >> 16,
613 (ip_addr
& 0xff00) >> 8,
616 printf("\nWaiting for remote debugger connection.\n");
618 if (reattach_wait
== 0) {
619 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
621 printf("Options..... Type\n");
622 printf("------------ ----\n");
623 printf("continue.... 'c'\n");
624 printf("reboot...... 'r'\n");
626 printf("enter kdb... 'k'\n");
635 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
638 if (kdp_flag
& KDP_GETC_ENA
) {
641 printf("Continuing...\n");
644 printf("Rebooting...\n");
649 printf("calling kdb...\n");
653 printf("not implemented...\n");
663 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
665 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
667 if (hdr
->request
== KDP_HOSTREBOOT
) {
669 /* should not return! */
671 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
672 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
673 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
675 (unsigned short *)&reply_port
))
676 kdp_reply(reply_port
);
677 if (hdr
->request
== KDP_REATTACH
) {
679 hdr
->request
=KDP_DISCONNECT
;
685 } while (!kdp
.is_conn
);
687 if (current_debugger
== KDP_CUR_DB
)
689 printf("Connected to remote debugger.\n");
694 unsigned int exception
,
699 unsigned short remote_port
;
700 unsigned int timeout_count
= 100;
701 unsigned int poll_timeout
;
704 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
705 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
707 (unsigned short *)&remote_port
,
708 (unsigned int)exception
,
710 (unsigned int)subcode
);
712 kdp_send(remote_port
);
715 while(!pkt
.input
&& poll_timeout
)
722 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
729 if (kdp
.exception_ack_needed
)
732 } while (kdp
.exception_ack_needed
&& timeout_count
--);
734 if (kdp
.exception_ack_needed
) {
735 // give up & disconnect
736 printf("kdp: exception ack timeout\n");
737 if (current_debugger
== KDP_CUR_DB
)
745 unsigned int exception
,
747 unsigned int subcode
,
753 extern unsigned int disableDebugOuput
;
754 extern unsigned int disableConsoleOutput
;
756 disable_preemption();
758 if (saved_state
== 0)
759 printf("kdp_raise_exception with NULL state\n");
762 if (exception
!= EXC_BREAKPOINT
) {
763 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
766 printf("%s exception (%x,%x,%x)\n",
767 exception_message
[index
],
768 exception
, code
, subcode
);
773 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
774 * do this. I think the client and the host can get out of sync.
776 kdp
.saved_state
= saved_state
;
779 kdp_panic("kdp_raise_exception");
781 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
) || (kdp_flag
& PANIC_LOG_DUMP
))
782 && (panicstr
!= (char *) 0)) {
788 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && (panicstr
== (char *) 0) &&
791 disableDebugOuput
= disableConsoleOutput
= FALSE
;
794 if (!(kdp_flag
& DBG_POST_CORE
))
795 goto exit_raise_exception
;
800 kdp_connection_wait();
802 kdp_send_exception(exception
, code
, subcode
);
803 if (kdp
.exception_ack_needed
) {
804 kdp
.exception_ack_needed
= FALSE
;
805 kdp_remove_all_breakpoints();
806 printf("Remote debugger disconnected.\n");
811 kdp
.is_halted
= TRUE
; /* XXX */
812 kdp_handler(saved_state
);
815 kdp_remove_all_breakpoints();
816 printf("Remote debugger disconnected.\n");
819 /* Allow triggering a panic core dump when connected to the machine
820 * Continuing after setting kdp_trigger_core_dump should do the
823 if (1 == kdp_trigger_core_dump
) {
824 kdp_flag
&= ~PANIC_LOG_DUMP
;
825 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
831 if (reattach_wait
== 1)
833 exit_raise_exception
:
840 kdp
.reply_port
= kdp
.exception_port
= 0;
841 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
842 kdp
.exception_seq
= kdp
.conn_seq
= 0;
846 create_panic_header(unsigned int request
, const char *corename
,
847 unsigned length
, unsigned int block
)
849 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
850 struct ip aligned_ip
, *ip
= &aligned_ip
;
851 struct ether_header
*eh
;
852 struct corehdr
*coreh
;
853 const char *mode
= "octet";
854 char modelen
= strlen(mode
);
856 pkt
.off
= sizeof (struct ether_header
);
857 pkt
.len
= length
+ ((request
== KDP_WRQ
) ? modelen
: 0) +
858 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
);
861 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
863 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
865 ui
->ui_next
= ui
->ui_prev
= 0;
867 ui
->ui_pr
= IPPROTO_UDP
;
868 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
869 ui
->ui_src
.s_addr
= htonl(kdp_current_ip_address
);
870 ui
->ui_dst
.s_addr
= panic_server_ip
;
871 ui
->ui_sport
= htons(CORE_REMOTE_PORT
);
872 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(CORE_REMOTE_PORT
) : last_panic_port
);
873 ui
->ui_ulen
= ui
->ui_len
;
876 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
877 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
879 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
881 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
882 ip
->ip_v
= IPVERSION
;
883 ip
->ip_id
= htons(ip_id
++);
884 ip
->ip_hl
= sizeof (struct ip
) >> 2;
885 ip
->ip_ttl
= udp_ttl
;
887 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
889 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
892 pkt
.len
+= sizeof (struct udpiphdr
);
894 pkt
.off
+= sizeof (struct udpiphdr
);
896 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
897 coreh
->th_opcode
= htons((u_short
)request
);
899 if (request
== KDP_WRQ
)
903 cp
= coreh
->th_u
.tu_rpl
;
904 strcpy (cp
, corename
);
905 cp
+= strlen(corename
);
913 coreh
->th_block
= htonl((unsigned int) block
);
916 pkt
.off
-= sizeof (struct udpiphdr
);
917 pkt
.off
-= sizeof (struct ether_header
);
919 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
920 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
921 enaddr_copy(&router_mac
, eh
->ether_dhost
);
922 eh
->ether_type
= htons(ETHERTYPE_IP
);
924 pkt
.len
+= sizeof (struct ether_header
);
928 int kdp_send_panic_packets (unsigned int request
, char *corename
,
929 unsigned int length
, unsigned int txstart
)
931 unsigned int txend
= txstart
+ length
;
934 if (length
<= SEGSIZE
) {
935 if ((panic_error
= kdp_send_panic_pkt (request
, corename
, length
, (caddr_t
) txstart
)) < 0) {
936 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
942 while (txstart
<= (txend
- SEGSIZE
)) {
943 if ((panic_error
= kdp_send_panic_pkt (KDP_DATA
, NULL
, SEGSIZE
, (caddr_t
) txstart
)) < 0) {
944 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
948 if (!(panic_block
% 2000))
951 if (txstart
< txend
) {
952 kdp_send_panic_pkt(request
, corename
, (txend
- txstart
), (caddr_t
) txstart
);
958 kdp_send_panic_pkt (unsigned int request
, char *corename
,
959 unsigned int length
, void *panic_data
)
961 struct corehdr
*th
= NULL
;
962 int poll_count
= 2500;
964 char rretries
= 0, tretries
= 0;
966 extern signed long gIODebuggerSemaphore;
968 pkt
.off
= pkt
.len
= 0;
970 if (request
== KDP_WRQ
) /* longer timeout for initial request */
977 printf("TX retry #%d ", tretries
);
980 /* This iokit layer issue can potentially
981 *cause a hang, uncomment to check if it's happening.
984 if (gIODebuggerSemaphore)
985 printf("The gIODebuggerSemaphore is raised, preventing packet transmission (2760413)\n");
988 printf ("Cannot contact panic server, timing out.\n");
992 th
= create_panic_header(request
, corename
, length
, panic_block
);
994 if (request
== KDP_DATA
|| request
== KDP_SEEK
) {
995 if (!kdp_vm_read ((caddr_t
) panic_data
, (caddr_t
) th
->th_data
, length
)) {
996 memset ((caddr_t
) th
->th_data
, 'X', length
);
1000 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
1002 /* Now we have to listen for the ACK */
1005 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1014 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1015 /* These will eventually have to be ntoh[ls]'ed as appropriate */
1017 if (th
->th_opcode
== KDP_ACK
&& th
->th_block
== panic_block
) {
1020 if (th
->th_opcode
== KDP_ERROR
) {
1021 printf("Panic server returned error %d, retrying\n", th
->th_code
);
1023 goto TRANSMIT_RETRY
;
1026 if (th
->th_block
== (panic_block
-1)) {
1027 printf("RX retry ");
1029 goto TRANSMIT_RETRY
;
1035 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1037 printf("Received a debugger packet,transferring control to debugger\n");
1038 /* Configure that if not set ..*/
1039 kdp_flag
|= DBG_POST_CORE
;
1042 else /* We timed out */
1043 if (0 == poll_count
) {
1045 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1046 goto TRANSMIT_RETRY
;
1051 if (request
== KDP_EOF
)
1052 printf ("\nTotal number of packets transmitted: %d\n", panic_block
);
1057 /* Since we don't seem to have an isdigit() .. */
1061 return ((c
> 47) && (c
< 58));
1063 /* From user mode Libc - this ought to be in a library */
1065 strnstr(s
, find
, slen
)
1073 if ((c
= *find
++) != '\0') {
1077 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1082 } while (strncmp(s
, find
, len
) != 0);
1088 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1089 * would be to have the integrator run a script which would copy the
1090 * xnu version into a string or an int somewhere at project submission
1091 * time - makes assumptions about sizeof(version), but will not fail if
1092 * it changes, but may be incorrect.
1096 kdp_get_xnu_version(char *versionbuf
)
1098 extern const char version
[];
1103 strcpy(vstr
, "custom");
1105 if (kdp_vm_read(version
, versionbuf
, 90)) {
1107 versionbuf
[89] = '\0';
1109 versionpos
= strnstr(versionbuf
, "xnu-", 80);
1112 strncpy (vstr
, versionpos
, (isdigit (versionpos
[7]) ? 8 : 7));
1113 vstr
[(isdigit (versionpos
[7]) ? 8 : 7)] = '\0';
1118 strcpy(versionbuf
, vstr
);
1121 /* Primary dispatch routine for the system dump */
1126 char coreprefix
[10];
1128 extern char *debug_buf
;
1129 extern vm_map_t kernel_map
;
1131 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1133 extern char *debug_buf
;
1134 extern char *debug_buf_ptr
;
1137 printf ("Entering system dump routine\n");
1139 if (!panicd_specified
) {
1140 printf ("A panic server was not specified in the boot-args, terminating kernel core dump.\n");
1141 goto panic_dump_exit
;
1144 flag_panic_dump_in_progress
= 1;
1148 kdp_panic("kdp_panic_dump");
1150 kdp_get_xnu_version((char *) &pkt
.data
[0]);
1152 /* Panic log bit takes precedence over core dump bit */
1153 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
))
1154 strncpy(coreprefix
, "paniclog", sizeof(coreprefix
));
1156 strncpy(coreprefix
, "core", sizeof(coreprefix
));
1158 abstime
= mach_absolute_time();
1159 pkt
.data
[10] = '\0';
1160 snprintf (corename
, sizeof(corename
), "%s-%s-%d.%d.%d.%d-%x",
1161 coreprefix
, &pkt
.data
[0],
1162 (kdp_current_ip_address
& 0xff000000) >> 24,
1163 (kdp_current_ip_address
& 0xff0000) >> 16,
1164 (kdp_current_ip_address
& 0xff00) >> 8,
1165 (kdp_current_ip_address
& 0xff),
1166 (unsigned int) (abstime
& 0xffffffff));
1168 if (0 == inet_aton(panicd_ip_str
, (struct in_addr
*) &panic_server_ip
)) {
1169 printf("inet_aton() failed interpreting %s as a panic server IP\n",
1173 printf("Attempting connection to panic server configured at IP %s\n",
1176 if (router_specified
) {
1177 if (0 == inet_aton(router_ip_str
, (struct in_addr
*) &parsed_router_ip
)){
1178 printf("inet_aton() failed interpreting %s as an IP\n", router_ip
);
1181 router_ip
= parsed_router_ip
;
1182 printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
1183 /* We will eventually need to resolve the router's MAC ourselves,
1184 * if one is specified,rather than being set through the BSD callback
1185 * but the _router_ip option does not function currently
1189 /* These & 0xffs aren't necessary,but cut&paste is ever so convenient */
1190 printf("Routing via router MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1191 router_mac
.ether_addr_octet
[0] & 0xff,
1192 router_mac
.ether_addr_octet
[1] & 0xff,
1193 router_mac
.ether_addr_octet
[2] & 0xff,
1194 router_mac
.ether_addr_octet
[3] & 0xff,
1195 router_mac
.ether_addr_octet
[4] & 0xff,
1196 router_mac
.ether_addr_octet
[5] & 0xff);
1198 printf("Kernel map size is %d\n", get_vmmap_size(kernel_map
));
1199 printf ("Sending write request for %s\n", corename
);
1201 if ((panic_error
= kdp_send_panic_pkt (KDP_WRQ
, corename
, 0 , NULL
) < 0)) {
1202 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
1203 goto panic_dump_exit
;
1206 /* Just the panic log requested */
1207 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
1208 printf("Transmitting panic log, please wait: ");
1209 kdp_send_panic_packets (KDP_DATA
, corename
, (debug_buf_ptr
- debug_buf
), (unsigned int) debug_buf
);
1210 kdp_send_panic_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1211 printf("Please file a bug report on this panic, if possible.\n");
1212 goto panic_dump_exit
;
1215 /* We want a core dump if we're here */
1219 flag_panic_dump_in_progress
= 0;
1228 abort_panic_transfer()
1230 flag_panic_dump_in_progress
= 0;