uipc_syscalls_40.c revision 1.15.2.4 1 1.15.2.4 pgoyette /* $NetBSD: uipc_syscalls_40.c,v 1.15.2.4 2018/03/08 00:25:30 pgoyette Exp $ */
2 1.1 christos
3 1.1 christos /* written by Pavel Cahyna, 2006. Public domain. */
4 1.1 christos
5 1.1 christos #include <sys/cdefs.h>
6 1.15.2.4 pgoyette __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_40.c,v 1.15.2.4 2018/03/08 00:25:30 pgoyette Exp $");
7 1.1 christos
8 1.1 christos /*
9 1.1 christos * System call interface to the socket abstraction.
10 1.1 christos */
11 1.1 christos
12 1.1 christos #include <sys/param.h>
13 1.1 christos #include <sys/kernel.h>
14 1.1 christos #include <sys/msg.h>
15 1.1 christos #include <sys/sysctl.h>
16 1.1 christos #include <sys/syscallargs.h>
17 1.1 christos #include <sys/errno.h>
18 1.1 christos
19 1.1 christos #include <net/if.h>
20 1.1 christos
21 1.15.2.4 pgoyette #include <compat/sys/if.h>
22 1.1 christos #include <compat/sys/socket.h>
23 1.3 christos #include <compat/sys/sockio.h>
24 1.1 christos
25 1.15.2.3 pgoyette #include <compat/common/if_40.h>
26 1.15.2.3 pgoyette
27 1.2 christos #ifdef COMPAT_OIFREQ
28 1.1 christos /*
29 1.1 christos * Return interface configuration
30 1.1 christos * of system. List may be used
31 1.1 christos * in later ioctl's (above) to get
32 1.1 christos * other information.
33 1.1 christos */
34 1.1 christos /*ARGSUSED*/
35 1.1 christos int
36 1.1 christos compat_ifconf(u_long cmd, void *data)
37 1.1 christos {
38 1.1 christos struct oifconf *ifc = data;
39 1.1 christos struct ifnet *ifp;
40 1.8 ozaki struct oifreq ifr, *ifrp = NULL;
41 1.8 ozaki int space = 0, error = 0;
42 1.1 christos const int sz = (int)sizeof(ifr);
43 1.8 ozaki const bool docopy = ifc->ifc_req != NULL;
44 1.9 ozaki int s;
45 1.10 ozaki int bound;
46 1.9 ozaki struct psref psref;
47 1.1 christos
48 1.8 ozaki if (docopy) {
49 1.4 enami space = ifc->ifc_len;
50 1.8 ozaki ifrp = ifc->ifc_req;
51 1.8 ozaki }
52 1.8 ozaki
53 1.10 ozaki bound = curlwp_bind();
54 1.9 ozaki s = pserialize_read_enter();
55 1.9 ozaki IFNET_READER_FOREACH(ifp) {
56 1.12 ozaki struct ifaddr *ifa;
57 1.12 ozaki
58 1.13 ozaki if_acquire(ifp, &psref);
59 1.14 ozaki pserialize_read_exit(s);
60 1.9 ozaki
61 1.1 christos (void)strncpy(ifr.ifr_name, ifp->if_xname,
62 1.1 christos sizeof(ifr.ifr_name));
63 1.9 ozaki if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0') {
64 1.9 ozaki error = ENAMETOOLONG;
65 1.9 ozaki goto release_exit;
66 1.9 ozaki }
67 1.11 ozaki if (IFADDR_READER_EMPTY(ifp)) {
68 1.1 christos memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
69 1.4 enami if (space >= sz) {
70 1.1 christos error = copyout(&ifr, ifrp, sz);
71 1.1 christos if (error != 0)
72 1.9 ozaki goto release_exit;
73 1.1 christos ifrp++;
74 1.1 christos }
75 1.4 enami space -= sizeof(ifr);
76 1.14 ozaki goto next;
77 1.1 christos }
78 1.1 christos
79 1.14 ozaki s = pserialize_read_enter();
80 1.11 ozaki IFADDR_READER_FOREACH(ifa, ifp) {
81 1.1 christos struct sockaddr *sa = ifa->ifa_addr;
82 1.12 ozaki struct psref psref_ifa;
83 1.12 ozaki
84 1.12 ozaki ifa_acquire(ifa, &psref_ifa);
85 1.12 ozaki pserialize_read_exit(s);
86 1.1 christos #ifdef COMPAT_OSOCK
87 1.1 christos if (cmd == OOSIOCGIFCONF) {
88 1.1 christos struct osockaddr *osa =
89 1.4 enami (struct osockaddr *)&ifr.ifr_addr;
90 1.1 christos /*
91 1.1 christos * If it does not fit, we don't bother with it
92 1.1 christos */
93 1.14 ozaki if (sa->sa_len > sizeof(*osa))
94 1.14 ozaki goto next_ifa;
95 1.1 christos memcpy(&ifr.ifr_addr, sa, sa->sa_len);
96 1.1 christos osa->sa_family = sa->sa_family;
97 1.4 enami if (space >= sz) {
98 1.1 christos error = copyout(&ifr, ifrp, sz);
99 1.1 christos ifrp++;
100 1.1 christos }
101 1.1 christos } else
102 1.1 christos #endif
103 1.1 christos if (sa->sa_len <= sizeof(*sa)) {
104 1.1 christos memcpy(&ifr.ifr_addr, sa, sa->sa_len);
105 1.4 enami if (space >= sz) {
106 1.1 christos error = copyout(&ifr, ifrp, sz);
107 1.1 christos ifrp++;
108 1.1 christos }
109 1.1 christos } else {
110 1.4 enami space -= sa->sa_len - sizeof(*sa);
111 1.4 enami if (space >= sz) {
112 1.1 christos error = copyout(&ifr, ifrp,
113 1.1 christos sizeof(ifr.ifr_name));
114 1.1 christos if (error == 0) {
115 1.1 christos error = copyout(sa,
116 1.1 christos &ifrp->ifr_addr,
117 1.1 christos sa->sa_len);
118 1.1 christos }
119 1.1 christos ifrp = (struct oifreq *)
120 1.1 christos (sa->sa_len +
121 1.1 christos (char *)&ifrp->ifr_addr);
122 1.1 christos }
123 1.1 christos }
124 1.14 ozaki if (error != 0) {
125 1.14 ozaki ifa_release(ifa, &psref_ifa);
126 1.14 ozaki goto release_exit;
127 1.14 ozaki }
128 1.14 ozaki space -= sz;
129 1.14 ozaki
130 1.15 martin #ifdef COMPAT_OSOCK
131 1.14 ozaki next_ifa:
132 1.15 martin #endif
133 1.12 ozaki s = pserialize_read_enter();
134 1.12 ozaki ifa_release(ifa, &psref_ifa);
135 1.1 christos }
136 1.14 ozaki pserialize_read_exit(s);
137 1.9 ozaki
138 1.14 ozaki next:
139 1.14 ozaki s = pserialize_read_enter();
140 1.13 ozaki if_release(ifp, &psref);
141 1.1 christos }
142 1.9 ozaki pserialize_read_exit(s);
143 1.10 ozaki curlwp_bindx(bound);
144 1.9 ozaki
145 1.8 ozaki if (docopy)
146 1.1 christos ifc->ifc_len -= space;
147 1.1 christos else
148 1.4 enami ifc->ifc_len = -space;
149 1.4 enami return (0);
150 1.9 ozaki
151 1.9 ozaki release_exit:
152 1.13 ozaki if_release(ifp, &psref);
153 1.10 ozaki curlwp_bindx(bound);
154 1.9 ozaki return error;
155 1.1 christos }
156 1.2 christos #endif
157 1.15.2.1 pgoyette #if defined(COMPAT_40)
158 1.15.2.1 pgoyette static int (*orig_compat_ifconf)(u_long, void *);
159 1.15.2.2 pgoyette static int (*orig_compat_ifconf)(u_long, void *);
160 1.15.2.1 pgoyette
161 1.15.2.1 pgoyette void
162 1.15.2.1 pgoyette if_40_init(void)
163 1.15.2.1 pgoyette {
164 1.15.2.1 pgoyette
165 1.15.2.1 pgoyette orig_compat_ifconf = vec_compat_ifconf;
166 1.15.2.1 pgoyette vec_compat_ifconf = compat_ifconf;
167 1.15.2.1 pgoyette }
168 1.15.2.1 pgoyette
169 1.15.2.1 pgoyette void
170 1.15.2.1 pgoyette if_40_fini(void)
171 1.15.2.1 pgoyette {
172 1.15.2.1 pgoyette
173 1.15.2.1 pgoyette vec_compat_ifconf = orig_compat_ifconf;
174 1.15.2.1 pgoyette }
175 1.15.2.1 pgoyette #endif /* defined(COMPAT_40) */
176