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* 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* 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 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); 78219b2ee8SDavid du Colombier sprintf(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 */ 90219b2ee8SDavid du Colombier sprintf(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 109219b2ee8SDavid du Colombier socket(int domain, int stype, int protocol) 110219b2ee8SDavid du Colombier { 111219b2ee8SDavid du Colombier Rock *r; 112219b2ee8SDavid du Colombier int cfd, fd, n; 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 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 } 162*7dd7cddfSDavid du Colombier 163*7dd7cddfSDavid du Colombier /* 164*7dd7cddfSDavid du Colombier * probably should do better than this 165*7dd7cddfSDavid du Colombier */ 166*7dd7cddfSDavid du Colombier int getsockopt(int, int, int, void *, int *) 167*7dd7cddfSDavid du Colombier { 168*7dd7cddfSDavid du Colombier return -1; 169*7dd7cddfSDavid du Colombier } 170*7dd7cddfSDavid du Colombier 171*7dd7cddfSDavid du Colombier int setsockopt(int, int, int, void *, int) 172*7dd7cddfSDavid du Colombier { 173*7dd7cddfSDavid du Colombier return 0; 174*7dd7cddfSDavid du Colombier } 175*7dd7cddfSDavid du Colombier 176