xref: /netbsd-src/sys/compat/common/if_media_80.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: if_media_80.c,v 1.3 2019/12/12 02:15:42 pgoyette 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, M_WAITOK);
145 		if (kptr == NULL)
146 			return ENOMEM;
147 
148 		/*
149 		 * Convert ifm_current and ifm_active.
150 		 * It's not required to convert ifm_mask.
151 		 */
152 		ifmword_n2o(&ifmr->ifm_current, &ifmr->ifm_current);
153 		ifmword_n2o(&ifmr->ifm_active, &ifmr->ifm_active);
154 
155 		/* Convert ifm_ulist array */
156 		for (count = 0; count < minwords; count++) {
157 			int oldmwd;
158 
159 			error = ufetch_int(&ifmr->ifm_ulist[count], &oldmwd);
160 			if (error != 0)
161 				goto out;
162 			ifmword_n2o(&kptr[count], &oldmwd);
163 		}
164 
165 		/* Copy to userland in old format */
166 		error = copyout(kptr, ifmr->ifm_ulist,
167 		    minwords * sizeof(*kptr));
168 out:
169 		free(kptr, M_TEMP);
170 		return error;
171 	default:
172 		return 0;
173 	}
174 }
175 
176 void
177 ifmedia_80_init(void)
178 {
179 
180 	MODULE_HOOK_SET(ifmedia_80_pre_hook, compat_ifmediareq_pre);
181 	MODULE_HOOK_SET(ifmedia_80_post_hook, compat_ifmediareq_post);
182 }
183 
184 void
185 ifmedia_80_fini(void)
186 {
187 
188 	MODULE_HOOK_UNSET(ifmedia_80_post_hook);
189 	MODULE_HOOK_UNSET(ifmedia_80_pre_hook);
190 }
191