/* $NetBSD: if_media_80.c,v 1.5 2022/08/03 01:38:51 riastradh Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
* NASA Ames Research Center.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright (c) 1997
* Jonathan Stone and Jason R. Thorpe. All rights reserved.
*
* This software is derived from information provided by Matt Thomas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Jonathan Stone
* and Jason R. Thorpe for the NetBSD Project.
* 4. The names of the authors may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_media_80.c,v 1.5 2022/08/03 01:38:51 riastradh Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/syscallargs.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/compat_stub.h>
#include <net/if.h>
#include <net/if_media.h>
#include <compat/sys/sockio.h>
#include <compat/common/compat_mod.h>
static void
ifmword_n2o(int *oldwd, int *newwd)
{
if (IFM_SUBTYPE(*newwd) > IFM_OTHER)
*oldwd = (*newwd & ~(_IFM_ETH_XTMASK | IFM_TMASK)) | IFM_OTHER;
else
*oldwd = *newwd;
}
/*ARGSUSED*/
static int
compat_ifmediareq_pre(struct ifreq *ifr, u_long *cmd, bool *do_post)
{
struct ifmediareq *ifmr = (struct ifmediareq *)ifr;
switch (*cmd) {
case SIOCSIFMEDIA_80:
*cmd = SIOCSIFMEDIA; /* Convert to new one */
if ((IFM_TYPE(ifr->ifr_media) == IFM_ETHER) &&
IFM_SUBTYPE(ifr->ifr_media) > IFM_OTHER) {
/* Clear unused bits to not to change to wrong media */
ifr->ifr_media &= ~_IFM_ETH_XTMASK;
}
return 0;
case SIOCGIFMEDIA_80:
*cmd = SIOCGIFMEDIA; /* Convert to new one */
if (ifmr->ifm_count != 0) {
/*
* Tell the upper layer to try to convert each ifmedia
* entry in the post process.
*/
*do_post = true;
}
return 0;
default:
return 0;
}
}
/*ARGSUSED*/
static int
compat_ifmediareq_post(struct ifreq *ifr, u_long cmd)
{
struct ifmediareq *ifmr = (struct ifmediareq *)ifr;
size_t minwords;
size_t count;
int error, *kptr;
switch (cmd) {
case SIOCSIFMEDIA:
return 0;
case SIOCGIFMEDIA:
if (ifmr->ifm_count < 0)
return EINVAL;
/*
* ifmr->ifm_count was already ajusted in ifmedia_ioctl(), so
* there is no problem to trust ifm_count.
*/
minwords = ifmr->ifm_count;
kptr = malloc(minwords * sizeof(*kptr), M_TEMP,
M_WAITOK|M_ZERO);
if (kptr == NULL)
return ENOMEM;
/*
* Convert ifm_current and ifm_active.
* It's not required to convert ifm_mask.
*/
ifmword_n2o(&ifmr->ifm_current, &ifmr->ifm_current);
ifmword_n2o(&ifmr->ifm_active, &ifmr->ifm_active);
/* Convert ifm_ulist array */
for (count = 0; count < minwords; count++) {
int oldmwd;
error = ufetch_int(&ifmr->ifm_ulist[count], &oldmwd);
if (error != 0)
goto out;
ifmword_n2o(&kptr[count], &oldmwd);
}
/* Copy to userland in old format */
error = copyout(kptr, ifmr->ifm_ulist,
minwords * sizeof(*kptr));
out:
free(kptr, M_TEMP);
return error;
default:
return 0;
}
}
void
ifmedia_80_init(void)
{
MODULE_HOOK_SET(ifmedia_80_pre_hook, compat_ifmediareq_pre);
MODULE_HOOK_SET(ifmedia_80_post_hook, compat_ifmediareq_post);
}
void
ifmedia_80_fini(void)
{
MODULE_HOOK_UNSET(ifmedia_80_post_hook);
MODULE_HOOK_UNSET(ifmedia_80_pre_hook);
}