Print this page
9352 netstat(1M) should be able to print IPv4 networks in CIDR form

*** 21,31 **** /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1990 Mentat Inc. * netstat.c 2.2, last change 9/9/91 * MROUTING Revision 3.5 ! * Copyright (c) 2017, Joyent, Inc. */ /* * simple netstat based on snmp/mib-2 interface to the TCP/IP stack * --- 21,31 ---- /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1990 Mentat Inc. * netstat.c 2.2, last change 9/9/91 * MROUTING Revision 3.5 ! * Copyright 2018, Joyent, Inc. */ /* * simple netstat based on snmp/mib-2 interface to the TCP/IP stack *
*** 234,243 **** --- 234,244 ---- #define MDIFF(diff, elem2, elem1, member) (diff)->member = \ (elem2)->member - (elem1)->member static boolean_t Aflag = B_FALSE; /* All sockets/ifs/rtng-tbls */ + static boolean_t CIDRflag = B_FALSE; /* CIDR for IPv4 -i/-r addrs */ static boolean_t Dflag = B_FALSE; /* DCE info */ static boolean_t Iflag = B_FALSE; /* IP Traffic Interfaces */ static boolean_t Mflag = B_FALSE; /* STREAMS Memory Statistics */ static boolean_t Nflag = B_FALSE; /* Numeric Network Addresses */ static boolean_t Rflag = B_FALSE; /* Routing Tables */
*** 444,459 **** free(default_ip_str); (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); ! while ((c = getopt(argc, argv, "adimnrspMgvxf:P:I:DRT:")) != -1) { switch ((char)c) { case 'a': /* all connections */ Aflag = B_TRUE; break; case 'd': /* DCE info */ Dflag = B_TRUE; IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ break; --- 445,464 ---- free(default_ip_str); (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); ! while ((c = getopt(argc, argv, "acdimnrspMgvxf:P:I:DRT:")) != -1) { switch ((char)c) { case 'a': /* all connections */ Aflag = B_TRUE; break; + case 'c': + CIDRflag = B_TRUE; + break; + case 'd': /* DCE info */ Dflag = B_TRUE; IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ break;
*** 3338,3348 **** if_report_ip4(mib2_ipAddrEntry_t *ap, char ifname[], char logintname[], struct ifstat *statptr, boolean_t ksp_not_null) { ! char abuf[MAXHOSTNAMELEN + 1]; char dstbuf[MAXHOSTNAMELEN + 1]; if (ksp_not_null) { (void) printf("%-5s %-4u ", ifname, ap->ipAdEntInfo.ae_mtu); --- 3343,3353 ---- if_report_ip4(mib2_ipAddrEntry_t *ap, char ifname[], char logintname[], struct ifstat *statptr, boolean_t ksp_not_null) { ! char abuf[MAXHOSTNAMELEN + 4]; /* Include /<num> for CIDR-printing. */ char dstbuf[MAXHOSTNAMELEN + 1]; if (ksp_not_null) { (void) printf("%-5s %-4u ", ifname, ap->ipAdEntInfo.ae_mtu);
*** 4437,4447 **** static boolean_t ire_report_item_v4(const mib2_ipRouteEntry_t *rp, boolean_t first, const sec_attr_list_t *attrs) { ! char dstbuf[MAXHOSTNAMELEN + 1]; char maskbuf[MAXHOSTNAMELEN + 1]; char gwbuf[MAXHOSTNAMELEN + 1]; char ifname[LIFNAMSIZ + 1]; char flags[10]; /* RTF_ flags */ uint_t flag_b; --- 4442,4452 ---- static boolean_t ire_report_item_v4(const mib2_ipRouteEntry_t *rp, boolean_t first, const sec_attr_list_t *attrs) { ! char dstbuf[MAXHOSTNAMELEN + 4]; /* + "/<num>" */ char maskbuf[MAXHOSTNAMELEN + 1]; char gwbuf[MAXHOSTNAMELEN + 1]; char ifname[LIFNAMSIZ + 1]; char flags[10]; /* RTF_ flags */ uint_t flag_b;
*** 5555,5565 **** struct vifctl *vip; vifi_t vifi; struct mfcctl *mfccp; int numvifs = 0; int nmfc = 0; ! char abuf[MAXHOSTNAMELEN + 1]; if (!(family_selected(AF_INET))) return; /* 'for' loop 1: */ --- 5560,5570 ---- struct vifctl *vip; vifi_t vifi; struct mfcctl *mfccp; int numvifs = 0; int nmfc = 0; ! char abuf[MAXHOSTNAMELEN + 4]; /* Include CIDR /<num>. */ if (!(family_selected(AF_INET))) return; /* 'for' loop 1: */
*** 5974,5983 **** --- 5979,6039 ---- } return (dst); } /* + * Returns -2 to indicate a discontiguous mask. Otherwise returns between + * 0 and 32. + */ + static int + v4_cidr_len(uint_t mask) + { + int rc = 0; + int i; + + for (i = 0; i < 32; i++) { + if (mask & 0x1) + rc++; + else if (rc > 0) + return (-2); /* Discontiguous IPv4 netmask. */ + + mask >>= 1; + } + + return (rc); + } + + static void + append_v4_cidr_len(char *dst, uint_t dstlen, int prefixlen) + { + char *prefixptr; + + /* 4 bytes leaves room for '/' 'N' 'N' '\0' */ + if (strlen(dst) <= dstlen - 4) { + prefixptr = dst + strlen(dst); + } else { + /* + * Cut off last 3 chars of very-long DNS name. All callers + * should give us enough room, but name services COULD give us + * a way-too-big name (see above). + */ + prefixptr = dst + strlen(dst) - 3; + } + /* At this point "prefixptr" is guaranteed to point to 4 bytes. */ + + if (prefixlen >= 0) { + if (prefixlen > 32) /* Shouldn't happen, but... */ + prefixlen = 32; + (void) snprintf(prefixptr, 4, "/%d", prefixlen); + } else if (prefixlen == -2) { + /* "/NM" == Noncontiguous Mask. */ + (void) strcat(prefixptr, "/NM"); + } + /* Else print nothing extra. */ + } + + /* * Return the name of the network whose address is given. The address is * assumed to be that of a net or subnet, not a host. */ static char * pr_net(uint_t addr, uint_t mask, char *dst, uint_t dstlen)
*** 5986,6002 **** struct netent *np = NULL; struct hostent *hp = NULL; uint_t net; int subnetshift; int error_num; if (addr == INADDR_ANY && mask == INADDR_ANY) { ! (void) strncpy(dst, "default", dstlen); ! dst[dstlen - 1] = 0; return (dst); } if (!Nflag && addr) { if (mask == 0) { if (IN_CLASSA(addr)) { mask = (uint_t)IN_CLASSA_NET; subnetshift = 8; --- 6042,6062 ---- struct netent *np = NULL; struct hostent *hp = NULL; uint_t net; int subnetshift; int error_num; + int prefixlen = -1; /* -1 == Don't print prefix! */ + /* -2 == Noncontiguous mask... */ if (addr == INADDR_ANY && mask == INADDR_ANY) { ! (void) strlcpy(dst, "default", dstlen); return (dst); } + if (CIDRflag) + prefixlen = v4_cidr_len(ntohl(mask)); + if (!Nflag && addr) { if (mask == 0) { if (IN_CLASSA(addr)) { mask = (uint_t)IN_CLASSA_NET; subnetshift = 8;
*** 6014,6023 **** --- 6074,6085 ---- * fields. */ while (addr & ~mask) /* compiler doesn't sign extend! */ mask = (mask | ((int)mask >> subnetshift)); + if (CIDRflag) + prefixlen = v4_cidr_len(mask); } net = addr & mask; while ((mask & 1) == 0) mask >>= 1, net >>= 1; ns_lookup_start();
*** 6036,6050 **** if (hp) cp = hp->h_name; } } if (cp != NULL) { ! (void) strncpy(dst, cp, dstlen); ! dst[dstlen - 1] = 0; } else { (void) inet_ntop(AF_INET, (char *)&addr, dst, dstlen); } if (hp != NULL) freehostent(hp); return (dst); } --- 6098,6114 ---- if (hp) cp = hp->h_name; } } if (cp != NULL) { ! (void) strlcpy(dst, cp, dstlen); } else { (void) inet_ntop(AF_INET, (char *)&addr, dst, dstlen); } + + append_v4_cidr_len(dst, dstlen, prefixlen); + if (hp != NULL) freehostent(hp); return (dst); }
*** 6062,6080 **** uint_t netshifted; int subnetshift; struct in_addr in; int error_num; uint_t nbo_addr = addr; /* network byte order */ addr = ntohl(addr); mask = ntohl(mask); if (addr == INADDR_ANY && mask == INADDR_ANY) { ! (void) strncpy(dst, "default", dstlen); ! dst[dstlen - 1] = 0; return (dst); } /* Figure out network portion of address (with host portion = 0) */ if (addr) { /* Try figuring out mask if unknown (all 0s). */ if (mask == 0) { if (IN_CLASSA(addr)) { --- 6126,6148 ---- uint_t netshifted; int subnetshift; struct in_addr in; int error_num; uint_t nbo_addr = addr; /* network byte order */ + int prefixlen = -1; /* -1 == Don't print prefix! */ + /* -2 == Noncontiguous mask... */ addr = ntohl(addr); mask = ntohl(mask); if (addr == INADDR_ANY && mask == INADDR_ANY) { ! (void) strlcpy(dst, "default", dstlen); return (dst); } + if (CIDRflag) + prefixlen = v4_cidr_len(mask); + /* Figure out network portion of address (with host portion = 0) */ if (addr) { /* Try figuring out mask if unknown (all 0s). */ if (mask == 0) { if (IN_CLASSA(addr)) {
*** 6094,6103 **** --- 6162,6173 ---- * fields. */ while (addr & ~mask) /* compiler doesn't sign extend! */ mask = (mask | ((int)mask >> subnetshift)); + if (CIDRflag) + prefixlen = v4_cidr_len(mask); } net = netshifted = addr & mask; while ((mask & 1) == 0) mask >>= 1, netshifted >>= 1; }
*** 6122,6133 **** if (hp) cp = hp->h_name; } if (cp != NULL) { ! (void) strncpy(dst, cp, dstlen); ! dst[dstlen - 1] = 0; if (hp != NULL) freehostent(hp); return (dst); } /* --- 6192,6203 ---- if (hp) cp = hp->h_name; } if (cp != NULL) { ! (void) strlcpy(dst, cp, dstlen); ! append_v4_cidr_len(dst, dstlen, prefixlen); if (hp != NULL) freehostent(hp); return (dst); } /*
*** 6136,6145 **** --- 6206,6216 ---- */ } in.s_addr = htonl(net); (void) inet_ntop(AF_INET, (char *)&in, dst, dstlen); + append_v4_cidr_len(dst, dstlen, prefixlen); if (hp != NULL) freehostent(hp); return (dst); }