if_media_80.c revision 1.4 1 /* $NetBSD: if_media_80.c,v 1.4 2021/09/07 11:43:02 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
69 #include <sys/param.h>
70 #include <sys/kernel.h>
71 #include <sys/syscallargs.h>
72 #include <sys/errno.h>
73 #include <sys/malloc.h>
74 #include <sys/proc.h>
75 #include <sys/compat_stub.h>
76
77 #include <net/if.h>
78 #include <net/if_media.h>
79
80 #include <compat/sys/sockio.h>
81 #include <compat/common/compat_mod.h>
82
83 static void
84 ifmword_n2o(int *oldwd, int *newwd)
85 {
86
87 if (IFM_SUBTYPE(*newwd) > IFM_OTHER)
88 *oldwd = (*newwd & ~(_IFM_ETH_XTMASK | IFM_TMASK)) | IFM_OTHER;
89 else
90 *oldwd = *newwd;
91 }
92
93 /*ARGSUSED*/
94 static int
95 compat_ifmediareq_pre(struct ifreq *ifr, u_long *cmd, bool *do_post)
96 {
97 struct ifmediareq *ifmr = (struct ifmediareq *)ifr;
98
99 switch (*cmd) {
100 case SIOCSIFMEDIA_80:
101 *cmd = SIOCSIFMEDIA; /* Convert to new one */
102 if ((IFM_TYPE(ifr->ifr_media) == IFM_ETHER) &&
103 IFM_SUBTYPE(ifr->ifr_media) > IFM_OTHER) {
104 /* Clear unused bits to not to change to wrong media */
105 ifr->ifr_media &= ~_IFM_ETH_XTMASK;
106 }
107 return 0;
108 case SIOCGIFMEDIA_80:
109 *cmd = SIOCGIFMEDIA; /* Convert to new one */
110 if (ifmr->ifm_count != 0) {
111 /*
112 * Tell the upper layer to try to convert each ifmedia
113 * entry in the post process.
114 */
115 *do_post = true;
116 }
117 return 0;
118 default:
119 return 0;
120 }
121 }
122
123 /*ARGSUSED*/
124 static int
125 compat_ifmediareq_post(struct ifreq *ifr, u_long cmd)
126 {
127 struct ifmediareq *ifmr = (struct ifmediareq *)ifr;
128 size_t minwords;
129 size_t count;
130 int error, *kptr;
131
132 switch (cmd) {
133 case SIOCSIFMEDIA:
134 return 0;
135 case SIOCGIFMEDIA:
136 if (ifmr->ifm_count < 0)
137 return EINVAL;
138
139 /*
140 * ifmr->ifm_count was already ajusted in ifmedia_ioctl(), so
141 * there is no problem to trust ifm_count.
142 */
143 minwords = ifmr->ifm_count;
144 kptr = malloc(minwords * sizeof(*kptr), M_TEMP,
145 M_WAITOK|M_ZERO);
146 if (kptr == NULL)
147 return ENOMEM;
148
149 /*
150 * Convert ifm_current and ifm_active.
151 * It's not required to convert ifm_mask.
152 */
153 ifmword_n2o(&ifmr->ifm_current, &ifmr->ifm_current);
154 ifmword_n2o(&ifmr->ifm_active, &ifmr->ifm_active);
155
156 /* Convert ifm_ulist array */
157 for (count = 0; count < minwords; count++) {
158 int oldmwd;
159
160 error = ufetch_int(&ifmr->ifm_ulist[count], &oldmwd);
161 if (error != 0)
162 goto out;
163 ifmword_n2o(&kptr[count], &oldmwd);
164 }
165
166 /* Copy to userland in old format */
167 error = copyout(kptr, ifmr->ifm_ulist,
168 minwords * sizeof(*kptr));
169 out:
170 free(kptr, M_TEMP);
171 return error;
172 default:
173 return 0;
174 }
175 }
176
177 void
178 ifmedia_80_init(void)
179 {
180
181 MODULE_HOOK_SET(ifmedia_80_pre_hook, compat_ifmediareq_pre);
182 MODULE_HOOK_SET(ifmedia_80_post_hook, compat_ifmediareq_post);
183 }
184
185 void
186 ifmedia_80_fini(void)
187 {
188
189 MODULE_HOOK_UNSET(ifmedia_80_post_hook);
190 MODULE_HOOK_UNSET(ifmedia_80_pre_hook);
191 }
192