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 <vm/vm_protos.h>
47 #include <mach/memory_object_types.h>
51 #define DO_ALIGN 1 /* align all packet data accesses */
53 extern int kdp_getc(void);
54 extern int reattach_wait
;
56 static u_short ip_id
; /* ip packet ctr, for ids */
58 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
61 * UDP protocol implementation.
62 * Per RFC 768, August, 1980.
64 #define UDP_TTL 60 /* deflt time to live for UDP packets */
65 int udp_ttl
= UDP_TTL
;
66 static unsigned char exception_seq
;
69 unsigned char data
[KDP_MAXPACKET
];
70 unsigned int off
, len
;
86 *exception_message
[] = {
88 "Memory access", /* EXC_BAD_ACCESS */
89 "Failed instruction", /* EXC_BAD_INSTRUCTION */
90 "Arithmetic", /* EXC_ARITHMETIC */
91 "Emulation", /* EXC_EMULATION */
92 "Software", /* EXC_SOFTWARE */
93 "Breakpoint" /* EXC_BREAKPOINT */
98 static kdp_send_t kdp_en_send_pkt
= 0;
99 static kdp_receive_t kdp_en_recv_pkt
= 0;
102 static u_long kdp_current_ip_address
= 0;
103 static struct ether_addr kdp_current_mac_address
= {{0, 0, 0, 0, 0, 0}};
104 static void *kdp_current_ifp
= 0;
106 static void kdp_handler( void *);
108 static unsigned int panic_server_ip
= 0;
109 static unsigned int parsed_router_ip
= 0;
110 static unsigned int router_ip
= 0;
111 static unsigned int panicd_specified
= 0;
112 static unsigned int router_specified
= 0;
114 static struct ether_addr router_mac
= {{0, 0, 0 , 0, 0, 0}};
116 static u_char flag_panic_dump_in_progress
= 0;
117 static u_char flag_router_mac_initialized
= 0;
119 static unsigned int panic_timeout
= 100000;
120 static unsigned int last_panic_port
= CORE_REMOTE_PORT
;
122 unsigned int SEGSIZE
= 512;
124 static unsigned int PANIC_PKTSIZE
= 518;
125 static char panicd_ip_str
[20];
126 static char router_ip_str
[20];
128 static unsigned int panic_block
= 0;
129 static volatile unsigned int kdp_trigger_core_dump
= 0;
130 static volatile unsigned int flag_kdp_trigger_reboot
= 0;
132 extern unsigned int not_in_kdp
;
134 extern int kdp_vm_read( caddr_t
, caddr_t
, unsigned int);
137 kdp_register_send_receive(
139 kdp_receive_t receive
)
141 unsigned int debug
=0;
143 kdp_en_send_pkt
= send
;
144 kdp_en_recv_pkt
= receive
;
148 PE_parse_boot_arg("debug", &debug
);
150 if (debug
& DB_KDP_BP_DIS
)
151 kdp_flag
|= KDP_BP_DIS
;
152 if (debug
& DB_KDP_GETC_ENA
)
153 kdp_flag
|= KDP_GETC_ENA
;
157 if (debug
& DB_KERN_DUMP_ON_PANIC
)
158 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
159 if (debug
& DB_KERN_DUMP_ON_NMI
)
160 kdp_flag
|= PANIC_CORE_ON_NMI
;
162 if (debug
& DB_DBG_POST_CORE
)
163 kdp_flag
|= DBG_POST_CORE
;
165 if (debug
& DB_PANICLOG_DUMP
)
166 kdp_flag
|= PANIC_LOG_DUMP
;
168 if (PE_parse_boot_arg ("_panicd_ip", panicd_ip_str
))
169 panicd_specified
= 1;
170 /* For the future, currently non-functional */
171 if (PE_parse_boot_arg ("_router_ip", router_ip_str
))
172 router_specified
= 1;
174 kdp_flag
|= KDP_READY
;
175 if (current_debugger
== NO_CUR_DB
)
176 current_debugger
= KDP_CUR_DB
;
177 if (halt_in_debugger
) {
184 kdp_unregister_send_receive(
186 kdp_receive_t receive
)
188 if (current_debugger
== KDP_CUR_DB
)
189 current_debugger
= NO_CUR_DB
;
190 kdp_flag
&= ~KDP_READY
;
191 kdp_en_send_pkt
= NULL
;
192 kdp_en_recv_pkt
= NULL
;
201 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
204 static unsigned short
210 unsigned int high
, low
, sum
;
220 sum
= (high
<< 8) + low
;
221 sum
= (sum
>> 16) + (sum
& 65535);
223 return (sum
> 65535 ? sum
- 65535 : sum
);
228 unsigned short reply_port
231 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
232 struct ip aligned_ip
, *ip
= &aligned_ip
;
233 struct in_addr tmp_ipaddr
;
234 struct ether_addr tmp_enaddr
;
235 struct ether_header
*eh
;
238 kdp_panic("kdp_reply");
240 pkt
.off
-= sizeof (struct udpiphdr
);
243 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
245 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
247 ui
->ui_next
= ui
->ui_prev
= 0;
249 ui
->ui_pr
= IPPROTO_UDP
;
250 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
251 tmp_ipaddr
= ui
->ui_src
;
252 ui
->ui_src
= ui
->ui_dst
;
253 ui
->ui_dst
= tmp_ipaddr
;
254 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
255 ui
->ui_dport
= reply_port
;
256 ui
->ui_ulen
= ui
->ui_len
;
259 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
260 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
262 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
264 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
265 ip
->ip_v
= IPVERSION
;
266 ip
->ip_id
= htons(ip_id
++);
267 ip
->ip_hl
= sizeof (struct ip
) >> 2;
268 ip
->ip_ttl
= udp_ttl
;
270 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
272 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
275 pkt
.len
+= sizeof (struct udpiphdr
);
277 pkt
.off
-= sizeof (struct ether_header
);
279 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
280 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
281 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
282 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
283 eh
->ether_type
= htons(ETHERTYPE_IP
);
285 pkt
.len
+= sizeof (struct ether_header
);
287 // save reply for possible retransmission
288 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
290 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
292 // increment expected sequence number
298 unsigned short remote_port
301 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
302 struct ip aligned_ip
, *ip
= &aligned_ip
;
303 struct ether_header
*eh
;
306 kdp_panic("kdp_send");
308 pkt
.off
-= sizeof (struct udpiphdr
);
311 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
313 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
315 ui
->ui_next
= ui
->ui_prev
= 0;
317 ui
->ui_pr
= IPPROTO_UDP
;
318 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
319 ui
->ui_src
= adr
.loc
.in
;
320 ui
->ui_dst
= adr
.rmt
.in
;
321 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
322 ui
->ui_dport
= remote_port
;
323 ui
->ui_ulen
= ui
->ui_len
;
326 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
327 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
329 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
331 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
332 ip
->ip_v
= IPVERSION
;
333 ip
->ip_id
= htons(ip_id
++);
334 ip
->ip_hl
= sizeof (struct ip
) >> 2;
335 ip
->ip_ttl
= udp_ttl
;
337 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
339 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
342 pkt
.len
+= sizeof (struct udpiphdr
);
344 pkt
.off
-= sizeof (struct ether_header
);
346 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
347 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
348 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
349 eh
->ether_type
= htons(ETHERTYPE_IP
);
351 pkt
.len
+= sizeof (struct ether_header
);
352 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
355 /* We don't interpret this pointer, we just give it to the
356 bsd stack so it can decide when to set the MAC and IP info. */
358 kdp_set_interface(void *ifp
)
360 kdp_current_ifp
= ifp
;
366 return kdp_current_ifp
;
370 kdp_set_ip_and_mac_addresses(
371 struct in_addr
*ipaddr
,
372 struct ether_addr
*macaddr
)
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
;
382 flag_router_mac_initialized
= 1;
386 kdp_get_mac_addr(void)
388 return kdp_current_mac_address
;
392 kdp_get_ip_address(void)
394 return kdp_current_ip_address
;
397 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
398 is set. A workaround if you don't want to reboot is to set
399 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
405 struct ether_header
*eh
;
406 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
408 struct in_addr isaddr
, itaddr
, myaddr
;
409 struct ether_addr my_enaddr
;
411 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
412 pkt
.off
+= sizeof(struct ether_header
);
414 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
416 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
419 myaddr
.s_addr
= kdp_get_ip_address();
420 my_enaddr
= kdp_get_mac_addr();
422 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
425 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
426 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
428 if (itaddr
.s_addr
== myaddr
.s_addr
) {
429 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
430 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
432 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
433 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
435 ea
->arp_op
= htons(ARPOP_REPLY
);
436 ea
->arp_pro
= htons(ETHERTYPE_IP
);
437 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
438 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
439 eh
->ether_type
= htons(ETHERTYPE_ARP
);
440 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
441 pkt
.off
-= sizeof (struct ether_header
);
442 /* pkt.len is still the length we want, ether_header+ether_arp */
443 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
450 struct ether_header
*eh
;
451 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
452 struct ip aligned_ip
, *ip
= &aligned_ip
;
453 static int msg_printed
;
457 kdp_panic("kdp_poll");
459 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
460 if( msg_printed
== 0) {
462 printf("kdp_poll: no debugger device\n");
467 pkt
.off
= pkt
.len
= 0;
468 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
473 if (pkt
.len
>= sizeof(struct ether_header
))
475 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
477 if (kdp_flag
& KDP_ARP
)
479 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
487 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
490 pkt
.off
+= sizeof (struct ether_header
);
491 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
496 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
497 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
499 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
500 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
503 pkt
.off
+= sizeof (struct udpiphdr
);
504 if (ui
->ui_pr
!= IPPROTO_UDP
) {
508 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
512 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
513 if (CORE_REMOTE_PORT
== (ntohs(ui
->ui_dport
)) &&
514 flag_panic_dump_in_progress
) {
515 last_panic_port
= ui
->ui_sport
;
520 /* If we receive a kernel debugging packet whilst a
521 * core dump is in progress, abort the transfer and
522 * enter the debugger.
525 if (flag_panic_dump_in_progress
)
527 abort_panic_transfer();
531 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
532 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
533 adr
.loc
.in
= ui
->ui_dst
;
535 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
536 adr
.rmt
.in
= ui
->ui_src
;
540 * Calculate kdp packet length.
542 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
551 unsigned short reply_port
;
552 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
555 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
562 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
564 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
567 // ignore replies -- we're not expecting them anyway.
572 if (hdr
->request
== KDP_REATTACH
)
573 exception_seq
= hdr
->seq
;
575 // check for retransmitted request
576 if (hdr
->seq
== (exception_seq
- 1)) {
577 /* retransmit last reply */
578 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
581 } else if (hdr
->seq
!= exception_seq
) {
582 printf("kdp: bad sequence %d (want %d)\n",
583 hdr
->seq
, exception_seq
);
587 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
589 (unsigned short *)&reply_port
)) {
590 kdp_reply(reply_port
);
595 } while (kdp
.is_halted
);
599 kdp_connection_wait(void)
601 unsigned short reply_port
;
602 boolean_t
kdp_call_kdb();
603 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
604 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
606 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
607 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
608 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
609 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
610 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
611 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
612 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
614 printf( "ip address: %d.%d.%d.%d\n",
615 (ip_addr
& 0xff000000) >> 24,
616 (ip_addr
& 0xff0000) >> 16,
617 (ip_addr
& 0xff00) >> 8,
620 printf("\nWaiting for remote debugger connection.\n");
622 if (reattach_wait
== 0) {
623 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
625 printf("Options..... Type\n");
626 printf("------------ ----\n");
627 printf("continue.... 'c'\n");
628 printf("reboot...... 'r'\n");
630 printf("enter kdb... 'k'\n");
639 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
642 if (kdp_flag
& KDP_GETC_ENA
) {
645 printf("Continuing...\n");
648 printf("Rebooting...\n");
653 printf("calling kdb...\n");
657 printf("not implemented...\n");
667 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
669 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
671 if (hdr
->request
== KDP_HOSTREBOOT
) {
673 /* should not return! */
675 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
676 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
677 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
679 (unsigned short *)&reply_port
))
680 kdp_reply(reply_port
);
681 if (hdr
->request
== KDP_REATTACH
) {
683 hdr
->request
=KDP_DISCONNECT
;
689 } while (!kdp
.is_conn
);
691 if (current_debugger
== KDP_CUR_DB
)
693 printf("Connected to remote debugger.\n");
698 unsigned int exception
,
703 unsigned short remote_port
;
704 unsigned int timeout_count
= 100;
705 unsigned int poll_timeout
;
708 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
709 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
711 (unsigned short *)&remote_port
,
712 (unsigned int)exception
,
714 (unsigned int)subcode
);
716 kdp_send(remote_port
);
719 while(!pkt
.input
&& poll_timeout
)
726 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
733 if (kdp
.exception_ack_needed
)
736 } while (kdp
.exception_ack_needed
&& timeout_count
--);
738 if (kdp
.exception_ack_needed
) {
739 // give up & disconnect
740 printf("kdp: exception ack timeout\n");
741 if (current_debugger
== KDP_CUR_DB
)
749 unsigned int exception
,
751 unsigned int subcode
,
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
827 if (1 == kdp_trigger_core_dump
) {
828 kdp_flag
&= ~PANIC_LOG_DUMP
;
829 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
833 /* Trigger a reboot if the user has set this flag through the
834 * debugger.Ideally, this would be done through the HOSTREBOOT packet
835 * in the protocol,but that will need gdb support,and when it's
836 * available, it should work automatically.
838 if (1 == flag_kdp_trigger_reboot
) {
840 /* If we're still around, reset the flag */
841 flag_kdp_trigger_reboot
= 0;
846 if (reattach_wait
== 1)
849 exit_raise_exception
:
856 kdp
.reply_port
= kdp
.exception_port
= 0;
857 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
858 kdp
.exception_seq
= kdp
.conn_seq
= 0;
862 create_panic_header(unsigned int request
, const char *corename
,
863 unsigned length
, unsigned int block
)
865 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
866 struct ip aligned_ip
, *ip
= &aligned_ip
;
867 struct ether_header
*eh
;
868 struct corehdr
*coreh
;
869 const char *mode
= "octet";
870 char modelen
= strlen(mode
);
872 pkt
.off
= sizeof (struct ether_header
);
873 pkt
.len
= length
+ ((request
== KDP_WRQ
) ? modelen
: 0) +
874 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
);
877 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
879 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
881 ui
->ui_next
= ui
->ui_prev
= 0;
883 ui
->ui_pr
= IPPROTO_UDP
;
884 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
885 ui
->ui_src
.s_addr
= htonl(kdp_current_ip_address
);
886 ui
->ui_dst
.s_addr
= panic_server_ip
;
887 ui
->ui_sport
= htons(CORE_REMOTE_PORT
);
888 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(CORE_REMOTE_PORT
) : last_panic_port
);
889 ui
->ui_ulen
= ui
->ui_len
;
892 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
893 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
895 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
897 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
898 ip
->ip_v
= IPVERSION
;
899 ip
->ip_id
= htons(ip_id
++);
900 ip
->ip_hl
= sizeof (struct ip
) >> 2;
901 ip
->ip_ttl
= udp_ttl
;
903 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
905 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
908 pkt
.len
+= sizeof (struct udpiphdr
);
910 pkt
.off
+= sizeof (struct udpiphdr
);
912 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
913 coreh
->th_opcode
= htons((u_short
)request
);
915 if (request
== KDP_WRQ
)
919 cp
= coreh
->th_u
.tu_rpl
;
920 strcpy (cp
, corename
);
921 cp
+= strlen(corename
);
929 coreh
->th_block
= htonl((unsigned int) block
);
932 pkt
.off
-= sizeof (struct udpiphdr
);
933 pkt
.off
-= sizeof (struct ether_header
);
935 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
936 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
937 enaddr_copy(&router_mac
, eh
->ether_dhost
);
938 eh
->ether_type
= htons(ETHERTYPE_IP
);
940 pkt
.len
+= sizeof (struct ether_header
);
944 int kdp_send_panic_packets (unsigned int request
, char *corename
,
945 unsigned int length
, unsigned int txstart
)
947 unsigned int txend
= txstart
+ length
;
950 if (length
<= SEGSIZE
) {
951 if ((panic_error
= kdp_send_panic_pkt (request
, corename
, length
, (caddr_t
) txstart
)) < 0) {
952 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
958 while (txstart
<= (txend
- SEGSIZE
)) {
959 if ((panic_error
= kdp_send_panic_pkt (KDP_DATA
, NULL
, SEGSIZE
, (caddr_t
) txstart
)) < 0) {
960 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
964 if (!(panic_block
% 2000))
967 if (txstart
< txend
) {
968 kdp_send_panic_pkt(request
, corename
, (txend
- txstart
), (caddr_t
) txstart
);
975 kdp_send_panic_pkt (unsigned int request
, char *corename
,
976 unsigned int length
, void *panic_data
)
978 struct corehdr
*th
= NULL
;
979 int poll_count
= 2500;
981 char rretries
= 0, tretries
= 0;
983 extern signed long gIODebuggerSemaphore;
985 pkt
.off
= pkt
.len
= 0;
987 if (request
== KDP_WRQ
) /* longer timeout for initial request */
994 printf("TX retry #%d ", tretries
);
997 /* This iokit layer issue can potentially
998 *cause a hang, uncomment to check if it's happening.
1001 if (gIODebuggerSemaphore)
1002 printf("The gIODebuggerSemaphore is raised, preventing packet transmission (2760413)\n");
1005 printf ("Cannot contact panic server, timing out.\n");
1009 th
= create_panic_header(request
, corename
, length
, panic_block
);
1011 if (request
== KDP_DATA
|| request
== KDP_SEEK
) {
1012 if (!kdp_vm_read ((caddr_t
) panic_data
, (caddr_t
) th
->th_data
, length
)) {
1013 memset ((caddr_t
) th
->th_data
, 'X', length
);
1017 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
1019 /* Now we have to listen for the ACK */
1022 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1031 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1032 /* These will eventually have to be ntoh[ls]'ed as appropriate */
1034 if (th
->th_opcode
== KDP_ACK
&& th
->th_block
== panic_block
) {
1037 if (th
->th_opcode
== KDP_ERROR
) {
1038 printf("Panic server returned error %d, retrying\n", th
->th_code
);
1040 goto TRANSMIT_RETRY
;
1043 if (th
->th_block
== (panic_block
-1)) {
1044 printf("RX retry ");
1046 goto TRANSMIT_RETRY
;
1052 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1054 printf("Received a debugger packet,transferring control to debugger\n");
1055 /* Configure that if not set ..*/
1056 kdp_flag
|= DBG_POST_CORE
;
1059 else /* We timed out */
1060 if (0 == poll_count
) {
1062 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1063 goto TRANSMIT_RETRY
;
1068 if (request
== KDP_EOF
)
1069 printf ("\nTotal number of packets transmitted: %d\n", panic_block
);
1074 /* Since we don't seem to have an isdigit() .. */
1078 return ((c
> 47) && (c
< 58));
1080 /* From user mode Libc - this ought to be in a library */
1082 strnstr(s
, find
, slen
)
1090 if ((c
= *find
++) != '\0') {
1094 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1099 } while (strncmp(s
, find
, len
) != 0);
1105 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1106 * would be to have the integrator run a script which would copy the
1107 * xnu version into a string or an int somewhere at project submission
1108 * time - makes assumptions about sizeof(version), but will not fail if
1109 * it changes, but may be incorrect.
1113 kdp_get_xnu_version(char *versionbuf
)
1115 extern const char version
[];
1120 strcpy(vstr
, "custom");
1122 if (kdp_vm_read(version
, versionbuf
, 90)) {
1124 versionbuf
[89] = '\0';
1126 versionpos
= strnstr(versionbuf
, "xnu-", 80);
1129 strncpy (vstr
, versionpos
, (isdigit (versionpos
[7]) ? 8 : 7));
1130 vstr
[(isdigit (versionpos
[7]) ? 8 : 7)] = '\0';
1135 strcpy(versionbuf
, vstr
);
1139 /* Primary dispatch routine for the system dump */
1144 char coreprefix
[10];
1147 extern vm_map_t kernel_map
;
1149 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1153 printf ("Entering system dump routine\n");
1155 if (!panicd_specified
) {
1156 printf ("A panic server was not specified in the boot-args, terminating kernel core dump.\n");
1157 goto panic_dump_exit
;
1160 flag_panic_dump_in_progress
= 1;
1164 kdp_panic("kdp_panic_dump");
1166 kdp_get_xnu_version((char *) &pkt
.data
[0]);
1168 /* Panic log bit takes precedence over core dump bit */
1169 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
))
1170 strncpy(coreprefix
, "paniclog", sizeof(coreprefix
));
1172 strncpy(coreprefix
, "core", sizeof(coreprefix
));
1174 abstime
= mach_absolute_time();
1175 pkt
.data
[10] = '\0';
1176 snprintf (corename
, sizeof(corename
), "%s-%s-%d.%d.%d.%d-%x",
1177 coreprefix
, &pkt
.data
[0],
1178 (kdp_current_ip_address
& 0xff000000) >> 24,
1179 (kdp_current_ip_address
& 0xff0000) >> 16,
1180 (kdp_current_ip_address
& 0xff00) >> 8,
1181 (kdp_current_ip_address
& 0xff),
1182 (unsigned int) (abstime
& 0xffffffff));
1184 if (0 == inet_aton(panicd_ip_str
, (struct in_addr
*) &panic_server_ip
)) {
1185 printf("inet_aton() failed interpreting %s as a panic server IP\n",
1189 printf("Attempting connection to panic server configured at IP %s\n",
1192 if (router_specified
) {
1193 if (0 == inet_aton(router_ip_str
, (struct in_addr
*) &parsed_router_ip
)){
1194 printf("inet_aton() failed interpreting %s as an IP\n", router_ip
);
1197 router_ip
= parsed_router_ip
;
1198 printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
1199 /* We will eventually need to resolve the router's MAC ourselves,
1200 * if one is specified,rather than being set through the BSD callback
1201 * but the _router_ip option does not function currently
1206 printf("Routing via router MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1207 router_mac
.ether_addr_octet
[0] & 0xff,
1208 router_mac
.ether_addr_octet
[1] & 0xff,
1209 router_mac
.ether_addr_octet
[2] & 0xff,
1210 router_mac
.ether_addr_octet
[3] & 0xff,
1211 router_mac
.ether_addr_octet
[4] & 0xff,
1212 router_mac
.ether_addr_octet
[5] & 0xff);
1214 printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map
));
1215 printf ("Sending write request for %s\n", corename
);
1217 if ((panic_error
= kdp_send_panic_pkt (KDP_WRQ
, corename
, 0 , NULL
)) < 0) {
1218 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
1219 goto panic_dump_exit
;
1222 /* Just the panic log requested */
1223 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
1224 printf("Transmitting panic log, please wait: ");
1225 kdp_send_panic_packets (KDP_DATA
, corename
, (debug_buf_ptr
- debug_buf
), (unsigned int) debug_buf
);
1226 kdp_send_panic_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1227 printf("Please file a bug report on this panic, if possible.\n");
1228 goto panic_dump_exit
;
1231 /* We want a core dump if we're here */
1235 flag_panic_dump_in_progress
= 0;
1244 abort_panic_transfer()
1246 flag_panic_dump_in_progress
= 0;