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/exception_types.h>
34 #include <mach/mach_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 #define DO_ALIGN 1 /* align all packet data accesses */
44 extern int kdp_getc(void);
45 extern int reattach_wait
;
47 static u_short ip_id
; /* ip packet ctr, for ids */
49 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
52 * UDP protocol implementation.
53 * Per RFC 768, August, 1980.
55 #define UDP_TTL 60 /* deflt time to live for UDP packets */
57 static unsigned char exception_seq
;
60 unsigned char data
[KDP_MAXPACKET
];
61 unsigned int off
, len
;
77 *exception_message
[] = {
79 "Memory access", /* EXC_BAD_ACCESS */
80 "Failed instruction", /* EXC_BAD_INSTRUCTION */
81 "Arithmetic", /* EXC_ARITHMETIC */
82 "Emulation", /* EXC_EMULATION */
83 "Software", /* EXC_SOFTWARE */
84 "Breakpoint" /* EXC_BREAKPOINT */
89 static kdp_send_t kdp_en_send_pkt
= 0;
90 static kdp_receive_t kdp_en_recv_pkt
= 0;
93 static unsigned int kdp_current_ip_address
= 0;
94 static struct ether_addr kdp_current_mac_address
= {{0, 0, 0, 0, 0, 0}};
95 static char kdp_arp_init
= 0;
97 static void kdp_handler( void *);
100 kdp_register_send_receive(
102 kdp_receive_t receive
)
106 kdp_en_send_pkt
= send
;
107 kdp_en_recv_pkt
= receive
;
109 PE_parse_boot_arg("debug", &debug
);
110 if (debug
& DB_KDP_BP_DIS
)
111 kdp_flag
|= KDP_BP_DIS
;
113 kdp_flag
|= KDP_READY
;
114 if (current_debugger
== NO_CUR_DB
)
115 current_debugger
= KDP_CUR_DB
;
116 if (halt_in_debugger
) {
123 kdp_unregister_send_receive(
125 kdp_receive_t receive
)
127 if (current_debugger
== KDP_CUR_DB
)
128 current_debugger
= NO_CUR_DB
;
129 kdp_flag
&= ~KDP_READY
;
130 kdp_en_send_pkt
= NULL
;
131 kdp_en_recv_pkt
= NULL
;
140 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
143 static unsigned short
149 unsigned int high
, low
, sum
;
159 sum
= (high
<< 8) + low
;
160 sum
= (sum
>> 16) + (sum
& 65535);
162 return (sum
> 65535 ? sum
- 65535 : sum
);
167 unsigned short reply_port
170 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
171 struct ip aligned_ip
, *ip
= &aligned_ip
;
172 struct in_addr tmp_ipaddr
;
173 struct ether_addr tmp_enaddr
;
174 struct ether_header
*eh
;
177 kdp_panic("kdp_reply");
179 pkt
.off
-= sizeof (struct udpiphdr
);
182 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
184 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
186 ui
->ui_next
= ui
->ui_prev
= 0;
188 ui
->ui_pr
= IPPROTO_UDP
;
189 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
190 tmp_ipaddr
= ui
->ui_src
;
191 ui
->ui_src
= ui
->ui_dst
;
192 ui
->ui_dst
= tmp_ipaddr
;
193 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
194 ui
->ui_dport
= reply_port
;
195 ui
->ui_ulen
= ui
->ui_len
;
198 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
200 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
202 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
204 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
205 ip
->ip_v
= IPVERSION
;
206 ip
->ip_id
= htons(ip_id
++);
207 ip
->ip_hl
= sizeof (struct ip
) >> 2;
208 ip
->ip_ttl
= udp_ttl
;
210 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
212 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
215 pkt
.len
+= sizeof (struct udpiphdr
);
217 pkt
.off
-= sizeof (struct ether_header
);
219 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
220 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
221 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
222 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
223 eh
->ether_type
= htons(ETHERTYPE_IP
);
225 pkt
.len
+= sizeof (struct ether_header
);
227 // save reply for possible retransmission
228 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
230 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
232 // increment expected sequence number
238 unsigned short remote_port
241 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
242 struct ip aligned_ip
, *ip
= &aligned_ip
;
243 struct ether_header
*eh
;
246 kdp_panic("kdp_send");
248 pkt
.off
-= sizeof (struct udpiphdr
);
251 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
253 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
255 ui
->ui_next
= ui
->ui_prev
= 0;
257 ui
->ui_pr
= IPPROTO_UDP
;
258 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
259 ui
->ui_src
= adr
.loc
.in
;
260 ui
->ui_dst
= adr
.rmt
.in
;
261 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
262 ui
->ui_dport
= remote_port
;
263 ui
->ui_ulen
= ui
->ui_len
;
266 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
267 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
269 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
271 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
272 ip
->ip_v
= IPVERSION
;
273 ip
->ip_id
= htons(ip_id
++);
274 ip
->ip_hl
= sizeof (struct ip
) >> 2;
275 ip
->ip_ttl
= udp_ttl
;
277 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
279 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
282 pkt
.len
+= sizeof (struct udpiphdr
);
284 pkt
.off
-= sizeof (struct ether_header
);
286 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
287 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
288 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
289 eh
->ether_type
= htons(ETHERTYPE_IP
);
291 pkt
.len
+= sizeof (struct ether_header
);
292 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
297 kdp_set_ip_and_mac_addresses(
298 struct in_addr
*ipaddr
,
299 struct ether_addr
*macaddr
)
301 unsigned int debug
= 0;
303 kdp_current_ip_address
= ipaddr
->s_addr
;
304 kdp_current_mac_address
= *macaddr
;
306 /* Get the debug boot-arg to decide if ARP replies are allowed */
307 if (kdp_arp_init
== 0) {
308 PE_parse_boot_arg("debug", &debug
);
316 kdp_get_mac_addr(void)
318 return kdp_current_mac_address
;
322 kdp_get_ip_address(void)
324 return kdp_current_ip_address
;
327 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
328 is set. A workaround if you don't want to reboot is to set
329 kdpDEBUGFlag &= DB_ARP when connected (but that certainly isn't a published
336 struct ether_header
*eh
;
337 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
339 struct in_addr isaddr
, itaddr
, myaddr
;
340 struct ether_addr my_enaddr
;
342 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
343 pkt
.off
+= sizeof(struct ether_header
);
345 memcpy((void *)ea
, (void *)&pkt
.data
[pkt
.off
],sizeof(*ea
));
347 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
350 myaddr
.s_addr
= kdp_get_ip_address();
351 my_enaddr
= kdp_get_mac_addr();
353 if (!(myaddr
.s_addr
) || !(my_enaddr
.ether_addr_octet
[1]))
356 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
357 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
359 if (itaddr
.s_addr
== myaddr
.s_addr
) {
360 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
361 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
363 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
364 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
366 ea
->arp_op
= htons(ARPOP_REPLY
);
367 ea
->arp_pro
= htons(ETHERTYPE_IP
);
368 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
369 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
370 eh
->ether_type
= htons(ETHERTYPE_ARP
);
371 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
372 pkt
.off
-= sizeof (struct ether_header
);
373 /* pkt.len is still the length we want, ether_header+ether_arp */
374 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
381 struct ether_header
*eh
;
382 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
383 struct ip aligned_ip
, *ip
= &aligned_ip
;
384 static int msg_printed
;
388 kdp_panic("kdp_poll");
390 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
391 if( msg_printed
== 0) {
393 printf("kdp_poll: no debugger device\n");
398 pkt
.off
= pkt
.len
= 0;
399 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
404 if (pkt
.len
>= sizeof(struct ether_header
))
406 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
408 if (kdp_flag
& KDP_ARP
)
410 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
418 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
421 pkt
.off
+= sizeof (struct ether_header
);
422 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
427 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
428 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
430 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
431 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
434 pkt
.off
+= sizeof (struct udpiphdr
);
435 if (ui
->ui_pr
!= IPPROTO_UDP
) {
439 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
443 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
448 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
449 adr
.loc
.in
= ui
->ui_dst
;
451 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
452 adr
.rmt
.in
= ui
->ui_src
;
456 * Calculate kdp packet length.
458 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
468 unsigned short reply_port
;
469 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
472 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
479 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
481 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
484 // ignore replies -- we're not expecting them anyway.
489 if (hdr
->request
== KDP_REATTACH
)
490 exception_seq
= hdr
->seq
;
492 // check for retransmitted request
493 if (hdr
->seq
== (exception_seq
- 1)) {
494 /* retransmit last reply */
495 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
498 } else if (hdr
->seq
!= exception_seq
) {
499 printf("kdp: bad sequence %d (want %d)\n",
500 hdr
->seq
, exception_seq
);
504 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
506 (unsigned short *)&reply_port
)) {
507 kdp_reply(reply_port
);
512 } while (kdp
.is_halted
);
516 kdp_connection_wait(void)
518 unsigned short reply_port
;
519 boolean_t
kdp_call_kdb();
520 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
521 unsigned int ip_addr
= kdp_get_ip_address();
523 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
524 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
525 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
526 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
527 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
528 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
529 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
531 printf( "ip address: %d.%d.%d.%d\n",
532 (ip_addr
& 0xff000000) >> 24,
533 (ip_addr
& 0xff0000) >> 16,
534 (ip_addr
& 0xff00) >> 8,
537 printf("\nWaiting for remote debugger connection.\n");
539 if (reattach_wait
== 0)
545 printf("Options..... Type\n");
546 printf("------------ ----\n");
547 printf("continue.... 'c'\n");
548 printf("reboot...... 'r'\n");
550 printf("enter kdb... 'k'\n");
559 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
566 printf("Continuing...\n");
569 printf("Rebooting...\n");
574 printf("calling kdb...\n");
578 printf("not implemented...\n");
586 // check for sequence number of 0
588 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
590 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
592 if (hdr
->request
== KDP_HOSTREBOOT
) {
594 /* should not return! */
596 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
597 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
598 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
600 (unsigned short *)&reply_port
))
601 kdp_reply(reply_port
);
602 if (hdr
->request
== KDP_REATTACH
)
605 hdr
->request
=KDP_DISCONNECT
;
611 } while (!kdp
.is_conn
);
613 if (current_debugger
== KDP_CUR_DB
)
615 printf("Connected to remote debugger.\n");
620 unsigned int exception
,
625 unsigned short remote_port
;
626 unsigned int timeout_count
= 100;
627 unsigned int poll_timeout
;
630 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
631 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
633 (unsigned short *)&remote_port
,
634 (unsigned int)exception
,
636 (unsigned int)subcode
);
638 kdp_send(remote_port
);
641 while(!pkt
.input
&& poll_timeout
)
648 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
655 if (kdp
.exception_ack_needed
)
658 } while (kdp
.exception_ack_needed
&& timeout_count
--);
660 if (kdp
.exception_ack_needed
) {
661 // give up & disconnect
662 printf("kdp: exception ack timeout\n");
663 if (current_debugger
== KDP_CUR_DB
)
671 unsigned int exception
,
673 unsigned int subcode
,
679 disable_preemption();
681 if (saved_state
== 0)
682 printf("kdp_raise_exception with NULL state\n");
685 if (exception
!= EXC_BREAKPOINT
) {
686 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
689 printf("%s exception (%x,%x,%x)\n",
690 exception_message
[index
],
691 exception
, code
, subcode
);
696 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
697 * do this. I think the client and the host can get out of sync.
699 kdp
.saved_state
= saved_state
;
702 kdp_panic("kdp_raise_exception");
705 kdp_connection_wait();
708 kdp_send_exception(exception
, code
, subcode
);
709 if (kdp
.exception_ack_needed
)
711 kdp
.exception_ack_needed
= FALSE
;
712 kdp_remove_all_breakpoints();
713 printf("Remote debugger disconnected.\n");
718 kdp
.is_halted
= TRUE
; /* XXX */
719 kdp_handler(saved_state
);
722 kdp_remove_all_breakpoints();
723 printf("Remote debugger disconnected.\n");
729 if (reattach_wait
== 1)
738 kdp
.reply_port
= kdp
.exception_port
= 0;
739 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
740 kdp
.exception_seq
= kdp
.conn_seq
= 0;