more socket stuff
authorbrian <brian@brianweb.net>
Thu, 1 Jul 2004 01:12:20 +0000 (18:12 -0700)
committerbrian <brian@brianweb.net>
Thu, 1 Jul 2004 01:12:20 +0000 (18:12 -0700)
darcs-hash:20040701011220-24bed-e27abfaaeda5e7638568cbfaf77d73b0d7ae60fd.gz

src/org/ibex/nestedvm/support_aux.c
upstream/misc/extraheaders.sh

index fcb7b31..603f6ee 100644 (file)
@@ -286,6 +286,33 @@ void herror(const char *string) {
     fprintf(stderr,"%s: %s\n",string,hstrerror(h_errno));
 }
 
+extern int _resolve_ip(int addr, char *buf, size_t size);
+
+struct hostent *gethostbyaddr(const char *addr, int len, int type) {
+    static struct hostent hostent;
+    static char name[128];
+    static char *aliases[1];
+    static char *addr_list[1];
+    static char addr_list_buf[4];
+    int err,i;
+    
+    if(type != AF_INET || len != 4) return NULL;
+    memcpy(&i,addr,4);
+    memcpy(addr_list_buf,addr,4);
+    err = _resolve_ip(i,name,sizeof(name));
+    if(err != 0) { h_errno = err; return NULL; }
+    
+    hostent.h_name = name;
+    hostent.h_aliases = aliases;
+    aliases[0] = NULL;
+    hostent.h_addrtype = AF_INET;
+    hostent.h_length = sizeof(struct in_addr);
+    hostent.h_addr_list = addr_list;
+    addr_list[0] = addr_list_buf;
+    
+    return &hostent;
+}
+
 extern int _resolve_hostname(const char *, char *buf, size_t *size);
 
 struct hostent *gethostbyname(const char *hostname) {
@@ -515,6 +542,23 @@ struct utsname *name;
        return (rval);
 }
 
+/* FreeBSD's gethostname */
+int
+gethostname(name, namelen)
+char *name;
+int namelen;
+{
+    int mib[2];
+    size_t size;
+    
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_HOSTNAME;
+    size = namelen;
+    if (sysctl(mib, 2, name, &size, NULL, 0) == -1)
+        return (-1);
+    return (0);
+}
+
 /* FreeBSD's daemon() - modified for nestedvm */
 int
 daemon(nochdir, noclose)
@@ -546,3 +590,184 @@ int nochdir, noclose;
        }
        return (0);
 }
