uipc_syscalls_40.c revision 1.4.4.2 1 1.4.4.2 mjf /* $NetBSD: uipc_syscalls_40.c,v 1.4.4.2 2007/07/11 20:03:49 mjf Exp $ */
2 1.4.4.2 mjf
3 1.4.4.2 mjf /* written by Pavel Cahyna, 2006. Public domain. */
4 1.4.4.2 mjf
5 1.4.4.2 mjf #include <sys/cdefs.h>
6 1.4.4.2 mjf __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_40.c,v 1.4.4.2 2007/07/11 20:03:49 mjf Exp $");
7 1.4.4.2 mjf
8 1.4.4.2 mjf /*
9 1.4.4.2 mjf * System call interface to the socket abstraction.
10 1.4.4.2 mjf */
11 1.4.4.2 mjf
12 1.4.4.2 mjf #include <sys/param.h>
13 1.4.4.2 mjf #include <sys/kernel.h>
14 1.4.4.2 mjf #include <sys/msg.h>
15 1.4.4.2 mjf #include <sys/sysctl.h>
16 1.4.4.2 mjf #include <sys/mount.h>
17 1.4.4.2 mjf #include <sys/syscallargs.h>
18 1.4.4.2 mjf #include <sys/errno.h>
19 1.4.4.2 mjf
20 1.4.4.2 mjf #include <net/if.h>
21 1.4.4.2 mjf
22 1.4.4.2 mjf #include <compat/sys/socket.h>
23 1.4.4.2 mjf #include <compat/sys/sockio.h>
24 1.4.4.2 mjf
25 1.4.4.2 mjf #ifdef COMPAT_OIFREQ
26 1.4.4.2 mjf /*
27 1.4.4.2 mjf * Return interface configuration
28 1.4.4.2 mjf * of system. List may be used
29 1.4.4.2 mjf * in later ioctl's (above) to get
30 1.4.4.2 mjf * other information.
31 1.4.4.2 mjf */
32 1.4.4.2 mjf /*ARGSUSED*/
33 1.4.4.2 mjf int
34 1.4.4.2 mjf compat_ifconf(u_long cmd, void *data)
35 1.4.4.2 mjf {
36 1.4.4.2 mjf struct oifconf *ifc = data;
37 1.4.4.2 mjf struct ifnet *ifp;
38 1.4.4.2 mjf struct ifaddr *ifa;
39 1.4.4.2 mjf struct oifreq ifr, *ifrp;
40 1.4.4.2 mjf int space, error = 0;
41 1.4.4.2 mjf const int sz = (int)sizeof(ifr);
42 1.4.4.2 mjf
43 1.4.4.2 mjf if ((ifrp = ifc->ifc_req) == NULL)
44 1.4.4.2 mjf space = 0;
45 1.4.4.2 mjf else
46 1.4.4.2 mjf space = ifc->ifc_len;
47 1.4.4.2 mjf IFNET_FOREACH(ifp) {
48 1.4.4.2 mjf (void)strncpy(ifr.ifr_name, ifp->if_xname,
49 1.4.4.2 mjf sizeof(ifr.ifr_name));
50 1.4.4.2 mjf if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0')
51 1.4.4.2 mjf return ENAMETOOLONG;
52 1.4.4.2 mjf if (TAILQ_EMPTY(&ifp->if_addrlist)) {
53 1.4.4.2 mjf memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
54 1.4.4.2 mjf if (space >= sz) {
55 1.4.4.2 mjf error = copyout(&ifr, ifrp, sz);
56 1.4.4.2 mjf if (error != 0)
57 1.4.4.2 mjf return (error);
58 1.4.4.2 mjf ifrp++;
59 1.4.4.2 mjf }
60 1.4.4.2 mjf space -= sizeof(ifr);
61 1.4.4.2 mjf continue;
62 1.4.4.2 mjf }
63 1.4.4.2 mjf
64 1.4.4.2 mjf TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
65 1.4.4.2 mjf struct sockaddr *sa = ifa->ifa_addr;
66 1.4.4.2 mjf #ifdef COMPAT_OSOCK
67 1.4.4.2 mjf if (cmd == OOSIOCGIFCONF) {
68 1.4.4.2 mjf struct osockaddr *osa =
69 1.4.4.2 mjf (struct osockaddr *)&ifr.ifr_addr;
70 1.4.4.2 mjf /*
71 1.4.4.2 mjf * If it does not fit, we don't bother with it
72 1.4.4.2 mjf */
73 1.4.4.2 mjf if (sa->sa_len > sizeof(*osa))
74 1.4.4.2 mjf continue;
75 1.4.4.2 mjf memcpy(&ifr.ifr_addr, sa, sa->sa_len);
76 1.4.4.2 mjf osa->sa_family = sa->sa_family;
77 1.4.4.2 mjf if (space >= sz) {
78 1.4.4.2 mjf error = copyout(&ifr, ifrp, sz);
79 1.4.4.2 mjf ifrp++;
80 1.4.4.2 mjf }
81 1.4.4.2 mjf } else
82 1.4.4.2 mjf #endif
83 1.4.4.2 mjf if (sa->sa_len <= sizeof(*sa)) {
84 1.4.4.2 mjf memcpy(&ifr.ifr_addr, sa, sa->sa_len);
85 1.4.4.2 mjf if (space >= sz) {
86 1.4.4.2 mjf error = copyout(&ifr, ifrp, sz);
87 1.4.4.2 mjf ifrp++;
88 1.4.4.2 mjf }
89 1.4.4.2 mjf } else {
90 1.4.4.2 mjf space -= sa->sa_len - sizeof(*sa);
91 1.4.4.2 mjf if (space >= sz) {
92 1.4.4.2 mjf error = copyout(&ifr, ifrp,
93 1.4.4.2 mjf sizeof(ifr.ifr_name));
94 1.4.4.2 mjf if (error == 0) {
95 1.4.4.2 mjf error = copyout(sa,
96 1.4.4.2 mjf &ifrp->ifr_addr,
97 1.4.4.2 mjf sa->sa_len);
98 1.4.4.2 mjf }
99 1.4.4.2 mjf ifrp = (struct oifreq *)
100 1.4.4.2 mjf (sa->sa_len +
101 1.4.4.2 mjf (char *)&ifrp->ifr_addr);
102 1.4.4.2 mjf }
103 1.4.4.2 mjf }
104 1.4.4.2 mjf if (error != 0)
105 1.4.4.2 mjf return (error);
106 1.4.4.2 mjf space -= sz;
107 1.4.4.2 mjf }
108 1.4.4.2 mjf }
109 1.4.4.2 mjf if (ifrp != NULL)
110 1.4.4.2 mjf ifc->ifc_len -= space;
111 1.4.4.2 mjf else
112 1.4.4.2 mjf ifc->ifc_len = -space;
113 1.4.4.2 mjf return (0);
114 1.4.4.2 mjf }
115 1.4.4.2 mjf #endif
116