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}};
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;
131 extern unsigned int not_in_kdp
;
134 kdp_register_send_receive(
136 kdp_receive_t receive
)
140 kdp_en_send_pkt
= send
;
141 kdp_en_recv_pkt
= receive
;
145 PE_parse_boot_arg("debug", &debug
);
147 if (debug
& DB_KDP_BP_DIS
)
148 kdp_flag
|= KDP_BP_DIS
;
149 if (debug
& DB_KDP_GETC_ENA
)
150 kdp_flag
|= KDP_GETC_ENA
;
154 if (debug
& DB_KERN_DUMP_ON_PANIC
)
155 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
156 if (debug
& DB_KERN_DUMP_ON_NMI
)
157 kdp_flag
|= PANIC_CORE_ON_NMI
;
159 if (debug
& DB_DBG_POST_CORE
)
160 kdp_flag
|= DBG_POST_CORE
;
162 if (debug
& DB_PANICLOG_DUMP
)
163 kdp_flag
|= PANIC_LOG_DUMP
;
165 if (PE_parse_boot_arg ("_panicd_ip", panicd_ip_str
))
166 panicd_specified
= 1;
167 /* For the future, currently non-functional */
168 if (PE_parse_boot_arg ("_router_ip", router_ip_str
))
169 router_specified
= 1;
171 kdp_flag
|= KDP_READY
;
172 if (current_debugger
== NO_CUR_DB
)
173 current_debugger
= KDP_CUR_DB
;
174 if (halt_in_debugger
) {
181 kdp_unregister_send_receive(
183 kdp_receive_t receive
)
185 if (current_debugger
== KDP_CUR_DB
)
186 current_debugger
= NO_CUR_DB
;
187 kdp_flag
&= ~KDP_READY
;
188 kdp_en_send_pkt
= NULL
;
189 kdp_en_recv_pkt
= NULL
;
198 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
201 static unsigned short
207 unsigned int high
, low
, sum
;
217 sum
= (high
<< 8) + low
;
218 sum
= (sum
>> 16) + (sum
& 65535);
220 return (sum
> 65535 ? sum
- 65535 : sum
);
225 unsigned short reply_port
228 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
229 struct ip aligned_ip
, *ip
= &aligned_ip
;
230 struct in_addr tmp_ipaddr
;
231 struct ether_addr tmp_enaddr
;
232 struct ether_header
*eh
;
235 kdp_panic("kdp_reply");
237 pkt
.off
-= sizeof (struct udpiphdr
);
240 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
242 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
244 ui
->ui_next
= ui
->ui_prev
= 0;
246 ui
->ui_pr
= IPPROTO_UDP
;
247 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
248 tmp_ipaddr
= ui
->ui_src
;
249 ui
->ui_src
= ui
->ui_dst
;
250 ui
->ui_dst
= tmp_ipaddr
;
251 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
252 ui
->ui_dport
= reply_port
;
253 ui
->ui_ulen
= ui
->ui_len
;
256 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
257 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
259 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
261 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
262 ip
->ip_v
= IPVERSION
;
263 ip
->ip_id
= htons(ip_id
++);
264 ip
->ip_hl
= sizeof (struct ip
) >> 2;
265 ip
->ip_ttl
= udp_ttl
;
267 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
269 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
272 pkt
.len
+= sizeof (struct udpiphdr
);
274 pkt
.off
-= sizeof (struct ether_header
);
276 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
277 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
278 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
279 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
280 eh
->ether_type
= htons(ETHERTYPE_IP
);
282 pkt
.len
+= sizeof (struct ether_header
);
284 // save reply for possible retransmission
285 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
287 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
289 // increment expected sequence number
295 unsigned short remote_port
298 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
299 struct ip aligned_ip
, *ip
= &aligned_ip
;
300 struct ether_header
*eh
;
303 kdp_panic("kdp_send");
305 pkt
.off
-= sizeof (struct udpiphdr
);
308 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
310 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
312 ui
->ui_next
= ui
->ui_prev
= 0;
314 ui
->ui_pr
= IPPROTO_UDP
;
315 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
316 ui
->ui_src
= adr
.loc
.in
;
317 ui
->ui_dst
= adr
.rmt
.in
;
318 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
319 ui
->ui_dport
= remote_port
;
320 ui
->ui_ulen
= ui
->ui_len
;
323 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
324 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
326 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
328 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
329 ip
->ip_v
= IPVERSION
;
330 ip
->ip_id
= htons(ip_id
++);
331 ip
->ip_hl
= sizeof (struct ip
) >> 2;
332 ip
->ip_ttl
= udp_ttl
;
334 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
336 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
339 pkt
.len
+= sizeof (struct udpiphdr
);
341 pkt
.off
-= sizeof (struct ether_header
);
343 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
344 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
345 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
346 eh
->ether_type
= htons(ETHERTYPE_IP
);
348 pkt
.len
+= sizeof (struct ether_header
);
349 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
354 kdp_set_ip_and_mac_addresses(
355 struct in_addr
*ipaddr
,
356 struct ether_addr
*macaddr
)
358 unsigned int debug
= 0;
360 kdp_current_ip_address
= ipaddr
->s_addr
;
361 kdp_current_mac_address
= *macaddr
;
365 kdp_set_gateway_mac(void *gatewaymac
)
367 router_mac
= *(struct ether_addr
*)gatewaymac
;
371 kdp_get_mac_addr(void)
373 return kdp_current_mac_address
;
377 kdp_get_ip_address(void)
379 return kdp_current_ip_address
;
382 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
383 is set. A workaround if you don't want to reboot is to set
384 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
390 struct ether_header
*eh
;
391 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
393 struct in_addr isaddr
, itaddr
, myaddr
;
394 struct ether_addr my_enaddr
;
396 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
397 pkt
.off
+= sizeof(struct ether_header
);
399 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
401 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
404 myaddr
.s_addr
= kdp_get_ip_address();
405 my_enaddr
= kdp_get_mac_addr();
407 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
410 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
411 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
413 if (itaddr
.s_addr
== myaddr
.s_addr
) {
414 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
415 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
417 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
418 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
420 ea
->arp_op
= htons(ARPOP_REPLY
);
421 ea
->arp_pro
= htons(ETHERTYPE_IP
);
422 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
423 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
424 eh
->ether_type
= htons(ETHERTYPE_ARP
);
425 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
426 pkt
.off
-= sizeof (struct ether_header
);
427 /* pkt.len is still the length we want, ether_header+ether_arp */
428 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
435 struct ether_header
*eh
;
436 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
437 struct ip aligned_ip
, *ip
= &aligned_ip
;
438 static int msg_printed
;
442 kdp_panic("kdp_poll");
444 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
445 if( msg_printed
== 0) {
447 printf("kdp_poll: no debugger device\n");
452 pkt
.off
= pkt
.len
= 0;
453 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
458 if (pkt
.len
>= sizeof(struct ether_header
))
460 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
462 if (kdp_flag
& KDP_ARP
)
464 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
472 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
475 pkt
.off
+= sizeof (struct ether_header
);
476 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
481 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
482 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
484 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
485 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
488 pkt
.off
+= sizeof (struct udpiphdr
);
489 if (ui
->ui_pr
!= IPPROTO_UDP
) {
493 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
497 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
498 if (CORE_REMOTE_PORT
== (ntohs(ui
->ui_dport
)) &&
499 flag_panic_dump_in_progress
) {
500 last_panic_port
= ui
->ui_sport
;
505 /* If we receive a kernel debugging packet whilst a
506 * core dump is in progress, abort the transfer and
507 * enter the debugger.
510 if (flag_panic_dump_in_progress
)
512 abort_panic_transfer();
516 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
517 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
518 adr
.loc
.in
= ui
->ui_dst
;
520 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
521 adr
.rmt
.in
= ui
->ui_src
;
525 * Calculate kdp packet length.
527 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
536 unsigned short reply_port
;
537 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
540 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
547 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
549 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
552 // ignore replies -- we're not expecting them anyway.
557 if (hdr
->request
== KDP_REATTACH
)
558 exception_seq
= hdr
->seq
;
560 // check for retransmitted request
561 if (hdr
->seq
== (exception_seq
- 1)) {
562 /* retransmit last reply */
563 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
566 } else if (hdr
->seq
!= exception_seq
) {
567 printf("kdp: bad sequence %d (want %d)\n",
568 hdr
->seq
, exception_seq
);
572 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
574 (unsigned short *)&reply_port
)) {
575 kdp_reply(reply_port
);
580 } while (kdp
.is_halted
);
584 kdp_connection_wait(void)
586 unsigned short reply_port
;
587 boolean_t
kdp_call_kdb();
588 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
589 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
591 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
592 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
593 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
594 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
595 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
596 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
597 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
599 printf( "ip address: %d.%d.%d.%d\n",
600 (ip_addr
& 0xff000000) >> 24,
601 (ip_addr
& 0xff0000) >> 16,
602 (ip_addr
& 0xff00) >> 8,
605 printf("\nWaiting for remote debugger connection.\n");
607 if (reattach_wait
== 0) {
608 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
610 printf("Options..... Type\n");
611 printf("------------ ----\n");
612 printf("continue.... 'c'\n");
613 printf("reboot...... 'r'\n");
615 printf("enter kdb... 'k'\n");
624 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
627 if (kdp_flag
& KDP_GETC_ENA
) {
630 printf("Continuing...\n");
633 printf("Rebooting...\n");
638 printf("calling kdb...\n");
642 printf("not implemented...\n");
652 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
654 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
656 if (hdr
->request
== KDP_HOSTREBOOT
) {
658 /* should not return! */
660 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
661 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
662 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
664 (unsigned short *)&reply_port
))
665 kdp_reply(reply_port
);
666 if (hdr
->request
== KDP_REATTACH
) {
668 hdr
->request
=KDP_DISCONNECT
;
674 } while (!kdp
.is_conn
);
676 if (current_debugger
== KDP_CUR_DB
)
678 printf("Connected to remote debugger.\n");
683 unsigned int exception
,
688 unsigned short remote_port
;
689 unsigned int timeout_count
= 100;
690 unsigned int poll_timeout
;
693 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
694 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
696 (unsigned short *)&remote_port
,
697 (unsigned int)exception
,
699 (unsigned int)subcode
);
701 kdp_send(remote_port
);
704 while(!pkt
.input
&& poll_timeout
)
711 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
718 if (kdp
.exception_ack_needed
)
721 } while (kdp
.exception_ack_needed
&& timeout_count
--);
723 if (kdp
.exception_ack_needed
) {
724 // give up & disconnect
725 printf("kdp: exception ack timeout\n");
726 if (current_debugger
== KDP_CUR_DB
)
734 unsigned int exception
,
736 unsigned int subcode
,
742 extern unsigned int disableDebugOuput
;
743 extern unsigned int disableConsoleOutput
;
745 disable_preemption();
747 if (saved_state
== 0)
748 printf("kdp_raise_exception with NULL state\n");
751 if (exception
!= EXC_BREAKPOINT
) {
752 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
755 printf("%s exception (%x,%x,%x)\n",
756 exception_message
[index
],
757 exception
, code
, subcode
);
762 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
763 * do this. I think the client and the host can get out of sync.
765 kdp
.saved_state
= saved_state
;
768 kdp_panic("kdp_raise_exception");
770 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
) || (kdp_flag
& PANIC_LOG_DUMP
))
771 && (panicstr
!= (char *) 0)) {
777 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && (panicstr
== (char *) 0) &&
780 disableDebugOuput
= disableConsoleOutput
= FALSE
;
783 if (!(kdp_flag
& DBG_POST_CORE
))
784 goto exit_raise_exception
;
789 kdp_connection_wait();
791 kdp_send_exception(exception
, code
, subcode
);
792 if (kdp
.exception_ack_needed
) {
793 kdp
.exception_ack_needed
= FALSE
;
794 kdp_remove_all_breakpoints();
795 printf("Remote debugger disconnected.\n");
800 kdp
.is_halted
= TRUE
; /* XXX */
801 kdp_handler(saved_state
);
804 kdp_remove_all_breakpoints();
805 printf("Remote debugger disconnected.\n");
808 /* Allow triggering a panic core dump when connected to the machine
809 * Continuing after setting kdp_trigger_core_dump should do the
812 if (1 == kdp_trigger_core_dump
) {
813 kdp_flag
&= ~PANIC_LOG_DUMP
;
814 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
820 if (reattach_wait
== 1)
822 exit_raise_exception
:
829 kdp
.reply_port
= kdp
.exception_port
= 0;
830 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
831 kdp
.exception_seq
= kdp
.conn_seq
= 0;
835 create_panic_header(unsigned int request
, const char *corename
,
836 unsigned length
, unsigned int block
)
838 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
839 struct ip aligned_ip
, *ip
= &aligned_ip
;
840 struct ether_header
*eh
;
841 struct corehdr
*coreh
;
842 const char *mode
= "octet";
843 char modelen
= strlen(mode
);
845 pkt
.off
= sizeof (struct ether_header
);
846 pkt
.len
= length
+ ((request
== KDP_WRQ
) ? modelen
: 0) +
847 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
);
850 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
852 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
854 ui
->ui_next
= ui
->ui_prev
= 0;
856 ui
->ui_pr
= IPPROTO_UDP
;
857 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
858 ui
->ui_src
.s_addr
= htonl(kdp_current_ip_address
);
859 ui
->ui_dst
.s_addr
= panic_server_ip
;
860 ui
->ui_sport
= htons(CORE_REMOTE_PORT
);
861 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(CORE_REMOTE_PORT
) : last_panic_port
);
862 ui
->ui_ulen
= ui
->ui_len
;
865 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
866 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
868 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
870 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
871 ip
->ip_v
= IPVERSION
;
872 ip
->ip_id
= htons(ip_id
++);
873 ip
->ip_hl
= sizeof (struct ip
) >> 2;
874 ip
->ip_ttl
= udp_ttl
;
876 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
878 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
881 pkt
.len
+= sizeof (struct udpiphdr
);
883 pkt
.off
+= sizeof (struct udpiphdr
);
885 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
886 coreh
->th_opcode
= htons((u_short
)request
);
888 if (request
== KDP_WRQ
)
892 cp
= coreh
->th_u
.tu_rpl
;
893 strcpy (cp
, corename
);
894 cp
+= strlen(corename
);
902 coreh
->th_block
= htonl((unsigned int) block
);
905 pkt
.off
-= sizeof (struct udpiphdr
);
906 pkt
.off
-= sizeof (struct ether_header
);
908 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
909 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
910 enaddr_copy(&router_mac
, eh
->ether_dhost
);
911 eh
->ether_type
= htons(ETHERTYPE_IP
);
913 pkt
.len
+= sizeof (struct ether_header
);
917 int kdp_send_panic_packets (unsigned int request
, char *corename
,
918 unsigned int length
, unsigned int txstart
)
920 unsigned int txend
= txstart
+ length
;
923 if (length
<= SEGSIZE
) {
924 if ((panic_error
= kdp_send_panic_pkt (request
, corename
, length
, (caddr_t
) txstart
)) < 0) {
925 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
931 while (txstart
<= (txend
- SEGSIZE
)) {
932 if ((panic_error
= kdp_send_panic_pkt (KDP_DATA
, NULL
, SEGSIZE
, (caddr_t
) txstart
)) < 0) {
933 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
937 if (!(panic_block
% 2000))
940 if (txstart
< txend
) {
941 kdp_send_panic_pkt(request
, corename
, (txend
- txstart
), (caddr_t
) txstart
);
947 kdp_send_panic_pkt (unsigned int request
, char *corename
,
948 unsigned int length
, void *panic_data
)
950 struct corehdr
*th
= NULL
;
951 int poll_count
= 2500;
953 char rretries
= 0, tretries
= 0;
955 extern signed long gIODebuggerSemaphore;
957 pkt
.off
= pkt
.len
= 0;
959 if (request
== KDP_WRQ
) /* longer timeout for initial request */
966 printf("TX retry #%d ", tretries
);
969 /* This iokit layer issue can potentially
970 *cause a hang, uncomment to check if it's happening.
973 if (gIODebuggerSemaphore)
974 printf("The gIODebuggerSemaphore is raised, preventing packet transmission (2760413)\n");
977 printf ("Cannot contact panic server, timing out.\n");
981 th
= create_panic_header(request
, corename
, length
, panic_block
);
983 if (request
== KDP_DATA
|| request
== KDP_SEEK
) {
984 if (!kdp_vm_read ((caddr_t
) panic_data
, (caddr_t
) th
->th_data
, length
)) {
985 memset ((caddr_t
) th
->th_data
, 'X', length
);
989 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
991 /* Now we have to listen for the ACK */
994 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1003 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1004 /* These will eventually have to be ntoh[ls]'ed as appropriate */
1006 if (th
->th_opcode
== KDP_ACK
&& th
->th_block
== panic_block
) {
1009 if (th
->th_opcode
== KDP_ERROR
) {
1010 printf("Panic server returned error %d, retrying\n", th
->th_code
);
1012 goto TRANSMIT_RETRY
;
1015 if (th
->th_block
== (panic_block
-1)) {
1016 printf("RX retry ");
1018 goto TRANSMIT_RETRY
;
1024 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1026 printf("Received a debugger packet,transferring control to debugger\n");
1027 /* Configure that if not set ..*/
1028 kdp_flag
|= DBG_POST_CORE
;
1031 else /* We timed out */
1032 if (0 == poll_count
) {
1034 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1035 goto TRANSMIT_RETRY
;
1040 if (request
== KDP_EOF
)
1041 printf ("\nTotal number of packets transmitted: %d\n", panic_block
);
1046 /* Since we don't seem to have an isdigit() .. */
1050 return ((c
> 47) && (c
< 58));
1052 /* From user mode Libc - this ought to be in a library */
1054 strnstr(s
, find
, slen
)
1062 if ((c
= *find
++) != '\0') {
1066 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1071 } while (strncmp(s
, find
, len
) != 0);
1077 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1078 * would be to have the integrator run a script which would copy the
1079 * xnu version into a string or an int somewhere at project submission
1080 * time - makes assumptions about sizeof(version), but will not fail if
1081 * it changes, but may be incorrect.
1085 kdp_get_xnu_version(char *versionbuf
)
1087 extern const char version
[];
1092 strcpy(vstr
, "custom");
1094 if (kdp_vm_read(version
, versionbuf
, 90)) {
1096 versionbuf
[89] = '\0';
1098 versionpos
= strnstr(versionbuf
, "xnu-", 80);
1101 strncpy (vstr
, versionpos
, (isdigit (versionpos
[7]) ? 8 : 7));
1102 vstr
[(isdigit (versionpos
[7]) ? 8 : 7)] = '\0';
1107 strcpy(versionbuf
, vstr
);
1110 /* Primary dispatch routine for the system dump */
1115 char coreprefix
[10];
1117 extern char *debug_buf
;
1118 extern vm_map_t kernel_map
;
1120 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1122 extern char *debug_buf
;
1123 extern char *debug_buf_ptr
;
1126 printf ("Entering system dump routine\n");
1128 if (!panicd_specified
) {
1129 printf ("A panic server was not specified in the boot-args, terminating kernel core dump.\n");
1130 goto panic_dump_exit
;
1133 flag_panic_dump_in_progress
= 1;
1137 kdp_panic("kdp_panic_dump");
1139 kdp_get_xnu_version((char *) &pkt
.data
[0]);
1141 /* Panic log bit takes precedence over core dump bit */
1142 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
))
1143 strncpy(coreprefix
, "paniclog", sizeof(coreprefix
));
1145 strncpy(coreprefix
, "core", sizeof(coreprefix
));
1147 abstime
= mach_absolute_time();
1148 pkt
.data
[10] = '\0';
1149 snprintf (corename
, sizeof(corename
), "%s-%s-%d.%d.%d.%d-%x",
1150 coreprefix
, &pkt
.data
[0],
1151 (kdp_current_ip_address
& 0xff000000) >> 24,
1152 (kdp_current_ip_address
& 0xff0000) >> 16,
1153 (kdp_current_ip_address
& 0xff00) >> 8,
1154 (kdp_current_ip_address
& 0xff),
1155 (unsigned int) (abstime
& 0xffffffff));
1157 if (0 == inet_aton(panicd_ip_str
, (struct in_addr
*) &panic_server_ip
)) {
1158 printf("inet_aton() failed interpreting %s as a panic server IP\n",
1162 printf("Attempting connection to panic server configured at IP %s\n",
1165 if (router_specified
) {
1166 if (0 == inet_aton(router_ip_str
, (struct in_addr
*) &parsed_router_ip
)){
1167 printf("inet_aton() failed interpreting %s as an IP\n", router_ip
);
1170 router_ip
= parsed_router_ip
;
1171 printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
1172 /* We will eventually need to resolve the router's MAC ourselves,
1173 * if one is specified,rather than being set through the BSD callback
1174 * but the _router_ip option does not function currently
1178 /* These & 0xffs aren't necessary,but cut&paste is ever so convenient */
1179 printf("Routing via router MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1180 router_mac
.ether_addr_octet
[0] & 0xff,
1181 router_mac
.ether_addr_octet
[1] & 0xff,
1182 router_mac
.ether_addr_octet
[2] & 0xff,
1183 router_mac
.ether_addr_octet
[3] & 0xff,
1184 router_mac
.ether_addr_octet
[4] & 0xff,
1185 router_mac
.ether_addr_octet
[5] & 0xff);
1187 printf("Kernel map size is %d\n", get_vmmap_size(kernel_map
));
1188 printf ("Sending write request for %s\n", corename
);
1190 if ((panic_error
= kdp_send_panic_pkt (KDP_WRQ
, corename
, 0 , NULL
) < 0)) {
1191 printf ("kdp_send_panic_pkt failed with error %d\n", panic_error
);
1192 goto panic_dump_exit
;
1195 /* Just the panic log requested */
1196 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
1197 printf("Transmitting panic log, please wait: ");
1198 kdp_send_panic_packets (KDP_DATA
, corename
, (debug_buf_ptr
- debug_buf
), (unsigned int) debug_buf
);
1199 kdp_send_panic_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1200 printf("Please file a bug report on this panic, if possible.\n");
1201 goto panic_dump_exit
;
1204 /* We want a core dump if we're here */
1208 flag_panic_dump_in_progress
= 0;
1217 abort_panic_transfer()
1219 flag_panic_dump_in_progress
= 0;