1219b2ee8SDavid du Colombier /* posix */
2219b2ee8SDavid du Colombier #include <sys/types.h>
3219b2ee8SDavid du Colombier #include <unistd.h>
4219b2ee8SDavid du Colombier #include <stdlib.h>
5219b2ee8SDavid du Colombier #include <stdio.h>
6219b2ee8SDavid du Colombier #include <errno.h>
7219b2ee8SDavid du Colombier #include <string.h>
8219b2ee8SDavid du Colombier #include <fcntl.h>
9219b2ee8SDavid du Colombier #include <sys/stat.h>
10219b2ee8SDavid du Colombier
11219b2ee8SDavid du Colombier /* bsd extensions */
12219b2ee8SDavid du Colombier #include <sys/uio.h>
13219b2ee8SDavid du Colombier #include <sys/socket.h>
14219b2ee8SDavid du Colombier
15219b2ee8SDavid du Colombier #include "priv.h"
16219b2ee8SDavid du Colombier
17219b2ee8SDavid du Colombier Rock *_sock_rock;
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier Rock*
_sock_findrock(int fd,struct stat * dp)20219b2ee8SDavid du Colombier _sock_findrock(int fd, struct stat *dp)
21219b2ee8SDavid du Colombier {
22219b2ee8SDavid du Colombier Rock *r;
23219b2ee8SDavid du Colombier struct stat d;
24219b2ee8SDavid du Colombier
25219b2ee8SDavid du Colombier if(dp == 0)
26219b2ee8SDavid du Colombier dp = &d;
27219b2ee8SDavid du Colombier fstat(fd, dp);
28219b2ee8SDavid du Colombier for(r = _sock_rock; r; r = r->next){
29219b2ee8SDavid du Colombier if(r->inode == dp->st_ino
30219b2ee8SDavid du Colombier && r->dev == dp->st_dev)
31219b2ee8SDavid du Colombier break;
32219b2ee8SDavid du Colombier }
33219b2ee8SDavid du Colombier return r;
34219b2ee8SDavid du Colombier }
35219b2ee8SDavid du Colombier
36219b2ee8SDavid du Colombier Rock*
_sock_newrock(int fd)37219b2ee8SDavid du Colombier _sock_newrock(int fd)
38219b2ee8SDavid du Colombier {
39219b2ee8SDavid du Colombier Rock *r;
40219b2ee8SDavid du Colombier struct stat d;
41219b2ee8SDavid du Colombier
42219b2ee8SDavid du Colombier r = _sock_findrock(fd, &d);
43219b2ee8SDavid du Colombier if(r == 0){
44219b2ee8SDavid du Colombier r = malloc(sizeof(Rock));
45219b2ee8SDavid du Colombier if(r == 0)
46219b2ee8SDavid du Colombier return 0;
47219b2ee8SDavid du Colombier r->dev = d.st_dev;
48219b2ee8SDavid du Colombier r->inode = d.st_ino;
49219b2ee8SDavid du Colombier r->other = -1;
50219b2ee8SDavid du Colombier r->next = _sock_rock;
51219b2ee8SDavid du Colombier _sock_rock = r;
52219b2ee8SDavid du Colombier }
53219b2ee8SDavid du Colombier memset(&r->raddr, 0, sizeof(r->raddr));
54219b2ee8SDavid du Colombier memset(&r->addr, 0, sizeof(r->addr));
55219b2ee8SDavid du Colombier r->reserved = 0;
56219b2ee8SDavid du Colombier r->dev = d.st_dev;
57219b2ee8SDavid du Colombier r->inode = d.st_ino;
58219b2ee8SDavid du Colombier r->other = -1;
59219b2ee8SDavid du Colombier return r;
60219b2ee8SDavid du Colombier }
61219b2ee8SDavid du Colombier
62219b2ee8SDavid du Colombier int
_sock_data(int cfd,char * net,int domain,int stype,int protocol,Rock ** rp)63219b2ee8SDavid du Colombier _sock_data(int cfd, char *net, int domain, int stype, int protocol, Rock **rp)
64219b2ee8SDavid du Colombier {
65219b2ee8SDavid du Colombier int n, fd;
66219b2ee8SDavid du Colombier Rock *r;
67219b2ee8SDavid du Colombier char name[Ctlsize];
68219b2ee8SDavid du Colombier
69219b2ee8SDavid du Colombier /* get the data file name */
70219b2ee8SDavid du Colombier n = read(cfd, name, sizeof(name)-1);
71219b2ee8SDavid du Colombier if(n < 0){
72219b2ee8SDavid du Colombier close(cfd);
73219b2ee8SDavid du Colombier errno = ENOBUFS;
74219b2ee8SDavid du Colombier return -1;
75219b2ee8SDavid du Colombier }
76219b2ee8SDavid du Colombier name[n] = 0;
77219b2ee8SDavid du Colombier n = strtoul(name, 0, 0);
787e125112SDavid du Colombier snprintf(name, sizeof name, "/net/%s/%d/data", net, n);
79219b2ee8SDavid du Colombier
80219b2ee8SDavid du Colombier /* open data file */
81219b2ee8SDavid du Colombier fd = open(name, O_RDWR);
82219b2ee8SDavid du Colombier close(cfd);
83219b2ee8SDavid du Colombier if(fd < 0){
84219b2ee8SDavid du Colombier close(cfd);
85219b2ee8SDavid du Colombier errno = ENOBUFS;
86219b2ee8SDavid du Colombier return -1;
87219b2ee8SDavid du Colombier }
88219b2ee8SDavid du Colombier
89219b2ee8SDavid du Colombier /* hide stuff under the rock */
907e125112SDavid du Colombier snprintf(name, sizeof name, "/net/%s/%d/ctl", net, n);
91219b2ee8SDavid du Colombier r = _sock_newrock(fd);
92219b2ee8SDavid du Colombier if(r == 0){
93219b2ee8SDavid du Colombier errno = ENOBUFS;
94219b2ee8SDavid du Colombier close(fd);
95219b2ee8SDavid du Colombier return -1;
96219b2ee8SDavid du Colombier }
97219b2ee8SDavid du Colombier if(rp)
98219b2ee8SDavid du Colombier *rp = r;
99219b2ee8SDavid du Colombier memset(&r->raddr, 0, sizeof(r->raddr));
100219b2ee8SDavid du Colombier memset(&r->addr, 0, sizeof(r->addr));
101219b2ee8SDavid du Colombier r->domain = domain;
102219b2ee8SDavid du Colombier r->stype = stype;
103219b2ee8SDavid du Colombier r->protocol = protocol;
104219b2ee8SDavid du Colombier strcpy(r->ctl, name);
105219b2ee8SDavid du Colombier return fd;
106219b2ee8SDavid du Colombier }
107219b2ee8SDavid du Colombier
108219b2ee8SDavid du Colombier int
socket(int domain,int stype,int protocol)109219b2ee8SDavid du Colombier socket(int domain, int stype, int protocol)
110219b2ee8SDavid du Colombier {
111219b2ee8SDavid du Colombier Rock *r;
112*781103c4SDavid du Colombier int cfd;
113219b2ee8SDavid du Colombier int pfd[2];
114219b2ee8SDavid du Colombier char *net;
115219b2ee8SDavid du Colombier
116219b2ee8SDavid du Colombier switch(domain){
117219b2ee8SDavid du Colombier case PF_INET:
118219b2ee8SDavid du Colombier /* get a free network directory */
119219b2ee8SDavid du Colombier switch(stype){
120219b2ee8SDavid du Colombier case SOCK_DGRAM:
121219b2ee8SDavid du Colombier net = "udp";
122219b2ee8SDavid du Colombier cfd = open("/net/udp/clone", O_RDWR);
123219b2ee8SDavid du Colombier break;
124219b2ee8SDavid du Colombier case SOCK_STREAM:
125219b2ee8SDavid du Colombier net = "tcp";
126219b2ee8SDavid du Colombier cfd = open("/net/tcp/clone", O_RDWR);
127219b2ee8SDavid du Colombier break;
128219b2ee8SDavid du Colombier default:
129219b2ee8SDavid du Colombier errno = EPROTONOSUPPORT;
130219b2ee8SDavid du Colombier return -1;
131219b2ee8SDavid du Colombier }
132219b2ee8SDavid du Colombier if(cfd < 0){
133219b2ee8SDavid du Colombier _syserrno();
134219b2ee8SDavid du Colombier return -1;
135219b2ee8SDavid du Colombier }
136219b2ee8SDavid du Colombier return _sock_data(cfd, net, domain, stype, protocol, 0);
137219b2ee8SDavid du Colombier case PF_UNIX:
138219b2ee8SDavid du Colombier if(pipe(pfd) < 0){
139219b2ee8SDavid du Colombier _syserrno();
140219b2ee8SDavid du Colombier return -1;
141219b2ee8SDavid du Colombier }
142219b2ee8SDavid du Colombier r = _sock_newrock(pfd[0]);
143219b2ee8SDavid du Colombier r->domain = domain;
144219b2ee8SDavid du Colombier r->stype = stype;
145219b2ee8SDavid du Colombier r->protocol = protocol;
146219b2ee8SDavid du Colombier r->other = pfd[1];
147219b2ee8SDavid du Colombier return pfd[0];
148219b2ee8SDavid du Colombier default:
149219b2ee8SDavid du Colombier errno = EPROTONOSUPPORT;
150219b2ee8SDavid du Colombier return -1;
151219b2ee8SDavid du Colombier }
152219b2ee8SDavid du Colombier }
153219b2ee8SDavid du Colombier
154219b2ee8SDavid du Colombier int
issocket(int fd)155219b2ee8SDavid du Colombier issocket(int fd)
156219b2ee8SDavid du Colombier {
157219b2ee8SDavid du Colombier Rock *r;
158219b2ee8SDavid du Colombier
159219b2ee8SDavid du Colombier r = _sock_findrock(fd, 0);
160219b2ee8SDavid du Colombier return (r != 0);
161219b2ee8SDavid du Colombier }
1627dd7cddfSDavid du Colombier
1637dd7cddfSDavid du Colombier /*
1647dd7cddfSDavid du Colombier * probably should do better than this
1657dd7cddfSDavid du Colombier */
getsockopt(int,int,int,void *,int *)1667dd7cddfSDavid du Colombier int getsockopt(int, int, int, void *, int *)
1677dd7cddfSDavid du Colombier {
1687dd7cddfSDavid du Colombier return -1;
1697dd7cddfSDavid du Colombier }
1707dd7cddfSDavid du Colombier
setsockopt(int,int,int,void *,int)1717dd7cddfSDavid du Colombier int setsockopt(int, int, int, void *, int)
1727dd7cddfSDavid du Colombier {
1737dd7cddfSDavid du Colombier return 0;
1747dd7cddfSDavid du Colombier }
1757dd7cddfSDavid du Colombier
176