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