Blame


1 06f4d920 2005-02-13 devnull #include <u.h>
2 06f4d920 2005-02-13 devnull #define NOPLAN9DEFINES
3 06f4d920 2005-02-13 devnull #include <libc.h>
4 06f4d920 2005-02-13 devnull
5 06f4d920 2005-02-13 devnull #include <sys/socket.h>
6 06f4d920 2005-02-13 devnull #include <netinet/in.h>
7 06f4d920 2005-02-13 devnull #include <netinet/tcp.h>
8 d24b8141 2012-08-03 0intro #include <arpa/inet.h>
9 06f4d920 2005-02-13 devnull #include <sys/un.h>
10 06f4d920 2005-02-13 devnull #include <errno.h>
11 06f4d920 2005-02-13 devnull
12 06f4d920 2005-02-13 devnull #undef sun
13 06f4d920 2005-02-13 devnull #define sun sockun
14 06f4d920 2005-02-13 devnull
15 06f4d920 2005-02-13 devnull extern int _p9netfd(char*);
16 06f4d920 2005-02-13 devnull
17 06f4d920 2005-02-13 devnull static char *unknown = "unknown";
18 06f4d920 2005-02-13 devnull
19 06f4d920 2005-02-13 devnull static int
20 06f4d920 2005-02-13 devnull convert(int s, struct sockaddr *sa, char **lsys, char **lserv, char **laddr)
21 06f4d920 2005-02-13 devnull {
22 06f4d920 2005-02-13 devnull struct sockaddr_un *sun;
23 06f4d920 2005-02-13 devnull struct sockaddr_in *sin;
24 d24b8141 2012-08-03 0intro struct sockaddr_in6 *sin6;
25 06f4d920 2005-02-13 devnull uchar *ip;
26 06f4d920 2005-02-13 devnull u32int ipl;
27 06f4d920 2005-02-13 devnull socklen_t sn;
28 06f4d920 2005-02-13 devnull int n;
29 06f4d920 2005-02-13 devnull char *net;
30 fa325e9b 2020-01-10 cross
31 06f4d920 2005-02-13 devnull switch(sa->sa_family){
32 06f4d920 2005-02-13 devnull case AF_INET:
33 06f4d920 2005-02-13 devnull sin = (void*)sa;
34 06f4d920 2005-02-13 devnull ip = (uchar*)&sin->sin_addr;
35 06f4d920 2005-02-13 devnull ipl = *(u32int*)ip;
36 06f4d920 2005-02-13 devnull if(ipl == 0)
37 06f4d920 2005-02-13 devnull *lsys = strdup("*");
38 06f4d920 2005-02-13 devnull else
39 06f4d920 2005-02-13 devnull *lsys = smprint("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
40 06f4d920 2005-02-13 devnull *lserv = smprint("%d", ntohs(sin->sin_port));
41 06f4d920 2005-02-13 devnull sn = sizeof n;
42 06f4d920 2005-02-13 devnull if(getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) < 0)
43 06f4d920 2005-02-13 devnull return -1;
44 06f4d920 2005-02-13 devnull if(n == SOCK_STREAM)
45 06f4d920 2005-02-13 devnull net = "tcp";
46 06f4d920 2005-02-13 devnull else if(n == SOCK_DGRAM)
47 06f4d920 2005-02-13 devnull net = "udp";
48 06f4d920 2005-02-13 devnull else{
49 06f4d920 2005-02-13 devnull werrstr("unknown network type");
50 06f4d920 2005-02-13 devnull return -1;
51 06f4d920 2005-02-13 devnull }
52 06f4d920 2005-02-13 devnull *laddr = smprint("%s!%s!%s", net, *lsys, *lserv);
53 06f4d920 2005-02-13 devnull if(*lsys == nil || *lserv == nil || *laddr == nil)
54 06f4d920 2005-02-13 devnull return -1;
55 06f4d920 2005-02-13 devnull return 0;
56 d24b8141 2012-08-03 0intro case AF_INET6:
57 d24b8141 2012-08-03 0intro sin6 = (void*)sa;
58 d24b8141 2012-08-03 0intro if (memcmp(&sin6->sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0)
59 d24b8141 2012-08-03 0intro *lsys = strdup("*");
60 d24b8141 2012-08-03 0intro else{
61 d24b8141 2012-08-03 0intro *lsys = malloc(INET6_ADDRSTRLEN);
62 d24b8141 2012-08-03 0intro inet_ntop(AF_INET6, &sin6->sin6_addr, *lsys, INET6_ADDRSTRLEN);
63 d24b8141 2012-08-03 0intro }
64 d24b8141 2012-08-03 0intro *lserv = smprint("%d", ntohs(sin6->sin6_port));
65 d24b8141 2012-08-03 0intro sn = sizeof n;
66 d24b8141 2012-08-03 0intro if(getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) < 0)
67 d24b8141 2012-08-03 0intro return -1;
68 d24b8141 2012-08-03 0intro if(n == SOCK_STREAM)
69 d24b8141 2012-08-03 0intro net = "tcp";
70 d24b8141 2012-08-03 0intro else if(n == SOCK_DGRAM)
71 d24b8141 2012-08-03 0intro net = "udp";
72 d24b8141 2012-08-03 0intro else{
73 d24b8141 2012-08-03 0intro werrstr("unknown network type");
74 d24b8141 2012-08-03 0intro return -1;
75 d24b8141 2012-08-03 0intro }
76 d24b8141 2012-08-03 0intro *laddr = smprint("%s!%s!%s", net, *lsys, *lserv);
77 d24b8141 2012-08-03 0intro if(*lsys == nil || *lserv == nil || *laddr == nil)
78 d24b8141 2012-08-03 0intro return -1;
79 d24b8141 2012-08-03 0intro return 0;
80 06f4d920 2005-02-13 devnull case AF_UNIX:
81 06f4d920 2005-02-13 devnull sun = (void*)sa;
82 06f4d920 2005-02-13 devnull *lsys = unknown;
83 06f4d920 2005-02-13 devnull *lserv = unknown;
84 06f4d920 2005-02-13 devnull *laddr = smprint("unix!%s", sun->sun_path);
85 06f4d920 2005-02-13 devnull if(*laddr == nil)
86 06f4d920 2005-02-13 devnull return -1;
87 06f4d920 2005-02-13 devnull return 0;
88 06f4d920 2005-02-13 devnull default:
89 06f4d920 2005-02-13 devnull werrstr("unknown socket family");
90 06f4d920 2005-02-13 devnull return -1;
91 06f4d920 2005-02-13 devnull }
92 06f4d920 2005-02-13 devnull }
93 06f4d920 2005-02-13 devnull
94 06f4d920 2005-02-13 devnull NetConnInfo*
95 06f4d920 2005-02-13 devnull getnetconninfo(char *dir, int fd)
96 06f4d920 2005-02-13 devnull {
97 06f4d920 2005-02-13 devnull socklen_t sn;
98 06f4d920 2005-02-13 devnull union {
99 06f4d920 2005-02-13 devnull struct sockaddr sa;
100 06f4d920 2005-02-13 devnull struct sockaddr_in sin;
101 d24b8141 2012-08-03 0intro struct sockaddr_in6 sin6;
102 06f4d920 2005-02-13 devnull struct sockaddr_un sun;
103 06f4d920 2005-02-13 devnull } u;
104 06f4d920 2005-02-13 devnull NetConnInfo *nci;
105 06f4d920 2005-02-13 devnull
106 06f4d920 2005-02-13 devnull if(dir){
107 06f4d920 2005-02-13 devnull if((fd = _p9netfd(dir)) < 0){
108 06f4d920 2005-02-13 devnull werrstr("no such network connection %s", dir);
109 06f4d920 2005-02-13 devnull return nil;
110 06f4d920 2005-02-13 devnull }
111 06f4d920 2005-02-13 devnull }
112 06f4d920 2005-02-13 devnull
113 06f4d920 2005-02-13 devnull nci = mallocz(sizeof *nci, 1);
114 06f4d920 2005-02-13 devnull if(nci == nil)
115 06f4d920 2005-02-13 devnull goto err;
116 06f4d920 2005-02-13 devnull nci->dir = smprint("/dev/fd/%d", fd);
117 06f4d920 2005-02-13 devnull nci->root = strdup("/net");
118 06f4d920 2005-02-13 devnull nci->spec = unknown;
119 06f4d920 2005-02-13 devnull if(nci->dir == nil || nci->root == nil)
120 06f4d920 2005-02-13 devnull goto err;
121 493b97a4 2006-02-18 devnull sn = sizeof u;
122 06f4d920 2005-02-13 devnull if(getsockname(fd, &u.sa, &sn) < 0)
123 06f4d920 2005-02-13 devnull goto err;
124 06f4d920 2005-02-13 devnull if(convert(fd, &u.sa, &nci->lsys, &nci->lserv, &nci->laddr) < 0)
125 06f4d920 2005-02-13 devnull goto err;
126 493b97a4 2006-02-18 devnull sn = sizeof u;
127 06f4d920 2005-02-13 devnull if(getpeername(fd, &u.sa, &sn) < 0)
128 06f4d920 2005-02-13 devnull goto err;
129 06f4d920 2005-02-13 devnull if(convert(fd, &u.sa, &nci->rsys, &nci->rserv, &nci->raddr) < 0)
130 06f4d920 2005-02-13 devnull goto err;
131 06f4d920 2005-02-13 devnull return nci;
132 06f4d920 2005-02-13 devnull
133 06f4d920 2005-02-13 devnull err:
134 06f4d920 2005-02-13 devnull freenetconninfo(nci);
135 06f4d920 2005-02-13 devnull return nil;
136 06f4d920 2005-02-13 devnull }
137 06f4d920 2005-02-13 devnull
138 06f4d920 2005-02-13 devnull static void
139 06f4d920 2005-02-13 devnull xfree(void *v)
140 06f4d920 2005-02-13 devnull {
141 06f4d920 2005-02-13 devnull if(v != nil && v != unknown)
142 06f4d920 2005-02-13 devnull free(v);
143 06f4d920 2005-02-13 devnull }
144 06f4d920 2005-02-13 devnull
145 06f4d920 2005-02-13 devnull void
146 06f4d920 2005-02-13 devnull freenetconninfo(NetConnInfo *nci)
147 06f4d920 2005-02-13 devnull {
148 06f4d920 2005-02-13 devnull if(nci == nil)
149 06f4d920 2005-02-13 devnull return;
150 06f4d920 2005-02-13 devnull xfree(nci->dir);
151 06f4d920 2005-02-13 devnull xfree(nci->root);
152 06f4d920 2005-02-13 devnull xfree(nci->spec);
153 06f4d920 2005-02-13 devnull xfree(nci->lsys);
154 06f4d920 2005-02-13 devnull xfree(nci->lserv);
155 06f4d920 2005-02-13 devnull xfree(nci->rsys);
156 06f4d920 2005-02-13 devnull xfree(nci->rserv);
157 06f4d920 2005-02-13 devnull xfree(nci->laddr);
158 06f4d920 2005-02-13 devnull xfree(nci->raddr);
159 06f4d920 2005-02-13 devnull free(nci);
160 06f4d920 2005-02-13 devnull }