1234353Sdim/*- 2234353Sdim * SPDX-License-Identifier: BSD-4-Clause 3193323Sed * 4193323Sed * Copyright (c) 1989 Stephen Deering 5193323Sed * Copyright (c) 1992, 1993 6193323Sed * The Regents of the University of California. All rights reserved. 7234353Sdim * 8193323Sed * This code is derived from software contributed to Berkeley by 9193323Sed * Stephen Deering of Stanford University. 10193323Sed * 11193323Sed * Redistribution and use in source and binary forms, with or without 12193323Sed * modification, are permitted provided that the following conditions 13193323Sed * are met: 14193323Sed * 1. Redistributions of source code must retain the above copyright 15193323Sed * notice, this list of conditions and the following disclaimer. 16193323Sed * 2. Redistributions in binary form must reproduce the above copyright 17193323Sed * notice, this list of conditions and the following disclaimer in the 18193323Sed * documentation and/or other materials provided with the distribution. 19193323Sed * 3. All advertising materials mentioning features or use of this software 20193323Sed * must display the following acknowledgement: 21193323Sed * This product includes software developed by the University of 22193323Sed * California, Berkeley and its contributors. 23193323Sed * 4. Neither the name of the University nor the names of its contributors 24193323Sed * may be used to endorse or promote products derived from this software 25193323Sed * without specific prior written permission. 26193323Sed * 27193323Sed * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28193323Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29193323Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30193323Sed * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31193323Sed * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32239462Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33239462Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34239462Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35239462Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36239462Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37239462Sdim * SUCH DAMAGE. 38239462Sdim */ 39212904Sdim 40212904Sdim#include <sys/cdefs.h> 41193323Sed/* 42193323Sed * Print multicast routing structures and statistics. 43193323Sed * 44193323Sed * MROUTING 1.0 45193323Sed */ 46212904Sdim 47212904Sdim#include <sys/param.h> 48212904Sdim#include <sys/queue.h> 49212904Sdim#include <sys/socket.h> 50224145Sdim#include <sys/socketvar.h> 51212904Sdim#include <sys/sysctl.h> 52193323Sed#include <sys/protosw.h> 53193323Sed#include <sys/mbuf.h> 54224145Sdim#include <sys/time.h> 55193323Sed 56193323Sed#include <net/if.h> 57193323Sed#include <netinet/in.h> 58193323Sed#include <netinet/igmp.h> 59193323Sed#include <net/route.h> 60193323Sed 61193323Sed#define _NETSTAT 1 62193323Sed#include <netinet/ip_mroute.h> 63193323Sed#undef _NETSTAT_ 64193323Sed 65193323Sed#include <err.h> 66193323Sed#include <stdint.h> 67234353Sdim#include <stdio.h> 68193323Sed#include <stdlib.h> 69193323Sed#include <stdbool.h> 70193323Sed#include <string.h> 71193323Sed#include <libxo/xo.h> 72193323Sed#include "netstat.h" 73193323Sed#include "nl_defs.h" 74193323Sed 75193323Sedstatic void print_bw_meter(struct bw_meter *, int *); 76200581Srdivackystatic void print_mfc(struct mfc *, int, int *); 77193323Sed 78193323Sedstatic void 79234353Sdimprint_bw_meter(struct bw_meter *bw_meter, int *banner_printed) 80234353Sdim{ 81200581Srdivacky char s1[256], s2[256], s3[256]; 82200581Srdivacky struct timeval now, end, delta; 83200581Srdivacky 84200581Srdivacky gettimeofday(&now, NULL); 85200581Srdivacky 86200581Srdivacky if (! *banner_printed) { 87200581Srdivacky xo_open_list("bandwidth-meter"); 88193323Sed xo_emit(" {T:Bandwidth Meters}\n"); 89193323Sed xo_emit(" {T:/%-30s}", "Measured(Start|Packets|Bytes)"); 90193323Sed xo_emit(" {T:/%s}", "Type"); 91243830Sdim xo_emit(" {T:/%-30s}", "Thresh(Interval|Packets|Bytes)"); 92243830Sdim xo_emit(" {T:Remain}"); 93243830Sdim xo_emit("\n"); 94243830Sdim *banner_printed = 1; 95243830Sdim } 96243830Sdim 97243830Sdim xo_open_instance("bandwidth-meter"); 98243830Sdim 99243830Sdim /* The measured values */ 100243830Sdim if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) { 101243830Sdim snprintf(s1, sizeof(s1), "%ju", 102243830Sdim (uintmax_t)bw_meter->bm_measured.b_packets); 103243830Sdim xo_emit("{e:measured-packets/%ju}", 104243830Sdim (uintmax_t)bw_meter->bm_measured.b_packets); 105243830Sdim } else 106249423Sdim strcpy(s1, "?"); 107249423Sdim if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) { 108249423Sdim snprintf(s2, sizeof(s2), "%ju", 109249423Sdim (uintmax_t)bw_meter->bm_measured.b_bytes); 110249423Sdim xo_emit("{e:measured-bytes/%ju}", 111249423Sdim (uintmax_t)bw_meter->bm_measured.b_bytes); 112249423Sdim } else 113249423Sdim strcpy(s2, "?"); 114249423Sdim xo_emit(" {[:-30}{:start-time/%lu.%06lu}|{q:measured-packets/%s}" 115193323Sed "|{q:measured-bytes%s}{]:}", 116193323Sed (u_long)bw_meter->bm_start_time.tv_sec, 117193323Sed (u_long)bw_meter->bm_start_time.tv_usec, s1, s2); 118193323Sed 119193323Sed /* The type of entry */ 120193323Sed xo_emit(" {t:type/%-3s}", (bw_meter->bm_flags & BW_METER_GEQ) ? ">=" : 121224145Sdim (bw_meter->bm_flags & BW_METER_LEQ) ? "<=" : "?"); 122218893Sdim 123193323Sed /* The threshold values */ 124193323Sed if (bw_meter->bm_flags & BW_METER_UNIT_PACKETS) { 125193323Sed snprintf(s1, sizeof(s1), "%ju", 126193323Sed (uintmax_t)bw_meter->bm_threshold.b_packets); 127193323Sed xo_emit("{e:threshold-packets/%ju}", 128193323Sed (uintmax_t)bw_meter->bm_threshold.b_packets); 129224145Sdim } else 130193323Sed strcpy(s1, "?"); 131193323Sed if (bw_meter->bm_flags & BW_METER_UNIT_BYTES) { 132193323Sed snprintf(s2, sizeof(s2), "%ju", 133193323Sed (uintmax_t)bw_meter->bm_threshold.b_bytes); 134193323Sed xo_emit("{e:threshold-bytes/%ju}", 135249423Sdim (uintmax_t)bw_meter->bm_threshold.b_bytes); 136249423Sdim } else 137249423Sdim strcpy(s2, "?"); 138249423Sdim 139193323Sed xo_emit(" {[:-30}{:threshold-time/%lu.%06lu}|{q:threshold-packets/%s}" 140249423Sdim "|{q:threshold-bytes%s}{]:}", 141249423Sdim (u_long)bw_meter->bm_threshold.b_time.tv_sec, 142249423Sdim (u_long)bw_meter->bm_threshold.b_time.tv_usec, s1, s2); 143249423Sdim 144193323Sed /* Remaining time */ 145193323Sed timeradd(&bw_meter->bm_start_time, 146193323Sed &bw_meter->bm_threshold.b_time, &end); 147193323Sed if (timercmp(&now, &end, <=)) { 148249423Sdim timersub(&end, &now, &delta); 149249423Sdim snprintf(s3, sizeof(s3), "%lu.%06lu", 150249423Sdim (u_long)delta.tv_sec, 151193323Sed (u_long)delta.tv_usec); 152193323Sed } else { 153193323Sed /* Negative time */ 154193323Sed timersub(&now, &end, &delta); 155193323Sed snprintf(s3, sizeof(s3), "-%lu.06%lu", 156193323Sed (u_long)delta.tv_sec, 157249423Sdim (u_long)delta.tv_usec); 158249423Sdim } 159256030Sdim xo_emit(" {:remaining-time/%s}", s3); 160256030Sdim 161256030Sdim xo_open_instance("bandwidth-meter"); 162256030Sdim 163256030Sdim xo_emit("\n"); 164193323Sed} 165193323Sed 166193323Sedstatic void 167193323Sedprint_mfc(struct mfc *m, int maxvif, int *banner_printed) 168193323Sed{ 169193323Sed struct sockaddr_in sin; 170193323Sed struct sockaddr *sa = (struct sockaddr *)&sin; 171193323Sed struct bw_meter bw_meter, *bwm; 172193323Sed int bw_banner_printed; 173243830Sdim int error; 174243830Sdim vifi_t vifi; 175243830Sdim 176243830Sdim bw_banner_printed = 0; 177193323Sed memset(&sin, 0, sizeof(sin)); 178193323Sed sin.sin_len = sizeof(sin); 179193323Sed sin.sin_family = AF_INET; 180193323Sed 181193323Sed if (! *banner_printed) { 182193323Sed xo_open_list("multicast-forwarding-entry"); 183193323Sed xo_emit("\n{T:IPv4 Multicast Forwarding Table}\n" 184193323Sed " {T:Origin} {T:Group} " 185193323Sed " {T:Packets In-Vif} {T:Out-Vifs:Ttls}\n"); 186193323Sed *banner_printed = 1; 187193323Sed } 188193323Sed 189193323Sed memcpy(&sin.sin_addr, &m->mfc_origin, sizeof(sin.sin_addr)); 190193323Sed xo_emit(" {:origin-address/%-15.15s}", routename(sa, numeric_addr)); 191193323Sed memcpy(&sin.sin_addr, &m->mfc_mcastgrp, sizeof(sin.sin_addr)); 192193323Sed xo_emit(" {:group-address/%-15.15s}", 193193323Sed routename(sa, numeric_addr)); 194193323Sed xo_emit(" {:sent-packets/%9lu}", m->mfc_pkt_cnt); 195193323Sed xo_emit(" {:parent/%3d} ", m->mfc_parent); 196193323Sed xo_open_list("vif-ttl"); 197193323Sed for (vifi = 0; vifi <= maxvif; vifi++) { 198193323Sed if (m->mfc_ttls[vifi] > 0) { 199224145Sdim xo_open_instance("vif-ttl"); 200218893Sdim xo_emit(" {k:vif/%u}:{:ttl/%u}", vifi, 201193323Sed m->mfc_ttls[vifi]); 202234353Sdim xo_close_instance("vif-ttl"); 203198090Srdivacky } 204193323Sed } 205198090Srdivacky xo_close_list("vif-ttl"); 206198090Srdivacky xo_emit("\n"); 207234353Sdim 208198090Srdivacky /* 209212904Sdim * XXX We break the rules and try to use KVM to read the 210234353Sdim * bandwidth meters, they are not retrievable via sysctl yet. 211234353Sdim */ 212234353Sdim bwm = m->mfc_bw_meter_leq; 213234353Sdim while (bwm != NULL) { 214234353Sdim error = kread((u_long)bwm, (char *)&bw_meter, 215234353Sdim sizeof(bw_meter)); 216234353Sdim if (error) 217234353Sdim break; 218234353Sdim print_bw_meter(&bw_meter, &bw_banner_printed); 219212904Sdim bwm = bw_meter.bm_mfc_next; 220193323Sed } 221193323Sed bwm = m->mfc_bw_meter_geq; 222193323Sed while (bwm != NULL) { 223212904Sdim error = kread((u_long)bwm, (char *)&bw_meter, 224193323Sed sizeof(bw_meter)); 225193323Sed if (error) 226193323Sed break; 227193323Sed print_bw_meter(&bw_meter, &bw_banner_printed); 228193323Sed bwm = bw_meter.bm_mfc_next; 229193323Sed } 230193323Sed if (banner_printed) 231212904Sdim xo_close_list("bandwidth-meter"); 232212904Sdim} 233224145Sdim 234193323Sedvoid 235193323Sedmroutepr(void) 236193323Sed{ 237193323Sed struct sockaddr_in sin; 238193323Sed struct sockaddr *sa = (struct sockaddr *)&sin; 239193323Sed struct vif viftable[MAXVIFS]; 240193323Sed struct vif *v; 241193323Sed struct mfc *m; 242193323Sed u_long pmfchashtbl, pmfctablesize, pviftbl; 243193323Sed int banner_printed; 244193323Sed int saved_numeric_addr; 245193323Sed size_t len; 246193323Sed vifi_t vifi, maxvif; 247198090Srdivacky 248198090Srdivacky saved_numeric_addr = numeric_addr; 249198090Srdivacky numeric_addr = 1; 250234353Sdim 251234353Sdim memset(&sin, 0, sizeof(sin)); 252234353Sdim sin.sin_len = sizeof(sin); 253234353Sdim sin.sin_family = AF_INET; 254198090Srdivacky 255224145Sdim /* 256198090Srdivacky * TODO: 257193323Sed * The VIF table will move to hanging off the struct if_info for 258193323Sed * each IPv4 configured interface. Currently it is statically 259193323Sed * allocated, and retrieved either using KVM or an opaque SYSCTL. 260221345Sdim * 261221345Sdim * This can't happen until the API documented in multicast(4) 262221345Sdim * is itself refactored. The historical reason why VIFs use 263221345Sdim * a separate ifindex space is entirely due to the legacy 264221345Sdim * capability of the MROUTING code to create IPIP tunnels on 265221345Sdim * the fly to support DVMRP. When gif(4) became available, this 266221345Sdim * functionality was deprecated, as PIM does not use it. 267193323Sed */ 268193323Sed maxvif = 0; 269193323Sed pmfchashtbl = pmfctablesize = pviftbl = 0; 270193323Sed 271193323Sed len = sizeof(viftable); 272193323Sed if (live) { 273193323Sed if (sysctlbyname("net.inet.ip.viftable", viftable, &len, NULL, 274193323Sed 0) < 0) { 275193323Sed xo_warn("sysctl: net.inet.ip.viftable"); 276198090Srdivacky return; 277198090Srdivacky } 278193323Sed } else { 279193323Sed pmfchashtbl = nl[N_MFCHASHTBL].n_value; 280193323Sed pmfctablesize = nl[N_MFCTABLESIZE].n_value; 281224145Sdim pviftbl = nl[N_VIFTABLE].n_value; 282193323Sed 283193323Sed if (pmfchashtbl == 0 || pmfctablesize == 0 || pviftbl == 0) { 284205218Srdivacky xo_warnx("No IPv4 MROUTING kernel support."); 285205218Srdivacky return; 286205218Srdivacky } 287205218Srdivacky 288205218Srdivacky kread(pviftbl, (char *)viftable, sizeof(viftable)); 289205218Srdivacky } 290205218Srdivacky 291205218Srdivacky banner_printed = 0; 292205218Srdivacky for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) { 293205218Srdivacky if (v->v_lcl_addr.s_addr == 0) 294234353Sdim continue; 295205218Srdivacky 296205218Srdivacky maxvif = vifi; 297205218Srdivacky if (!banner_printed) { 298249423Sdim xo_emit("\n{T:IPv4 Virtual Interface Table\n" 299249423Sdim " Vif Thresh Local-Address " 300249423Sdim "Remote-Address Pkts-In Pkts-Out}\n"); 301249423Sdim banner_printed = 1; 302249423Sdim xo_open_list("vif"); 303249423Sdim } 304249423Sdim 305249423Sdim xo_open_instance("vif"); 306249423Sdim memcpy(&sin.sin_addr, &v->v_lcl_addr, sizeof(sin.sin_addr)); 307249423Sdim xo_emit(" {:vif/%2u} {:threshold/%6u} {:route/%-15.15s}", 308249423Sdim /* opposite math of add_vif() */ 309249423Sdim vifi, v->v_threshold, 310193323Sed routename(sa, numeric_addr)); 311193323Sed memcpy(&sin.sin_addr, &v->v_rmt_addr, sizeof(sin.sin_addr)); 312193323Sed xo_emit(" {:source/%-15.15s}", (v->v_flags & VIFF_TUNNEL) ? 313193323Sed routename(sa, numeric_addr) : ""); 314193323Sed 315193323Sed xo_emit(" {:received-packets/%9lu} {:sent-packets/%9lu}\n", 316193323Sed v->v_pkt_in, v->v_pkt_out); 317193323Sed xo_close_instance("vif"); 318193323Sed } 319193323Sed if (banner_printed) 320193323Sed xo_close_list("vif"); 321193323Sed else 322193323Sed xo_emit("\n{T:IPv4 Virtual Interface Table is empty}\n"); 323193323Sed 324234353Sdim banner_printed = 0; 325193323Sed 326193323Sed /* 327224145Sdim * TODO: 328224145Sdim * The MFC table will move into the AF_INET radix trie in future. 329218893Sdim * In 8.x, it becomes a dynamically allocated structure referenced 330193323Sed * by a hashed LIST, allowing more than 256 entries w/o kernel tuning. 331193323Sed * 332193323Sed * If retrieved via opaque SYSCTL, the kernel will coalesce it into 333193323Sed * a static table for us. 334193323Sed * If retrieved via KVM, the hash list pointers must be followed. 335193323Sed */ 336193323Sed if (live) { 337193323Sed struct mfc *mfctable; 338193323Sed 339193323Sed len = 0; 340193323Sed if (sysctlbyname("net.inet.ip.mfctable", NULL, &len, NULL, 341193323Sed 0) < 0) { 342193323Sed xo_warn("sysctl: net.inet.ip.mfctable"); 343193323Sed return; 344193323Sed } 345193323Sed 346212904Sdim mfctable = malloc(len); 347212904Sdim if (mfctable == NULL) { 348212904Sdim xo_warnx("malloc %lu bytes", (u_long)len); 349212904Sdim return; 350212904Sdim } 351193323Sed if (sysctlbyname("net.inet.ip.mfctable", mfctable, &len, NULL, 352193323Sed 0) < 0) { 353193323Sed free(mfctable); 354212904Sdim xo_warn("sysctl: net.inet.ip.mfctable"); 355212904Sdim return; 356212904Sdim } 357212904Sdim 358193323Sed m = mfctable; 359193323Sed while (len >= sizeof(*m)) { 360224145Sdim print_mfc(m++, maxvif, &banner_printed); 361193323Sed len -= sizeof(*m); 362193323Sed } 363193323Sed if (banner_printed) 364193323Sed xo_close_list("multicast-forwarding-entry"); 365193323Sed if (len != 0) 366193323Sed xo_warnx("print_mfc: %lu trailing bytes", (u_long)len); 367193323Sed 368193323Sed free(mfctable); 369193323Sed } else { 370193323Sed LIST_HEAD(, mfc) *mfchashtbl; 371193323Sed u_long i, mfctablesize; 372193323Sed struct mfc mfc; 373193323Sed int error; 374193323Sed 375193323Sed error = kread(pmfctablesize, (char *)&mfctablesize, 376193323Sed sizeof(u_long)); 377193323Sed if (error) { 378193323Sed xo_warn("kread: mfctablesize"); 379193323Sed return; 380193323Sed } 381193323Sed 382193323Sed len = sizeof(*mfchashtbl) * mfctablesize; 383193323Sed mfchashtbl = malloc(len); 384193323Sed if (mfchashtbl == NULL) { 385243830Sdim xo_warnx("malloc %lu bytes", (u_long)len); 386193323Sed return; 387193323Sed } 388193323Sed kread(pmfchashtbl, (char *)&mfchashtbl, len); 389193323Sed 390193323Sed for (i = 0; i < mfctablesize; i++) { 391208599Srdivacky LIST_FOREACH(m, &mfchashtbl[i], mfc_hash) { 392208599Srdivacky kread((u_long)m, (char *)&mfc, sizeof(mfc)); 393208599Srdivacky print_mfc(m, maxvif, &banner_printed); 394208599Srdivacky } 395249423Sdim } 396249423Sdim if (banner_printed) 397208599Srdivacky xo_close_list("multicast-forwarding-entry"); 398208599Srdivacky 399208599Srdivacky free(mfchashtbl); 400208599Srdivacky } 401208599Srdivacky 402208599Srdivacky if (!banner_printed) 403208599Srdivacky xo_emit("\n{T:IPv4 Multicast Forwarding Table is empty}\n"); 404208599Srdivacky 405193323Sed xo_emit("\n"); 406193323Sed numeric_addr = saved_numeric_addr; 407193323Sed} 408193323Sed 409193323Sedvoid 410193323Sedmrt_stats(void) 411193323Sed{ 412193323Sed struct mrtstat mrtstat; 413193323Sed u_long mstaddr; 414193323Sed 415193323Sed mstaddr = nl[N_MRTSTAT].n_value; 416193323Sed 417193323Sed if (fetch_stats("net.inet.ip.mrtstat", mstaddr, &mrtstat, 418193323Sed sizeof(mrtstat), kread_counters) != 0) { 419193323Sed if ((live && errno == ENOENT) || (!live && mstaddr == 0)) 420193323Sed fprintf(stderr, "No IPv4 MROUTING kernel support.\n"); 421193323Sed return; 422193323Sed } 423234353Sdim 424193323Sed xo_emit("{T:IPv4 multicast forwarding}:\n"); 425193323Sed 426193323Sed#define p(f, m) if (mrtstat.f || sflag <= 1) \ 427193323Sed xo_emit(m, (uintmax_t)mrtstat.f, plural(mrtstat.f)) 428193323Sed#define p2(f, m) if (mrtstat.f || sflag <= 1) \ 429193323Sed xo_emit(m, (uintmax_t)mrtstat.f, plurales(mrtstat.f)) 430193323Sed 431193323Sed xo_open_container("multicast-statistics"); 432205218Srdivacky 433205218Srdivacky p(mrts_mfc_lookups, "\t{:cache-lookups/%ju} " 434205218Srdivacky "{N:/multicast forwarding cache lookup%s}\n"); 435205218Srdivacky p2(mrts_mfc_misses, "\t{:cache-misses/%ju} " 436205218Srdivacky "{N:/multicast forwarding cache miss%s}\n"); 437205218Srdivacky p(mrts_upcalls, "\t{:upcalls-total/%ju} " 438205218Srdivacky "{N:/upcall%s to multicast routing daemon}\n"); 439205218Srdivacky p(mrts_upq_ovflw, "\t{:upcall-overflows/%ju} " 440218893Sdim "{N:/upcall queue overflow%s}\n"); 441249423Sdim p(mrts_upq_sockfull, 442249423Sdim "\t{:upcalls-dropped-full-buffer/%ju} " 443249423Sdim "{N:/upcall%s dropped due to full socket buffer}\n"); 444249423Sdim p(mrts_cache_cleanups, "\t{:cache-cleanups/%ju} " 445249423Sdim "{N:/cache cleanup%s}\n"); 446249423Sdim p(mrts_no_route, "\t{:dropped-no-origin/%ju} " 447249423Sdim "{N:/datagram%s with no route for origin}\n"); 448249423Sdim p(mrts_bad_tunnel, "\t{:dropped-bad-tunnel/%ju} " 449249423Sdim "{N:/datagram%s arrived with bad tunneling}\n"); 450249423Sdim p(mrts_cant_tunnel, "\t{:dropped-could-not-tunnel/%ju} " 451249423Sdim "{N:/datagram%s could not be tunneled}\n"); 452249423Sdim p(mrts_wrong_if, "\t{:dropped-wrong-incoming-interface/%ju} " 453249423Sdim "{N:/datagram%s arrived on wrong interface}\n"); 454249423Sdim p(mrts_drop_sel, "\t{:dropped-selectively/%ju} " 455249423Sdim "{N:/datagram%s selectively dropped}\n"); 456249423Sdim p(mrts_q_overflow, "\t{:dropped-queue-overflow/%ju} " 457249423Sdim "{N:/datagram%s dropped due to queue overflow}\n"); 458249423Sdim p(mrts_pkt2large, "\t{:dropped-too-large/%ju} " 459249423Sdim "{N:/datagram%s dropped for being too large}\n"); 460249423Sdim 461249423Sdim#undef p2 462249423Sdim#undef p 463249423Sdim} 464249423Sdim