uipc_syscalls_40.c revision 1.2 1 1.2 christos /* $NetBSD: uipc_syscalls_40.c,v 1.2 2007/05/29 23:57:33 christos 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.2 christos __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_40.c,v 1.2 2007/05/29 23:57:33 christos 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 "opt_compat_netbsd.h"
13 1.1 christos #include "opt_compat_linux.h"
14 1.1 christos #include "opt_compat_svr4.h"
15 1.1 christos #include "opt_compat_ultrix.h"
16 1.1 christos #include "opt_compat_43.h"
17 1.1 christos
18 1.1 christos #include <sys/param.h>
19 1.1 christos #include <sys/kernel.h>
20 1.1 christos #include <sys/msg.h>
21 1.1 christos #include <sys/sysctl.h>
22 1.1 christos #include <sys/mount.h>
23 1.1 christos #include <sys/syscallargs.h>
24 1.1 christos #include <sys/errno.h>
25 1.1 christos
26 1.1 christos #include <net/if.h>
27 1.1 christos
28 1.1 christos #if defined(COMPAT_43) || defined(COMPAT_LINUX) || defined(COMPAT_SVR4) || \
29 1.1 christos defined(COMPAT_ULTRIX) || defined(LKM)
30 1.1 christos #define COMPAT_OSOCK
31 1.1 christos #include <compat/sys/socket.h>
32 1.1 christos #endif
33 1.1 christos
34 1.1 christos #if defined(COMPAT_09) || defined(COMPAT_10) || defined(COMPAT_11) || \
35 1.1 christos defined(COMPAT_12) || defined(COMPAT_13) || defined(COMPAT_14) || \
36 1.1 christos defined(COMPAT_15) || defined(COMPAT_16) || defined(COMPAT_20) || \
37 1.1 christos defined(COMPAT_30) || defined(COMPAT_40)
38 1.2 christos #define COMPAT_OIFREQ
39 1.1 christos #include <compat/sys/sockio.h>
40 1.1 christos #endif
41 1.2 christos #ifdef COMPAT_OIFREQ
42 1.1 christos /*
43 1.1 christos * Return interface configuration
44 1.1 christos * of system. List may be used
45 1.1 christos * in later ioctl's (above) to get
46 1.1 christos * other information.
47 1.1 christos */
48 1.1 christos /*ARGSUSED*/
49 1.1 christos int
50 1.1 christos compat_ifconf(u_long cmd, void *data)
51 1.1 christos {
52 1.1 christos struct oifconf *ifc = data;
53 1.1 christos struct ifnet *ifp;
54 1.1 christos struct ifaddr *ifa;
55 1.1 christos struct oifreq ifr, *ifrp;
56 1.1 christos int space = ifc->ifc_len, error = 0;
57 1.1 christos const int sz = (int)sizeof(ifr);
58 1.1 christos int sign;
59 1.1 christos
60 1.1 christos if ((ifrp = ifc->ifc_req) == NULL) {
61 1.1 christos space = 0;
62 1.1 christos sign = -1;
63 1.1 christos } else {
64 1.1 christos sign = 1;
65 1.1 christos }
66 1.1 christos IFNET_FOREACH(ifp) {
67 1.1 christos (void)strncpy(ifr.ifr_name, ifp->if_xname,
68 1.1 christos sizeof(ifr.ifr_name));
69 1.1 christos if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0')
70 1.1 christos return ENAMETOOLONG;
71 1.1 christos if (TAILQ_EMPTY(&ifp->if_addrlist)) {
72 1.1 christos memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
73 1.1 christos if (ifrp != NULL && space >= sz) {
74 1.1 christos error = copyout(&ifr, ifrp, sz);
75 1.1 christos if (error != 0)
76 1.1 christos break;
77 1.1 christos ifrp++;
78 1.1 christos }
79 1.1 christos space -= sizeof(ifr) * sign;
80 1.1 christos continue;
81 1.1 christos }
82 1.1 christos
83 1.1 christos TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
84 1.1 christos struct sockaddr *sa = ifa->ifa_addr;
85 1.1 christos #ifdef COMPAT_OSOCK
86 1.1 christos if (cmd == OOSIOCGIFCONF) {
87 1.1 christos struct osockaddr *osa =
88 1.1 christos (struct osockaddr *)&ifr.ifr_addr;
89 1.1 christos /*
90 1.1 christos * If it does not fit, we don't bother with it
91 1.1 christos */
92 1.1 christos if (sa->sa_len > sizeof(*osa))
93 1.1 christos continue;
94 1.1 christos memcpy(&ifr.ifr_addr, sa, sa->sa_len);
95 1.1 christos osa->sa_family = sa->sa_family;
96 1.1 christos if (ifrp != NULL && space >= sz) {
97 1.1 christos error = copyout(&ifr, ifrp, sz);
98 1.1 christos ifrp++;
99 1.1 christos }
100 1.1 christos } else
101 1.1 christos #endif
102 1.1 christos if (sa->sa_len <= sizeof(*sa)) {
103 1.1 christos memcpy(&ifr.ifr_addr, sa, sa->sa_len);
104 1.1 christos if (ifrp != NULL && space >= sz) {
105 1.1 christos error = copyout(&ifr, ifrp, sz);
106 1.1 christos ifrp++;
107 1.1 christos }
108 1.1 christos } else {
109 1.1 christos space -= (sa->sa_len - sizeof(*sa)) * sign;
110 1.1 christos if (ifrp != NULL && space >= sz) {
111 1.1 christos error = copyout(&ifr, ifrp,
112 1.1 christos sizeof(ifr.ifr_name));
113 1.1 christos if (error == 0) {
114 1.1 christos error = copyout(sa,
115 1.1 christos &ifrp->ifr_addr,
116 1.1 christos sa->sa_len);
117 1.1 christos }
118 1.1 christos ifrp = (struct oifreq *)
119 1.1 christos (sa->sa_len +
120 1.1 christos (char *)&ifrp->ifr_addr);
121 1.1 christos }
122 1.1 christos }
123 1.1 christos if (error != 0)
124 1.1 christos break;
125 1.1 christos space -= sz * sign;
126 1.1 christos }
127 1.1 christos }
128 1.1 christos if (ifrp != NULL)
129 1.1 christos ifc->ifc_len -= space;
130 1.1 christos else
131 1.1 christos ifc->ifc_len = space;
132 1.1 christos return error;
133 1.1 christos }
134 1.2 christos #endif
135