]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kdp/kdp_udp.c
xnu-1228.15.4.tar.gz
[apple/xnu.git] / osfmk / kdp / kdp_udp.c
CommitLineData
1c79356b 1/*
593a1d5f 2 * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b 27 */
2d21ac55 28
1c79356b 29/*
9bccf70c
A
30 * Copyright (c) 1982, 1986, 1993
31 * The Regents of the University of California. All rights reserved.
32 */
33
34/*
35 * Kernel Debugging Protocol UDP implementation.
1c79356b
A
36 */
37
38#include <mach_kdb.h>
39#include <mach/boolean.h>
de355530 40#include <mach/mach_types.h>
55e303ae 41#include <mach/exception_types.h>
9bccf70c 42#include <kern/cpu_data.h>
1c79356b 43#include <kern/debug.h>
593a1d5f 44#include <kern/clock.h>
1c79356b 45
0c530ab8 46#include <kdp/kdp_core.h>
1c79356b
A
47#include <kdp/kdp_internal.h>
48#include <kdp/kdp_en_debugger.h>
593a1d5f 49#include <kdp/kdp_callout.h>
1c79356b 50#include <kdp/kdp_udp.h>
593a1d5f
A
51#if CONFIG_SERIAL_KDP
52#include <kdp/kdp_serial.h>
53#endif
1c79356b 54
55e303ae 55#include <vm/vm_map.h>
91447636 56#include <vm/vm_protos.h>
0c530ab8 57#include <vm/vm_kern.h> /* kernel_map */
91447636 58
55e303ae
A
59#include <mach/memory_object_types.h>
60
61#include <string.h>
62
1c79356b
A
63#define DO_ALIGN 1 /* align all packet data accesses */
64
65extern int kdp_getc(void);
9bccf70c 66extern int reattach_wait;
1c79356b 67
593a1d5f
A
68extern int serial_getc(void);
69extern void serial_putc(char);
70extern int serial_init(void);
71
9bccf70c 72static u_short ip_id; /* ip packet ctr, for ids */
1c79356b
A
73
74/* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
75
76/*
77 * UDP protocol implementation.
78 * Per RFC 768, August, 1980.
79 */
80#define UDP_TTL 60 /* deflt time to live for UDP packets */
55e303ae 81int udp_ttl = UDP_TTL;
1c79356b
A
82static unsigned char exception_seq;
83
84static struct {
85 unsigned char data[KDP_MAXPACKET];
86 unsigned int off, len;
87 boolean_t input;
88} pkt, saved_reply;
89
90struct {
91 struct {
92 struct in_addr in;
93 struct ether_addr ea;
94 } loc;
95 struct {
96 struct in_addr in;
97 struct ether_addr ea;
98 } rmt;
99} adr;
100
0c530ab8 101static const char
1c79356b
A
102*exception_message[] = {
103 "Unknown",
104 "Memory access", /* EXC_BAD_ACCESS */
105 "Failed instruction", /* EXC_BAD_INSTRUCTION */
106 "Arithmetic", /* EXC_ARITHMETIC */
107 "Emulation", /* EXC_EMULATION */
108 "Software", /* EXC_SOFTWARE */
109 "Breakpoint" /* EXC_BREAKPOINT */
110};
111
0c530ab8 112volatile int kdp_flag = 0;
9bccf70c 113
2d21ac55
A
114static kdp_send_t kdp_en_send_pkt;
115static kdp_receive_t kdp_en_recv_pkt;
1c79356b 116
9bccf70c 117
55e303ae 118static u_long kdp_current_ip_address = 0;
9bccf70c 119static struct ether_addr kdp_current_mac_address = {{0, 0, 0, 0, 0, 0}};
2d21ac55 120static void *kdp_current_ifp;
9bccf70c 121
55e303ae
A
122static void kdp_handler( void *);
123
0c530ab8
A
124static uint32_t panic_server_ip = 0;
125static uint32_t parsed_router_ip = 0;
126static uint32_t router_ip = 0;
127static uint32_t target_ip = 0;
128
129static volatile boolean_t panicd_specified = FALSE;
130static boolean_t router_specified = FALSE;
131static unsigned int panicd_port = CORE_REMOTE_PORT;
132
0c530ab8 133static struct ether_addr etherbroadcastaddr = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
55e303ae
A
134
135static struct ether_addr router_mac = {{0, 0, 0 , 0, 0, 0}};
0c530ab8
A
136static struct ether_addr destination_mac = {{0, 0, 0 , 0, 0, 0}};
137static struct ether_addr temp_mac = {{0, 0, 0 , 0, 0, 0}};
138static struct ether_addr current_resolved_MAC = {{0, 0, 0 , 0, 0, 0}};
4452a7af 139
0c530ab8
A
140static boolean_t flag_panic_dump_in_progress = FALSE;
141static boolean_t flag_router_mac_initialized = FALSE;
142
143static boolean_t flag_arp_resolved = FALSE;
55e303ae
A
144
145static unsigned int panic_timeout = 100000;
146static unsigned int last_panic_port = CORE_REMOTE_PORT;
147
148unsigned int SEGSIZE = 512;
149
0c530ab8 150__unused static unsigned int PANIC_PKTSIZE = 518;
55e303ae
A
151static char panicd_ip_str[20];
152static char router_ip_str[20];
153
154static unsigned int panic_block = 0;
2d21ac55
A
155volatile unsigned int kdp_trigger_core_dump = 0;
156__private_extern__ volatile unsigned int flag_kdp_trigger_reboot = 0;
55e303ae
A
157
158extern unsigned int not_in_kdp;
1c79356b 159
0c530ab8
A
160extern unsigned int disableConsoleOutput;
161
162extern int kdp_vm_read( caddr_t, caddr_t, unsigned int);
163extern void kdp_call(void);
164extern boolean_t kdp_call_kdb(void);
165extern int kern_dump(void);
166
167void * kdp_get_interface(void);
168void kdp_set_gateway_mac(void *);
169void kdp_set_ip_and_mac_addresses(struct in_addr *, struct ether_addr *);
170void kdp_set_interface(void *);
171
172void kdp_disable_arp(void);
173static void kdp_arp_reply(struct ether_arp *);
174static void kdp_process_arp_reply(struct ether_arp *);
175static boolean_t kdp_arp_resolve(uint32_t, struct ether_addr *);
176
2d21ac55
A
177static volatile unsigned kdp_reentry_deadline;
178
0c530ab8
A
179static boolean_t gKDPDebug = FALSE;
180#define KDP_DEBUG(...) if (gKDPDebug) printf(__VA_ARGS__);
181
182int kdp_snapshot = 0;
183static int stack_snapshot_ret = 0;
184static unsigned stack_snapshot_bytes_traced = 0;
185
186static void *stack_snapshot_buf;
187static uint32_t stack_snapshot_bufsize;
188static int stack_snapshot_pid;
189static uint32_t stack_snapshot_options;
190
2d21ac55
A
191static unsigned int old_debugger;
192
0c530ab8
A
193void
194kdp_snapshot_preflight(int pid, void * tracebuf, uint32_t tracebuf_size,
195 uint32_t options);
196
197void
198kdp_snapshot_postflight(void);
199
200extern int
2d21ac55 201kdp_stackshot(int pid, void *tracebuf, uint32_t tracebuf_size,
0c530ab8
A
202 unsigned trace_options, uint32_t *pbytesTraced);
203
204int
205kdp_stack_snapshot_geterror(void);
206
207int
208kdp_stack_snapshot_bytes_traced(void);
91447636 209
2d21ac55
A
210static thread_call_t
211kdp_timer_call;
212
213static void
214kdp_ml_enter_debugger_wrapper(__unused void *param0, __unused void *param1) {
215 kdp_ml_enter_debugger();
216}
217
218static void
219kdp_timer_callout_init(void) {
220 kdp_timer_call = thread_call_allocate(kdp_ml_enter_debugger_wrapper, NULL);
221}
222
223
1c79356b 224void
9bccf70c 225kdp_register_send_receive(
55e303ae 226 kdp_send_t send,
9bccf70c 227 kdp_receive_t receive)
1c79356b 228{
2d21ac55 229 unsigned int debug = 0;
1c79356b 230
9bccf70c 231 debug_log_init();
55e303ae 232
2d21ac55
A
233 kdp_timer_callout_init();
234
593a1d5f 235 PE_parse_boot_argn("debug", &debug, sizeof (debug));
55e303ae 236
2d21ac55
A
237
238 if (!debug)
239 return;
240
593a1d5f
A
241 kdp_en_send_pkt = send;
242 kdp_en_recv_pkt = receive;
243
9bccf70c
A
244 if (debug & DB_KDP_BP_DIS)
245 kdp_flag |= KDP_BP_DIS;
55e303ae
A
246 if (debug & DB_KDP_GETC_ENA)
247 kdp_flag |= KDP_GETC_ENA;
248 if (debug & DB_ARP)
2d21ac55 249 kdp_flag |= KDP_ARP;
55e303ae
A
250
251 if (debug & DB_KERN_DUMP_ON_PANIC)
2d21ac55 252 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
55e303ae 253 if (debug & DB_KERN_DUMP_ON_NMI)
2d21ac55
A
254 kdp_flag |= PANIC_CORE_ON_NMI;
255
55e303ae 256 if (debug & DB_DBG_POST_CORE)
2d21ac55
A
257 kdp_flag |= DBG_POST_CORE;
258
55e303ae 259 if (debug & DB_PANICLOG_DUMP)
2d21ac55
A
260 kdp_flag |= PANIC_LOG_DUMP;
261
593a1d5f 262 if (PE_parse_boot_argn("_panicd_ip", panicd_ip_str, sizeof (panicd_ip_str)))
2d21ac55 263 panicd_specified = TRUE;
0c530ab8 264
593a1d5f 265 if (PE_parse_boot_argn("_router_ip", router_ip_str, sizeof (router_ip_str)))
2d21ac55 266 router_specified = TRUE;
0c530ab8 267
593a1d5f 268 if (!PE_parse_boot_argn("panicd_port", &panicd_port, sizeof (panicd_port)))
0c530ab8 269 panicd_port = CORE_REMOTE_PORT;
9bccf70c 270
1c79356b
A
271 kdp_flag |= KDP_READY;
272 if (current_debugger == NO_CUR_DB)
273 current_debugger = KDP_CUR_DB;
2d21ac55 274 if ((kdp_current_ip_address != 0) && halt_in_debugger) {
1c79356b
A
275 kdp_call();
276 halt_in_debugger=0;
277 }
278}
279
1c79356b 280void
9bccf70c 281kdp_unregister_send_receive(
0c530ab8
A
282 __unused kdp_send_t send,
283 __unused kdp_receive_t receive)
9bccf70c
A
284{
285 if (current_debugger == KDP_CUR_DB)
286 current_debugger = NO_CUR_DB;
287 kdp_flag &= ~KDP_READY;
288 kdp_en_send_pkt = NULL;
289 kdp_en_recv_pkt = NULL;
290}
291
0c530ab8
A
292/* Cache stack snapshot parameters in preparation for a trace */
293void
294kdp_snapshot_preflight(int pid, void * tracebuf, uint32_t tracebuf_size, uint32_t options)
295{
296 stack_snapshot_pid = pid;
297 stack_snapshot_buf = tracebuf;
298 stack_snapshot_bufsize = tracebuf_size;
299 stack_snapshot_options = options;
300 kdp_snapshot++;
2d21ac55
A
301 /* Mark this debugger as active, since the polled mode driver that
302 * ordinarily does this may not be enabled (yet), or since KDB may be
303 * the primary debugger.
304 */
305 old_debugger = current_debugger;
306 if (old_debugger != KDP_CUR_DB) {
307 current_debugger = KDP_CUR_DB;
308 }
0c530ab8
A
309}
310
311void
312kdp_snapshot_postflight(void)
313{
314 kdp_snapshot--;
2d21ac55
A
315 if ((kdp_en_send_pkt == NULL) || (old_debugger == KDB_CUR_DB))
316 current_debugger = old_debugger;
0c530ab8
A
317}
318
319int
320kdp_stack_snapshot_geterror(void)
321{
322 return stack_snapshot_ret;
323}
324
325int
326kdp_stack_snapshot_bytes_traced(void)
327{
328 return stack_snapshot_bytes_traced;
329}
330
2d21ac55
A
331static void
332kdp_schedule_debugger_reentry(unsigned interval) {
333 uint64_t deadline;;
334
335 clock_interval_to_deadline(interval, 1000 * 1000, &deadline);
336 thread_call_enter_delayed(kdp_timer_call, deadline);
337}
338
9bccf70c 339static void
1c79356b 340enaddr_copy(
9bccf70c
A
341 void *src,
342 void *dst
1c79356b
A
343)
344{
9bccf70c 345 bcopy((char *)src, (char *)dst, sizeof (struct ether_addr));
1c79356b
A
346}
347
9bccf70c 348static unsigned short
1c79356b 349ip_sum(
9bccf70c
A
350 unsigned char *c,
351 unsigned int hlen
0c530ab8 352 )
1c79356b 353{
0c530ab8 354 unsigned int high, low, sum;
1c79356b 355
0c530ab8
A
356 high = low = 0;
357 while (hlen-- > 0) {
358 low += c[1] + c[3];
359 high += c[0] + c[2];
1c79356b 360
0c530ab8
A
361 c += sizeof (int);
362 }
1c79356b 363
0c530ab8
A
364 sum = (high << 8) + low;
365 sum = (sum >> 16) + (sum & 65535);
1c79356b 366
0c530ab8 367 return (sum > 65535 ? sum - 65535 : sum);
1c79356b
A
368}
369
9bccf70c 370static void
1c79356b 371kdp_reply(
9bccf70c 372 unsigned short reply_port
0c530ab8 373 )
1c79356b 374{
0c530ab8
A
375 struct udpiphdr aligned_ui, *ui = &aligned_ui;
376 struct ip aligned_ip, *ip = &aligned_ip;
377 struct in_addr tmp_ipaddr;
378 struct ether_addr tmp_enaddr;
379 struct ether_header *eh = NULL;
1c79356b 380
0c530ab8
A
381 if (!pkt.input)
382 kdp_panic("kdp_reply");
1c79356b 383
0c530ab8 384 pkt.off -= sizeof (struct udpiphdr);
1c79356b
A
385
386#if DO_ALIGN
0c530ab8 387 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
1c79356b 388#else
0c530ab8 389 ui = (struct udpiphdr *)&pkt.data[pkt.off];
1c79356b 390#endif
2d21ac55 391 ui->ui_next = ui->ui_prev = NULL;
0c530ab8
A
392 ui->ui_x1 = 0;
393 ui->ui_pr = IPPROTO_UDP;
394 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
395 tmp_ipaddr = ui->ui_src;
396 ui->ui_src = ui->ui_dst;
397 ui->ui_dst = tmp_ipaddr;
398 ui->ui_sport = htons(KDP_REMOTE_PORT);
399 ui->ui_dport = reply_port;
400 ui->ui_ulen = ui->ui_len;
401 ui->ui_sum = 0;
1c79356b 402#if DO_ALIGN
0c530ab8
A
403 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
404 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
1c79356b 405#else
0c530ab8 406 ip = (struct ip *)&pkt.data[pkt.off];
1c79356b 407#endif
0c530ab8
A
408 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
409 ip->ip_v = IPVERSION;
410 ip->ip_id = htons(ip_id++);
411 ip->ip_hl = sizeof (struct ip) >> 2;
412 ip->ip_ttl = udp_ttl;
413 ip->ip_sum = 0;
414 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
1c79356b 415#if DO_ALIGN
0c530ab8 416 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
1c79356b
A
417#endif
418
0c530ab8 419 pkt.len += sizeof (struct udpiphdr);
1c79356b 420
0c530ab8 421 pkt.off -= sizeof (struct ether_header);
1c79356b 422
0c530ab8
A
423 eh = (struct ether_header *)&pkt.data[pkt.off];
424 enaddr_copy(eh->ether_shost, &tmp_enaddr);
425 enaddr_copy(eh->ether_dhost, eh->ether_shost);
426 enaddr_copy(&tmp_enaddr, eh->ether_dhost);
427 eh->ether_type = htons(ETHERTYPE_IP);
1c79356b 428
0c530ab8 429 pkt.len += sizeof (struct ether_header);
1c79356b 430
0c530ab8
A
431 // save reply for possible retransmission
432 bcopy((char *)&pkt, (char *)&saved_reply, sizeof(pkt));
1c79356b 433
0c530ab8 434 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
1c79356b 435
0c530ab8
A
436 // increment expected sequence number
437 exception_seq++;
1c79356b
A
438}
439
9bccf70c 440static void
1c79356b
A
441kdp_send(
442 unsigned short remote_port
443)
444{
445 struct udpiphdr aligned_ui, *ui = &aligned_ui;
446 struct ip aligned_ip, *ip = &aligned_ip;
447 struct ether_header *eh;
448
449 if (pkt.input)
450 kdp_panic("kdp_send");
451
452 pkt.off -= sizeof (struct udpiphdr);
453
454#if DO_ALIGN
455 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
456#else
457 ui = (struct udpiphdr *)&pkt.data[pkt.off];
458#endif
2d21ac55 459 ui->ui_next = ui->ui_prev = NULL;
1c79356b
A
460 ui->ui_x1 = 0;
461 ui->ui_pr = IPPROTO_UDP;
462 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
463 ui->ui_src = adr.loc.in;
464 ui->ui_dst = adr.rmt.in;
465 ui->ui_sport = htons(KDP_REMOTE_PORT);
466 ui->ui_dport = remote_port;
467 ui->ui_ulen = ui->ui_len;
468 ui->ui_sum = 0;
469#if DO_ALIGN
470 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
471 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
472#else
473 ip = (struct ip *)&pkt.data[pkt.off];
474#endif
475 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
476 ip->ip_v = IPVERSION;
477 ip->ip_id = htons(ip_id++);
478 ip->ip_hl = sizeof (struct ip) >> 2;
479 ip->ip_ttl = udp_ttl;
480 ip->ip_sum = 0;
481 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
482#if DO_ALIGN
483 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
484#endif
485
486 pkt.len += sizeof (struct udpiphdr);
487
488 pkt.off -= sizeof (struct ether_header);
489
490 eh = (struct ether_header *)&pkt.data[pkt.off];
491 enaddr_copy(&adr.loc.ea, eh->ether_shost);
492 enaddr_copy(&adr.rmt.ea, eh->ether_dhost);
493 eh->ether_type = htons(ETHERTYPE_IP);
494
495 pkt.len += sizeof (struct ether_header);
1c79356b
A
496 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
497}
498
4a249263
A
499/* We don't interpret this pointer, we just give it to the
500bsd stack so it can decide when to set the MAC and IP info. */
501void
502kdp_set_interface(void *ifp)
503{
504 kdp_current_ifp = ifp;
505}
506
507void *
2d21ac55 508kdp_get_interface(void)
4a249263
A
509{
510 return kdp_current_ifp;
511}
9bccf70c
A
512
513void
514kdp_set_ip_and_mac_addresses(
515 struct in_addr *ipaddr,
516 struct ether_addr *macaddr)
1c79356b 517{
9bccf70c
A
518 kdp_current_ip_address = ipaddr->s_addr;
519 kdp_current_mac_address = *macaddr;
2d21ac55
A
520 if ((current_debugger == KDP_CUR_DB) && halt_in_debugger) {
521 kdp_call();
522 halt_in_debugger=0;
523 }
9bccf70c
A
524}
525
55e303ae
A
526void
527kdp_set_gateway_mac(void *gatewaymac)
528{
529 router_mac = *(struct ether_addr *)gatewaymac;
0c530ab8 530 flag_router_mac_initialized = TRUE;
55e303ae
A
531}
532
9bccf70c
A
533struct ether_addr
534kdp_get_mac_addr(void)
535{
536 return kdp_current_mac_address;
537}
538
539unsigned int
540kdp_get_ip_address(void)
541{
542 return kdp_current_ip_address;
543}
544
0c530ab8
A
545void
546kdp_disable_arp(void)
547{
548 kdp_flag &= ~(DB_ARP);
549}
550
551static void
552kdp_arp_dispatch(void)
553{
554 struct ether_arp aligned_ea, *ea = &aligned_ea;
555 unsigned arp_header_offset;
556
557 arp_header_offset = sizeof(struct ether_header) + pkt.off;
558 memcpy((void *)ea, (void *)&pkt.data[arp_header_offset], sizeof(*ea));
559
560 switch(ntohs(ea->arp_op)) {
561 case ARPOP_REQUEST:
562 kdp_arp_reply(ea);
563 break;
564 case ARPOP_REPLY:
565 kdp_process_arp_reply(ea);
566 break;
567 default:
568 return;
569 }
570}
571
572static void
573kdp_process_arp_reply(struct ether_arp *ea)
574{
575 /* Are we interested in ARP replies? */
576 if (flag_arp_resolved == TRUE)
577 return;
578
579 /* Did we receive a reply from the right source? */
580 if (((struct in_addr *)(ea->arp_spa))->s_addr != target_ip)
581 return;
582
583 flag_arp_resolved = TRUE;
584 current_resolved_MAC = *(struct ether_addr *) (ea->arp_sha);
585
586 return;
587}
588
9bccf70c 589/* ARP responses are enabled when the DB_ARP bit of the debug boot arg
0c530ab8
A
590 * is set.
591 */
592
9bccf70c 593static void
0c530ab8 594kdp_arp_reply(struct ether_arp *ea)
9bccf70c
A
595{
596 struct ether_header *eh;
9bccf70c
A
597
598 struct in_addr isaddr, itaddr, myaddr;
55e303ae 599 struct ether_addr my_enaddr;
9bccf70c
A
600
601 eh = (struct ether_header *)&pkt.data[pkt.off];
602 pkt.off += sizeof(struct ether_header);
603
55e303ae
A
604 if(ntohs(ea->arp_op) != ARPOP_REQUEST)
605 return;
9bccf70c
A
606
607 myaddr.s_addr = kdp_get_ip_address();
608 my_enaddr = kdp_get_mac_addr();
609
0c530ab8
A
610 if ((ntohl(myaddr.s_addr) == 0) ||
611 ((my_enaddr.ether_addr_octet[0] & 0xff) == 0
612 && (my_enaddr.ether_addr_octet[1] & 0xff) == 0
613 && (my_enaddr.ether_addr_octet[2] & 0xff) == 0
614 && (my_enaddr.ether_addr_octet[3] & 0xff) == 0
615 && (my_enaddr.ether_addr_octet[4] & 0xff) == 0
616 && (my_enaddr.ether_addr_octet[5] & 0xff) == 0
617 ))
9bccf70c
A
618 return;
619
620 (void)memcpy((void *)&isaddr, (void *)ea->arp_spa, sizeof (isaddr));
621 (void)memcpy((void *)&itaddr, (void *)ea->arp_tpa, sizeof (itaddr));
0c530ab8 622
9bccf70c
A
623 if (itaddr.s_addr == myaddr.s_addr) {
624 (void)memcpy((void *)ea->arp_tha, (void *)ea->arp_sha, sizeof(ea->arp_sha));
625 (void)memcpy((void *)ea->arp_sha, (void *)&my_enaddr, sizeof(ea->arp_sha));
626
627 (void)memcpy((void *)ea->arp_tpa, (void *) ea->arp_spa, sizeof(ea->arp_spa));
628 (void)memcpy((void *)ea->arp_spa, (void *) &itaddr, sizeof(ea->arp_spa));
629
630 ea->arp_op = htons(ARPOP_REPLY);
631 ea->arp_pro = htons(ETHERTYPE_IP);
632 (void)memcpy(eh->ether_dhost, ea->arp_tha, sizeof(eh->ether_dhost));
633 (void)memcpy(eh->ether_shost, &my_enaddr, sizeof(eh->ether_shost));
634 eh->ether_type = htons(ETHERTYPE_ARP);
635 (void)memcpy(&pkt.data[pkt.off], ea, sizeof(*ea));
636 pkt.off -= sizeof (struct ether_header);
637 /* pkt.len is still the length we want, ether_header+ether_arp */
638 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
639 }
640}
641
642static void
643kdp_poll(void)
644{
0c530ab8
A
645 struct ether_header *eh = NULL;
646 struct udpiphdr aligned_ui, *ui = &aligned_ui;
647 struct ip aligned_ip, *ip = &aligned_ip;
648 static int msg_printed;
8f6c56a5 649
0c530ab8
A
650 if (pkt.input)
651 kdp_panic("kdp_poll");
1c79356b 652
0c530ab8
A
653 if (!kdp_en_recv_pkt || !kdp_en_send_pkt) {
654 if( msg_printed == 0) {
655 msg_printed = 1;
656 printf("kdp_poll: no debugger device\n");
657 }
658 return;
1c79356b 659 }
1c79356b 660
0c530ab8
A
661 pkt.off = pkt.len = 0;
662 (*kdp_en_recv_pkt)(pkt.data, &pkt.len, 3/* ms */);
8f6c56a5 663
0c530ab8 664 if (pkt.len == 0)
4452a7af 665 return;
21362eb3 666
0c530ab8
A
667 if (pkt.len >= sizeof(struct ether_header))
668 {
669 eh = (struct ether_header *)&pkt.data[pkt.off];
670
671 if (kdp_flag & KDP_ARP)
672 {
673 if (ntohs(eh->ether_type) == ETHERTYPE_ARP)
674 {
675 kdp_arp_dispatch();
676 return;
677 }
678 }
679 }
680
681 if (pkt.len < (sizeof (struct ether_header) + sizeof (struct udpiphdr)))
682 return;
6601e61a 683
0c530ab8
A
684 pkt.off += sizeof (struct ether_header);
685 if (ntohs(eh->ether_type) != ETHERTYPE_IP) {
686 return;
687 }
1c79356b
A
688
689#if DO_ALIGN
0c530ab8
A
690 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
691 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
1c79356b 692#else
0c530ab8
A
693 ui = (struct udpiphdr *)&pkt.data[pkt.off];
694 ip = (struct ip *)&pkt.data[pkt.off];
1c79356b
A
695#endif
696
0c530ab8
A
697 pkt.off += sizeof (struct udpiphdr);
698 if (ui->ui_pr != IPPROTO_UDP) {
699 return;
700 }
1c79356b 701
0c530ab8
A
702 if (ip->ip_hl > (sizeof (struct ip) >> 2)) {
703 return;
704 }
4452a7af 705
0c530ab8
A
706 if (ntohs(ui->ui_dport) != KDP_REMOTE_PORT) {
707 if (panicd_port == (ntohs(ui->ui_dport)) &&
708 flag_panic_dump_in_progress) {
709 last_panic_port = ui->ui_sport;
710 }
711 else
712 return;
89b3af67 713 }
0c530ab8
A
714 /* If we receive a kernel debugging packet whilst a
715 * core dump is in progress, abort the transfer and
716 * enter the debugger.
717 */
718 else
719 if (flag_panic_dump_in_progress)
720 {
721 abort_panic_transfer();
722 return;
723 }
724
725 if (!kdp.is_conn && !flag_panic_dump_in_progress) {
726 enaddr_copy(eh->ether_dhost, &adr.loc.ea);
727 adr.loc.in = ui->ui_dst;
728
729 enaddr_copy(eh->ether_shost, &adr.rmt.ea);
730 adr.rmt.in = ui->ui_src;
4452a7af
A
731 }
732
0c530ab8
A
733 /*
734 * Calculate kdp packet length.
735 */
736 pkt.len = ntohs((u_short)ui->ui_ulen) - sizeof (struct udphdr);
737 pkt.input = TRUE;
738}
4452a7af 739
0c530ab8
A
740/* Create and transmit an ARP resolution request for the target IP address.
741 * This is modeled on ether_inet_arp()/RFC 826.
742 */
4452a7af 743
0c530ab8
A
744static void
745transmit_ARP_request(uint32_t ip_addr)
746{
747 struct ether_header *eh = (struct ether_header *) &pkt.data[0];
748 struct ether_arp *ea = (struct ether_arp *) &pkt.data[sizeof(struct ether_header)];
749
750 KDP_DEBUG("Transmitting ARP request\n");
751 /* Populate the ether_header */
752 eh->ether_type = htons(ETHERTYPE_ARP);
753 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
754 enaddr_copy(&etherbroadcastaddr, eh->ether_dhost);
755
756 /* Populate the ARP header */
757 ea->arp_pro = htons(ETHERTYPE_IP);
758 ea->arp_hln = sizeof(ea->arp_sha);
759 ea->arp_pln = sizeof(ea->arp_spa);
760 ea->arp_hrd = htons(ARPHRD_ETHER);
761 ea->arp_op = htons(ARPOP_REQUEST);
762
763 /* Target fields */
764 enaddr_copy(&etherbroadcastaddr, ea->arp_tha);
765 memcpy(ea->arp_tpa, (void *) &ip_addr, sizeof(ip_addr));
766
767 /* Source fields */
768 enaddr_copy(&kdp_current_mac_address, ea->arp_sha);
769 memcpy(ea->arp_spa, (void *) &kdp_current_ip_address, sizeof(kdp_current_ip_address));
770
771 pkt.off = 0;
772 pkt.len = sizeof(struct ether_header) + sizeof(struct ether_arp);
773 /* Transmit */
774 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
775}
776
777static boolean_t
778kdp_arp_resolve(uint32_t arp_target_ip, struct ether_addr *resolved_MAC)
779{
780 int poll_count = 256; /* ~770 ms modulo broadcast/delayed traffic? */
781 char tretries = 0;
782
783#define NUM_ARP_TX_RETRIES 5
784
785 target_ip = arp_target_ip;
786 flag_arp_resolved = FALSE;
787
788TRANSMIT_RETRY:
789 pkt.off = pkt.len = 0;
790
791 tretries++;
792
793 if (tretries >= NUM_ARP_TX_RETRIES) {
794 return FALSE;
795 }
796
797 KDP_DEBUG("ARP TX attempt #%d \n", tretries);
798
799 transmit_ARP_request(arp_target_ip);
800
801 while (!pkt.input && !flag_arp_resolved && flag_panic_dump_in_progress && --poll_count) {
802 kdp_poll();
803 }
804
805 if (flag_arp_resolved) {
806 *resolved_MAC = current_resolved_MAC;
807 return TRUE;
808 }
809
810 if (!flag_panic_dump_in_progress || pkt.input) /* we received a debugging packet, bail*/
811 {
812 printf("Received a debugger packet,transferring control to debugger\n");
813 /* Indicate that we should wait in the debugger when we return */
814 kdp_flag |= DBG_POST_CORE;
815 pkt.input = FALSE;
816 return FALSE;
817 }
818 else /* We timed out */
819 if (0 == poll_count) {
820 poll_count = 256;
821 goto TRANSMIT_RETRY;
822 }
823 return FALSE;
1c79356b
A
824}
825
9bccf70c 826static void
1c79356b 827kdp_handler(
9bccf70c 828 void *saved_state
1c79356b
A
829)
830{
831 unsigned short reply_port;
832 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
833
1c79356b
A
834 kdp.saved_state = saved_state; // see comment in kdp_raise_exception
835
836 do {
837 while (!pkt.input)
838 kdp_poll();
839
840#if DO_ALIGN
841 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
842#else
843 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
844#endif
845
846 // ignore replies -- we're not expecting them anyway.
847 if (hdr->is_reply) {
848 goto again;
849 }
850
9bccf70c
A
851 if (hdr->request == KDP_REATTACH)
852 exception_seq = hdr->seq;
853
1c79356b
A
854 // check for retransmitted request
855 if (hdr->seq == (exception_seq - 1)) {
856 /* retransmit last reply */
857 (*kdp_en_send_pkt)(&saved_reply.data[saved_reply.off],
858 saved_reply.len);
859 goto again;
860 } else if (hdr->seq != exception_seq) {
861 printf("kdp: bad sequence %d (want %d)\n",
862 hdr->seq, exception_seq);
863 goto again;
864 }
865
866 if (kdp_packet((unsigned char*)&pkt.data[pkt.off],
867 (int *)&pkt.len,
868 (unsigned short *)&reply_port)) {
869 kdp_reply(reply_port);
870 }
871
872again:
873 pkt.input = FALSE;
874 } while (kdp.is_halted);
875}
876
9bccf70c
A
877static void
878kdp_connection_wait(void)
1c79356b 879{
55e303ae 880 unsigned short reply_port;
55e303ae
A
881 struct ether_addr kdp_mac_addr = kdp_get_mac_addr();
882 unsigned int ip_addr = ntohl(kdp_get_ip_address());
9bccf70c 883
0c530ab8
A
884 /*
885 * Do both a printf() and a kprintf() of the MAC and IP so that
886 * they will print out on headless machines but not be added to
887 * the panic.log
888 */
889
9bccf70c
A
890 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
891 kdp_mac_addr.ether_addr_octet[0] & 0xff,
892 kdp_mac_addr.ether_addr_octet[1] & 0xff,
893 kdp_mac_addr.ether_addr_octet[2] & 0xff,
894 kdp_mac_addr.ether_addr_octet[3] & 0xff,
895 kdp_mac_addr.ether_addr_octet[4] & 0xff,
896 kdp_mac_addr.ether_addr_octet[5] & 0xff);
897
0c530ab8
A
898 kprintf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
899 kdp_mac_addr.ether_addr_octet[0] & 0xff,
900 kdp_mac_addr.ether_addr_octet[1] & 0xff,
901 kdp_mac_addr.ether_addr_octet[2] & 0xff,
902 kdp_mac_addr.ether_addr_octet[3] & 0xff,
903 kdp_mac_addr.ether_addr_octet[4] & 0xff,
904 kdp_mac_addr.ether_addr_octet[5] & 0xff);
905
9bccf70c
A
906 printf( "ip address: %d.%d.%d.%d\n",
907 (ip_addr & 0xff000000) >> 24,
908 (ip_addr & 0xff0000) >> 16,
909 (ip_addr & 0xff00) >> 8,
910 (ip_addr & 0xff));
911
0c530ab8
A
912 kprintf( "ip address: %d.%d.%d.%d\n",
913 (ip_addr & 0xff000000) >> 24,
914 (ip_addr & 0xff0000) >> 16,
915 (ip_addr & 0xff00) >> 8,
916 (ip_addr & 0xff));
917
55e303ae
A
918 printf("\nWaiting for remote debugger connection.\n");
919
2d21ac55 920
55e303ae
A
921 if (reattach_wait == 0) {
922 if((kdp_flag & KDP_GETC_ENA) && (0 != kdp_getc()))
923 {
924 printf("Options..... Type\n");
925 printf("------------ ----\n");
926 printf("continue.... 'c'\n");
927 printf("reboot...... 'r'\n");
1c79356b 928#if MACH_KDB
55e303ae 929 printf("enter kdb... 'k'\n");
1c79356b 930#endif
55e303ae
A
931 }
932 } else
933 reattach_wait = 0;
9bccf70c 934
55e303ae
A
935 exception_seq = 0;
936
937 do {
938 kdp_hdr_t aligned_hdr, *hdr = &aligned_hdr;
1c79356b 939
55e303ae
A
940 while (!pkt.input) {
941 if (kdp_flag & KDP_GETC_ENA) {
942 switch(kdp_getc()) {
943 case 'c':
944 printf("Continuing...\n");
945 return;
946 case 'r':
947 printf("Rebooting...\n");
948 kdp_reboot();
949 break;
1c79356b 950#if MACH_KDB
55e303ae
A
951 case 'k':
952 printf("calling kdb...\n");
953 if (kdp_call_kdb())
954 return;
955 else
956 printf("not implemented...\n");
1c79356b 957#endif
55e303ae
A
958 default:
959 break;
960 }
961 }
962 kdp_poll();
963 }
1c79356b 964
1c79356b 965#if DO_ALIGN
55e303ae 966 bcopy((char *)&pkt.data[pkt.off], (char *)hdr, sizeof(*hdr));
1c79356b 967#else
55e303ae 968 hdr = (kdp_hdr_t *)&pkt.data[pkt.off];
1c79356b 969#endif
55e303ae
A
970 if (hdr->request == KDP_HOSTREBOOT) {
971 kdp_reboot();
972 /* should not return! */
973 }
974 if (((hdr->request == KDP_CONNECT) || (hdr->request == KDP_REATTACH)) &&
975 !hdr->is_reply && (hdr->seq == exception_seq)) {
976 if (kdp_packet((unsigned char *)&pkt.data[pkt.off],
977 (int *)&pkt.len,
978 (unsigned short *)&reply_port))
979 kdp_reply(reply_port);
980 if (hdr->request == KDP_REATTACH) {
981 reattach_wait = 0;
982 hdr->request=KDP_DISCONNECT;
983 exception_seq = 0;
984 }
985 }
986
987 pkt.input = FALSE;
988 } while (!kdp.is_conn);
1c79356b 989
55e303ae
A
990 if (current_debugger == KDP_CUR_DB)
991 active_debugger=1;
992 printf("Connected to remote debugger.\n");
1c79356b
A
993}
994
9bccf70c 995static void
1c79356b
A
996kdp_send_exception(
997 unsigned int exception,
998 unsigned int code,
999 unsigned int subcode
1000)
1001{
1002 unsigned short remote_port;
9bccf70c
A
1003 unsigned int timeout_count = 100;
1004 unsigned int poll_timeout;
1c79356b 1005
1c79356b
A
1006 do {
1007 pkt.off = sizeof (struct ether_header) + sizeof (struct udpiphdr);
1008 kdp_exception((unsigned char *)&pkt.data[pkt.off],
1009 (int *)&pkt.len,
1010 (unsigned short *)&remote_port,
1011 (unsigned int)exception,
1012 (unsigned int)code,
1013 (unsigned int)subcode);
9bccf70c 1014
1c79356b
A
1015 kdp_send(remote_port);
1016
9bccf70c
A
1017 poll_timeout = 50;
1018 while(!pkt.input && poll_timeout)
1019 {
1020 kdp_poll();
1021 poll_timeout--;
1022 }
1023
1c79356b
A
1024 if (pkt.input) {
1025 if (!kdp_exception_ack(&pkt.data[pkt.off], pkt.len)) {
1026 pkt.input = FALSE;
1c79356b 1027 }
1c79356b 1028 }
9bccf70c 1029
1c79356b 1030 pkt.input = FALSE;
9bccf70c 1031
1c79356b 1032 if (kdp.exception_ack_needed)
9bccf70c 1033 kdp_us_spin(250000);
1c79356b
A
1034
1035 } while (kdp.exception_ack_needed && timeout_count--);
1036
1037 if (kdp.exception_ack_needed) {
1038 // give up & disconnect
1039 printf("kdp: exception ack timeout\n");
9bccf70c
A
1040 if (current_debugger == KDP_CUR_DB)
1041 active_debugger=0;
1c79356b
A
1042 kdp_reset();
1043 }
1044}
1045
1046void
1047kdp_raise_exception(
1048 unsigned int exception,
1049 unsigned int code,
1050 unsigned int subcode,
1051 void *saved_state
1052)
1053{
1c79356b
A
1054 int index;
1055
2d21ac55
A
1056 /* Was a system trace requested ? */
1057 if (kdp_snapshot && (!panic_active()) && (panic_caller == 0)) {
1058 stack_snapshot_ret = kdp_stackshot(stack_snapshot_pid,
1059 stack_snapshot_buf, stack_snapshot_bufsize,
1060 stack_snapshot_options, &stack_snapshot_bytes_traced);
1061 return;
1062 }
1063
9bccf70c
A
1064 disable_preemption();
1065
1c79356b
A
1066 if (saved_state == 0)
1067 printf("kdp_raise_exception with NULL state\n");
1068
1069 index = exception;
1070 if (exception != EXC_BREAKPOINT) {
1071 if (exception > EXC_BREAKPOINT || exception < EXC_BAD_ACCESS) {
1072 index = 0;
1073 }
1074 printf("%s exception (%x,%x,%x)\n",
1075 exception_message[index],
1076 exception, code, subcode);
1077 }
1078
1079 kdp_sync_cache();
1080
1081 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
1082 * do this. I think the client and the host can get out of sync.
1083 */
1084 kdp.saved_state = saved_state;
cf7d32b8
A
1085 kdp.kdp_cpu = cpu_number();
1086 kdp.kdp_thread = current_thread();
1087
1c79356b
A
1088 if (pkt.input)
1089 kdp_panic("kdp_raise_exception");
55e303ae 1090
0c530ab8 1091
55e303ae
A
1092 if (((kdp_flag & KDP_PANIC_DUMP_ENABLED) || (kdp_flag & PANIC_LOG_DUMP))
1093 && (panicstr != (char *) 0)) {
1094
0c530ab8 1095 kdp_panic_dump();
55e303ae
A
1096 }
1097 else
1098 if ((kdp_flag & PANIC_CORE_ON_NMI) && (panicstr == (char *) 0) &&
1099 !kdp.is_conn) {
1100
2d21ac55 1101 disable_debug_output = disableConsoleOutput = FALSE;
55e303ae
A
1102 kdp_panic_dump();
1103
1104 if (!(kdp_flag & DBG_POST_CORE))
1105 goto exit_raise_exception;
1106 }
1107
9bccf70c 1108 again:
1c79356b
A
1109 if (!kdp.is_conn)
1110 kdp_connection_wait();
55e303ae 1111 else {
1c79356b 1112 kdp_send_exception(exception, code, subcode);
55e303ae 1113 if (kdp.exception_ack_needed) {
9bccf70c
A
1114 kdp.exception_ack_needed = FALSE;
1115 kdp_remove_all_breakpoints();
1116 printf("Remote debugger disconnected.\n");
1117 }
1118 }
1c79356b
A
1119
1120 if (kdp.is_conn) {
1121 kdp.is_halted = TRUE; /* XXX */
1122 kdp_handler(saved_state);
1123 if (!kdp.is_conn)
9bccf70c
A
1124 {
1125 kdp_remove_all_breakpoints();
1c79356b 1126 printf("Remote debugger disconnected.\n");
9bccf70c 1127 }
1c79356b 1128 }
55e303ae
A
1129 /* Allow triggering a panic core dump when connected to the machine
1130 * Continuing after setting kdp_trigger_core_dump should do the
1131 * trick.
1132 */
91447636 1133
55e303ae
A
1134 if (1 == kdp_trigger_core_dump) {
1135 kdp_flag &= ~PANIC_LOG_DUMP;
1136 kdp_flag |= KDP_PANIC_DUMP_ENABLED;
1137 kdp_panic_dump();
2d21ac55 1138 kdp_trigger_core_dump = 0;
55e303ae 1139 }
1c79356b 1140
91447636
A
1141/* Trigger a reboot if the user has set this flag through the
1142 * debugger.Ideally, this would be done through the HOSTREBOOT packet
1143 * in the protocol,but that will need gdb support,and when it's
1144 * available, it should work automatically.
1145 */
1146 if (1 == flag_kdp_trigger_reboot) {
1147 kdp_reboot();
1148 /* If we're still around, reset the flag */
1149 flag_kdp_trigger_reboot = 0;
1150 }
2d21ac55
A
1151
1152 if (kdp_reentry_deadline) {
1153 kdp_schedule_debugger_reentry(kdp_reentry_deadline);
1154 printf("Debugger re-entry scheduled in %d milliseconds\n", kdp_reentry_deadline);
1155 kdp_reentry_deadline = 0;
1156 }
1157
1c79356b 1158 kdp_sync_cache();
9bccf70c
A
1159
1160 if (reattach_wait == 1)
1161 goto again;
91447636
A
1162
1163exit_raise_exception:
9bccf70c 1164 enable_preemption();
1c79356b
A
1165}
1166
1167void
1168kdp_reset(void)
1169{
9bccf70c
A
1170 kdp.reply_port = kdp.exception_port = 0;
1171 kdp.is_halted = kdp.is_conn = FALSE;
1172 kdp.exception_seq = kdp.conn_seq = 0;
1c79356b
A
1173}
1174
55e303ae
A
1175struct corehdr *
1176create_panic_header(unsigned int request, const char *corename,
0c530ab8 1177 unsigned length, unsigned int block)
55e303ae 1178{
0c530ab8
A
1179 struct udpiphdr aligned_ui, *ui = &aligned_ui;
1180 struct ip aligned_ip, *ip = &aligned_ip;
1181 struct ether_header *eh;
1182 struct corehdr *coreh;
1183 const char *mode = "octet";
1184 char modelen = strlen(mode);
55e303ae 1185
0c530ab8
A
1186 pkt.off = sizeof (struct ether_header);
1187 pkt.len = length + ((request == KDP_WRQ) ? modelen : 0) +
1188 (corename ? strlen(corename): 0) + sizeof(struct corehdr);
55e303ae
A
1189
1190#if DO_ALIGN
0c530ab8 1191 bcopy((char *)&pkt.data[pkt.off], (char *)ui, sizeof(*ui));
55e303ae 1192#else
0c530ab8 1193 ui = (struct udpiphdr *)&pkt.data[pkt.off];
55e303ae 1194#endif
2d21ac55 1195 ui->ui_next = ui->ui_prev = NULL;
0c530ab8
A
1196 ui->ui_x1 = 0;
1197 ui->ui_pr = IPPROTO_UDP;
1198 ui->ui_len = htons((u_short)pkt.len + sizeof (struct udphdr));
1199 ui->ui_src.s_addr = kdp_current_ip_address;
1200 /* Already in network byte order via inet_aton() */
1201 ui->ui_dst.s_addr = panic_server_ip;
1202 ui->ui_sport = htons(panicd_port);
1203 ui->ui_dport = ((request == KDP_WRQ) ? htons(panicd_port) : last_panic_port);
1204 ui->ui_ulen = ui->ui_len;
1205 ui->ui_sum = 0;
55e303ae 1206#if DO_ALIGN
0c530ab8
A
1207 bcopy((char *)ui, (char *)&pkt.data[pkt.off], sizeof(*ui));
1208 bcopy((char *)&pkt.data[pkt.off], (char *)ip, sizeof(*ip));
55e303ae 1209#else
0c530ab8 1210 ip = (struct ip *)&pkt.data[pkt.off];
55e303ae 1211#endif
0c530ab8
A
1212 ip->ip_len = htons(sizeof (struct udpiphdr) + pkt.len);
1213 ip->ip_v = IPVERSION;
1214 ip->ip_id = htons(ip_id++);
1215 ip->ip_hl = sizeof (struct ip) >> 2;
1216 ip->ip_ttl = udp_ttl;
1217 ip->ip_sum = 0;
1218 ip->ip_sum = htons(~ip_sum((unsigned char *)ip, ip->ip_hl));
55e303ae 1219#if DO_ALIGN
0c530ab8 1220 bcopy((char *)ip, (char *)&pkt.data[pkt.off], sizeof(*ip));
55e303ae
A
1221#endif
1222
0c530ab8 1223 pkt.len += sizeof (struct udpiphdr);
55e303ae 1224
0c530ab8 1225 pkt.off += sizeof (struct udpiphdr);
55e303ae 1226
0c530ab8
A
1227 coreh = (struct corehdr *) &pkt.data[pkt.off];
1228 coreh->th_opcode = htons((u_short)request);
55e303ae 1229
0c530ab8
A
1230 if (request == KDP_WRQ)
1231 {
2d21ac55 1232 char *cp;
0c530ab8
A
1233
1234 cp = coreh->th_u.tu_rpl;
2d21ac55 1235 cp += strlcpy (cp, corename, KDP_MAXPACKET);
0c530ab8 1236 *cp++ = '\0';
2d21ac55 1237 cp += strlcpy (cp, mode, KDP_MAXPACKET - strlen(corename));
0c530ab8
A
1238 *cp++ = '\0';
1239 }
1240 else
1241 {
1242 coreh->th_block = htonl((unsigned int) block);
1243 }
55e303ae 1244
0c530ab8
A
1245 pkt.off -= sizeof (struct udpiphdr);
1246 pkt.off -= sizeof (struct ether_header);
55e303ae 1247
0c530ab8
A
1248 eh = (struct ether_header *)&pkt.data[pkt.off];
1249 enaddr_copy(&kdp_current_mac_address, eh->ether_shost);
1250 enaddr_copy(&destination_mac, eh->ether_dhost);
1251 eh->ether_type = htons(ETHERTYPE_IP);
55e303ae 1252
0c530ab8
A
1253 pkt.len += sizeof (struct ether_header);
1254 return coreh;
55e303ae
A
1255}
1256
0c530ab8
A
1257int kdp_send_crashdump_data(unsigned int request, char *corename,
1258 unsigned int length, caddr_t txstart)
55e303ae 1259{
0c530ab8
A
1260 caddr_t txend = txstart + length;
1261 int panic_error = 0;
55e303ae 1262
0c530ab8
A
1263 if (length <= SEGSIZE) {
1264 if ((panic_error = kdp_send_crashdump_pkt(request, corename, length, (caddr_t) txstart)) < 0) {
1265 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
1266 return panic_error ;
1267 }
4452a7af 1268 }
0c530ab8
A
1269 else
1270 {
1271 while (txstart <= (txend - SEGSIZE)) {
1272 if ((panic_error = kdp_send_crashdump_pkt(KDP_DATA, NULL, SEGSIZE, txstart)) < 0) {
1273 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
1274 return panic_error;
1275 }
1276 txstart += SEGSIZE;
1277 if (!(panic_block % 2000))
1278 printf(".");
1279 }
1280 if (txstart < txend) {
1281 kdp_send_crashdump_pkt(request, corename, (txend - txstart), txstart);
1282 }
1283 }
1284 return 0;
55e303ae
A
1285}
1286
0c530ab8
A
1287int
1288kdp_send_crashdump_pkt(unsigned int request, char *corename,
1289 unsigned int length, void *panic_data)
55e303ae 1290{
0c530ab8
A
1291 struct corehdr *th = NULL;
1292 int poll_count = 2500;
55e303ae 1293
0c530ab8
A
1294 char rretries = 0, tretries = 0;
1295
1296 pkt.off = pkt.len = 0;
55e303ae 1297
0c530ab8
A
1298 if (request == KDP_WRQ) /* longer timeout for initial request */
1299 poll_count += 1000;
55e303ae
A
1300
1301TRANSMIT_RETRY:
0c530ab8 1302 tretries++;
8f6c56a5 1303
0c530ab8
A
1304 if (tretries >=15) {
1305/* The crashdump server is unreachable for some reason. This could be a network
1306 * issue or, if we've been especially unfortunate, we've hit Radar 2760413,
1307 * which is a long standing problem with the IOKit polled mode network driver
1308 * shim which can prevent transmits/receives completely.
1309 */
1310 printf ("Cannot contact panic server, timing out.\n");
1311 return (-3);
1312 }
8f6c56a5 1313
0c530ab8
A
1314 if (tretries > 2)
1315 printf("TX retry #%d ", tretries );
1316
1317 th = create_panic_header(request, corename, length, panic_block);
21362eb3 1318
0c530ab8
A
1319 if (request == KDP_DATA) {
1320 if (!kdp_vm_read((caddr_t) panic_data, (caddr_t) th->th_data, length)) {
1321 memset ((caddr_t) th->th_data, 'X', length);
1322 }
1323 }
1324 else if (request == KDP_SEEK) {
1325 *(unsigned int *) th->th_data = htonl(*(unsigned int *) panic_data);
1326 }
21362eb3 1327
0c530ab8 1328 (*kdp_en_send_pkt)(&pkt.data[pkt.off], pkt.len);
6601e61a 1329
0c530ab8
A
1330 /* Listen for the ACK */
1331RECEIVE_RETRY:
1332 while (!pkt.input && flag_panic_dump_in_progress && poll_count) {
1333 kdp_poll();
1334 poll_count--;
1335 }
6601e61a 1336
0c530ab8 1337 if (pkt.input) {
55e303ae 1338
0c530ab8 1339 pkt.input = FALSE;
55e303ae 1340
0c530ab8 1341 th = (struct corehdr *) &pkt.data[pkt.off];
55e303ae 1342
0c530ab8
A
1343 if (ntohs(th->th_opcode) == KDP_ACK && ntohl(th->th_block) == panic_block) {
1344 }
1345 else
1346 if (ntohs(th->th_opcode) == KDP_ERROR) {
1347 printf("Panic server returned error %d, retrying\n", ntohl(th->th_code));
1348 poll_count = 1000;
1349 goto TRANSMIT_RETRY;
1350 }
1351 else
1352 if (ntohl(th->th_block) == (panic_block - 1)) {
1353 printf("RX retry ");
1354 if (++rretries > 1)
1355 goto TRANSMIT_RETRY;
1356 else
1357 goto RECEIVE_RETRY;
1358 }
55e303ae 1359 }
0c530ab8
A
1360 else
1361 if (!flag_panic_dump_in_progress) /* we received a debugging packet, bail*/
1362 {
1363 printf("Received a debugger packet,transferring control to debugger\n");
1364 /* Configure that if not set ..*/
1365 kdp_flag |= DBG_POST_CORE;
1366 return (-2);
1367 }
1368 else /* We timed out */
1369 if (0 == poll_count) {
1370 poll_count = 1000;
1371 kdp_us_spin ((tretries%4) * panic_timeout); /* capped linear backoff */
1372 goto TRANSMIT_RETRY;
1373 }
55e303ae 1374
0c530ab8 1375 panic_block++;
55e303ae 1376
0c530ab8
A
1377 if (request == KDP_EOF)
1378 printf("\nTotal number of packets transmitted: %d\n", panic_block);
55e303ae 1379
0c530ab8 1380 return 1;
55e303ae
A
1381}
1382
55e303ae
A
1383static int
1384isdigit (char c)
1385{
1386 return ((c > 47) && (c < 58));
1387}
1388/* From user mode Libc - this ought to be in a library */
1389static char *
0c530ab8 1390strnstr(char *s, const char *find, size_t slen)
55e303ae
A
1391{
1392 char c, sc;
1393 size_t len;
1394
1395 if ((c = *find++) != '\0') {
1396 len = strlen(find);
1397 do {
1398 do {
1399 if ((sc = *s++) == '\0' || slen-- < 1)
1400 return (NULL);
1401 } while (sc != c);
1402 if (len > slen)
1403 return (NULL);
1404 } while (strncmp(s, find, len) != 0);
1405 s--;
1406 }
2d21ac55 1407 return (s);
55e303ae
A
1408}
1409
0c530ab8
A
1410extern char version[];
1411
55e303ae
A
1412/* Horrid hack to extract xnu version if possible - a much cleaner approach
1413 * would be to have the integrator run a script which would copy the
1414 * xnu version into a string or an int somewhere at project submission
1415 * time - makes assumptions about sizeof(version), but will not fail if
1416 * it changes, but may be incorrect.
1417 */
0c530ab8
A
1418/* 2006: Incorporated a change from Darwin user P. Lovell to extract
1419 * the minor kernel version numbers from the version string.
1420 */
55e303ae
A
1421static int
1422kdp_get_xnu_version(char *versionbuf)
1423{
0c530ab8
A
1424 char *versionpos;
1425 char vstr[20];
1426 int retval = -1;
1427 char *vptr;
1428
2d21ac55 1429 strlcpy(vstr, "custom", 10);
cf7d32b8
A
1430 if (strlcpy(versionbuf, version, 95) < 95) {
1431 versionpos = strnstr(versionbuf, "xnu-", 90);
1432 if (versionpos) {
1433 strncpy(vstr, versionpos, sizeof(vstr));
1434 vstr[sizeof(vstr)-1] = '\0';
1435 vptr = vstr + 4; /* Begin after "xnu-" */
1436 while (*vptr && (isdigit(*vptr) || *vptr == '.'))
1437 vptr++;
1438 *vptr = '\0';
1439 /* Remove trailing period, if any */
1440 if (*(--vptr) == '.')
0c530ab8 1441 *vptr = '\0';
cf7d32b8 1442 retval = 0;
0c530ab8
A
1443 }
1444 }
2d21ac55 1445 strlcpy(versionbuf, vstr, KDP_MAXPACKET);
0c530ab8 1446 return retval;
55e303ae 1447}
91447636 1448
0c530ab8 1449extern char *inet_aton(const char *cp, struct in_addr *pin);
0c530ab8 1450
55e303ae
A
1451/* Primary dispatch routine for the system dump */
1452void
2d21ac55 1453kdp_panic_dump(void)
55e303ae 1454{
0c530ab8
A
1455 char corename[50];
1456 char coreprefix[10];
1457 int panic_error;
55e303ae 1458
0c530ab8
A
1459 uint64_t abstime;
1460 uint32_t current_ip = ntohl(kdp_current_ip_address);
c0fea474 1461
0c530ab8
A
1462 if (flag_panic_dump_in_progress) {
1463 printf("System dump aborted.\n");
1464 goto panic_dump_exit;
1465 }
1466
1467 printf("Entering system dump routine\n");
8f6c56a5 1468
0c530ab8
A
1469 if (!panicd_specified) {
1470 printf("A dump server was not specified in the boot-args, terminating kernel core dump.\n");
1471 goto panic_dump_exit;
1472 }
8f6c56a5 1473
0c530ab8
A
1474 flag_panic_dump_in_progress = TRUE;
1475 not_in_kdp = 0;
55e303ae 1476
0c530ab8
A
1477 if (pkt.input)
1478 kdp_panic("kdp_panic_dump: unexpected pending input packet");
55e303ae 1479
0c530ab8 1480 kdp_get_xnu_version((char *) &pkt.data[0]);
55e303ae 1481
0c530ab8
A
1482 /* Panic log bit takes precedence over core dump bit */
1483 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP))
1484 strncpy(coreprefix, "paniclog", sizeof(coreprefix));
1485 else
1486 strncpy(coreprefix, "core", sizeof(coreprefix));
55e303ae 1487
0c530ab8
A
1488 abstime = mach_absolute_time();
1489 pkt.data[20] = '\0';
1490 snprintf (corename, sizeof(corename), "%s-%s-%d.%d.%d.%d-%x",
55e303ae 1491 coreprefix, &pkt.data[0],
0c530ab8
A
1492 (current_ip & 0xff000000) >> 24,
1493 (current_ip & 0xff0000) >> 16,
1494 (current_ip & 0xff00) >> 8,
1495 (current_ip & 0xff),
1496 (unsigned int) (abstime & 0xffffffff));
1497
1498 if (0 == inet_aton(panicd_ip_str, (struct in_addr *) &panic_server_ip)) {
1499 printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str);
1500 }
1501 else
1502 printf("Attempting connection to panic server configured at IP %s, port %d\n", panicd_ip_str, panicd_port);
4452a7af 1503
0c530ab8
A
1504 destination_mac = router_mac;
1505
1506 if (kdp_arp_resolve(panic_server_ip, &temp_mac)) {
1507 printf("Resolved %s's (or proxy's) link level address\n", panicd_ip_str);
1508 destination_mac = temp_mac;
55e303ae 1509 }
0c530ab8
A
1510 else {
1511 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
1512 if (router_specified) {
1513 if (0 == inet_aton(router_ip_str, (struct in_addr *) &parsed_router_ip))
1514 printf("inet_aton() failed interpreting %s as an IP\n", router_ip_str);
1515 else {
1516 router_ip = parsed_router_ip;
1517 if (kdp_arp_resolve(router_ip, &temp_mac)) {
1518 destination_mac = temp_mac;
1519 printf("Routing through specified router IP %s (%d)\n", router_ip_str, router_ip);
1520 }
1521 }
1522 }
55e303ae 1523 }
91447636 1524
0c530ab8 1525 if (!flag_panic_dump_in_progress) goto panic_dump_exit;
5d5c5d0d 1526
0c530ab8
A
1527 printf("Transmitting packets to link level address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1528 destination_mac.ether_addr_octet[0] & 0xff,
1529 destination_mac.ether_addr_octet[1] & 0xff,
1530 destination_mac.ether_addr_octet[2] & 0xff,
1531 destination_mac.ether_addr_octet[3] & 0xff,
1532 destination_mac.ether_addr_octet[4] & 0xff,
1533 destination_mac.ether_addr_octet[5] & 0xff);
89b3af67 1534
0c530ab8
A
1535 printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map));
1536 printf("Sending write request for %s\n", corename);
4452a7af 1537
0c530ab8
A
1538 if ((panic_error = kdp_send_crashdump_pkt(KDP_WRQ, corename, 0 , NULL)) < 0) {
1539 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error);
1540 goto panic_dump_exit;
1541 }
1542
1543 /* Just the panic log requested */
1544 if ((panicstr != (char *) 0) && (kdp_flag & PANIC_LOG_DUMP)) {
1545 printf("Transmitting panic log, please wait: ");
1546 kdp_send_crashdump_data(KDP_DATA, corename, (debug_buf_ptr - debug_buf), debug_buf);
1547 kdp_send_crashdump_pkt (KDP_EOF, NULL, 0, ((void *) 0));
1548 printf("Please file a bug report on this panic, if possible.\n");
1549 goto panic_dump_exit;
1550 }
55e303ae 1551
0c530ab8
A
1552 /* We want a core dump if we're here */
1553 kern_dump();
55e303ae 1554panic_dump_exit:
0c530ab8
A
1555 abort_panic_transfer();
1556 pkt.input = FALSE;
1557 pkt.len = 0;
1558 kdp_reset();
1559 return;
55e303ae
A
1560}
1561
1562void
0c530ab8 1563abort_panic_transfer(void)
55e303ae 1564{
0c530ab8
A
1565 flag_panic_dump_in_progress = FALSE;
1566 not_in_kdp = 1;
1567 panic_block = 0;
55e303ae 1568}
593a1d5f
A
1569
1570#if CONFIG_SERIAL_KDP
1571
1572static boolean_t needs_serial_init = TRUE;
1573
1574static void
1575kdp_serial_send(void *rpkt, unsigned int rpkt_len)
1576{
1577 if (needs_serial_init)
1578 {
1579 serial_init();
1580 needs_serial_init = FALSE;
1581 }
1582
1583 // printf("tx\n");
1584 kdp_serialize_packet((unsigned char *)rpkt, rpkt_len, serial_putc);
1585}
1586
1587static void
1588kdp_serial_receive(void *rpkt, unsigned int *rpkt_len, unsigned int timeout)
1589{
1590 int readkar;
1591 uint64_t now, deadline;
1592
1593 if (needs_serial_init)
1594 {
1595 serial_init();
1596 needs_serial_init = FALSE;
1597 }
1598
1599 clock_interval_to_deadline(timeout, 1000 * 1000 /* milliseconds */, &deadline);
1600
1601// printf("rx\n");
1602 for(clock_get_uptime(&now); now < deadline; clock_get_uptime(&now))
1603 {
1604 readkar = serial_getc();
1605 if(readkar >= 0)
1606 {
1607 unsigned char *packet;
1608 // printf("got char %02x\n", readkar);
1609 if((packet = kdp_unserialize_packet(readkar,rpkt_len)))
1610 {
1611 memcpy(rpkt, packet, *rpkt_len);
1612 return;
1613 }
1614 }
1615 }
1616 *rpkt_len = 0;
1617}
1618
1619static void kdp_serial_callout(__unused void *arg, kdp_event_t event)
1620{
1621 /* When we stop KDP, set the bit to re-initialize the console serial port
1622 * the next time we send/receive a KDP packet. We don't do it on
1623 * KDP_EVENT_ENTER directly because it also gets called when we trap to KDP
1624 * for non-external debugging, i.e., stackshot or core dumps.
1625 *
1626 * Set needs_serial_init on exit (and initialization, see above) and not
1627 * enter because enter is sent multiple times and causes excess reinitialization.
1628 */
1629
1630 switch (event)
1631 {
1632 case KDP_EVENT_PANICLOG:
1633 case KDP_EVENT_ENTER:
1634 break;
1635 case KDP_EVENT_EXIT:
1636 needs_serial_init = TRUE;
1637 break;
1638 }
1639}
1640
1641#endif /* CONFIG_SERIAL_KDP */
1642
1643void
1644kdp_init(void)
1645{
1646#if CONFIG_SERIAL_KDP
1647 char kdpname[80];
1648 struct in_addr ipaddr;
1649 struct ether_addr macaddr;
1650
1651#if CONFIG_EMBEDDED
1652 //serial will be the debugger, unless match name is explicitly provided, and it's not "serial"
1653 if(PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname)) && strncmp(kdpname, "serial", sizeof(kdpname)) != 0)
1654 return;
1655#else
1656 // serial must be explicitly requested
1657 if(!PE_parse_boot_argn("kdp_match_name", kdpname, sizeof(kdpname)) || strncmp(kdpname, "serial", sizeof(kdpname)) != 0)
1658 return;
1659#endif
1660
1661 kprintf("Intializing serial KDP\n");
1662
1663 kdp_register_callout(kdp_serial_callout, NULL);
1664 kdp_register_send_receive(kdp_serial_send, kdp_serial_receive);
1665
1666 /* fake up an ip and mac for early serial debugging */
1667 macaddr.ether_addr_octet[0] = 's';
1668 macaddr.ether_addr_octet[1] = 'e';
1669 macaddr.ether_addr_octet[2] = 'r';
1670 macaddr.ether_addr_octet[3] = 'i';
1671 macaddr.ether_addr_octet[4] = 'a';
1672 macaddr.ether_addr_octet[5] = 'l';
1673 ipaddr.s_addr = 0xABADBABE;
1674 kdp_set_ip_and_mac_addresses(&ipaddr, &macaddr);
1675#endif /* CONFIG_SERIAL_KDP */
1676}