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 */

Reply via email to