1 /* $NetBSD: if_media_80.c,v 1.5 2022/08/03 01:38:51 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Copyright (c) 1997 35 * Jonathan Stone and Jason R. Thorpe. All rights reserved. 36 * 37 * This software is derived from information provided by Matt Thomas. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. All advertising materials mentioning features or use of this software 48 * must display the following acknowledgement: 49 * This product includes software developed by Jonathan Stone 50 * and Jason R. Thorpe for the NetBSD Project. 51 * 4. The names of the authors may not be used to endorse or promote products 52 * derived from this software without specific prior written permission. 53 * 54 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 55 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 56 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 57 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 58 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 59 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 60 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 61 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 62 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 64 * SUCH DAMAGE. 65 */ 66 67 #include <sys/cdefs.h> 68 __KERNEL_RCSID(0, "$NetBSD: if_media_80.c,v 1.5 2022/08/03 01:38:51 riastradh Exp $"); 69 70 #include <sys/param.h> 71 #include <sys/kernel.h> 72 #include <sys/syscallargs.h> 73 #include <sys/errno.h> 74 #include <sys/malloc.h> 75 #include <sys/proc.h> 76 #include <sys/compat_stub.h> 77 78 #include <net/if.h> 79 #include <net/if_media.h> 80 81 #include <compat/sys/sockio.h> 82 #include <compat/common/compat_mod.h> 83 84 static void 85 ifmword_n2o(int *oldwd, int *newwd) 86 { 87 88 if (IFM_SUBTYPE(*newwd) > IFM_OTHER) 89 *oldwd = (*newwd & ~(_IFM_ETH_XTMASK | IFM_TMASK)) | IFM_OTHER; 90 else 91 *oldwd = *newwd; 92 } 93 94 /*ARGSUSED*/ 95 static int 96 compat_ifmediareq_pre(struct ifreq *ifr, u_long *cmd, bool *do_post) 97 { 98 struct ifmediareq *ifmr = (struct ifmediareq *)ifr; 99 100 switch (*cmd) { 101 case SIOCSIFMEDIA_80: 102 *cmd = SIOCSIFMEDIA; /* Convert to new one */ 103 if ((IFM_TYPE(ifr->ifr_media) == IFM_ETHER) && 104 IFM_SUBTYPE(ifr->ifr_media) > IFM_OTHER) { 105 /* Clear unused bits to not to change to wrong media */ 106 ifr->ifr_media &= ~_IFM_ETH_XTMASK; 107 } 108 return 0; 109 case SIOCGIFMEDIA_80: 110 *cmd = SIOCGIFMEDIA; /* Convert to new one */ 111 if (ifmr->ifm_count != 0) { 112 /* 113 * Tell the upper layer to try to convert each ifmedia 114 * entry in the post process. 115 */ 116 *do_post = true; 117 } 118 return 0; 119 default: 120 return 0; 121 } 122 } 123 124 /*ARGSUSED*/ 125 static int 126 compat_ifmediareq_post(struct ifreq *ifr, u_long cmd) 127 { 128 struct ifmediareq *ifmr = (struct ifmediareq *)ifr; 129 size_t minwords; 130 size_t count; 131 int error, *kptr; 132 133 switch (cmd) { 134 case SIOCSIFMEDIA: 135 return 0; 136 case SIOCGIFMEDIA: 137 if (ifmr->ifm_count < 0) 138 return EINVAL; 139 140 /* 141 * ifmr->ifm_count was already ajusted in ifmedia_ioctl(), so 142 * there is no problem to trust ifm_count. 143 */ 144 minwords = ifmr->ifm_count; 145 kptr = malloc(minwords * sizeof(*kptr), M_TEMP, 146 M_WAITOK|M_ZERO); 147 if (kptr == NULL) 148 return ENOMEM; 149 150 /* 151 * Convert ifm_current and ifm_active. 152 * It's not required to convert ifm_mask. 153 */ 154 ifmword_n2o(&ifmr->ifm_current, &ifmr->ifm_current); 155 ifmword_n2o(&ifmr->ifm_active, &ifmr->ifm_active); 156 157 /* Convert ifm_ulist array */ 158 for (count = 0; count < minwords; count++) { 159 int oldmwd; 160 161 error = ufetch_int(&ifmr->ifm_ulist[count], &oldmwd); 162 if (error != 0) 163 goto out; 164 ifmword_n2o(&kptr[count], &oldmwd); 165 } 166 167 /* Copy to userland in old format */ 168 error = copyout(kptr, ifmr->ifm_ulist, 169 minwords * sizeof(*kptr)); 170 out: 171 free(kptr, M_TEMP); 172 return error; 173 default: 174 return 0; 175 } 176 } 177 178 void 179 ifmedia_80_init(void) 180 { 181 182 MODULE_HOOK_SET(ifmedia_80_pre_hook, compat_ifmediareq_pre); 183 MODULE_HOOK_SET(ifmedia_80_post_hook, compat_ifmediareq_post); 184 } 185 186 void 187 ifmedia_80_fini(void) 188 { 189 190 MODULE_HOOK_UNSET(ifmedia_80_post_hook); 191 MODULE_HOOK_UNSET(ifmedia_80_pre_hook); 192 } 193