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/exception_types.h>
37 #include <mach/mach_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 #define DO_ALIGN 1 /* align all packet data accesses */
47 extern int kdp_getc(void);
48 extern int reattach_wait
;
50 static u_short ip_id
; /* ip packet ctr, for ids */
52 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
55 * UDP protocol implementation.
56 * Per RFC 768, August, 1980.
58 #define UDP_TTL 60 /* deflt time to live for UDP packets */
60 static unsigned char exception_seq
;
63 unsigned char data
[KDP_MAXPACKET
];
64 unsigned int off
, len
;
80 *exception_message
[] = {
82 "Memory access", /* EXC_BAD_ACCESS */
83 "Failed instruction", /* EXC_BAD_INSTRUCTION */
84 "Arithmetic", /* EXC_ARITHMETIC */
85 "Emulation", /* EXC_EMULATION */
86 "Software", /* EXC_SOFTWARE */
87 "Breakpoint" /* EXC_BREAKPOINT */
92 static kdp_send_t kdp_en_send_pkt
= 0;
93 static kdp_receive_t kdp_en_recv_pkt
= 0;
96 static unsigned int kdp_current_ip_address
= 0;
97 static struct ether_addr kdp_current_mac_address
= {{0, 0, 0, 0, 0, 0}};
98 static char kdp_arp_init
= 0;
100 static void kdp_handler( void *);
103 kdp_register_send_receive(
105 kdp_receive_t receive
)
109 kdp_en_send_pkt
= send
;
110 kdp_en_recv_pkt
= receive
;
112 PE_parse_boot_arg("debug", &debug
);
113 if (debug
& DB_KDP_BP_DIS
)
114 kdp_flag
|= KDP_BP_DIS
;
116 kdp_flag
|= KDP_READY
;
117 if (current_debugger
== NO_CUR_DB
)
118 current_debugger
= KDP_CUR_DB
;
119 if (halt_in_debugger
) {
126 kdp_unregister_send_receive(
128 kdp_receive_t receive
)
130 if (current_debugger
== KDP_CUR_DB
)
131 current_debugger
= NO_CUR_DB
;
132 kdp_flag
&= ~KDP_READY
;
133 kdp_en_send_pkt
= NULL
;
134 kdp_en_recv_pkt
= NULL
;
143 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
146 static unsigned short
152 unsigned int high
, low
, sum
;
162 sum
= (high
<< 8) + low
;
163 sum
= (sum
>> 16) + (sum
& 65535);
165 return (sum
> 65535 ? sum
- 65535 : sum
);
170 unsigned short reply_port
173 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
174 struct ip aligned_ip
, *ip
= &aligned_ip
;
175 struct in_addr tmp_ipaddr
;
176 struct ether_addr tmp_enaddr
;
177 struct ether_header
*eh
;
180 kdp_panic("kdp_reply");
182 pkt
.off
-= sizeof (struct udpiphdr
);
185 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
187 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
189 ui
->ui_next
= ui
->ui_prev
= 0;
191 ui
->ui_pr
= IPPROTO_UDP
;
192 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
193 tmp_ipaddr
= ui
->ui_src
;
194 ui
->ui_src
= ui
->ui_dst
;
195 ui
->ui_dst
= tmp_ipaddr
;
196 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
197 ui
->ui_dport
= reply_port
;
198 ui
->ui_ulen
= ui
->ui_len
;
201 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
203 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
205 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
207 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
208 ip
->ip_v
= IPVERSION
;
209 ip
->ip_id
= htons(ip_id
++);
210 ip
->ip_hl
= sizeof (struct ip
) >> 2;
211 ip
->ip_ttl
= udp_ttl
;
213 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
215 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
218 pkt
.len
+= sizeof (struct udpiphdr
);
220 pkt
.off
-= sizeof (struct ether_header
);
222 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
223 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
224 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
225 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
226 eh
->ether_type
= htons(ETHERTYPE_IP
);
228 pkt
.len
+= sizeof (struct ether_header
);
230 // save reply for possible retransmission
231 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
233 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
235 // increment expected sequence number
241 unsigned short remote_port
244 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
245 struct ip aligned_ip
, *ip
= &aligned_ip
;
246 struct ether_header
*eh
;
249 kdp_panic("kdp_send");
251 pkt
.off
-= sizeof (struct udpiphdr
);
254 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
256 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
258 ui
->ui_next
= ui
->ui_prev
= 0;
260 ui
->ui_pr
= IPPROTO_UDP
;
261 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
262 ui
->ui_src
= adr
.loc
.in
;
263 ui
->ui_dst
= adr
.rmt
.in
;
264 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
265 ui
->ui_dport
= remote_port
;
266 ui
->ui_ulen
= ui
->ui_len
;
269 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
270 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
272 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
274 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
275 ip
->ip_v
= IPVERSION
;
276 ip
->ip_id
= htons(ip_id
++);
277 ip
->ip_hl
= sizeof (struct ip
) >> 2;
278 ip
->ip_ttl
= udp_ttl
;
280 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
282 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
285 pkt
.len
+= sizeof (struct udpiphdr
);
287 pkt
.off
-= sizeof (struct ether_header
);
289 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
290 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
291 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
292 eh
->ether_type
= htons(ETHERTYPE_IP
);
294 pkt
.len
+= sizeof (struct ether_header
);
295 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
300 kdp_set_ip_and_mac_addresses(
301 struct in_addr
*ipaddr
,
302 struct ether_addr
*macaddr
)
304 unsigned int debug
= 0;
306 kdp_current_ip_address
= ipaddr
->s_addr
;
307 kdp_current_mac_address
= *macaddr
;
309 /* Get the debug boot-arg to decide if ARP replies are allowed */
310 if (kdp_arp_init
== 0) {
311 PE_parse_boot_arg("debug", &debug
);
319 kdp_get_mac_addr(void)
321 return kdp_current_mac_address
;
325 kdp_get_ip_address(void)
327 return kdp_current_ip_address
;
330 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
331 is set. A workaround if you don't want to reboot is to set
332 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
339 struct ether_header
*eh
;
340 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
342 struct in_addr isaddr
, itaddr
, myaddr
;
343 struct ether_addr my_enaddr
;
345 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
346 pkt
.off
+= sizeof(struct ether_header
);
348 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
350 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
353 myaddr
.s_addr
= kdp_get_ip_address();
354 my_enaddr
= kdp_get_mac_addr();
356 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
359 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
360 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
362 if (itaddr
.s_addr
== myaddr
.s_addr
) {
363 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
364 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
366 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
367 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
369 ea
->arp_op
= htons(ARPOP_REPLY
);
370 ea
->arp_pro
= htons(ETHERTYPE_IP
);
371 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
372 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
373 eh
->ether_type
= htons(ETHERTYPE_ARP
);
374 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
375 pkt
.off
-= sizeof (struct ether_header
);
376 /* pkt.len is still the length we want, ether_header+ether_arp */
377 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
384 struct ether_header
*eh
;
385 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
386 struct ip aligned_ip
, *ip
= &aligned_ip
;
387 static int msg_printed
;
391 kdp_panic("kdp_poll");
393 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
394 if( msg_printed
== 0) {
396 printf("kdp_poll: no debugger device\n");
401 pkt
.off
= pkt
.len
= 0;
402 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
407 if (pkt
.len
>= sizeof(struct ether_header
))
409 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
411 if (kdp_flag
& KDP_ARP
)
413 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
421 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
424 pkt
.off
+= sizeof (struct ether_header
);
425 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
430 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
431 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
433 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
434 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
437 pkt
.off
+= sizeof (struct udpiphdr
);
438 if (ui
->ui_pr
!= IPPROTO_UDP
) {
442 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
446 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
451 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
452 adr
.loc
.in
= ui
->ui_dst
;
454 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
455 adr
.rmt
.in
= ui
->ui_src
;
459 * Calculate kdp packet length.
461 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
471 unsigned short reply_port
;
472 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
475 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
482 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
484 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
487 // ignore replies -- we're not expecting them anyway.
492 if (hdr
->request
== KDP_REATTACH
)
493 exception_seq
= hdr
->seq
;
495 // check for retransmitted request
496 if (hdr
->seq
== (exception_seq
- 1)) {
497 /* retransmit last reply */
498 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
501 } else if (hdr
->seq
!= exception_seq
) {
502 printf("kdp: bad sequence %d (want %d)\n",
503 hdr
->seq
, exception_seq
);
507 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
509 (unsigned short *)&reply_port
)) {
510 kdp_reply(reply_port
);
515 } while (kdp
.is_halted
);
519 kdp_connection_wait(void)
521 unsigned short reply_port
;
522 boolean_t
kdp_call_kdb();
523 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
524 unsigned int ip_addr
= kdp_get_ip_address();
526 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
527 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
528 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
529 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
530 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
531 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
532 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
534 printf( "ip address: %d.%d.%d.%d\n",
535 (ip_addr
& 0xff000000) >> 24,
536 (ip_addr
& 0xff0000) >> 16,
537 (ip_addr
& 0xff00) >> 8,
540 printf("\nWaiting for remote debugger connection.\n");
542 if (reattach_wait
== 0)
548 printf("Options..... Type\n");
549 printf("------------ ----\n");
550 printf("continue.... 'c'\n");
551 printf("reboot...... 'r'\n");
553 printf("enter kdb... 'k'\n");
562 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
569 printf("Continuing...\n");
572 printf("Rebooting...\n");
577 printf("calling kdb...\n");
581 printf("not implemented...\n");
589 // check for sequence number of 0
591 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
593 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
595 if (hdr
->request
== KDP_HOSTREBOOT
) {
597 /* should not return! */
599 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
600 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
601 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
603 (unsigned short *)&reply_port
))
604 kdp_reply(reply_port
);
605 if (hdr
->request
== KDP_REATTACH
)
608 hdr
->request
=KDP_DISCONNECT
;
614 } while (!kdp
.is_conn
);
616 if (current_debugger
== KDP_CUR_DB
)
618 printf("Connected to remote debugger.\n");
623 unsigned int exception
,
628 unsigned short remote_port
;
629 unsigned int timeout_count
= 100;
630 unsigned int poll_timeout
;
633 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
634 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
636 (unsigned short *)&remote_port
,
637 (unsigned int)exception
,
639 (unsigned int)subcode
);
641 kdp_send(remote_port
);
644 while(!pkt
.input
&& poll_timeout
)
651 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
658 if (kdp
.exception_ack_needed
)
661 } while (kdp
.exception_ack_needed
&& timeout_count
--);
663 if (kdp
.exception_ack_needed
) {
664 // give up & disconnect
665 printf("kdp: exception ack timeout\n");
666 if (current_debugger
== KDP_CUR_DB
)
674 unsigned int exception
,
676 unsigned int subcode
,
682 disable_preemption();
684 if (saved_state
== 0)
685 printf("kdp_raise_exception with NULL state\n");
688 if (exception
!= EXC_BREAKPOINT
) {
689 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
692 printf("%s exception (%x,%x,%x)\n",
693 exception_message
[index
],
694 exception
, code
, subcode
);
699 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
700 * do this. I think the client and the host can get out of sync.
702 kdp
.saved_state
= saved_state
;
705 kdp_panic("kdp_raise_exception");
708 kdp_connection_wait();
711 kdp_send_exception(exception
, code
, subcode
);
712 if (kdp
.exception_ack_needed
)
714 kdp
.exception_ack_needed
= FALSE
;
715 kdp_remove_all_breakpoints();
716 printf("Remote debugger disconnected.\n");
721 kdp
.is_halted
= TRUE
; /* XXX */
722 kdp_handler(saved_state
);
725 kdp_remove_all_breakpoints();
726 printf("Remote debugger disconnected.\n");
732 if (reattach_wait
== 1)
741 kdp
.reply_port
= kdp
.exception_port
= 0;
742 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
743 kdp
.exception_seq
= kdp
.conn_seq
= 0;