svr4_sockio.c revision 182145
198684Sdes/*- 299051Sdes * Copyright (c) 1998 Mark Newton 357429Smarkm * Copyright (c) 1995 Christos Zoulas 498684Sdes * All rights reserved. 598684Sdes * 676262Sgreen * Redistribution and use in source and binary forms, with or without 798941Sdes * modification, are permitted provided that the following conditions 898941Sdes * are met: 992559Sdes * 1. Redistributions of source code must retain the above copyright 1092559Sdes * notice, this list of conditions and the following disclaimer. 1192559Sdes * 2. Redistributions in binary form must reproduce the above copyright 1292559Sdes * notice, this list of conditions and the following disclaimer in the 1392559Sdes * documentation and/or other materials provided with the distribution. 1499051Sdes * 3. The name of the author may not be used to endorse or promote products 1599051Sdes * derived from this software without specific prior written permission 1699051Sdes * 1799051Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1899051Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1992559Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2060576Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2157429Smarkm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2257429Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2369591Sgreen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2492559Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2592559Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2692559Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2792559Sdes */ 2892559Sdes 2957429Smarkm#include <sys/cdefs.h> 3092559Sdes__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_sockio.c 182145 2008-08-25 05:38:18Z julian $"); 3192559Sdes 3292559Sdes#include <sys/param.h> 3392559Sdes#include <sys/proc.h> 3457429Smarkm#include <sys/systm.h> 3557429Smarkm#include <sys/file.h> 3692559Sdes#include <sys/filedesc.h> 3792559Sdes#include <sys/sockio.h> 3857429Smarkm#include <sys/socket.h> 3992559Sdes#include <sys/vimage.h> 4092559Sdes 4199051Sdes#include <net/if.h> 4299051Sdes 4392559Sdes#include <compat/svr4/svr4.h> 4492559Sdes#include <compat/svr4/svr4_util.h> 4592559Sdes#include <compat/svr4/svr4_ioctl.h> 4692559Sdes#include <compat/svr4/svr4_sockio.h> 4792559Sdes 4892559Sdesstatic int bsd_to_svr4_flags(int); 4992559Sdes 5092559Sdes#define bsd_to_svr4_flag(a) \ 5192559Sdes if (bf & __CONCAT(I,a)) sf |= __CONCAT(SVR4_I,a) 5292559Sdes 5392559Sdesstatic int 5492559Sdesbsd_to_svr4_flags(bf) 5576262Sgreen int bf; 5692559Sdes{ 5792559Sdes int sf = 0; 5892559Sdes bsd_to_svr4_flag(FF_UP); 5992559Sdes bsd_to_svr4_flag(FF_BROADCAST); 6057429Smarkm bsd_to_svr4_flag(FF_DEBUG); 6157429Smarkm bsd_to_svr4_flag(FF_LOOPBACK); 6292559Sdes bsd_to_svr4_flag(FF_POINTOPOINT); 6392559Sdes#if defined(IFF_NOTRAILERS) 6476262Sgreen bsd_to_svr4_flag(FF_NOTRAILERS); 6595456Sdes#endif 6695456Sdes if (bf & IFF_DRV_RUNNING) 6757429Smarkm sf |= SVR4_IFF_RUNNING; 6892559Sdes bsd_to_svr4_flag(FF_NOARP); 6998684Sdes bsd_to_svr4_flag(FF_PROMISC); 7057429Smarkm bsd_to_svr4_flag(FF_ALLMULTI); 7192559Sdes bsd_to_svr4_flag(FF_MULTICAST); 7257429Smarkm return sf; 7398684Sdes} 7457429Smarkm 7592559Sdesint 7692559Sdessvr4_sock_ioctl(fp, td, retval, fd, cmd, data) 7792559Sdes struct file *fp; 7898941Sdes struct thread *td; 7998941Sdes register_t *retval; 8098941Sdes int fd; 8198941Sdes u_long cmd; 8299051Sdes caddr_t data; 8392559Sdes{ 8492559Sdes int error; 8592559Sdes 8692559Sdes *retval = 0; 8792559Sdes 8857429Smarkm switch (cmd) { 8998941Sdes case SVR4_SIOCGIFNUM: 9098684Sdes { 9165674Skris struct ifnet *ifp; 9292559Sdes struct ifaddr *ifa; 9392559Sdes int ifnum = 0; 9492559Sdes 9592559Sdes /* 9676262Sgreen * This does not return the number of physical 9792559Sdes * interfaces (if_index), but the number of interfaces 9876262Sgreen * + addresses like ifconf() does, because this number 99 * is used by code that will call SVR4_SIOCGIFCONF to 100 * find the space needed for SVR4_SIOCGIFCONF. So we 101 * count the number of ifreq entries that the next 102 * SVR4_SIOCGIFCONF will return. Maybe a more correct 103 * fix is to make SVR4_SIOCGIFCONF return only one 104 * entry per physical interface? 105 */ 106 IFNET_RLOCK(); 107 TAILQ_FOREACH(ifp, &V_ifnet, if_link) 108 if (TAILQ_EMPTY(&ifp->if_addrhead)) 109 ifnum++; 110 else 111 TAILQ_FOREACH(ifa, &ifp->if_addrhead, 112 ifa_link) 113 ifnum++; 114 IFNET_RUNLOCK(); 115 DPRINTF(("SIOCGIFNUM %d\n", ifnum)); 116 return copyout(&ifnum, data, sizeof(ifnum)); 117 } 118 119 case SVR4_SIOCGIFFLAGS: 120 { 121 struct ifreq br; 122 struct svr4_ifreq sr; 123 124 if ((error = copyin(data, &sr, sizeof(sr))) != 0) 125 return error; 126 127 (void) strlcpy(br.ifr_name, sr.svr4_ifr_name, 128 sizeof(br.ifr_name)); 129 if ((error = fo_ioctl(fp, SIOCGIFFLAGS, 130 (caddr_t) &br, td->td_ucred, 131 td)) != 0) { 132 DPRINTF(("SIOCGIFFLAGS (%s) %s: error %d\n", 133 br.ifr_name, sr.svr4_ifr_name, error)); 134 return error; 135 } 136 137 sr.svr4_ifr_flags = bsd_to_svr4_flags(br.ifr_flags); 138 DPRINTF(("SIOCGIFFLAGS %s = %x\n", 139 sr.svr4_ifr_name, sr.svr4_ifr_flags)); 140 return copyout(&sr, data, sizeof(sr)); 141 } 142 143 case SVR4_SIOCGIFCONF: 144 { 145 struct svr4_ifconf sc; 146 147 if ((error = copyin(data, &sc, sizeof(sc))) != 0) 148 return error; 149 150 DPRINTF(("ifreq %d svr4_ifreq %d ifc_len %d\n", 151 sizeof(struct ifreq), sizeof(struct svr4_ifreq), 152 sc.svr4_ifc_len)); 153 154 if ((error = fo_ioctl(fp, OSIOCGIFCONF, 155 (caddr_t) &sc, td->td_ucred, 156 td)) != 0) 157 return error; 158 159 DPRINTF(("SIOCGIFCONF\n")); 160 return 0; 161 } 162 163 164 default: 165 DPRINTF(("Unknown svr4 sockio %lx\n", cmd)); 166 return 0; /* ENOSYS really */ 167 } 168} 169