+
+/* FreeBSD's inet_addr/inet_aton */
+
+/* 
+* Check whether "cp" is a valid ASCII representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+inet_aton(cp, addr)
+register const char *cp;
+struct in_addr *addr;
+{
+       u_long parts[4];
+       in_addr_t val;
+       char *c;
+       char *endptr;
+       int gotend, n;
+    
+       c = (char *)cp;
+       n = 0;
+       /*
+        * Run through the string, grabbing numbers until
+        * the end of the string, or some error
+        */
+       gotend = 0;
+       while (!gotend) {
+               errno = 0;
+               val = strtoul(c, &endptr, 0);
+        
+               if (errno == ERANGE)    /* Fail completely if it overflowed. */
+                       return (0);
+               
+               /* 
+            * If the whole string is invalid, endptr will equal
+                * c.. this way we can make sure someone hasn't
+                * gone '.12' or something which would get past
+                * the next check.
+                */
+               if (endptr == c)
+                       return (0);
+               parts[n] = val;
+               c = endptr;
+        
+               /* Check the next character past the previous number's end */
+               switch (*c) {
+            case '.' :
+                /* Make sure we only do 3 dots .. */
+                if (n == 3)    /* Whoops. Quit. */
+                    return (0);
+                n++;
+                c++;
+                break;
+                
+            case '\0':
+                gotend = 1;
+                break;
+                
+            default:
+                if (isspace((unsigned char)*c)) {
+                    gotend = 1;
+                    break;
+                } else
+                    return (0);        /* Invalid character, so fail */
+               }
+        
+       }
+    
+       /*
+        * Concoct the address according to
+        * the number of parts specified.
+        */
+    
+       switch (n) {
+        case 0:                                /* a -- 32 bits */
+            /*
+             * Nothing is necessary here.  Overflow checking was
+             * already done in strtoul().
+             */
+            break;
+        case 1:                                /* a.b -- 8.24 bits */
+            if (val > 0xffffff || parts[0] > 0xff)
+                return (0);
+            val |= parts[0] << 24;
+            break;
+            
+        case 2:                                /* a.b.c -- 8.8.16 bits */
+            if (val > 0xffff || parts[0] > 0xff || parts[1] > 0xff)
+                return (0);
+            val |= (parts[0] << 24) | (parts[1] << 16);
+                break;
+                
+            case 3:                            /* a.b.c.d -- 8.8.8.8 bits */
+                if (val > 0xff || parts[0] > 0xff || parts[1] > 0xff ||
+                    parts[2] > 0xff)
+                    return (0);
+                val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+                    break;
+       }
+    
+       if (addr != NULL)
+               addr->s_addr = htonl(val);
+       return (1);
+}
+
+/*
+ * ASCII internet address interpretation routine.
+ * The value returned is in network order.
+ */
+in_addr_t              /* XXX should be struct in_addr :( */
+inet_addr(cp)
+register const char *cp;
+{
+       struct in_addr val;
+    
+       if (inet_aton(cp, &val))
+               return (val.s_addr);
+       return (INADDR_NONE);
+}
+
+int
+getgrouplist(uname, agroup, groups, grpcnt)
+const char *uname;
+gid_t agroup;
+register gid_t *groups;
+int *grpcnt;
+{
+       register struct group *grp;
+       register int i, ngroups;
+       int ret, maxgroups;
+    
+       ret = 0;
+       ngroups = 0;
+       maxgroups = *grpcnt;
+       /*
+        * When installing primary group, duplicate it;
+        * the first element of groups is the effective gid
+        * and will be overwritten when a setgid file is executed.
+        */
+       groups[ngroups++] = agroup;
+       if (maxgroups > 1)
+               groups[ngroups++] = agroup;
+       /*
+        * Scan the group file to find additional groups.
+        */
+       setgrent();
+       while ((grp = getgrent())) {
+               for (i = 0; i < ngroups; i++) {
+                       if (grp->gr_gid == groups[i])
+                               goto skip;
+               }
+               for (i = 0; grp->gr_mem[i]; i++) {
+                       if (!strcmp(grp->gr_mem[i], uname)) {
+                               if (ngroups >= maxgroups) {
+                                       ret = -1;
+                                       break;
+                               }
+                               groups[ngroups++] = grp->gr_gid;
+                               break;
+                       }
+               }
+skip: ;
+       }
+       endgrent();
+       *grpcnt = ngroups;
+       return (ret);
+}
+
+int
+initgroups(uname, agroup)
+const char *uname;
+gid_t agroup;
+{
+    gid_t groups[32], ngroups;
+    
+    ngroups = 32;
+    getgrouplist(uname, agroup, groups, &ngroups);
+    return (setgroups(ngroups, groups));
+}
index 7550e07..61fe163 100755 (executable)
@@ -1,9 +1,9 @@
 
 #!/bin/sh -e
 
-mkdir -p arpa netinet sys nestedvm
+mkdir -p arpa netinet sys nestedvm net
 
-for f in arpa/inet.h netdb.h netinet/in.h sys/socket.h; do
+for f in arpa/inet.h netdb.h netinet/in.h sys/socket.h net/if.h; do
     test -f $f || echo "#include <nestedvm/socket.h>" > $f
 done
 
@@ -377,6 +377,10 @@ static unsigned long htonl(int x) { return x; }
 static unsigned short ntohs(int x) { return x; }
 static unsigned long ntohl(int x) { return x; }
 
+/* Note AF_UNIX isn't supported */
+#define AF_UNIX 1
+#define PF_UNIX AF_UNIX
+
 #define AF_INET 2
 #define PF_INET AF_INET
 
@@ -392,12 +396,17 @@ static unsigned long ntohl(int x) { return x; }
 
 #define SO_REUSEADDR 0x0004
 #define SO_KEEPALIVE 0x0008 
+#define SO_BROADCAST 0x0020
+#define SO_TYPE      0x1008
 
 #define SHUT_RD 0
 #define SHUT_WR 1
 #define SHUT_RDWR 2
 
 #define INADDR_ANY 0
+#define INADDR_NONE -1
+#define INADDR_LOOPBACK 0x7f000001
+#define INADDR_BROADCAST 0xffffffff
 
 typedef unsigned long in_addr_t;
 typedef int socklen_t;
@@ -419,6 +428,14 @@ struct sockaddr_in {
        struct  in_addr sin_addr;
 };
 
+struct sockaddr_un {
+       u_char  sun_len;
+       u_char  sun_family;
+       char    sun_path[256];
+};
+
+#define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
+
 struct  servent {
     char    *s_name;        /* official name of service */
     char    **s_aliases;    /* alias list */
@@ -445,7 +462,11 @@ int listen(int s, int backlog);
 int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
 int shutdown(int s, int how);
 int connect(int s, const struct sockaddr *name, socklen_t namelen);
+
 char *inet_ntoa(struct in_addr in);
+in_addr_t inet_addr(const char *cp);
+int inet_aton(const char *cp, struct in_addr *addr);
+
 int recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
 int sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen);
 int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);