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