1 /*- 2 * Copyright (c) 2005-2014 Sandvine Incorporated. All rights reserved. 3 * Copyright (c) 2000 Darrell Anderson 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 /* 29 * netdump_client.c 30 * FreeBSD subsystem supporting netdump network dumps. 31 * A dedicated server must be running to accept client dumps. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include <sys/param.h> 38 #include <sys/conf.h> 39 #include <sys/disk.h> 40 #include <sys/endian.h> 41 #include <sys/eventhandler.h> 42 #include <sys/jail.h> 43 #include <sys/kernel.h> 44 #include <sys/kerneldump.h> 45 #include <sys/mbuf.h> 46 #include <sys/module.h> 47 #include <sys/priv.h> 48 #include <sys/proc.h> 49 #include <sys/protosw.h> 50 #include <sys/socket.h> 51 #include <sys/sysctl.h> 52 #include <sys/systm.h> 53 54 #include <net/ethernet.h> 55 #include <net/if.h> 56 #include <net/if_arp.h> 57 #include <net/if_dl.h> 58 #include <net/if_types.h> 59 #include <net/if_var.h> 60 61 #include <netinet/in.h> 62 #include <netinet/in_systm.h> 63 #include <netinet/in_var.h> 64 #include <netinet/ip.h> 65 #include <netinet/ip_var.h> 66 #include <netinet/ip_options.h> 67 #include <netinet/udp.h> 68 #include <netinet/udp_var.h> 69 #include <netinet/netdump/netdump.h> 70 71 #include <machine/in_cksum.h> 72 #include <machine/pcb.h> 73 74 #define NETDDEBUG(f, ...) do { \ 75 if (nd_debug > 0) \ 76 printf(("%s: " f), __func__, ## __VA_ARGS__); \ 77 } while (0) 78 #define NETDDEBUG_IF(i, f, ...) do { \ 79 if (nd_debug > 0) \ 80 if_printf((i), ("%s: " f), __func__, ## __VA_ARGS__); \ 81 } while (0) 82 #define NETDDEBUGV(f, ...) do { \ 83 if (nd_debug > 1) \ 84 printf(("%s: " f), __func__, ## __VA_ARGS__); \ 85 } while (0) 86 #define NETDDEBUGV_IF(i, f, ...) do { \ 87 if (nd_debug > 1) \ 88 if_printf((i), ("%s: " f), __func__, ## __VA_ARGS__); \ 89 } while (0) 90 91 static int netdump_arp_gw(void); 92 static void netdump_cleanup(void); 93 static int netdump_configure(struct diocskerneldump_arg *, 94 struct thread *); 95 static int netdump_dumper(void *priv __unused, void *virtual, 96 vm_offset_t physical __unused, off_t offset, size_t length); 97 static bool netdump_enabled(void); 98 static int netdump_enabled_sysctl(SYSCTL_HANDLER_ARGS); 99 static int netdump_ether_output(struct mbuf *m, struct ifnet *ifp, 100 struct ether_addr dst, u_short etype); 101 static void netdump_handle_arp(struct mbuf **mb); 102 static void netdump_handle_ip(struct mbuf **mb); 103 static int netdump_ioctl(struct cdev *dev __unused, u_long cmd, 104 caddr_t addr, int flags __unused, struct thread *td); 105 static int netdump_modevent(module_t mod, int type, void *priv); 106 static void netdump_network_poll(void); 107 static void netdump_pkt_in(struct ifnet *ifp, struct mbuf *m); 108 static void netdump_reinit_internal(struct ifnet *ifp); 109 static int netdump_send(uint32_t type, off_t offset, unsigned char *data, 110 uint32_t datalen); 111 static int netdump_send_arp(in_addr_t dst); 112 static int netdump_start(struct dumperinfo *di); 113 static int netdump_udp_output(struct mbuf *m); 114 static void netdump_unconfigure(void); 115 116 /* Must be at least as big as the chunks dumpsys() gives us. */ 117 static unsigned char nd_buf[MAXDUMPPGS * PAGE_SIZE]; 118 static uint32_t nd_seqno; 119 static int dump_failed, have_gw_mac; 120 static void (*drv_if_input)(struct ifnet *, struct mbuf *); 121 static int restore_gw_addr; 122 123 static uint64_t rcvd_acks; 124 CTASSERT(sizeof(rcvd_acks) * NBBY == NETDUMP_MAX_IN_FLIGHT); 125 126 /* Configuration parameters. */ 127 static struct { 128 char ndc_iface[IFNAMSIZ]; 129 union kd_ip ndc_server; 130 union kd_ip ndc_client; 131 union kd_ip ndc_gateway; 132 uint8_t ndc_af; 133 /* Runtime State */ 134 off_t nd_tx_off; 135 size_t nd_buf_len; 136 } nd_conf; 137 #define nd_server nd_conf.ndc_server.in4 138 #define nd_client nd_conf.ndc_client.in4 139 #define nd_gateway nd_conf.ndc_gateway.in4 140 141 /* General dynamic settings. */ 142 static struct sx nd_conf_lk; 143 SX_SYSINIT(nd_conf, &nd_conf_lk, "netdump configuration lock"); 144 #define NETDUMP_WLOCK() sx_xlock(&nd_conf_lk) 145 #define NETDUMP_WUNLOCK() sx_xunlock(&nd_conf_lk) 146 #define NETDUMP_RLOCK() sx_slock(&nd_conf_lk) 147 #define NETDUMP_RUNLOCK() sx_sunlock(&nd_conf_lk) 148 #define NETDUMP_ASSERT_WLOCKED() sx_assert(&nd_conf_lk, SA_XLOCKED) 149 #define NETDUMP_ASSERT_LOCKED() sx_assert(&nd_conf_lk, SA_LOCKED) 150 static struct ether_addr nd_gw_mac; 151 static struct ifnet *nd_ifp; 152 static eventhandler_tag nd_detach_cookie; 153 static uint16_t nd_server_port = NETDUMP_PORT; 154 155 FEATURE(netdump, "Netdump client support"); 156 157 static SYSCTL_NODE(_net, OID_AUTO, netdump, CTLFLAG_RD, NULL, 158 "netdump parameters"); 159 160 static int nd_debug; 161 SYSCTL_INT(_net_netdump, OID_AUTO, debug, CTLFLAG_RWTUN, 162 &nd_debug, 0, 163 "Debug message verbosity"); 164 SYSCTL_PROC(_net_netdump, OID_AUTO, enabled, CTLFLAG_RD | CTLTYPE_INT, 165 &nd_ifp, 0, netdump_enabled_sysctl, "I", "netdump configuration status"); 166 static char nd_path[MAXPATHLEN]; 167 SYSCTL_STRING(_net_netdump, OID_AUTO, path, CTLFLAG_RW, 168 nd_path, sizeof(nd_path), 169 "Server path for output files"); 170 static int nd_polls = 2000; 171 SYSCTL_INT(_net_netdump, OID_AUTO, polls, CTLFLAG_RWTUN, 172 &nd_polls, 0, 173 "Number of times to poll before assuming packet loss (0.5ms per poll)"); 174 static int nd_retries = 10; 175 SYSCTL_INT(_net_netdump, OID_AUTO, retries, CTLFLAG_RWTUN, 176 &nd_retries, 0, 177 "Number of retransmit attempts before giving up"); 178 static int nd_arp_retries = 3; 179 SYSCTL_INT(_net_netdump, OID_AUTO, arp_retries, CTLFLAG_RWTUN, 180 &nd_arp_retries, 0, 181 "Number of ARP attempts before giving up"); 182 183 static bool 184 netdump_enabled(void) 185 { 186 187 NETDUMP_ASSERT_LOCKED(); 188 return (nd_ifp != NULL); 189 } 190 191 static int 192 netdump_enabled_sysctl(SYSCTL_HANDLER_ARGS) 193 { 194 int en, error; 195 196 NETDUMP_RLOCK(); 197 en = netdump_enabled(); 198 NETDUMP_RUNLOCK(); 199 200 error = SYSCTL_OUT(req, &en, sizeof(en)); 201 if (error != 0 || req->newptr == NULL) 202 return (error); 203 return (EPERM); 204 } 205 206 /* 207 * Checks for netdump support on a network interface 208 * 209 * Parameters: 210 * ifp The network interface that is being tested for support 211 * 212 * Returns: 213 * int 1 if the interface is supported, 0 if not 214 */ 215 static bool 216 netdump_supported_nic(struct ifnet *ifp) 217 { 218 219 return (ifp->if_netdump_methods != NULL); 220 } 221 222 /*- 223 * Network specific primitives. 224 * Following down the code they are divided ordered as: 225 * - Packet buffer primitives 226 * - Output primitives 227 * - Input primitives 228 * - Polling primitives 229 */ 230 231 /* 232 * Handles creation of the ethernet header, then places outgoing packets into 233 * the tx buffer for the NIC 234 * 235 * Parameters: 236 * m The mbuf containing the packet to be sent (will be freed by 237 * this function or the NIC driver) 238 * ifp The interface to send on 239 * dst The destination ethernet address (source address will be looked 240 * up using ifp) 241 * etype The ETHERTYPE_* value for the protocol that is being sent 242 * 243 * Returns: 244 * int see errno.h, 0 for success 245 */ 246 static int 247 netdump_ether_output(struct mbuf *m, struct ifnet *ifp, struct ether_addr dst, 248 u_short etype) 249 { 250 struct ether_header *eh; 251 252 if (((ifp->if_flags & (IFF_MONITOR | IFF_UP)) != IFF_UP) || 253 (ifp->if_drv_flags & IFF_DRV_RUNNING) != IFF_DRV_RUNNING) { 254 if_printf(ifp, "netdump_ether_output: interface isn't up\n"); 255 m_freem(m); 256 return (ENETDOWN); 257 } 258 259 /* Fill in the ethernet header. */ 260 M_PREPEND(m, ETHER_HDR_LEN, M_NOWAIT); 261 if (m == NULL) { 262 printf("%s: out of mbufs\n", __func__); 263 return (ENOBUFS); 264 } 265 eh = mtod(m, struct ether_header *); 266 memcpy(eh->ether_shost, IF_LLADDR(ifp), ETHER_ADDR_LEN); 267 memcpy(eh->ether_dhost, dst.octet, ETHER_ADDR_LEN); 268 eh->ether_type = htons(etype); 269 return ((ifp->if_netdump_methods->nd_transmit)(ifp, m)); 270 } 271 272 /* 273 * Unreliable transmission of an mbuf chain to the netdump server 274 * Note: can't handle fragmentation; fails if the packet is larger than 275 * nd_ifp->if_mtu after adding the UDP/IP headers 276 * 277 * Parameters: 278 * m mbuf chain 279 * 280 * Returns: 281 * int see errno.h, 0 for success 282 */ 283 static int 284 netdump_udp_output(struct mbuf *m) 285 { 286 struct udpiphdr *ui; 287 struct ip *ip; 288 289 MPASS(netdump_enabled()); 290 291 M_PREPEND(m, sizeof(struct udpiphdr), M_NOWAIT); 292 if (m == NULL) { 293 printf("%s: out of mbufs\n", __func__); 294 return (ENOBUFS); 295 } 296 297 if (m->m_pkthdr.len > nd_ifp->if_mtu) { 298 printf("netdump_udp_output: Packet is too big: %d > MTU %u\n", 299 m->m_pkthdr.len, nd_ifp->if_mtu); 300 m_freem(m); 301 return (ENOBUFS); 302 } 303 304 ui = mtod(m, struct udpiphdr *); 305 bzero(ui->ui_x1, sizeof(ui->ui_x1)); 306 ui->ui_pr = IPPROTO_UDP; 307 ui->ui_len = htons(m->m_pkthdr.len - sizeof(struct ip)); 308 ui->ui_ulen = ui->ui_len; 309 ui->ui_src = nd_client; 310 ui->ui_dst = nd_server; 311 /* Use this src port so that the server can connect() the socket */ 312 ui->ui_sport = htons(NETDUMP_ACKPORT); 313 ui->ui_dport = htons(nd_server_port); 314 ui->ui_sum = 0; 315 if ((ui->ui_sum = in_cksum(m, m->m_pkthdr.len)) == 0) 316 ui->ui_sum = 0xffff; 317 318 ip = mtod(m, struct ip *); 319 ip->ip_v = IPVERSION; 320 ip->ip_hl = sizeof(struct ip) >> 2; 321 ip->ip_tos = 0; 322 ip->ip_len = htons(m->m_pkthdr.len); 323 ip->ip_id = 0; 324 ip->ip_off = htons(IP_DF); 325 ip->ip_ttl = 255; 326 ip->ip_sum = 0; 327 ip->ip_sum = in_cksum(m, sizeof(struct ip)); 328 329 return (netdump_ether_output(m, nd_ifp, nd_gw_mac, ETHERTYPE_IP)); 330 } 331 332 /* 333 * Builds and sends a single ARP request to locate the server 334 * 335 * Return value: 336 * 0 on success 337 * errno on error 338 */ 339 static int 340 netdump_send_arp(in_addr_t dst) 341 { 342 struct ether_addr bcast; 343 struct mbuf *m; 344 struct arphdr *ah; 345 int pktlen; 346 347 MPASS(netdump_enabled()); 348 349 /* Fill-up a broadcast address. */ 350 memset(&bcast, 0xFF, ETHER_ADDR_LEN); 351 m = m_gethdr(M_NOWAIT, MT_DATA); 352 if (m == NULL) { 353 printf("netdump_send_arp: Out of mbufs\n"); 354 return (ENOBUFS); 355 } 356 pktlen = arphdr_len2(ETHER_ADDR_LEN, sizeof(struct in_addr)); 357 m->m_len = pktlen; 358 m->m_pkthdr.len = pktlen; 359 MH_ALIGN(m, pktlen); 360 ah = mtod(m, struct arphdr *); 361 ah->ar_hrd = htons(ARPHRD_ETHER); 362 ah->ar_pro = htons(ETHERTYPE_IP); 363 ah->ar_hln = ETHER_ADDR_LEN; 364 ah->ar_pln = sizeof(struct in_addr); 365 ah->ar_op = htons(ARPOP_REQUEST); 366 memcpy(ar_sha(ah), IF_LLADDR(nd_ifp), ETHER_ADDR_LEN); 367 ((struct in_addr *)ar_spa(ah))->s_addr = nd_client.s_addr; 368 bzero(ar_tha(ah), ETHER_ADDR_LEN); 369 ((struct in_addr *)ar_tpa(ah))->s_addr = dst; 370 return (netdump_ether_output(m, nd_ifp, bcast, ETHERTYPE_ARP)); 371 } 372 373 /* 374 * Sends ARP requests to locate the server and waits for a response. 375 * We first try to ARP the server itself, and fall back to the provided 376 * gateway if the server appears to be off-link. 377 * 378 * Return value: 379 * 0 on success 380 * errno on error 381 */ 382 static int 383 netdump_arp_gw(void) 384 { 385 in_addr_t dst; 386 int error, polls, retries; 387 388 dst = nd_server.s_addr; 389 restart: 390 for (retries = 0; retries < nd_arp_retries && have_gw_mac == 0; 391 retries++) { 392 error = netdump_send_arp(dst); 393 if (error != 0) 394 return (error); 395 for (polls = 0; polls < nd_polls && have_gw_mac == 0; polls++) { 396 netdump_network_poll(); 397 DELAY(500); 398 } 399 if (have_gw_mac == 0) 400 printf("(ARP retry)"); 401 } 402 if (have_gw_mac != 0) 403 return (0); 404 if (dst == nd_server.s_addr && nd_server.s_addr != nd_gateway.s_addr) { 405 printf("Failed to ARP server, trying to reach gateway...\n"); 406 dst = nd_gateway.s_addr; 407 goto restart; 408 } 409 410 printf("\nARP timed out.\n"); 411 return (ETIMEDOUT); 412 } 413 414 /* 415 * Dummy free function for netdump clusters. 416 */ 417 static void 418 netdump_mbuf_free(struct mbuf *m __unused) 419 { 420 } 421 422 /* 423 * Construct and reliably send a netdump packet. May fail from a resource 424 * shortage or extreme number of unacknowledged retransmissions. Wait for 425 * an acknowledgement before returning. Splits packets into chunks small 426 * enough to be sent without fragmentation (looks up the interface MTU) 427 * 428 * Parameters: 429 * type netdump packet type (HERALD, FINISHED, or VMCORE) 430 * offset vmcore data offset (bytes) 431 * data vmcore data 432 * datalen vmcore data size (bytes) 433 * 434 * Returns: 435 * int see errno.h, 0 for success 436 */ 437 static int 438 netdump_send(uint32_t type, off_t offset, unsigned char *data, uint32_t datalen) 439 { 440 struct netdump_msg_hdr *nd_msg_hdr; 441 struct mbuf *m, *m2; 442 uint64_t want_acks; 443 uint32_t i, pktlen, sent_so_far; 444 int retries, polls, error; 445 446 want_acks = 0; 447 rcvd_acks = 0; 448 retries = 0; 449 450 MPASS(netdump_enabled()); 451 452 retransmit: 453 /* Chunks can be too big to fit in packets. */ 454 for (i = sent_so_far = 0; sent_so_far < datalen || 455 (i == 0 && datalen == 0); i++) { 456 pktlen = datalen - sent_so_far; 457 458 /* First bound: the packet structure. */ 459 pktlen = min(pktlen, NETDUMP_DATASIZE); 460 461 /* Second bound: the interface MTU (assume no IP options). */ 462 pktlen = min(pktlen, nd_ifp->if_mtu - sizeof(struct udpiphdr) - 463 sizeof(struct netdump_msg_hdr)); 464 465 /* 466 * Check if it is retransmitting and this has been ACKed 467 * already. 468 */ 469 if ((rcvd_acks & (1 << i)) != 0) { 470 sent_so_far += pktlen; 471 continue; 472 } 473 474 /* 475 * Get and fill a header mbuf, then chain data as an extended 476 * mbuf. 477 */ 478 m = m_gethdr(M_NOWAIT, MT_DATA); 479 if (m == NULL) { 480 printf("netdump_send: Out of mbufs\n"); 481 return (ENOBUFS); 482 } 483 m->m_len = sizeof(struct netdump_msg_hdr); 484 m->m_pkthdr.len = sizeof(struct netdump_msg_hdr); 485 MH_ALIGN(m, sizeof(struct netdump_msg_hdr)); 486 nd_msg_hdr = mtod(m, struct netdump_msg_hdr *); 487 nd_msg_hdr->mh_seqno = htonl(nd_seqno + i); 488 nd_msg_hdr->mh_type = htonl(type); 489 nd_msg_hdr->mh_offset = htobe64(offset + sent_so_far); 490 nd_msg_hdr->mh_len = htonl(pktlen); 491 nd_msg_hdr->mh__pad = 0; 492 493 if (pktlen != 0) { 494 m2 = m_get(M_NOWAIT, MT_DATA); 495 if (m2 == NULL) { 496 m_freem(m); 497 printf("netdump_send: Out of mbufs\n"); 498 return (ENOBUFS); 499 } 500 MEXTADD(m2, data + sent_so_far, pktlen, 501 netdump_mbuf_free, NULL, NULL, 0, EXT_DISPOSABLE); 502 m2->m_len = pktlen; 503 504 m_cat(m, m2); 505 m->m_pkthdr.len += pktlen; 506 } 507 error = netdump_udp_output(m); 508 if (error != 0) 509 return (error); 510 511 /* Note that we're waiting for this packet in the bitfield. */ 512 want_acks |= (1 << i); 513 sent_so_far += pktlen; 514 } 515 if (i >= NETDUMP_MAX_IN_FLIGHT) 516 printf("Warning: Sent more than %d packets (%d). " 517 "Acknowledgements will fail unless the size of " 518 "rcvd_acks/want_acks is increased.\n", 519 NETDUMP_MAX_IN_FLIGHT, i); 520 521 /* 522 * Wait for acks. A *real* window would speed things up considerably. 523 */ 524 polls = 0; 525 while (rcvd_acks != want_acks) { 526 if (polls++ > nd_polls) { 527 if (retries++ > nd_retries) 528 return (ETIMEDOUT); 529 printf(". "); 530 goto retransmit; 531 } 532 netdump_network_poll(); 533 DELAY(500); 534 } 535 nd_seqno += i; 536 return (0); 537 } 538 539 /* 540 * Handler for IP packets: checks their sanity and then processes any netdump 541 * ACK packets it finds. 542 * 543 * It needs to replicate partially the behaviour of ip_input() and 544 * udp_input(). 545 * 546 * Parameters: 547 * mb a pointer to an mbuf * containing the packet received 548 * Updates *mb if m_pullup et al change the pointer 549 * Assumes the calling function will take care of freeing the mbuf 550 */ 551 static void 552 netdump_handle_ip(struct mbuf **mb) 553 { 554 struct ip *ip; 555 struct udpiphdr *udp; 556 struct netdump_ack *nd_ack; 557 struct mbuf *m; 558 int rcv_ackno; 559 unsigned short hlen; 560 561 /* IP processing. */ 562 m = *mb; 563 if (m->m_pkthdr.len < sizeof(struct ip)) { 564 NETDDEBUG("dropping packet too small for IP header\n"); 565 return; 566 } 567 if (m->m_len < sizeof(struct ip)) { 568 m = m_pullup(m, sizeof(struct ip)); 569 *mb = m; 570 if (m == NULL) { 571 NETDDEBUG("m_pullup failed\n"); 572 return; 573 } 574 } 575 ip = mtod(m, struct ip *); 576 577 /* IP version. */ 578 if (ip->ip_v != IPVERSION) { 579 NETDDEBUG("bad IP version %d\n", ip->ip_v); 580 return; 581 } 582 583 /* Header length. */ 584 hlen = ip->ip_hl << 2; 585 if (hlen < sizeof(struct ip)) { 586 NETDDEBUG("bad IP header length (%hu)\n", hlen); 587 return; 588 } 589 if (hlen > m->m_len) { 590 m = m_pullup(m, hlen); 591 *mb = m; 592 if (m == NULL) { 593 NETDDEBUG("m_pullup failed\n"); 594 return; 595 } 596 ip = mtod(m, struct ip *); 597 } 598 /* Ignore packets with IP options. */ 599 if (hlen > sizeof(struct ip)) { 600 NETDDEBUG("drop packet with IP options\n"); 601 return; 602 } 603 604 #ifdef INVARIANTS 605 if ((IN_LOOPBACK(ntohl(ip->ip_dst.s_addr)) || 606 IN_LOOPBACK(ntohl(ip->ip_src.s_addr))) && 607 (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) { 608 NETDDEBUG("Bad IP header (RFC1122)\n"); 609 return; 610 } 611 #endif 612 613 /* Checksum. */ 614 if ((m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) != 0) { 615 if ((m->m_pkthdr.csum_flags & CSUM_IP_VALID) == 0) { 616 NETDDEBUG("bad IP checksum\n"); 617 return; 618 } 619 } else { 620 /* XXX */ ; 621 } 622 623 /* Convert fields to host byte order. */ 624 ip->ip_len = ntohs(ip->ip_len); 625 if (ip->ip_len < hlen) { 626 NETDDEBUG("IP packet smaller (%hu) than header (%hu)\n", 627 ip->ip_len, hlen); 628 return; 629 } 630 if (m->m_pkthdr.len < ip->ip_len) { 631 NETDDEBUG("IP packet bigger (%hu) than ethernet packet (%d)\n", 632 ip->ip_len, m->m_pkthdr.len); 633 return; 634 } 635 if (m->m_pkthdr.len > ip->ip_len) { 636 637 /* Truncate the packet to the IP length. */ 638 if (m->m_len == m->m_pkthdr.len) { 639 m->m_len = ip->ip_len; 640 m->m_pkthdr.len = ip->ip_len; 641 } else 642 m_adj(m, ip->ip_len - m->m_pkthdr.len); 643 } 644 645 ip->ip_off = ntohs(ip->ip_off); 646 647 /* Check that the source is the server's IP. */ 648 if (ip->ip_src.s_addr != nd_server.s_addr) { 649 NETDDEBUG("drop packet not from server (from 0x%x)\n", 650 ip->ip_src.s_addr); 651 return; 652 } 653 654 /* Check if the destination IP is ours. */ 655 if (ip->ip_dst.s_addr != nd_client.s_addr) { 656 NETDDEBUGV("drop packet not to our IP\n"); 657 return; 658 } 659 660 if (ip->ip_p != IPPROTO_UDP) { 661 NETDDEBUG("drop non-UDP packet\n"); 662 return; 663 } 664 665 /* Do not deal with fragments. */ 666 if ((ip->ip_off & (IP_MF | IP_OFFMASK)) != 0) { 667 NETDDEBUG("drop fragmented packet\n"); 668 return; 669 } 670 671 /* UDP custom is to have packet length not include IP header. */ 672 ip->ip_len -= hlen; 673 674 /* UDP processing. */ 675 676 /* Get IP and UDP headers together, along with the netdump packet. */ 677 if (m->m_pkthdr.len < 678 sizeof(struct udpiphdr) + sizeof(struct netdump_ack)) { 679 NETDDEBUG("ignoring small packet\n"); 680 return; 681 } 682 if (m->m_len < sizeof(struct udpiphdr) + sizeof(struct netdump_ack)) { 683 m = m_pullup(m, sizeof(struct udpiphdr) + 684 sizeof(struct netdump_ack)); 685 *mb = m; 686 if (m == NULL) { 687 NETDDEBUG("m_pullup failed\n"); 688 return; 689 } 690 } 691 udp = mtod(m, struct udpiphdr *); 692 693 if (ntohs(udp->ui_u.uh_dport) != NETDUMP_ACKPORT) { 694 NETDDEBUG("not on the netdump port.\n"); 695 return; 696 } 697 698 /* Netdump processing. */ 699 700 /* 701 * Packet is meant for us. Extract the ack sequence number and the 702 * port number if necessary. 703 */ 704 nd_ack = (struct netdump_ack *)(mtod(m, caddr_t) + 705 sizeof(struct udpiphdr)); 706 rcv_ackno = ntohl(nd_ack->na_seqno); 707 if (nd_server_port == NETDUMP_PORT) 708 nd_server_port = ntohs(udp->ui_u.uh_sport); 709 if (rcv_ackno >= nd_seqno + NETDUMP_MAX_IN_FLIGHT) 710 printf("%s: ACK %d too far in future!\n", __func__, rcv_ackno); 711 else if (rcv_ackno >= nd_seqno) { 712 /* We're interested in this ack. Record it. */ 713 rcvd_acks |= 1 << (rcv_ackno - nd_seqno); 714 } 715 } 716 717 /* 718 * Handler for ARP packets: checks their sanity and then 719 * 1. If the ARP is a request for our IP, respond with our MAC address 720 * 2. If the ARP is a response from our server, record its MAC address 721 * 722 * It needs to replicate partially the behaviour of arpintr() and 723 * in_arpinput(). 724 * 725 * Parameters: 726 * mb a pointer to an mbuf * containing the packet received 727 * Updates *mb if m_pullup et al change the pointer 728 * Assumes the calling function will take care of freeing the mbuf 729 */ 730 static void 731 netdump_handle_arp(struct mbuf **mb) 732 { 733 char buf[INET_ADDRSTRLEN]; 734 struct in_addr isaddr, itaddr, myaddr; 735 struct ether_addr dst; 736 struct mbuf *m; 737 struct arphdr *ah; 738 struct ifnet *ifp; 739 uint8_t *enaddr; 740 int req_len, op; 741 742 m = *mb; 743 ifp = m->m_pkthdr.rcvif; 744 if (m->m_len < sizeof(struct arphdr)) { 745 m = m_pullup(m, sizeof(struct arphdr)); 746 *mb = m; 747 if (m == NULL) { 748 NETDDEBUG("runt packet: m_pullup failed\n"); 749 return; 750 } 751 } 752 753 ah = mtod(m, struct arphdr *); 754 if (ntohs(ah->ar_hrd) != ARPHRD_ETHER) { 755 NETDDEBUG("unknown hardware address 0x%2D)\n", 756 (unsigned char *)&ah->ar_hrd, ""); 757 return; 758 } 759 if (ntohs(ah->ar_pro) != ETHERTYPE_IP) { 760 NETDDEBUG("drop ARP for unknown protocol %d\n", 761 ntohs(ah->ar_pro)); 762 return; 763 } 764 req_len = arphdr_len2(ifp->if_addrlen, sizeof(struct in_addr)); 765 if (m->m_len < req_len) { 766 m = m_pullup(m, req_len); 767 *mb = m; 768 if (m == NULL) { 769 NETDDEBUG("runt packet: m_pullup failed\n"); 770 return; 771 } 772 } 773 ah = mtod(m, struct arphdr *); 774 775 op = ntohs(ah->ar_op); 776 memcpy(&isaddr, ar_spa(ah), sizeof(isaddr)); 777 memcpy(&itaddr, ar_tpa(ah), sizeof(itaddr)); 778 enaddr = (uint8_t *)IF_LLADDR(ifp); 779 myaddr = nd_client; 780 781 if (memcmp(ar_sha(ah), enaddr, ifp->if_addrlen) == 0) { 782 NETDDEBUG("ignoring ARP from myself\n"); 783 return; 784 } 785 786 if (isaddr.s_addr == nd_client.s_addr) { 787 printf("%s: %*D is using my IP address %s!\n", __func__, 788 ifp->if_addrlen, (u_char *)ar_sha(ah), ":", 789 inet_ntoa_r(isaddr, buf)); 790 return; 791 } 792 793 if (memcmp(ar_sha(ah), ifp->if_broadcastaddr, ifp->if_addrlen) == 0) { 794 NETDDEBUG("ignoring ARP from broadcast address\n"); 795 return; 796 } 797 798 if (op == ARPOP_REPLY) { 799 if (isaddr.s_addr != nd_gateway.s_addr && 800 isaddr.s_addr != nd_server.s_addr) { 801 inet_ntoa_r(isaddr, buf); 802 NETDDEBUG( 803 "ignoring ARP reply from %s (not netdump server)\n", 804 buf); 805 return; 806 } 807 memcpy(nd_gw_mac.octet, ar_sha(ah), 808 min(ah->ar_hln, ETHER_ADDR_LEN)); 809 have_gw_mac = 1; 810 NETDDEBUG("got server MAC address %6D\n", nd_gw_mac.octet, ":"); 811 return; 812 } 813 814 if (op != ARPOP_REQUEST) { 815 NETDDEBUG("ignoring ARP non-request/reply\n"); 816 return; 817 } 818 819 if (itaddr.s_addr != nd_client.s_addr) { 820 NETDDEBUG("ignoring ARP not to our IP\n"); 821 return; 822 } 823 824 memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln); 825 memcpy(ar_sha(ah), enaddr, ah->ar_hln); 826 memcpy(ar_tpa(ah), ar_spa(ah), ah->ar_pln); 827 memcpy(ar_spa(ah), &itaddr, ah->ar_pln); 828 ah->ar_op = htons(ARPOP_REPLY); 829 ah->ar_pro = htons(ETHERTYPE_IP); 830 m->m_flags &= ~(M_BCAST|M_MCAST); 831 m->m_len = arphdr_len(ah); 832 m->m_pkthdr.len = m->m_len; 833 834 memcpy(dst.octet, ar_tha(ah), ETHER_ADDR_LEN); 835 netdump_ether_output(m, ifp, dst, ETHERTYPE_ARP); 836 *mb = NULL; 837 } 838 839 /* 840 * Handler for incoming packets directly from the network adapter 841 * Identifies the packet type (IP or ARP) and passes it along to one of the 842 * helper functions netdump_handle_ip or netdump_handle_arp. 843 * 844 * It needs to replicate partially the behaviour of ether_input() and 845 * ether_demux(). 846 * 847 * Parameters: 848 * ifp the interface the packet came from (should be nd_ifp) 849 * m an mbuf containing the packet received 850 */ 851 static void 852 netdump_pkt_in(struct ifnet *ifp, struct mbuf *m) 853 { 854 struct ifreq ifr; 855 struct ether_header *eh; 856 u_short etype; 857 858 /* Ethernet processing. */ 859 if ((m->m_flags & M_PKTHDR) == 0) { 860 NETDDEBUG_IF(ifp, "discard frame without packet header\n"); 861 goto done; 862 } 863 if (m->m_len < ETHER_HDR_LEN) { 864 NETDDEBUG_IF(ifp, 865 "discard frame without leading eth header (len %u pktlen %u)\n", 866 m->m_len, m->m_pkthdr.len); 867 goto done; 868 } 869 if ((m->m_flags & M_HASFCS) != 0) { 870 m_adj(m, -ETHER_CRC_LEN); 871 m->m_flags &= ~M_HASFCS; 872 } 873 eh = mtod(m, struct ether_header *); 874 etype = ntohs(eh->ether_type); 875 if ((m->m_flags & M_VLANTAG) != 0 || etype == ETHERTYPE_VLAN) { 876 NETDDEBUG_IF(ifp, "ignoring vlan packets\n"); 877 goto done; 878 } 879 if (if_gethwaddr(ifp, &ifr) != 0) { 880 NETDDEBUG_IF(ifp, "failed to get hw addr for interface\n"); 881 goto done; 882 } 883 if (memcmp(ifr.ifr_addr.sa_data, eh->ether_dhost, 884 ETHER_ADDR_LEN) != 0) { 885 NETDDEBUG_IF(ifp, 886 "discard frame with incorrect destination addr\n"); 887 goto done; 888 } 889 890 /* Done ethernet processing. Strip off the ethernet header. */ 891 m_adj(m, ETHER_HDR_LEN); 892 switch (etype) { 893 case ETHERTYPE_ARP: 894 netdump_handle_arp(&m); 895 break; 896 case ETHERTYPE_IP: 897 netdump_handle_ip(&m); 898 break; 899 default: 900 NETDDEBUG_IF(ifp, "dropping unknown ethertype %hu\n", etype); 901 break; 902 } 903 done: 904 if (m != NULL) 905 m_freem(m); 906 } 907 908 /* 909 * After trapping, instead of assuming that most of the network stack is sane, 910 * we just poll the driver directly for packets. 911 */ 912 static void 913 netdump_network_poll(void) 914 { 915 916 MPASS(netdump_enabled()); 917 918 nd_ifp->if_netdump_methods->nd_poll(nd_ifp, 1000); 919 } 920 921 /*- 922 * Dumping specific primitives. 923 */ 924 925 /* 926 * Callback from dumpsys() to dump a chunk of memory. 927 * Copies it out to our static buffer then sends it across the network. 928 * Detects the initial KDH and makes sure it is given a special packet type. 929 * 930 * Parameters: 931 * priv Unused. Optional private pointer. 932 * virtual Virtual address (where to read the data from) 933 * physical Unused. Physical memory address. 934 * offset Offset from start of core file 935 * length Data length 936 * 937 * Return value: 938 * 0 on success 939 * errno on error 940 */ 941 static int 942 netdump_dumper(void *priv __unused, void *virtual, 943 vm_offset_t physical __unused, off_t offset, size_t length) 944 { 945 int error; 946 947 NETDDEBUGV("netdump_dumper(NULL, %p, NULL, %ju, %zu)\n", 948 virtual, (uintmax_t)offset, length); 949 950 if (virtual == NULL) { 951 if (nd_conf.nd_buf_len != 0) { 952 error = netdump_send(NETDUMP_VMCORE, nd_conf.nd_tx_off, nd_buf, 953 nd_conf.nd_buf_len); 954 if (error != 0) { 955 dump_failed = 1; 956 } 957 } 958 959 if (dump_failed != 0) 960 printf("failed to dump the kernel core\n"); 961 else if (netdump_send(NETDUMP_FINISHED, 0, NULL, 0) != 0) 962 printf("failed to close the transaction\n"); 963 else 964 printf("\nnetdump finished.\n"); 965 netdump_cleanup(); 966 return (0); 967 } 968 if (length > sizeof(nd_buf)) 969 return (ENOSPC); 970 971 if (nd_conf.nd_buf_len + length > sizeof(nd_buf) || 972 (nd_conf.nd_buf_len != 0 && nd_conf.nd_tx_off + 973 nd_conf.nd_buf_len != offset)) { 974 error = netdump_send(NETDUMP_VMCORE, nd_conf.nd_tx_off, nd_buf, 975 nd_conf.nd_buf_len); 976 if (error != 0) { 977 dump_failed = 1; 978 return (error); 979 } 980 nd_conf.nd_buf_len = 0; 981 nd_conf.nd_tx_off = offset; 982 } 983 984 memmove(nd_buf + nd_conf.nd_buf_len, virtual, length); 985 nd_conf.nd_buf_len += length; 986 987 return (0); 988 } 989 990 /* 991 * Perform any initalization needed prior to transmitting the kernel core. 992 */ 993 static int 994 netdump_start(struct dumperinfo *di) 995 { 996 char *path; 997 char buf[INET_ADDRSTRLEN]; 998 uint32_t len; 999 int error; 1000 1001 error = 0; 1002 1003 /* Check if the dumping is allowed to continue. */ 1004 if (!netdump_enabled()) 1005 return (EINVAL); 1006 1007 if (panicstr == NULL) { 1008 printf( 1009 "netdump_start: netdump may only be used after a panic\n"); 1010 return (EINVAL); 1011 } 1012 1013 if (nd_server.s_addr == INADDR_ANY) { 1014 printf("netdump_start: can't netdump; no server IP given\n"); 1015 return (EINVAL); 1016 } 1017 if (nd_client.s_addr == INADDR_ANY) { 1018 printf("netdump_start: can't netdump; no client IP given\n"); 1019 return (EINVAL); 1020 } 1021 1022 /* We start dumping at offset 0. */ 1023 di->dumpoff = 0; 1024 1025 nd_seqno = 1; 1026 1027 /* 1028 * nd_server_port could have switched after the first ack the 1029 * first time it gets called. Adjust it accordingly. 1030 */ 1031 nd_server_port = NETDUMP_PORT; 1032 1033 /* Switch to the netdump mbuf zones. */ 1034 netdump_mbuf_dump(); 1035 1036 nd_ifp->if_netdump_methods->nd_event(nd_ifp, NETDUMP_START); 1037 1038 /* Make the card use *our* receive callback. */ 1039 drv_if_input = nd_ifp->if_input; 1040 nd_ifp->if_input = netdump_pkt_in; 1041 1042 if (nd_gateway.s_addr == INADDR_ANY) { 1043 restore_gw_addr = 1; 1044 nd_gateway.s_addr = nd_server.s_addr; 1045 } 1046 1047 printf("netdump in progress. searching for server...\n"); 1048 if (netdump_arp_gw()) { 1049 printf("failed to locate server MAC address\n"); 1050 error = EINVAL; 1051 goto trig_abort; 1052 } 1053 1054 if (nd_path[0] != '\0') { 1055 path = nd_path; 1056 len = strlen(path) + 1; 1057 } else { 1058 path = NULL; 1059 len = 0; 1060 } 1061 if (netdump_send(NETDUMP_HERALD, 0, path, len) != 0) { 1062 printf("failed to contact netdump server\n"); 1063 error = EINVAL; 1064 goto trig_abort; 1065 } 1066 printf("netdumping to %s (%6D)\n", inet_ntoa_r(nd_server, buf), 1067 nd_gw_mac.octet, ":"); 1068 return (0); 1069 1070 trig_abort: 1071 netdump_cleanup(); 1072 return (error); 1073 } 1074 1075 static int 1076 netdump_write_headers(struct dumperinfo *di, struct kerneldumpheader *kdh, 1077 void *key, uint32_t keysize) 1078 { 1079 int error; 1080 1081 memcpy(nd_buf, kdh, sizeof(*kdh)); 1082 error = netdump_send(NETDUMP_KDH, 0, nd_buf, sizeof(*kdh)); 1083 if (error == 0 && keysize > 0) { 1084 if (keysize > sizeof(nd_buf)) 1085 return (EINVAL); 1086 memcpy(nd_buf, key, keysize); 1087 error = netdump_send(NETDUMP_EKCD_KEY, 0, nd_buf, keysize); 1088 } 1089 return (error); 1090 } 1091 1092 /* 1093 * Cleanup routine for a possibly failed netdump. 1094 */ 1095 static void 1096 netdump_cleanup(void) 1097 { 1098 1099 if (restore_gw_addr != 0) { 1100 nd_gateway.s_addr = INADDR_ANY; 1101 restore_gw_addr = 0; 1102 } 1103 if (drv_if_input != NULL) { 1104 nd_ifp->if_input = drv_if_input; 1105 drv_if_input = NULL; 1106 } 1107 nd_ifp->if_netdump_methods->nd_event(nd_ifp, NETDUMP_END); 1108 } 1109 1110 /*- 1111 * KLD specific code. 1112 */ 1113 1114 static struct cdevsw netdump_cdevsw = { 1115 .d_version = D_VERSION, 1116 .d_ioctl = netdump_ioctl, 1117 .d_name = "netdump", 1118 }; 1119 1120 static struct cdev *netdump_cdev; 1121 1122 static void 1123 netdump_unconfigure(void) 1124 { 1125 struct diocskerneldump_arg kda; 1126 1127 NETDUMP_ASSERT_WLOCKED(); 1128 KASSERT(netdump_enabled(), ("%s: nd_ifp NULL", __func__)); 1129 1130 bzero(&kda, sizeof(kda)); 1131 kda.kda_index = KDA_REMOVE_DEV; 1132 (void)dumper_remove(nd_conf.ndc_iface, &kda); 1133 1134 netdump_mbuf_drain(); 1135 1136 if_rele(nd_ifp); 1137 nd_ifp = NULL; 1138 1139 bzero(&nd_conf, sizeof(nd_conf)); 1140 } 1141 1142 static void 1143 netdump_ifdetach(void *arg __unused, struct ifnet *ifp) 1144 { 1145 1146 NETDUMP_WLOCK(); 1147 if (ifp == nd_ifp) 1148 netdump_unconfigure(); 1149 NETDUMP_WUNLOCK(); 1150 } 1151 1152 static int 1153 netdump_configure(struct diocskerneldump_arg *conf, struct thread *td) 1154 { 1155 struct ifnet *ifp; 1156 1157 NETDUMP_ASSERT_WLOCKED(); 1158 1159 CURVNET_SET(TD_TO_VNET(td)); 1160 if (!IS_DEFAULT_VNET(curvnet)) { 1161 CURVNET_RESTORE(); 1162 return (EINVAL); 1163 } 1164 ifp = ifunit_ref(conf->kda_iface); 1165 CURVNET_RESTORE(); 1166 1167 if (ifp == NULL) 1168 return (ENOENT); 1169 if ((if_getflags(ifp) & IFF_UP) == 0) { 1170 if_rele(ifp); 1171 return (ENXIO); 1172 } 1173 if (!netdump_supported_nic(ifp) || ifp->if_type != IFT_ETHER) { 1174 if_rele(ifp); 1175 return (ENODEV); 1176 } 1177 1178 if (netdump_enabled()) 1179 if_rele(nd_ifp); 1180 nd_ifp = ifp; 1181 1182 netdump_reinit_internal(ifp); 1183 1184 #define COPY_SIZED(elm) do { \ 1185 _Static_assert(sizeof(nd_conf.ndc_ ## elm) == \ 1186 sizeof(conf->kda_ ## elm), "elm " __XSTRING(elm) " mismatch"); \ 1187 memcpy(&nd_conf.ndc_ ## elm, &conf->kda_ ## elm, \ 1188 sizeof(nd_conf.ndc_ ## elm)); \ 1189 } while (0) 1190 COPY_SIZED(iface); 1191 COPY_SIZED(server); 1192 COPY_SIZED(client); 1193 COPY_SIZED(gateway); 1194 COPY_SIZED(af); 1195 #undef COPY_SIZED 1196 1197 return (0); 1198 } 1199 1200 /* 1201 * Reinitialize the mbuf pool used by drivers while dumping. This is called 1202 * from the generic ioctl handler for SIOCSIFMTU after any NIC driver has 1203 * reconfigured itself. (I.e., it may not be a configured netdump interface.) 1204 */ 1205 void 1206 netdump_reinit(struct ifnet *ifp) 1207 { 1208 1209 NETDUMP_WLOCK(); 1210 if (ifp != nd_ifp) { 1211 NETDUMP_WUNLOCK(); 1212 return; 1213 } 1214 netdump_reinit_internal(ifp); 1215 NETDUMP_WUNLOCK(); 1216 } 1217 1218 static void 1219 netdump_reinit_internal(struct ifnet *ifp) 1220 { 1221 int clsize, nmbuf, ncl, nrxr; 1222 1223 NETDUMP_ASSERT_WLOCKED(); 1224 1225 ifp->if_netdump_methods->nd_init(ifp, &nrxr, &ncl, &clsize); 1226 KASSERT(nrxr > 0, ("invalid receive ring count %d", nrxr)); 1227 1228 /* 1229 * We need two headers per message on the transmit side. Multiply by 1230 * four to give us some breathing room. 1231 */ 1232 nmbuf = ncl * (4 + nrxr); 1233 ncl *= nrxr; 1234 netdump_mbuf_reinit(nmbuf, ncl, clsize); 1235 } 1236 1237 /* 1238 * ioctl(2) handler for the netdump device. This is currently only used to 1239 * register netdump as a dump device. 1240 * 1241 * Parameters: 1242 * dev, Unused. 1243 * cmd, The ioctl to be handled. 1244 * addr, The parameter for the ioctl. 1245 * flags, Unused. 1246 * td, The thread invoking this ioctl. 1247 * 1248 * Returns: 1249 * 0 on success, and an errno value on failure. 1250 */ 1251 static int 1252 netdump_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr, 1253 int flags __unused, struct thread *td) 1254 { 1255 struct diocskerneldump_arg kda_copy, *conf; 1256 struct dumperinfo dumper; 1257 uint8_t *encryptedkey; 1258 int error; 1259 #ifdef COMPAT_FREEBSD11 1260 u_int u; 1261 #endif 1262 #ifdef COMPAT_FREEBSD12 1263 struct diocskerneldump_arg_freebsd12 *kda12; 1264 struct netdump_conf_freebsd12 *conf12; 1265 #endif 1266 1267 conf = NULL; 1268 error = 0; 1269 NETDUMP_WLOCK(); 1270 1271 switch (cmd) { 1272 #ifdef COMPAT_FREEBSD11 1273 case DIOCSKERNELDUMP_FREEBSD11: 1274 gone_in(13, "11.x ABI compatibility"); 1275 u = *(u_int *)addr; 1276 if (u != 0) { 1277 error = ENXIO; 1278 break; 1279 } 1280 if (netdump_enabled()) 1281 netdump_unconfigure(); 1282 break; 1283 #endif 1284 #ifdef COMPAT_FREEBSD12 1285 /* 1286 * Used by dumpon(8) in 12.x for clearing previous 1287 * configuration -- then NETDUMPSCONF_FREEBSD12 is used to 1288 * actually configure netdump. 1289 */ 1290 case DIOCSKERNELDUMP_FREEBSD12: 1291 gone_in(14, "12.x ABI compatibility"); 1292 1293 kda12 = (void *)addr; 1294 if (kda12->kda12_enable) { 1295 error = ENXIO; 1296 break; 1297 } 1298 if (netdump_enabled()) 1299 netdump_unconfigure(); 1300 break; 1301 1302 case NETDUMPGCONF_FREEBSD12: 1303 gone_in(14, "FreeBSD 12.x ABI compat"); 1304 conf12 = (void *)addr; 1305 1306 if (!netdump_enabled()) { 1307 error = ENXIO; 1308 break; 1309 } 1310 if (nd_conf.ndc_af != AF_INET) { 1311 error = EOPNOTSUPP; 1312 break; 1313 } 1314 1315 strlcpy(conf12->ndc12_iface, nd_ifp->if_xname, 1316 sizeof(conf12->ndc12_iface)); 1317 memcpy(&conf12->ndc12_server, &nd_server, 1318 sizeof(conf12->ndc12_server)); 1319 memcpy(&conf12->ndc12_client, &nd_client, 1320 sizeof(conf12->ndc12_client)); 1321 memcpy(&conf12->ndc12_gateway, &nd_gateway, 1322 sizeof(conf12->ndc12_gateway)); 1323 break; 1324 #endif 1325 case DIOCGKERNELDUMP: 1326 conf = (void *)addr; 1327 /* 1328 * For now, index is ignored; netdump doesn't support multiple 1329 * configurations (yet). 1330 */ 1331 if (!netdump_enabled()) { 1332 error = ENXIO; 1333 conf = NULL; 1334 break; 1335 } 1336 1337 strlcpy(conf->kda_iface, nd_ifp->if_xname, 1338 sizeof(conf->kda_iface)); 1339 memcpy(&conf->kda_server, &nd_server, sizeof(nd_server)); 1340 memcpy(&conf->kda_client, &nd_client, sizeof(nd_client)); 1341 memcpy(&conf->kda_gateway, &nd_gateway, sizeof(nd_gateway)); 1342 conf->kda_af = nd_conf.ndc_af; 1343 conf = NULL; 1344 break; 1345 1346 #ifdef COMPAT_FREEBSD12 1347 case NETDUMPSCONF_FREEBSD12: 1348 gone_in(14, "FreeBSD 12.x ABI compat"); 1349 1350 conf12 = (struct netdump_conf_freebsd12 *)addr; 1351 1352 _Static_assert(offsetof(struct diocskerneldump_arg, kda_server) 1353 == offsetof(struct netdump_conf_freebsd12, ndc12_server), 1354 "simplifying assumption"); 1355 1356 memset(&kda_copy, 0, sizeof(kda_copy)); 1357 memcpy(&kda_copy, conf12, 1358 offsetof(struct diocskerneldump_arg, kda_server)); 1359 1360 /* 12.x ABI could only configure IPv4 (INET) netdump. */ 1361 kda_copy.kda_af = AF_INET; 1362 memcpy(&kda_copy.kda_server.in4, &conf12->ndc12_server, 1363 sizeof(struct in_addr)); 1364 memcpy(&kda_copy.kda_client.in4, &conf12->ndc12_client, 1365 sizeof(struct in_addr)); 1366 memcpy(&kda_copy.kda_gateway.in4, &conf12->ndc12_gateway, 1367 sizeof(struct in_addr)); 1368 1369 kda_copy.kda_index = 1370 (conf12->ndc12_kda.kda12_enable ? 0 : KDA_REMOVE_ALL); 1371 1372 conf = &kda_copy; 1373 explicit_bzero(conf12, sizeof(*conf12)); 1374 /* FALLTHROUGH */ 1375 #endif 1376 case DIOCSKERNELDUMP: 1377 encryptedkey = NULL; 1378 if (cmd == DIOCSKERNELDUMP) { 1379 conf = (void *)addr; 1380 memcpy(&kda_copy, conf, sizeof(kda_copy)); 1381 } 1382 /* Netdump only supports IP4 at this time. */ 1383 if (conf->kda_af != AF_INET) { 1384 error = EPROTONOSUPPORT; 1385 break; 1386 } 1387 1388 conf->kda_iface[sizeof(conf->kda_iface) - 1] = '\0'; 1389 if (conf->kda_index == KDA_REMOVE || 1390 conf->kda_index == KDA_REMOVE_DEV || 1391 conf->kda_index == KDA_REMOVE_ALL) { 1392 if (netdump_enabled()) 1393 netdump_unconfigure(); 1394 if (conf->kda_index == KDA_REMOVE_ALL) 1395 error = dumper_remove(NULL, conf); 1396 break; 1397 } 1398 1399 error = netdump_configure(conf, td); 1400 if (error != 0) 1401 break; 1402 1403 if (conf->kda_encryption != KERNELDUMP_ENC_NONE) { 1404 if (conf->kda_encryptedkeysize <= 0 || 1405 conf->kda_encryptedkeysize > 1406 KERNELDUMP_ENCKEY_MAX_SIZE) { 1407 error = EINVAL; 1408 break; 1409 } 1410 encryptedkey = malloc(conf->kda_encryptedkeysize, 1411 M_TEMP, M_WAITOK); 1412 error = copyin(conf->kda_encryptedkey, encryptedkey, 1413 conf->kda_encryptedkeysize); 1414 if (error != 0) { 1415 free(encryptedkey, M_TEMP); 1416 break; 1417 } 1418 1419 conf->kda_encryptedkey = encryptedkey; 1420 } 1421 1422 memset(&dumper, 0, sizeof(dumper)); 1423 dumper.dumper_start = netdump_start; 1424 dumper.dumper_hdr = netdump_write_headers; 1425 dumper.dumper = netdump_dumper; 1426 dumper.priv = NULL; 1427 dumper.blocksize = NETDUMP_DATASIZE; 1428 dumper.maxiosize = MAXDUMPPGS * PAGE_SIZE; 1429 dumper.mediaoffset = 0; 1430 dumper.mediasize = 0; 1431 1432 error = dumper_insert(&dumper, conf->kda_iface, conf); 1433 if (encryptedkey != NULL) { 1434 explicit_bzero(encryptedkey, 1435 conf->kda_encryptedkeysize); 1436 free(encryptedkey, M_TEMP); 1437 } 1438 if (error != 0) 1439 netdump_unconfigure(); 1440 break; 1441 default: 1442 error = ENOTTY; 1443 break; 1444 } 1445 explicit_bzero(&kda_copy, sizeof(kda_copy)); 1446 if (conf != NULL) 1447 explicit_bzero(conf, sizeof(*conf)); 1448 NETDUMP_WUNLOCK(); 1449 return (error); 1450 } 1451 1452 /* 1453 * Called upon system init or kld load. Initializes the netdump parameters to 1454 * sane defaults (locates the first available NIC and uses the first IPv4 IP on 1455 * that card as the client IP). Leaves the server IP unconfigured. 1456 * 1457 * Parameters: 1458 * mod, Unused. 1459 * what, The module event type. 1460 * priv, Unused. 1461 * 1462 * Returns: 1463 * int, An errno value if an error occured, 0 otherwise. 1464 */ 1465 static int 1466 netdump_modevent(module_t mod __unused, int what, void *priv __unused) 1467 { 1468 struct diocskerneldump_arg conf; 1469 char *arg; 1470 int error; 1471 1472 error = 0; 1473 switch (what) { 1474 case MOD_LOAD: 1475 error = make_dev_p(MAKEDEV_WAITOK, &netdump_cdev, 1476 &netdump_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "netdump"); 1477 if (error != 0) 1478 return (error); 1479 1480 nd_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event, 1481 netdump_ifdetach, NULL, EVENTHANDLER_PRI_ANY); 1482 1483 if ((arg = kern_getenv("net.dump.iface")) != NULL) { 1484 strlcpy(conf.kda_iface, arg, sizeof(conf.kda_iface)); 1485 freeenv(arg); 1486 1487 if ((arg = kern_getenv("net.dump.server")) != NULL) { 1488 inet_aton(arg, &conf.kda_server.in4); 1489 freeenv(arg); 1490 } 1491 if ((arg = kern_getenv("net.dump.client")) != NULL) { 1492 inet_aton(arg, &conf.kda_client.in4); 1493 freeenv(arg); 1494 } 1495 if ((arg = kern_getenv("net.dump.gateway")) != NULL) { 1496 inet_aton(arg, &conf.kda_gateway.in4); 1497 freeenv(arg); 1498 } 1499 conf.kda_af = AF_INET; 1500 1501 /* Ignore errors; we print a message to the console. */ 1502 NETDUMP_WLOCK(); 1503 (void)netdump_configure(&conf, curthread); 1504 NETDUMP_WUNLOCK(); 1505 } 1506 break; 1507 case MOD_UNLOAD: 1508 NETDUMP_WLOCK(); 1509 if (netdump_enabled()) { 1510 printf("netdump: disabling dump device for unload\n"); 1511 netdump_unconfigure(); 1512 } 1513 NETDUMP_WUNLOCK(); 1514 destroy_dev(netdump_cdev); 1515 EVENTHANDLER_DEREGISTER(ifnet_departure_event, 1516 nd_detach_cookie); 1517 break; 1518 default: 1519 error = EOPNOTSUPP; 1520 break; 1521 } 1522 return (error); 1523 } 1524 1525 static moduledata_t netdump_mod = { 1526 "netdump", 1527 netdump_modevent, 1528 NULL, 1529 }; 1530 1531 MODULE_VERSION(netdump, 1); 1532 DECLARE_MODULE(netdump, netdump_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 1533