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_core.h>
47 #include <kdp/kdp_internal.h>
48 #include <kdp/kdp_en_debugger.h>
49 #include <kdp/kdp_udp.h>
51 #include <vm/vm_map.h>
52 #include <vm/vm_protos.h>
53 #include <vm/vm_kern.h> /* kernel_map */
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 */
104 volatile int kdp_flag
= 0;
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 uint32_t panic_server_ip
= 0;
117 static uint32_t parsed_router_ip
= 0;
118 static uint32_t router_ip
= 0;
119 static uint32_t target_ip
= 0;
121 static volatile boolean_t panicd_specified
= FALSE
;
122 static boolean_t router_specified
= FALSE
;
123 static unsigned int panicd_port
= CORE_REMOTE_PORT
;
125 /* As in bsd/net/ether_if_module.c */
126 static struct ether_addr etherbroadcastaddr
= {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
128 static struct ether_addr router_mac
= {{0, 0, 0 , 0, 0, 0}};
129 static struct ether_addr destination_mac
= {{0, 0, 0 , 0, 0, 0}};
130 static struct ether_addr temp_mac
= {{0, 0, 0 , 0, 0, 0}};
131 static struct ether_addr current_resolved_MAC
= {{0, 0, 0 , 0, 0, 0}};
133 static boolean_t flag_panic_dump_in_progress
= FALSE
;
134 static boolean_t flag_router_mac_initialized
= FALSE
;
136 static boolean_t flag_arp_resolved
= FALSE
;
138 static unsigned int panic_timeout
= 100000;
139 static unsigned int last_panic_port
= CORE_REMOTE_PORT
;
141 unsigned int SEGSIZE
= 512;
143 __unused
static unsigned int PANIC_PKTSIZE
= 518;
144 static char panicd_ip_str
[20];
145 static char router_ip_str
[20];
147 static unsigned int panic_block
= 0;
148 static volatile unsigned int kdp_trigger_core_dump
= 0;
149 static volatile unsigned int flag_kdp_trigger_reboot
= 0;
151 extern unsigned int not_in_kdp
;
153 extern unsigned long panic_caller
;
154 extern unsigned int disableConsoleOutput
;
156 extern int kdp_vm_read( caddr_t
, caddr_t
, unsigned int);
157 extern void kdp_call(void);
158 extern boolean_t
kdp_call_kdb(void);
159 extern int kern_dump(void);
161 void * kdp_get_interface(void);
162 void kdp_set_gateway_mac(void *);
163 void kdp_set_ip_and_mac_addresses(struct in_addr
*, struct ether_addr
*);
164 void kdp_set_interface(void *);
166 void kdp_disable_arp(void);
167 static void kdp_arp_reply(struct ether_arp
*);
168 static void kdp_process_arp_reply(struct ether_arp
*);
169 static boolean_t
kdp_arp_resolve(uint32_t, struct ether_addr
*);
171 static boolean_t gKDPDebug
= FALSE
;
172 #define KDP_DEBUG(...) if (gKDPDebug) printf(__VA_ARGS__);
174 int kdp_snapshot
= 0;
175 static int stack_snapshot_ret
= 0;
176 static unsigned stack_snapshot_bytes_traced
= 0;
178 static void *stack_snapshot_buf
;
179 static uint32_t stack_snapshot_bufsize
;
180 static int stack_snapshot_pid
;
181 static uint32_t stack_snapshot_options
;
184 kdp_snapshot_preflight(int pid
, void * tracebuf
, uint32_t tracebuf_size
,
188 kdp_snapshot_postflight(void);
191 kdp_stackshot(int pid
, uint32_t tracebuf
, uint32_t tracebuf_size
,
192 unsigned trace_options
, uint32_t *pbytesTraced
);
195 kdp_stack_snapshot_geterror(void);
198 kdp_stack_snapshot_bytes_traced(void);
201 kdp_register_send_receive(
203 kdp_receive_t receive
)
205 unsigned int debug
=0;
207 kdp_en_send_pkt
= send
;
208 kdp_en_recv_pkt
= receive
;
212 PE_parse_boot_arg("debug", &debug
);
214 if (debug
& DB_KDP_BP_DIS
)
215 kdp_flag
|= KDP_BP_DIS
;
216 if (debug
& DB_KDP_GETC_ENA
)
217 kdp_flag
|= KDP_GETC_ENA
;
221 if (debug
& DB_KERN_DUMP_ON_PANIC
)
222 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
223 if (debug
& DB_KERN_DUMP_ON_NMI
)
224 kdp_flag
|= PANIC_CORE_ON_NMI
;
226 if (debug
& DB_DBG_POST_CORE
)
227 kdp_flag
|= DBG_POST_CORE
;
229 if (debug
& DB_PANICLOG_DUMP
)
230 kdp_flag
|= PANIC_LOG_DUMP
;
232 if (PE_parse_boot_arg ("_panicd_ip", panicd_ip_str
))
233 panicd_specified
= TRUE
;
235 if (PE_parse_boot_arg ("_router_ip", router_ip_str
))
236 router_specified
= TRUE
;
238 if (!PE_parse_boot_arg ("panicd_port", &panicd_port
))
239 panicd_port
= CORE_REMOTE_PORT
;
241 kdp_flag
|= KDP_READY
;
242 if (current_debugger
== NO_CUR_DB
)
243 current_debugger
= KDP_CUR_DB
;
244 if (halt_in_debugger
) {
251 kdp_unregister_send_receive(
252 __unused kdp_send_t send
,
253 __unused kdp_receive_t receive
)
255 if (current_debugger
== KDP_CUR_DB
)
256 current_debugger
= NO_CUR_DB
;
257 kdp_flag
&= ~KDP_READY
;
258 kdp_en_send_pkt
= NULL
;
259 kdp_en_recv_pkt
= NULL
;
262 /* Cache stack snapshot parameters in preparation for a trace */
264 kdp_snapshot_preflight(int pid
, void * tracebuf
, uint32_t tracebuf_size
, uint32_t options
)
266 stack_snapshot_pid
= pid
;
267 stack_snapshot_buf
= tracebuf
;
268 stack_snapshot_bufsize
= tracebuf_size
;
269 stack_snapshot_options
= options
;
274 kdp_snapshot_postflight(void)
280 kdp_stack_snapshot_geterror(void)
282 return stack_snapshot_ret
;
286 kdp_stack_snapshot_bytes_traced(void)
288 return stack_snapshot_bytes_traced
;
297 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
300 static unsigned short
306 unsigned int high
, low
, sum
;
316 sum
= (high
<< 8) + low
;
317 sum
= (sum
>> 16) + (sum
& 65535);
319 return (sum
> 65535 ? sum
- 65535 : sum
);
324 unsigned short reply_port
327 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
328 struct ip aligned_ip
, *ip
= &aligned_ip
;
329 struct in_addr tmp_ipaddr
;
330 struct ether_addr tmp_enaddr
;
331 struct ether_header
*eh
= NULL
;
334 kdp_panic("kdp_reply");
336 pkt
.off
-= sizeof (struct udpiphdr
);
339 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
341 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
343 ui
->ui_next
= ui
->ui_prev
= 0;
345 ui
->ui_pr
= IPPROTO_UDP
;
346 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
347 tmp_ipaddr
= ui
->ui_src
;
348 ui
->ui_src
= ui
->ui_dst
;
349 ui
->ui_dst
= tmp_ipaddr
;
350 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
351 ui
->ui_dport
= reply_port
;
352 ui
->ui_ulen
= ui
->ui_len
;
355 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
356 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
358 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
360 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
361 ip
->ip_v
= IPVERSION
;
362 ip
->ip_id
= htons(ip_id
++);
363 ip
->ip_hl
= sizeof (struct ip
) >> 2;
364 ip
->ip_ttl
= udp_ttl
;
366 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
368 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
371 pkt
.len
+= sizeof (struct udpiphdr
);
373 pkt
.off
-= sizeof (struct ether_header
);
375 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
376 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
377 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
378 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
379 eh
->ether_type
= htons(ETHERTYPE_IP
);
381 pkt
.len
+= sizeof (struct ether_header
);
383 // save reply for possible retransmission
384 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
386 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
388 // increment expected sequence number
394 unsigned short remote_port
397 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
398 struct ip aligned_ip
, *ip
= &aligned_ip
;
399 struct ether_header
*eh
;
402 kdp_panic("kdp_send");
404 pkt
.off
-= sizeof (struct udpiphdr
);
407 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
409 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
411 ui
->ui_next
= ui
->ui_prev
= 0;
413 ui
->ui_pr
= IPPROTO_UDP
;
414 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
415 ui
->ui_src
= adr
.loc
.in
;
416 ui
->ui_dst
= adr
.rmt
.in
;
417 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
418 ui
->ui_dport
= remote_port
;
419 ui
->ui_ulen
= ui
->ui_len
;
422 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
423 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
425 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
427 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
428 ip
->ip_v
= IPVERSION
;
429 ip
->ip_id
= htons(ip_id
++);
430 ip
->ip_hl
= sizeof (struct ip
) >> 2;
431 ip
->ip_ttl
= udp_ttl
;
433 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
435 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
438 pkt
.len
+= sizeof (struct udpiphdr
);
440 pkt
.off
-= sizeof (struct ether_header
);
442 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
443 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
444 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
445 eh
->ether_type
= htons(ETHERTYPE_IP
);
447 pkt
.len
+= sizeof (struct ether_header
);
448 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
451 /* We don't interpret this pointer, we just give it to the
452 bsd stack so it can decide when to set the MAC and IP info. */
454 kdp_set_interface(void *ifp
)
456 kdp_current_ifp
= ifp
;
462 return kdp_current_ifp
;
466 kdp_set_ip_and_mac_addresses(
467 struct in_addr
*ipaddr
,
468 struct ether_addr
*macaddr
)
470 kdp_current_ip_address
= ipaddr
->s_addr
;
471 kdp_current_mac_address
= *macaddr
;
475 kdp_set_gateway_mac(void *gatewaymac
)
477 router_mac
= *(struct ether_addr
*)gatewaymac
;
478 flag_router_mac_initialized
= TRUE
;
482 kdp_get_mac_addr(void)
484 return kdp_current_mac_address
;
488 kdp_get_ip_address(void)
490 return kdp_current_ip_address
;
494 kdp_disable_arp(void)
496 kdp_flag
&= ~(DB_ARP
);
500 kdp_arp_dispatch(void)
502 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
503 unsigned arp_header_offset
;
505 arp_header_offset
= sizeof(struct ether_header
) + pkt
.off
;
506 memcpy((void *)ea
, (void *)&pkt
.data
[arp_header_offset
], sizeof(*ea
));
508 switch(ntohs(ea
->arp_op
)) {
513 kdp_process_arp_reply(ea
);
521 kdp_process_arp_reply(struct ether_arp
*ea
)
523 /* Are we interested in ARP replies? */
524 if (flag_arp_resolved
== TRUE
)
527 /* Did we receive a reply from the right source? */
528 if (((struct in_addr
*)(ea
->arp_spa
))->s_addr
!= target_ip
)
531 flag_arp_resolved
= TRUE
;
532 current_resolved_MAC
= *(struct ether_addr
*) (ea
->arp_sha
);
537 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
542 kdp_arp_reply(struct ether_arp
*ea
)
544 struct ether_header
*eh
;
546 struct in_addr isaddr
, itaddr
, myaddr
;
547 struct ether_addr my_enaddr
;
549 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
550 pkt
.off
+= sizeof(struct ether_header
);
552 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
555 myaddr
.s_addr
= kdp_get_ip_address();
556 my_enaddr
= kdp_get_mac_addr();
558 if ((ntohl(myaddr
.s_addr
) == 0) ||
559 ((my_enaddr
.ether_addr_octet
[0] & 0xff) == 0
560 && (my_enaddr
.ether_addr_octet
[1] & 0xff) == 0
561 && (my_enaddr
.ether_addr_octet
[2] & 0xff) == 0
562 && (my_enaddr
.ether_addr_octet
[3] & 0xff) == 0
563 && (my_enaddr
.ether_addr_octet
[4] & 0xff) == 0
564 && (my_enaddr
.ether_addr_octet
[5] & 0xff) == 0
568 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
569 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
571 if (itaddr
.s_addr
== myaddr
.s_addr
) {
572 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
573 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
575 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
576 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
578 ea
->arp_op
= htons(ARPOP_REPLY
);
579 ea
->arp_pro
= htons(ETHERTYPE_IP
);
580 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
581 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
582 eh
->ether_type
= htons(ETHERTYPE_ARP
);
583 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
584 pkt
.off
-= sizeof (struct ether_header
);
585 /* pkt.len is still the length we want, ether_header+ether_arp */
586 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
593 struct ether_header
*eh
= NULL
;
594 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
595 struct ip aligned_ip
, *ip
= &aligned_ip
;
596 static int msg_printed
;
599 kdp_panic("kdp_poll");
601 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
602 if( msg_printed
== 0) {
604 printf("kdp_poll: no debugger device\n");
609 pkt
.off
= pkt
.len
= 0;
610 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
615 if (pkt
.len
>= sizeof(struct ether_header
))
617 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
619 if (kdp_flag
& KDP_ARP
)
621 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
629 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
632 pkt
.off
+= sizeof (struct ether_header
);
633 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
638 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
639 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
641 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
642 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
645 pkt
.off
+= sizeof (struct udpiphdr
);
646 if (ui
->ui_pr
!= IPPROTO_UDP
) {
650 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
654 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
655 if (panicd_port
== (ntohs(ui
->ui_dport
)) &&
656 flag_panic_dump_in_progress
) {
657 last_panic_port
= ui
->ui_sport
;
662 /* If we receive a kernel debugging packet whilst a
663 * core dump is in progress, abort the transfer and
664 * enter the debugger.
667 if (flag_panic_dump_in_progress
)
669 abort_panic_transfer();
673 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
674 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
675 adr
.loc
.in
= ui
->ui_dst
;
677 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
678 adr
.rmt
.in
= ui
->ui_src
;
682 * Calculate kdp packet length.
684 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
688 /* Create and transmit an ARP resolution request for the target IP address.
689 * This is modeled on ether_inet_arp()/RFC 826.
693 transmit_ARP_request(uint32_t ip_addr
)
695 struct ether_header
*eh
= (struct ether_header
*) &pkt
.data
[0];
696 struct ether_arp
*ea
= (struct ether_arp
*) &pkt
.data
[sizeof(struct ether_header
)];
698 KDP_DEBUG("Transmitting ARP request\n");
699 /* Populate the ether_header */
700 eh
->ether_type
= htons(ETHERTYPE_ARP
);
701 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
702 enaddr_copy(ðerbroadcastaddr
, eh
->ether_dhost
);
704 /* Populate the ARP header */
705 ea
->arp_pro
= htons(ETHERTYPE_IP
);
706 ea
->arp_hln
= sizeof(ea
->arp_sha
);
707 ea
->arp_pln
= sizeof(ea
->arp_spa
);
708 ea
->arp_hrd
= htons(ARPHRD_ETHER
);
709 ea
->arp_op
= htons(ARPOP_REQUEST
);
712 enaddr_copy(ðerbroadcastaddr
, ea
->arp_tha
);
713 memcpy(ea
->arp_tpa
, (void *) &ip_addr
, sizeof(ip_addr
));
716 enaddr_copy(&kdp_current_mac_address
, ea
->arp_sha
);
717 memcpy(ea
->arp_spa
, (void *) &kdp_current_ip_address
, sizeof(kdp_current_ip_address
));
720 pkt
.len
= sizeof(struct ether_header
) + sizeof(struct ether_arp
);
722 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
726 kdp_arp_resolve(uint32_t arp_target_ip
, struct ether_addr
*resolved_MAC
)
728 int poll_count
= 256; /* ~770 ms modulo broadcast/delayed traffic? */
731 #define NUM_ARP_TX_RETRIES 5
733 target_ip
= arp_target_ip
;
734 flag_arp_resolved
= FALSE
;
737 pkt
.off
= pkt
.len
= 0;
741 if (tretries
>= NUM_ARP_TX_RETRIES
) {
745 KDP_DEBUG("ARP TX attempt #%d \n", tretries
);
747 transmit_ARP_request(arp_target_ip
);
749 while (!pkt
.input
&& !flag_arp_resolved
&& flag_panic_dump_in_progress
&& --poll_count
) {
753 if (flag_arp_resolved
) {
754 *resolved_MAC
= current_resolved_MAC
;
758 if (!flag_panic_dump_in_progress
|| pkt
.input
) /* we received a debugging packet, bail*/
760 printf("Received a debugger packet,transferring control to debugger\n");
761 /* Indicate that we should wait in the debugger when we return */
762 kdp_flag
|= DBG_POST_CORE
;
766 else /* We timed out */
767 if (0 == poll_count
) {
779 unsigned short reply_port
;
780 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
782 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
789 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
791 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
794 // ignore replies -- we're not expecting them anyway.
799 if (hdr
->request
== KDP_REATTACH
)
800 exception_seq
= hdr
->seq
;
802 // check for retransmitted request
803 if (hdr
->seq
== (exception_seq
- 1)) {
804 /* retransmit last reply */
805 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
808 } else if (hdr
->seq
!= exception_seq
) {
809 printf("kdp: bad sequence %d (want %d)\n",
810 hdr
->seq
, exception_seq
);
814 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
816 (unsigned short *)&reply_port
)) {
817 kdp_reply(reply_port
);
822 } while (kdp
.is_halted
);
826 kdp_connection_wait(void)
828 unsigned short reply_port
;
829 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
830 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
833 * Do both a printf() and a kprintf() of the MAC and IP so that
834 * they will print out on headless machines but not be added to
838 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
839 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
840 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
841 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
842 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
843 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
844 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
846 kprintf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
847 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
848 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
849 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
850 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
851 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
852 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
854 printf( "ip address: %d.%d.%d.%d\n",
855 (ip_addr
& 0xff000000) >> 24,
856 (ip_addr
& 0xff0000) >> 16,
857 (ip_addr
& 0xff00) >> 8,
860 kprintf( "ip address: %d.%d.%d.%d\n",
861 (ip_addr
& 0xff000000) >> 24,
862 (ip_addr
& 0xff0000) >> 16,
863 (ip_addr
& 0xff00) >> 8,
866 printf("\nWaiting for remote debugger connection.\n");
868 if (reattach_wait
== 0) {
869 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
871 printf("Options..... Type\n");
872 printf("------------ ----\n");
873 printf("continue.... 'c'\n");
874 printf("reboot...... 'r'\n");
876 printf("enter kdb... 'k'\n");
885 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
888 if (kdp_flag
& KDP_GETC_ENA
) {
891 printf("Continuing...\n");
894 printf("Rebooting...\n");
899 printf("calling kdb...\n");
903 printf("not implemented...\n");
913 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
915 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
917 if (hdr
->request
== KDP_HOSTREBOOT
) {
919 /* should not return! */
921 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
922 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
923 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
925 (unsigned short *)&reply_port
))
926 kdp_reply(reply_port
);
927 if (hdr
->request
== KDP_REATTACH
) {
929 hdr
->request
=KDP_DISCONNECT
;
935 } while (!kdp
.is_conn
);
937 if (current_debugger
== KDP_CUR_DB
)
939 printf("Connected to remote debugger.\n");
944 unsigned int exception
,
949 unsigned short remote_port
;
950 unsigned int timeout_count
= 100;
951 unsigned int poll_timeout
;
954 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
955 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
957 (unsigned short *)&remote_port
,
958 (unsigned int)exception
,
960 (unsigned int)subcode
);
962 kdp_send(remote_port
);
965 while(!pkt
.input
&& poll_timeout
)
972 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
979 if (kdp
.exception_ack_needed
)
982 } while (kdp
.exception_ack_needed
&& timeout_count
--);
984 if (kdp
.exception_ack_needed
) {
985 // give up & disconnect
986 printf("kdp: exception ack timeout\n");
987 if (current_debugger
== KDP_CUR_DB
)
995 unsigned int exception
,
997 unsigned int subcode
,
1003 disable_preemption();
1005 if (saved_state
== 0)
1006 printf("kdp_raise_exception with NULL state\n");
1009 if (exception
!= EXC_BREAKPOINT
) {
1010 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
1013 printf("%s exception (%x,%x,%x)\n",
1014 exception_message
[index
],
1015 exception
, code
, subcode
);
1020 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
1021 * do this. I think the client and the host can get out of sync.
1023 kdp
.saved_state
= saved_state
;
1026 kdp_panic("kdp_raise_exception");
1028 /* Was a system trace requested ? */
1029 if (kdp_snapshot
&& (panicstr
== ((char *) 0)) && (panic_caller
== 0) && !kdp
.is_conn
) {
1030 /* XXX This should be reworked to take a pointer to the buffer */
1031 stack_snapshot_ret
= kdp_stackshot(stack_snapshot_pid
,
1032 (uint32_t) stack_snapshot_buf
, stack_snapshot_bufsize
,
1033 stack_snapshot_options
, &stack_snapshot_bytes_traced
);
1034 goto exit_raise_exception
;
1037 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
) || (kdp_flag
& PANIC_LOG_DUMP
))
1038 && (panicstr
!= (char *) 0)) {
1043 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && (panicstr
== (char *) 0) &&
1046 disableDebugOuput
= disableConsoleOutput
= FALSE
;
1049 if (!(kdp_flag
& DBG_POST_CORE
))
1050 goto exit_raise_exception
;
1055 kdp_connection_wait();
1057 kdp_send_exception(exception
, code
, subcode
);
1058 if (kdp
.exception_ack_needed
) {
1059 kdp
.exception_ack_needed
= FALSE
;
1060 kdp_remove_all_breakpoints();
1061 printf("Remote debugger disconnected.\n");
1066 kdp
.is_halted
= TRUE
; /* XXX */
1067 kdp_handler(saved_state
);
1070 kdp_remove_all_breakpoints();
1071 printf("Remote debugger disconnected.\n");
1074 /* Allow triggering a panic core dump when connected to the machine
1075 * Continuing after setting kdp_trigger_core_dump should do the
1079 if (1 == kdp_trigger_core_dump
) {
1080 kdp_flag
&= ~PANIC_LOG_DUMP
;
1081 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
1085 /* Trigger a reboot if the user has set this flag through the
1086 * debugger.Ideally, this would be done through the HOSTREBOOT packet
1087 * in the protocol,but that will need gdb support,and when it's
1088 * available, it should work automatically.
1090 if (1 == flag_kdp_trigger_reboot
) {
1092 /* If we're still around, reset the flag */
1093 flag_kdp_trigger_reboot
= 0;
1098 if (reattach_wait
== 1)
1101 exit_raise_exception
:
1102 enable_preemption();
1108 kdp
.reply_port
= kdp
.exception_port
= 0;
1109 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
1110 kdp
.exception_seq
= kdp
.conn_seq
= 0;
1114 create_panic_header(unsigned int request
, const char *corename
,
1115 unsigned length
, unsigned int block
)
1117 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
1118 struct ip aligned_ip
, *ip
= &aligned_ip
;
1119 struct ether_header
*eh
;
1120 struct corehdr
*coreh
;
1121 const char *mode
= "octet";
1122 char modelen
= strlen(mode
);
1124 pkt
.off
= sizeof (struct ether_header
);
1125 pkt
.len
= length
+ ((request
== KDP_WRQ
) ? modelen
: 0) +
1126 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
);
1129 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
1131 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
1133 ui
->ui_next
= ui
->ui_prev
= 0;
1135 ui
->ui_pr
= IPPROTO_UDP
;
1136 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
1137 ui
->ui_src
.s_addr
= kdp_current_ip_address
;
1138 /* Already in network byte order via inet_aton() */
1139 ui
->ui_dst
.s_addr
= panic_server_ip
;
1140 ui
->ui_sport
= htons(panicd_port
);
1141 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(panicd_port
) : last_panic_port
);
1142 ui
->ui_ulen
= ui
->ui_len
;
1145 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
1146 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
1148 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
1150 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
1151 ip
->ip_v
= IPVERSION
;
1152 ip
->ip_id
= htons(ip_id
++);
1153 ip
->ip_hl
= sizeof (struct ip
) >> 2;
1154 ip
->ip_ttl
= udp_ttl
;
1156 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
1158 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
1161 pkt
.len
+= sizeof (struct udpiphdr
);
1163 pkt
.off
+= sizeof (struct udpiphdr
);
1165 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1166 coreh
->th_opcode
= htons((u_short
)request
);
1168 if (request
== KDP_WRQ
)
1172 cp
= coreh
->th_u
.tu_rpl
;
1173 strcpy (cp
, corename
);
1174 cp
+= strlen(corename
);
1182 coreh
->th_block
= htonl((unsigned int) block
);
1185 pkt
.off
-= sizeof (struct udpiphdr
);
1186 pkt
.off
-= sizeof (struct ether_header
);
1188 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
1189 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
1190 enaddr_copy(&destination_mac
, eh
->ether_dhost
);
1191 eh
->ether_type
= htons(ETHERTYPE_IP
);
1193 pkt
.len
+= sizeof (struct ether_header
);
1197 int kdp_send_crashdump_data(unsigned int request
, char *corename
,
1198 unsigned int length
, caddr_t txstart
)
1200 caddr_t txend
= txstart
+ length
;
1201 int panic_error
= 0;
1203 if (length
<= SEGSIZE
) {
1204 if ((panic_error
= kdp_send_crashdump_pkt(request
, corename
, length
, (caddr_t
) txstart
)) < 0) {
1205 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error
);
1206 return panic_error
;
1211 while (txstart
<= (txend
- SEGSIZE
)) {
1212 if ((panic_error
= kdp_send_crashdump_pkt(KDP_DATA
, NULL
, SEGSIZE
, txstart
)) < 0) {
1213 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error
);
1217 if (!(panic_block
% 2000))
1220 if (txstart
< txend
) {
1221 kdp_send_crashdump_pkt(request
, corename
, (txend
- txstart
), txstart
);
1228 kdp_send_crashdump_pkt(unsigned int request
, char *corename
,
1229 unsigned int length
, void *panic_data
)
1231 struct corehdr
*th
= NULL
;
1232 int poll_count
= 2500;
1234 char rretries
= 0, tretries
= 0;
1236 pkt
.off
= pkt
.len
= 0;
1238 if (request
== KDP_WRQ
) /* longer timeout for initial request */
1244 if (tretries
>=15) {
1245 /* The crashdump server is unreachable for some reason. This could be a network
1246 * issue or, if we've been especially unfortunate, we've hit Radar 2760413,
1247 * which is a long standing problem with the IOKit polled mode network driver
1248 * shim which can prevent transmits/receives completely.
1250 printf ("Cannot contact panic server, timing out.\n");
1255 printf("TX retry #%d ", tretries
);
1257 th
= create_panic_header(request
, corename
, length
, panic_block
);
1259 if (request
== KDP_DATA
) {
1260 if (!kdp_vm_read((caddr_t
) panic_data
, (caddr_t
) th
->th_data
, length
)) {
1261 memset ((caddr_t
) th
->th_data
, 'X', length
);
1264 else if (request
== KDP_SEEK
) {
1265 *(unsigned int *) th
->th_data
= htonl(*(unsigned int *) panic_data
);
1268 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
1270 /* Listen for the ACK */
1272 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1281 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1283 if (ntohs(th
->th_opcode
) == KDP_ACK
&& ntohl(th
->th_block
) == panic_block
) {
1286 if (ntohs(th
->th_opcode
) == KDP_ERROR
) {
1287 printf("Panic server returned error %d, retrying\n", ntohl(th
->th_code
));
1289 goto TRANSMIT_RETRY
;
1292 if (ntohl(th
->th_block
) == (panic_block
- 1)) {
1293 printf("RX retry ");
1295 goto TRANSMIT_RETRY
;
1301 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1303 printf("Received a debugger packet,transferring control to debugger\n");
1304 /* Configure that if not set ..*/
1305 kdp_flag
|= DBG_POST_CORE
;
1308 else /* We timed out */
1309 if (0 == poll_count
) {
1311 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1312 goto TRANSMIT_RETRY
;
1317 if (request
== KDP_EOF
)
1318 printf("\nTotal number of packets transmitted: %d\n", panic_block
);
1326 return ((c
> 47) && (c
< 58));
1328 /* From user mode Libc - this ought to be in a library */
1330 strnstr(char *s
, const char *find
, size_t slen
)
1335 if ((c
= *find
++) != '\0') {
1339 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1344 } while (strncmp(s
, find
, len
) != 0);
1350 extern char version
[];
1352 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1353 * would be to have the integrator run a script which would copy the
1354 * xnu version into a string or an int somewhere at project submission
1355 * time - makes assumptions about sizeof(version), but will not fail if
1356 * it changes, but may be incorrect.
1358 /* 2006: Incorporated a change from Darwin user P. Lovell to extract
1359 * the minor kernel version numbers from the version string.
1362 kdp_get_xnu_version(char *versionbuf
)
1370 strcpy(vstr
, "custom");
1372 if (kdp_vm_read(version
, versionbuf
, 95)) {
1373 versionbuf
[94] = '\0';
1374 versionpos
= strnstr(versionbuf
, "xnu-", 90);
1376 strncpy(vstr
, versionpos
, sizeof(vstr
));
1377 vstr
[sizeof(vstr
)-1] = '\0';
1378 vptr
= vstr
+ 4; /* Begin after "xnu-" */
1379 while (*vptr
&& (isdigit(*vptr
) || *vptr
== '.'))
1382 /* Remove trailing period, if any */
1383 if (*(--vptr
) == '.')
1389 strcpy(versionbuf
, vstr
);
1393 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1394 extern int snprintf(char *str
, size_t size
, const char *format
, ...);
1396 /* Primary dispatch routine for the system dump */
1401 char coreprefix
[10];
1405 uint32_t current_ip
= ntohl(kdp_current_ip_address
);
1407 if (flag_panic_dump_in_progress
) {
1408 printf("System dump aborted.\n");
1409 goto panic_dump_exit
;
1412 printf("Entering system dump routine\n");
1414 if (!panicd_specified
) {
1415 printf("A dump server was not specified in the boot-args, terminating kernel core dump.\n");
1416 goto panic_dump_exit
;
1419 if (current_ip
== 0) {
1420 printf("System dump failed: An IP address isn't assigned to this machine.\n");
1424 flag_panic_dump_in_progress
= TRUE
;
1428 kdp_panic("kdp_panic_dump: unexpected pending input packet");
1430 kdp_get_xnu_version((char *) &pkt
.data
[0]);
1432 /* Panic log bit takes precedence over core dump bit */
1433 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
))
1434 strncpy(coreprefix
, "paniclog", sizeof(coreprefix
));
1436 strncpy(coreprefix
, "core", sizeof(coreprefix
));
1438 abstime
= mach_absolute_time();
1439 pkt
.data
[20] = '\0';
1440 snprintf (corename
, sizeof(corename
), "%s-%s-%d.%d.%d.%d-%x",
1441 coreprefix
, &pkt
.data
[0],
1442 (current_ip
& 0xff000000) >> 24,
1443 (current_ip
& 0xff0000) >> 16,
1444 (current_ip
& 0xff00) >> 8,
1445 (current_ip
& 0xff),
1446 (unsigned int) (abstime
& 0xffffffff));
1448 if (0 == inet_aton(panicd_ip_str
, (struct in_addr
*) &panic_server_ip
)) {
1449 printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str
);
1452 printf("Attempting connection to panic server configured at IP %s, port %d\n", panicd_ip_str
, panicd_port
);
1454 destination_mac
= router_mac
;
1456 if (kdp_arp_resolve(panic_server_ip
, &temp_mac
)) {
1457 printf("Resolved %s's (or proxy's) link level address\n", panicd_ip_str
);
1458 destination_mac
= temp_mac
;
1461 if (!flag_panic_dump_in_progress
) goto panic_dump_exit
;
1462 if (router_specified
) {
1463 if (0 == inet_aton(router_ip_str
, (struct in_addr
*) &parsed_router_ip
))
1464 printf("inet_aton() failed interpreting %s as an IP\n", router_ip_str
);
1466 router_ip
= parsed_router_ip
;
1467 if (kdp_arp_resolve(router_ip
, &temp_mac
)) {
1468 destination_mac
= temp_mac
;
1469 printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
1475 if (!flag_panic_dump_in_progress
) goto panic_dump_exit
;
1477 printf("Transmitting packets to link level address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1478 destination_mac
.ether_addr_octet
[0] & 0xff,
1479 destination_mac
.ether_addr_octet
[1] & 0xff,
1480 destination_mac
.ether_addr_octet
[2] & 0xff,
1481 destination_mac
.ether_addr_octet
[3] & 0xff,
1482 destination_mac
.ether_addr_octet
[4] & 0xff,
1483 destination_mac
.ether_addr_octet
[5] & 0xff);
1485 printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map
));
1486 printf("Sending write request for %s\n", corename
);
1488 if ((panic_error
= kdp_send_crashdump_pkt(KDP_WRQ
, corename
, 0 , NULL
)) < 0) {
1489 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error
);
1490 goto panic_dump_exit
;
1493 /* Just the panic log requested */
1494 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
1495 printf("Transmitting panic log, please wait: ");
1496 kdp_send_crashdump_data(KDP_DATA
, corename
, (debug_buf_ptr
- debug_buf
), debug_buf
);
1497 kdp_send_crashdump_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1498 printf("Please file a bug report on this panic, if possible.\n");
1499 goto panic_dump_exit
;
1502 /* We want a core dump if we're here */
1505 abort_panic_transfer();
1513 abort_panic_transfer(void)
1515 flag_panic_dump_in_progress
= FALSE
;