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) 1993 NeXT Computer, Inc. All rights reserved.
25 * kdp_udp.c -- Kernel Debugging Protocol UDP implementation.
30 #include <mach/boolean.h>
31 #include <mach/exception_types.h>
32 #include <mach/mach_types.h>
33 #include <kern/debug.h>
35 #include <kdp/kdp_internal.h>
36 #include <kdp/kdp_en_debugger.h>
37 #include <kdp/kdp_udp.h>
39 #define DO_ALIGN 1 /* align all packet data accesses */
41 extern int kdp_getc(void);
44 u_short ip_id
; /* ip packet ctr, for ids */
46 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
49 * UDP protocol implementation.
50 * Per RFC 768, August, 1980.
52 #define UDP_TTL 60 /* deflt time to live for UDP packets */
54 static unsigned char exception_seq
;
57 unsigned char data
[KDP_MAXPACKET
];
58 unsigned int off
, len
;
74 *exception_message
[] = {
76 "Memory access", /* EXC_BAD_ACCESS */
77 "Failed instruction", /* EXC_BAD_INSTRUCTION */
78 "Arithmetic", /* EXC_ARITHMETIC */
79 "Emulation", /* EXC_EMULATION */
80 "Software", /* EXC_SOFTWARE */
81 "Breakpoint" /* EXC_BREAKPOINT */
84 static kdp_send_t kdp_en_send_pkt
= 0;
85 static kdp_receive_t kdp_en_recv_pkt
= 0;
87 static void kdp_handler( void *);
90 kdp_register_send_receive(kdp_send_t send
, kdp_receive_t receive
)
94 kdp_en_send_pkt
= send
;
95 kdp_en_recv_pkt
= receive
;
96 kdp_flag
|= KDP_READY
;
97 if (current_debugger
== NO_CUR_DB
)
98 current_debugger
= KDP_CUR_DB
;
99 if (halt_in_debugger
) {
112 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
122 unsigned int high
, low
, sum
;
132 sum
= (high
<< 8) + low
;
133 sum
= (sum
>> 16) + (sum
& 65535);
135 return (sum
> 65535 ? sum
- 65535 : sum
);
141 unsigned short reply_port
144 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
145 struct ip aligned_ip
, *ip
= &aligned_ip
;
146 struct in_addr tmp_ipaddr
;
147 struct ether_addr tmp_enaddr
;
148 struct ether_header
*eh
;
151 kdp_panic("kdp_reply");
153 pkt
.off
-= sizeof (struct udpiphdr
);
156 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
158 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
160 ui
->ui_next
= ui
->ui_prev
= 0;
162 ui
->ui_pr
= IPPROTO_UDP
;
163 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
164 tmp_ipaddr
= ui
->ui_src
;
165 ui
->ui_src
= ui
->ui_dst
;
166 ui
->ui_dst
= tmp_ipaddr
;
167 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
168 ui
->ui_dport
= reply_port
;
169 ui
->ui_ulen
= ui
->ui_len
;
172 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
174 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
176 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
178 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
179 ip
->ip_v
= IPVERSION
;
180 ip
->ip_id
= htons(ip_id
++);
181 ip
->ip_hl
= sizeof (struct ip
) >> 2;
182 ip
->ip_ttl
= udp_ttl
;
184 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
186 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
189 pkt
.len
+= sizeof (struct udpiphdr
);
191 pkt
.off
-= sizeof (struct ether_header
);
193 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
194 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
195 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
196 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
197 eh
->ether_type
= htons(ETHERTYPE_IP
);
199 pkt
.len
+= sizeof (struct ether_header
);
201 // save reply for possible retransmission
202 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
204 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
206 // increment expected sequence number
213 unsigned short remote_port
216 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
217 struct ip aligned_ip
, *ip
= &aligned_ip
;
218 struct ether_header
*eh
;
221 kdp_panic("kdp_send");
223 pkt
.off
-= sizeof (struct udpiphdr
);
226 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
228 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
230 ui
->ui_next
= ui
->ui_prev
= 0;
232 ui
->ui_pr
= IPPROTO_UDP
;
233 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
234 ui
->ui_src
= adr
.loc
.in
;
235 ui
->ui_dst
= adr
.rmt
.in
;
236 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
237 ui
->ui_dport
= remote_port
;
238 ui
->ui_ulen
= ui
->ui_len
;
241 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
242 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
244 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
246 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
247 ip
->ip_v
= IPVERSION
;
248 ip
->ip_id
= htons(ip_id
++);
249 ip
->ip_hl
= sizeof (struct ip
) >> 2;
250 ip
->ip_ttl
= udp_ttl
;
252 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
254 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
257 pkt
.len
+= sizeof (struct udpiphdr
);
259 pkt
.off
-= sizeof (struct ether_header
);
261 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
262 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
263 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
264 eh
->ether_type
= htons(ETHERTYPE_IP
);
266 pkt
.len
+= sizeof (struct ether_header
);
268 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
277 struct ether_header
*eh
;
278 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
279 struct ip aligned_ip
, *ip
= &aligned_ip
;
280 static int msg_printed
;
283 kdp_panic("kdp_poll");
285 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
286 if( msg_printed
== 0) {
288 printf("kdp_poll: no debugger device\n");
294 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
299 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
302 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
303 pkt
.off
+= sizeof (struct ether_header
);
304 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
309 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
310 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
312 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
313 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
316 pkt
.off
+= sizeof (struct udpiphdr
);
317 if (ui
->ui_pr
!= IPPROTO_UDP
) {
321 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
325 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
330 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
331 adr
.loc
.in
= ui
->ui_dst
;
333 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
334 adr
.rmt
.in
= ui
->ui_src
;
338 * Calculate kdp packet length.
340 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - sizeof (struct udphdr
);
351 unsigned short reply_port
;
352 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
355 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
362 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
364 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
367 // ignore replies -- we're not expecting them anyway.
372 // check for retransmitted request
373 if (hdr
->seq
== (exception_seq
- 1)) {
374 /* retransmit last reply */
375 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
378 } else if (hdr
->seq
!= exception_seq
) {
379 printf("kdp: bad sequence %d (want %d)\n",
380 hdr
->seq
, exception_seq
);
384 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
386 (unsigned short *)&reply_port
)) {
387 kdp_reply(reply_port
);
392 } while (kdp
.is_halted
);
401 unsigned short reply_port
;
402 boolean_t
kdp_call_kdb();
404 printf("\nWaiting for remote debugger connection.\n");
409 printf("Options..... Type\n");
410 printf("------------ ----\n");
411 printf("continue.... 'c'\n");
412 printf("reboot...... 'r'\n");
414 printf("enter kdb... 'k'\n");
420 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
427 printf("Continuing...\n");
430 printf("Rebooting...\n");
435 printf("calling kdb...\n");
439 printf("not implemented...\n");
447 // check for sequence number of 0
449 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
451 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
453 if (hdr
->request
== KDP_HOSTREBOOT
) {
455 /* should not return! */
457 if ((hdr
->request
== KDP_CONNECT
) &&
458 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
459 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
461 (unsigned short *)&reply_port
))
462 kdp_reply(reply_port
);
466 } while (!kdp
.is_conn
);
468 if (current_debugger
== KDP_CUR_DB
)
470 printf("Connected to remote debugger.\n");
476 unsigned int exception
,
481 unsigned short remote_port
;
482 unsigned int timeout_count
;
484 timeout_count
= 300; // should be about 30 seconds
486 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
487 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
489 (unsigned short *)&remote_port
,
490 (unsigned int)exception
,
492 (unsigned int)subcode
);
494 kdp_send(remote_port
);
500 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
509 if (kdp
.exception_ack_needed
)
510 kdp_us_spin(100000); // 1/10 sec
512 } while (kdp
.exception_ack_needed
&& timeout_count
--);
514 if (kdp
.exception_ack_needed
) {
515 // give up & disconnect
516 printf("kdp: exception ack timeout\n");
523 unsigned int exception
,
525 unsigned int subcode
,
532 if (saved_state
== 0)
533 printf("kdp_raise_exception with NULL state\n");
536 if (exception
!= EXC_BREAKPOINT
) {
537 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
540 printf("%s exception (%x,%x,%x)\n",
541 exception_message
[index
],
542 exception
, code
, subcode
);
547 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
548 * do this. I think the client and the host can get out of sync.
550 kdp
.saved_state
= saved_state
;
553 kdp_panic("kdp_raise_exception");
556 kdp_connection_wait();
558 kdp_send_exception(exception
, code
, subcode
);
561 kdp
.is_halted
= TRUE
; /* XXX */
562 kdp_handler(saved_state
);
564 printf("Remote debugger disconnected.\n");
573 kdp
.reply_port
= kdp
.exception_port
= 0;
574 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
575 kdp
.exception_seq
= kdp
.conn_seq
= 0;