Hi, This diff moves if_capabilities to if_data exposing it to userland via SIOCGIFDATA.
It also adds a 'capabilities' option to ifconfig which will print them in a similar way which is done with the 'media' keyword. Here is a sample output for re(4): gimli:ifconfig: sudo ./obj/ifconfig re0 capabilities re0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 lladdr 00:30:67:77:31:1f priority: 0 groups: egress media: Ethernet autoselect (100baseTX full-duplex) status: active capabilities: IPv4 hdr checksum tx/rx offloading IPv4 tcp checksum tx/rx offloading IPv4 udp checksum tx/rx offloading vlan compatible mtu vlan hardware tagging wake on lan inet 192.168.8.26 netmask 0xffffff00 broadcast 192.168.8.255 I'm not too keen on the keywords used, so suggestions are welcome. My main motivation was that I got sick of seeing tcpdump displaying wrong checksum messages due to hardware checksum. I also have a diff for tcpdump which will supress the checksum error message if hardware checksuming is present. Please let me know what you think. Index: sbin/ifconfig/ifconfig.c =================================================================== RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v retrieving revision 1.248 diff -d -u -p -w -r1.248 ifconfig.c --- sbin/ifconfig/ifconfig.c 9 Jul 2011 00:45:40 -0000 1.248 +++ sbin/ifconfig/ifconfig.c 17 Aug 2011 03:25:48 -0000 @@ -131,6 +131,7 @@ int Lflag = 1; #endif /* INET6 */ int showmediaflag; +int showcapsflag; int shownet80211chans; int shownet80211nodes; @@ -248,6 +249,7 @@ void setifipdst(const char *, int); void setifdesc(const char *, int); void unsetifdesc(const char *, int); int printgroup(char *, int); +void printifcapabilities(const char *, int); #else void setignore(const char *, int); #endif @@ -337,6 +339,7 @@ const struct cmd { { "-autoconfprivacy", -IFXF_INET6_PRIVACY, 0, setifxflags }, #endif /*INET6*/ #ifndef SMALL + { "capabilities",NEXTARG0, 0, printifcapabilities }, { "group", NEXTARG, 0, setifgroup }, { "-group", NEXTARG, 0, unsetifgroup }, { "trailers", -1, 0, notrailers }, @@ -2912,6 +2915,11 @@ status(int link, struct sockaddr_dl *sdl free(media_list); +#ifndef SMALL + if (showcapsflag) + printifcapabilities(NULL, 1); +#endif + proto_status: if (link == 0) { if ((p = afp) != NULL) { @@ -4703,7 +4711,48 @@ getifgroups(void) free(ifgr.ifgr_groups); } + +void +printifcapabilities(const char *unused, int show) +{ + struct if_data ifrdat; + const struct caps { + int c_mask; + const char *c_desc; + } *c, caps[] = { + { IFCAP_CSUM_IPv4, "IPv4 hdr checksum tx/rx offloading" }, + { IFCAP_CSUM_TCPv4, "IPv4 tcp checksum tx/rx offloading" }, + { IFCAP_CSUM_UDPv4, "IPv4 udp checksum tx/rx offloading" }, + { IFCAP_CSUM_TCPv4_Rx, "IPv4 tcp checksum rx offloading" }, + { IFCAP_CSUM_UDPv4_Rx, "IPv4 udp checksum rx offloading" }, + { IFCAP_IPSEC, "IPsec" }, + { IFCAP_VLAN_MTU, "vlan compatible mtu" }, + { IFCAP_VLAN_HWTAGGING, "vlan hardware tagging" }, + { IFCAP_IPCOMP, "IP compression" }, + { IFCAP_CSUM_TCPv6, "IPv6 tcp checksum tx/rx offloading" }, + { IFCAP_CSUM_UDPv6, "IPv6 udp checksum tx/rx offloading" }, + { IFCAP_WOL, "wake on lan" }, + { 0, NULL }, + }; + if (!show) { + if (showcapsflag) + usage(1); + showcapsflag = 1; + return; + } + bzero(&ifrdat, sizeof(ifrdat)); + ifr.ifr_data = (caddr_t)&ifrdat; + if (ioctl(s, SIOCGIFDATA, (caddr_t)&ifr) == -1) + err(1, "SIOCGIFDATA"); + if (!ifrdat.ifi_capabilities) + return; + printf("\tcapabilities:\n"); + for (c = caps; c->c_desc != NULL; c++) + if (ifrdat.ifi_capabilities & c->c_mask) + printf("\t\t%s\n", c->c_desc); +} #endif + #ifdef INET6 char * Index: sbin/ifconfig/ifconfig.8 =================================================================== RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v retrieving revision 1.219 diff -d -u -p -w -r1.219 ifconfig.8 --- sbin/ifconfig/ifconfig.8 9 Jul 2011 08:44:54 -0000 1.219 +++ sbin/ifconfig/ifconfig.8 17 Aug 2011 03:33:15 -0000 @@ -156,6 +156,8 @@ Disable the use of ARP. Specify the address to use to represent broadcasts to the network. The default broadcast address is the address with a host part of all 1's. +.It Cm capabilities +Display the interface hardware capabilities. .It Cm create Create the specified network pseudo-device. At least the following devices can be created on demand: Index: sys/net/if.h =================================================================== RCS file: /cvs/src/sys/net/if.h,v retrieving revision 1.128 diff -d -u -p -w -r1.128 if.h --- sys/net/if.h 8 Jul 2011 18:48:51 -0000 1.128 +++ sys/net/if.h 17 Aug 2011 03:17:31 -0000 @@ -142,6 +142,7 @@ struct if_data { u_int64_t ifi_omcasts; /* packets sent via multicast */ u_int64_t ifi_iqdrops; /* dropped on input, this interface */ u_int64_t ifi_noproto; /* destined for unsupported protocol */ + int ifi_capabilities; /* interface capabilities */ struct timeval ifi_lastchange; /* last operational state change */ struct mclpool ifi_mclpool[MCLPOOLS]; @@ -264,7 +265,6 @@ struct ifnet { /* and the entries */ int if_xflags; /* extra softnet flags */ struct if_data if_data; /* stats and other data about if */ u_int32_t if_hardmtu; /* maximum MTU device supports */ - int if_capabilities; /* interface capabilities */ u_int if_rdomain; /* routing instance */ char if_description[IFDESCRSIZE]; /* interface description */ u_short if_rtlabelid; /* next route label */ @@ -311,6 +311,7 @@ struct ifnet { /* and the entries */ #define if_iqdrops if_data.ifi_iqdrops #define if_noproto if_data.ifi_noproto #define if_lastchange if_data.ifi_lastchange +#define if_capabilities if_data.ifi_capabilities #define IFF_UP 0x1 /* interface is up */ #define IFF_BROADCAST 0x2 /* broadcast address valid */