uipc_syscalls_40.c revision 1.8 1 1.8 ozaki /* $NetBSD: uipc_syscalls_40.c,v 1.8 2014/11/26 09:53:53 ozaki-r 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.8 ozaki __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_40.c,v 1.8 2014/11/26 09:53:53 ozaki-r 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.1 christos #include <compat/sys/socket.h>
22 1.3 christos #include <compat/sys/sockio.h>
23 1.1 christos
24 1.2 christos #ifdef COMPAT_OIFREQ
25 1.1 christos /*
26 1.1 christos * Return interface configuration
27 1.1 christos * of system. List may be used
28 1.1 christos * in later ioctl's (above) to get
29 1.1 christos * other information.
30 1.1 christos */
31 1.1 christos /*ARGSUSED*/
32 1.1 christos int
33 1.1 christos compat_ifconf(u_long cmd, void *data)
34 1.1 christos {
35 1.1 christos struct oifconf *ifc = data;
36 1.1 christos struct ifnet *ifp;
37 1.1 christos struct ifaddr *ifa;
38 1.8 ozaki struct oifreq ifr, *ifrp = NULL;
39 1.8 ozaki int space = 0, error = 0;
40 1.1 christos const int sz = (int)sizeof(ifr);
41 1.8 ozaki const bool docopy = ifc->ifc_req != NULL;
42 1.1 christos
43 1.8 ozaki if (docopy) {
44 1.4 enami space = ifc->ifc_len;
45 1.8 ozaki ifrp = ifc->ifc_req;
46 1.8 ozaki }
47 1.8 ozaki
48 1.1 christos IFNET_FOREACH(ifp) {
49 1.1 christos (void)strncpy(ifr.ifr_name, ifp->if_xname,
50 1.1 christos sizeof(ifr.ifr_name));
51 1.1 christos if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0')
52 1.1 christos return ENAMETOOLONG;
53 1.6 dyoung if (IFADDR_EMPTY(ifp)) {
54 1.1 christos memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
55 1.4 enami if (space >= sz) {
56 1.1 christos error = copyout(&ifr, ifrp, sz);
57 1.1 christos if (error != 0)
58 1.4 enami return (error);
59 1.1 christos ifrp++;
60 1.1 christos }
61 1.4 enami space -= sizeof(ifr);
62 1.1 christos continue;
63 1.1 christos }
64 1.1 christos
65 1.5 dyoung IFADDR_FOREACH(ifa, ifp) {
66 1.1 christos struct sockaddr *sa = ifa->ifa_addr;
67 1.1 christos #ifdef COMPAT_OSOCK
68 1.1 christos if (cmd == OOSIOCGIFCONF) {
69 1.1 christos struct osockaddr *osa =
70 1.4 enami (struct osockaddr *)&ifr.ifr_addr;
71 1.1 christos /*
72 1.1 christos * If it does not fit, we don't bother with it
73 1.1 christos */
74 1.1 christos if (sa->sa_len > sizeof(*osa))
75 1.1 christos continue;
76 1.1 christos memcpy(&ifr.ifr_addr, sa, sa->sa_len);
77 1.1 christos osa->sa_family = sa->sa_family;
78 1.4 enami if (space >= sz) {
79 1.1 christos error = copyout(&ifr, ifrp, sz);
80 1.1 christos ifrp++;
81 1.1 christos }
82 1.1 christos } else
83 1.1 christos #endif
84 1.1 christos if (sa->sa_len <= sizeof(*sa)) {
85 1.1 christos memcpy(&ifr.ifr_addr, sa, sa->sa_len);
86 1.4 enami if (space >= sz) {
87 1.1 christos error = copyout(&ifr, ifrp, sz);
88 1.1 christos ifrp++;
89 1.1 christos }
90 1.1 christos } else {
91 1.4 enami space -= sa->sa_len - sizeof(*sa);
92 1.4 enami if (space >= sz) {
93 1.1 christos error = copyout(&ifr, ifrp,
94 1.1 christos sizeof(ifr.ifr_name));
95 1.1 christos if (error == 0) {
96 1.1 christos error = copyout(sa,
97 1.1 christos &ifrp->ifr_addr,
98 1.1 christos sa->sa_len);
99 1.1 christos }
100 1.1 christos ifrp = (struct oifreq *)
101 1.1 christos (sa->sa_len +
102 1.1 christos (char *)&ifrp->ifr_addr);
103 1.1 christos }
104 1.1 christos }
105 1.1 christos if (error != 0)
106 1.4 enami return (error);
107 1.4 enami space -= sz;
108 1.1 christos }
109 1.1 christos }
110 1.8 ozaki if (docopy)
111 1.1 christos ifc->ifc_len -= space;
112 1.1 christos else
113 1.4 enami ifc->ifc_len = -space;
114 1.4 enami return (0);
115 1.1 christos }
116 1.2 christos #endif
117