1 /* $NetBSD: svr4_sockio.c,v 1.26 2006/11/16 01:32:44 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1995 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: svr4_sockio.c,v 1.26 2006/11/16 01:32:44 christos Exp $");
41
42 #include <sys/param.h>
43 #include <sys/proc.h>
44 #include <sys/systm.h>
45 #include <sys/file.h>
46 #include <sys/filedesc.h>
47 #include <sys/ioctl.h>
48 #include <sys/termios.h>
49 #include <sys/tty.h>
50 #include <sys/socket.h>
51 #include <sys/ioctl.h>
52 #include <sys/mount.h>
53 #include <net/if.h>
54 #include <sys/malloc.h>
55
56 #include <sys/sa.h>
57 #include <sys/syscallargs.h>
58
59 #include <compat/sys/socket.h>
60
61 #include <compat/svr4/svr4_types.h>
62 #include <compat/svr4/svr4_util.h>
63 #include <compat/svr4/svr4_signal.h>
64 #include <compat/svr4/svr4_lwp.h>
65 #include <compat/svr4/svr4_ucontext.h>
66 #include <compat/svr4/svr4_syscallargs.h>
67 #include <compat/svr4/svr4_stropts.h>
68 #include <compat/svr4/svr4_ioctl.h>
69 #include <compat/svr4/svr4_sockio.h>
70
71 static int bsd_to_svr4_flags __P((int));
72
73 #define bsd_to_svr4_flag(a) \
74 if (bf & __CONCAT(I,a)) sf |= __CONCAT(SVR4_I,a)
75
76 static int
77 bsd_to_svr4_flags(bf)
78 int bf;
79 {
80 int sf = 0;
81 bsd_to_svr4_flag(FF_UP);
82 bsd_to_svr4_flag(FF_BROADCAST);
83 bsd_to_svr4_flag(FF_DEBUG);
84 bsd_to_svr4_flag(FF_LOOPBACK);
85 bsd_to_svr4_flag(FF_POINTOPOINT);
86 bsd_to_svr4_flag(FF_NOTRAILERS);
87 bsd_to_svr4_flag(FF_RUNNING);
88 bsd_to_svr4_flag(FF_NOARP);
89 bsd_to_svr4_flag(FF_PROMISC);
90 bsd_to_svr4_flag(FF_ALLMULTI);
91 bsd_to_svr4_flag(FF_MULTICAST);
92 return sf;
93 }
94
95 int
96 svr4_sock_ioctl(struct file *fp, struct lwp *l, register_t *retval,
97 int fd, u_long cmd, caddr_t data)
98 {
99 int error;
100 int (*ctl)(struct file *, u_long, void *, struct lwp *) =
101 fp->f_ops->fo_ioctl;
102
103 *retval = 0;
104
105 switch (cmd) {
106 case SVR4_SIOCGLIFNUM:
107 {
108 struct ifnet *ifp;
109 struct ifaddr *ifa;
110 struct svr4_lifnum lifnum;
111
112 error = copyin(data, &lifnum, sizeof(lifnum));
113 if (error)
114 return error;
115
116 lifnum.lifn_count = 0;
117 /* XXX: We don't pay attention to family or flags */
118 for (ifp = ifnet.tqh_first;
119 ifp != 0; ifp = ifp->if_list.tqe_next)
120 if ((ifa = ifp->if_addrlist.tqh_first) == NULL)
121 lifnum.lifn_count++;
122 else
123 for (;ifa != NULL;
124 ifa = ifa->ifa_list.tqe_next)
125 lifnum.lifn_count++;
126
127 DPRINTF(("SIOCGLIFNUM [family=%d,flags=%d,count=%d]\n",
128 lifnum.lifn_family, lifnum.lifn_flags,
129 lifnum.lifn_count));
130 return copyout(&lifnum, data, sizeof(lifnum));
131 }
132
133 case SVR4_SIOCGIFNUM:
134 {
135 struct ifnet *ifp;
136 struct ifaddr *ifa;
137 int ifnum = 0;
138
139 /*
140 * This does not return the number of physical
141 * interfaces (if_index), but the number of interfaces
142 * + addresses like ifconf() does, because this number
143 * is used by code that will call SVR4_SIOCGIFCONF to
144 * find the space needed for SVR4_SIOCGIFCONF. So we
145 * count the number of ifreq entries that the next
146 * SVR4_SIOCGIFCONF will return. Maybe a more correct
147 * fix is to make SVR4_SIOCGIFCONF return only one
148 * entry per physical interface?
149 */
150
151 for (ifp = ifnet.tqh_first;
152 ifp != 0; ifp = ifp->if_list.tqe_next)
153 if ((ifa = ifp->if_addrlist.tqh_first) == NULL)
154 ifnum++;
155 else
156 for (;ifa != NULL;
157 ifa = ifa->ifa_list.tqe_next)
158 ifnum++;
159
160
161 DPRINTF(("SIOCGIFNUM %d\n", ifnum));
162 return copyout(&ifnum, data, sizeof(ifnum));
163 }
164
165 case SVR4_SIOCGIFFLAGS:
166 {
167 struct ifreq br;
168 struct svr4_ifreq sr;
169
170 if ((error = copyin(data, &sr, sizeof(sr))) != 0)
171 return error;
172
173 (void) strncpy(br.ifr_name, sr.svr4_ifr_name,
174 sizeof(br.ifr_name));
175
176 if ((error = (*ctl)(fp, SIOCGIFFLAGS,
177 (caddr_t) &br, l)) != 0) {
178 DPRINTF(("SIOCGIFFLAGS %s: error %d\n",
179 sr.svr4_ifr_name, error));
180 return error;
181 }
182
183 sr.svr4_ifr_flags = bsd_to_svr4_flags(br.ifr_flags);
184 DPRINTF(("SIOCGIFFLAGS %s = %x\n",
185 sr.svr4_ifr_name, sr.svr4_ifr_flags));
186 return copyout(&sr, data, sizeof(sr));
187 }
188
189 case SVR4_SIOCGIFCONF:
190 {
191 struct svr4_ifconf sc;
192
193 if ((error = copyin(data, &sc, sizeof(sc))) != 0)
194 return error;
195
196 DPRINTF(("ifreq %ld svr4_ifreq %ld ifc_len %d\n",
197 (unsigned long)sizeof(struct ifreq),
198 (unsigned long)sizeof(struct svr4_ifreq),
199 sc.svr4_ifc_len));
200
201 if ((error = (*ctl)(fp, OSIOCGIFCONF,
202 (caddr_t) &sc, l)) != 0)
203 return error;
204
205 DPRINTF(("SIOCGIFCONF\n"));
206 return 0;
207 }
208
209
210 default:
211 DPRINTF(("Unknown svr4 sockio %lx\n", cmd));
212 return 0; /* ENOSYS really */
213 }
214 }
Cache object: 0bc67e580ab5d779a687f745c9704289
|