From 6fd5ea7e7a4a9137b636d41a34fb42b34de0930a Mon Sep 17 00:00:00 2001 From: markj Date: Sat, 6 Sep 2014 04:33:37 +0000 Subject: [PATCH] MFC r270348: Add some missing checks for unsupported interfaces (e.g. pflog(4)) when handling ioctls. While here, remove duplicated checks for a NULL ifp in in6_control(): this check is already done near the beginning of the function. MFC r270349: Suppress warnings when retrieving protocol stats from interfaces that don't support IPv6 (e.g. pflog(4)). PR: 189117 git-svn-id: svn://svn.freebsd.org/base/stable/9@271184 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/netinet6/in6.c | 27 +++++++++++---------------- sys/netinet6/scope6.c | 31 +++++++++++++++++++++++++++++-- sys/netinet6/scope6_var.h | 3 +-- usr.bin/netstat/inet6.c | 12 ++++++------ 4 files changed, 47 insertions(+), 26 deletions(-) diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 21e3d389d..8731ae022 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -284,7 +284,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, return (mrt6_ioctl ? mrt6_ioctl(cmd, data) : EOPNOTSUPP); } - switch(cmd) { + switch (cmd) { case SIOCAADDRCTL_POLICY: case SIOCDADDRCTL_POLICY: if (td != NULL) { @@ -356,14 +356,10 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, if (error) return (error); } - return (scope6_set(ifp, - (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + /* FALLTHROUGH */ case SIOCGSCOPE6: - return (scope6_get(ifp, - (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); case SIOCGSCOPE6DEF: - return (scope6_get_default((struct scope6_id *) - ifr->ifr_ifru.ifru_scope_id)); + return (scope6_ioctl(cmd, data, ifp)); } switch (cmd) { @@ -494,6 +490,13 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, if (error) goto out; } + /* FALLTHROUGH */ + case SIOCGIFSTAT_IN6: + case SIOCGIFSTAT_ICMP6: + if (ifp->if_afdata[AF_INET6] == NULL) { + error = EPFNOSUPPORT; + goto out; + } break; case SIOCGIFADDR_IN6: @@ -569,10 +572,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, break; case SIOCGIFSTAT_IN6: - if (ifp == NULL) { - error = EINVAL; - goto out; - } bzero(&ifr->ifr_ifru.ifru_stat, sizeof(ifr->ifr_ifru.ifru_stat)); ifr->ifr_ifru.ifru_stat = @@ -580,10 +579,6 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, break; case SIOCGIFSTAT_ICMP6: - if (ifp == NULL) { - error = EINVAL; - goto out; - } bzero(&ifr->ifr_ifru.ifru_icmp6stat, sizeof(ifr->ifr_ifru.ifru_icmp6stat)); ifr->ifr_ifru.ifru_icmp6stat = @@ -799,7 +794,7 @@ in6_control(struct socket *so, u_long cmd, caddr_t data, } default: - if (ifp == NULL || ifp->if_ioctl == 0) { + if (ifp->if_ioctl == NULL) { error = EOPNOTSUPP; goto out; } diff --git a/sys/netinet6/scope6.c b/sys/netinet6/scope6.c index 1cfe1036d..debb08d53 100644 --- a/sys/netinet6/scope6.c +++ b/sys/netinet6/scope6.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -72,6 +73,9 @@ static VNET_DEFINE(struct scope6_id, sid_default); #define SID(ifp) \ (((struct in6_ifextra *)(ifp)->if_afdata[AF_INET6])->scope6_id) +static int scope6_get(struct ifnet *, struct scope6_id *); +static int scope6_set(struct ifnet *, struct scope6_id *); + void scope6_init(void) { @@ -115,6 +119,30 @@ scope6_ifdetach(struct scope6_id *sid) } int +scope6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) +{ + struct in6_ifreq *ifr; + + if (ifp->if_afdata[AF_INET6] == NULL) + return (EPFNOSUPPORT); + + ifr = (struct in6_ifreq *)data; + switch (cmd) { + case SIOCSSCOPE6: + return (scope6_set(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + case SIOCGSCOPE6: + return (scope6_get(ifp, + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + case SIOCGSCOPE6DEF: + return (scope6_get_default( + (struct scope6_id *)ifr->ifr_ifru.ifru_scope_id)); + default: + return (EOPNOTSUPP); + } +} + +static int scope6_set(struct ifnet *ifp, struct scope6_id *idlist) { int i; @@ -177,7 +205,7 @@ scope6_set(struct ifnet *ifp, struct scope6_id *idlist) return (error); } -int +static int scope6_get(struct ifnet *ifp, struct scope6_id *idlist) { struct scope6_id *sid; @@ -196,7 +224,6 @@ scope6_get(struct ifnet *ifp, struct scope6_id *idlist) return (0); } - /* * Get a scope of the address. Node-local, link-local, site-local or global. */ diff --git a/sys/netinet6/scope6_var.h b/sys/netinet6/scope6_var.h index ae337b860..990325e97 100644 --- a/sys/netinet6/scope6_var.h +++ b/sys/netinet6/scope6_var.h @@ -45,8 +45,7 @@ struct scope6_id { void scope6_init(void); struct scope6_id *scope6_ifattach(struct ifnet *); void scope6_ifdetach(struct scope6_id *); -int scope6_set(struct ifnet *, struct scope6_id *); -int scope6_get(struct ifnet *, struct scope6_id *); +int scope6_ioctl(u_long cmd, caddr_t data, struct ifnet *); void scope6_setdefault(struct ifnet *); int scope6_get_default(struct scope6_id *); u_int32_t scope6_addr2default(struct in6_addr *); diff --git a/usr.bin/netstat/inet6.c b/usr.bin/netstat/inet6.c index df0a297d1..052b8c532 100644 --- a/usr.bin/netstat/inet6.c +++ b/usr.bin/netstat/inet6.c @@ -540,13 +540,13 @@ ip6_ifstats(char *ifname) } strcpy(ifr.ifr_name, ifname); - printf("ip6 on %s:\n", ifr.ifr_name); - if (ioctl(s, SIOCGIFSTAT_IN6, (char *)&ifr) < 0) { - perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); + if (errno != EPFNOSUPPORT) + perror("Warning: ioctl(SIOCGIFSTAT_IN6)"); goto end; } + printf("ip6 on %s:\n", ifr.ifr_name); p(ifs6_in_receive, "\t%ju total input datagram%s\n"); p(ifs6_in_hdrerr, "\t%ju datagram%s with invalid header received\n"); p(ifs6_in_toobig, "\t%ju datagram%s exceeded MTU received\n"); @@ -945,13 +945,13 @@ icmp6_ifstats(char *ifname) } strcpy(ifr.ifr_name, ifname); - printf("icmp6 on %s:\n", ifr.ifr_name); - if (ioctl(s, SIOCGIFSTAT_ICMP6, (char *)&ifr) < 0) { - perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); + if (errno != EPFNOSUPPORT) + perror("Warning: ioctl(SIOCGIFSTAT_ICMP6)"); goto end; } + printf("icmp6 on %s:\n", ifr.ifr_name); p(ifs6_in_msg, "\t%ju total input message%s\n"); p(ifs6_in_error, "\t%ju total input error message%s\n"); p(ifs6_in_dstunreach, "\t%ju input destination unreachable error%s\n"); -- 2.45.0