From: <ljs...@us...> - 2007-08-03 04:19:58
|
Revision: 430 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=430&view=rev Author: ljsebald Date: 2007-08-02 21:19:54 -0700 (Thu, 02 Aug 2007) Log Message: ----------- Adding in a few more inet functions for dealing with parsing and packing internet addresses. Modified Paths: -------------- kos/include/arpa/inet.h kos/include/netinet/in.h kos/kernel/libc/koslib/Makefile kos/kernel/libc/koslib/inet_addr.c Added Paths: ----------- kos/kernel/libc/koslib/inet_aton.c kos/kernel/libc/koslib/inet_ntoa.c kos/kernel/libc/koslib/inet_ntop.c kos/kernel/libc/koslib/inet_pton.c Modified: kos/include/arpa/inet.h =================================================================== --- kos/include/arpa/inet.h 2007-07-29 03:21:16 UTC (rev 429) +++ kos/include/arpa/inet.h 2007-08-03 04:19:54 UTC (rev 430) @@ -1,7 +1,7 @@ /* KallistiOS ##version## arpa/inet.h - Copyright (C)2006 Lawrence Sebald + Copyright (C) 2006, 2007 Lawrence Sebald */ @@ -9,10 +9,13 @@ #define __ARPA_INET_H #include <sys/cdefs.h> -#include <netinet/in.h> __BEGIN_DECLS +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/socket.h> + uint32 htonl(uint32 value); uint32 ntohl(uint32 value); @@ -20,7 +23,14 @@ uint16 ntohs(uint16 value); in_addr_t inet_addr(const char *cp); +int inet_aton(const char *cp, struct in_addr *pin); +int inet_pton(int af, const char *src, void *dst); +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); + +/* Non-reentrant */ +char *inet_ntoa(struct in_addr addr); + __END_DECLS #endif /* __ARPA_INET_H */ Modified: kos/include/netinet/in.h =================================================================== --- kos/include/netinet/in.h 2007-07-29 03:21:16 UTC (rev 429) +++ kos/include/netinet/in.h 2007-08-03 04:19:54 UTC (rev 430) @@ -1,7 +1,7 @@ /* KallistiOS ##version## netinet/in.h - Copyright (C)2006 Lawrence Sebald + Copyright (C) 2006, 2007 Lawrence Sebald */ @@ -13,8 +13,15 @@ __BEGIN_DECLS +#ifndef __IN_PORT_T_DEFINED +#define __IN_PORT_T_DEFINED typedef uint16 in_port_t; +#endif + +#ifndef __IN_ADDR_T_DEFINED +#define __IN_ADDR_T_DEFINED typedef uint32 in_addr_t; +#endif #ifndef __SA_FAMILY_T_DEFINED #define __SA_FAMILY_T_DEFINED @@ -34,10 +41,13 @@ #define INADDR_ANY 0x00000000 #define INADDR_BROADCAST 0xFFFFFFFF +#define INADDR_NONE 0xFFFFFFFF /* IP Protocols */ -#define IPPROTO_IP 0 -#define IPPROTO_UDP 17 +#define IPPROTO_IP 0 +#define IPPROTO_ICMP 1 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 __END_DECLS Modified: kos/kernel/libc/koslib/Makefile =================================================================== --- kos/kernel/libc/koslib/Makefile 2007-07-29 03:21:16 UTC (rev 429) +++ kos/kernel/libc/koslib/Makefile 2007-08-03 04:19:54 UTC (rev 430) @@ -11,6 +11,7 @@ assert.o dbglog.o malloc.o crtbegin.o crtend.o atexit.o \ opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \ telldir.o usleep.o inet_addr.o realpath.o getcwd.o chdir.o mkdir.o \ - creat.o sleep.o rmdir.o rename.o + creat.o sleep.o rmdir.o rename.o inet_pton.o inet_ntop.o \ + inet_ntoa.o inet_aton.o include $(KOS_BASE)/Makefile.prefab Modified: kos/kernel/libc/koslib/inet_addr.c =================================================================== --- kos/kernel/libc/koslib/inet_addr.c 2007-07-29 03:21:16 UTC (rev 429) +++ kos/kernel/libc/koslib/inet_addr.c 2007-08-03 04:19:54 UTC (rev 430) @@ -1,49 +1,19 @@ /* KallistiOS ##version## inet_addr.c - Copyright (C)2006 Lawrence Sebald + Copyright (C) 2006, 2007 Lawrence Sebald */ #include <arpa/inet.h> -#include <stdlib.h> in_addr_t inet_addr(const char *cp) { - in_addr_t result = 0; - long tmp; - char *ptr; + struct in_addr addr; - tmp = strtoul(cp, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; + /* inet_aton() returns 0 on failure, 1 on success */ + if(inet_aton(cp, &addr)) { + return addr.s_addr; } - else { - result = tmp << 24; - } - tmp = strtoul(ptr + 1, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; - } - else { - result |= tmp << 16; - } - - tmp = strtoul(ptr + 1, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; - } - else { - result |= tmp << 8; - } - - tmp = strtoul(ptr + 1, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; - } - else { - result |= tmp; - } - - return (in_addr_t) htonl(result); + return INADDR_NONE; } Added: kos/kernel/libc/koslib/inet_aton.c =================================================================== --- kos/kernel/libc/koslib/inet_aton.c (rev 0) +++ kos/kernel/libc/koslib/inet_aton.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,118 @@ +/* KallistiOS ##version## + + inet_aton.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> + +int inet_aton(const char *cp, struct in_addr *pin) { + int parts[4] = { 0 }; + int count = 0; + int base = 0; + char tmp; + + for(; *cp && count < 4; ++cp) { + if(*cp == '.') { + ++count; + base = 0; + } + else if(base == 0) { + /* Determine which base this part is in */ + if(*cp == '0') { + tmp = *++cp; + + if(tmp == '.') { + base = 0; + parts[count++] = 0; + } + else if(tmp == '\0') { + base = 0; + parts[count] = 0; + --cp; + } + else if(tmp != 'x' && tmp != 'X') { + /* Octal, handle the character just read too. */ + base = 8; + parts[count] = *cp - '0'; + } + else { + /* Hexadecimal */ + base = 16; + } + } + else if(*cp > '0' && *cp <= '9') { + /* Decimal, handle the digit */ + base = 10; + parts[count] = *cp - '0'; + } + else { + /* Non-number starting character... bail out. */ + return 0; + } + } + else if(base == 10 && *cp >= '0' && *cp <= '9') { + parts[count] *= 10; + parts[count] += *cp - '0'; + } + else if(base == 8 && *cp >= '0' && *cp <= '7') { + parts[count] <<= 3; + parts[count] += *cp - '0'; + } + else if(base == 16) { + parts[count] <<= 4; + + if(*cp >= '0' && *cp <= '9') { + parts[count] += *cp - '0'; + } + else if(*cp >= 'A' && *cp <= 'F') { + parts[count] += *cp - 'A' + 10; + } + else if(*cp >= 'a' && *cp <= 'f') { + parts[count] += *cp - 'a' + 10; + } + else { + /* Invalid hex digit */ + return 0; + } + } + else { + /* Invalid digit, and not a dot... bail */ + return 0; + } + } + + if(count == 4) { + /* Too many dots, bail out */ + return 0; + } + + /* Validate each part */ + if(count == 0) { + /* Easiest case, store our computed part, and it's done */ + pin->s_addr = htonl(parts[0]); + } + else if(count == 1) { + if(parts[0] > 0xFF || parts[1] > 0xFFFFFF) + return 0; + + pin->s_addr = htonl(parts[0] << 24 | parts[1]); + } + else if(count == 2) { + if(parts[0] > 0xFF || parts[1] > 0xFF || parts[2] > 0xFFFF) + return 0; + + pin->s_addr = htonl(parts[0] << 24 | parts[1] << 16 | parts[2]); + } + else { + if(parts[0] > 0xFF || parts[1] > 0xFF || + parts[2] > 0xFF || parts[3] > 0xFF) + return 0; + + pin->s_addr = htonl(parts[0] << 24 | parts[1] << 16 | + parts[2] << 8 | parts[3]); + } + + return 1; +} Added: kos/kernel/libc/koslib/inet_ntoa.c =================================================================== --- kos/kernel/libc/koslib/inet_ntoa.c (rev 0) +++ kos/kernel/libc/koslib/inet_ntoa.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,45 @@ +/* KallistiOS ##version## + + inet_ntoa.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> + +char *inet_ntoa(struct in_addr addr) { + static char str[16]; /* XXX.XXX.XXX.XXX = 15 chars + 1 for NUL */ + char tmp[3]; + int i, part; + char *ch = tmp; + char *ch2 = str; + + /* Parse each 8 bits individually. */ + for(i = 0; i < 4; ++i) { + /* Treat the 32-bit address value as if it were an array of 8-bit + values. This works, regardless of the endianness of the host system + because the specs require the address passed in here to be in + network byte order (big endian). */ + part = ((uint8 *) &addr.s_addr)[i]; + + do { + *ch++ = '0' + (char)(part % 10); + part /= 10; + } while(part); + + /* tmp now contains the inverse of the number that is in the given + 8 bits. Reverse it for the final result, rewinding ch to the + beginning of tmp in the process. */ + while(ch != tmp) { + *ch2++ = *--ch; + } + + *ch2++ = '.'; + } + + /* There's a trailing '.' at the end of the address, change it to the + required NUL character */ + *--ch2 = 0; + + return str; +} Added: kos/kernel/libc/koslib/inet_ntop.c =================================================================== --- kos/kernel/libc/koslib/inet_ntop.c (rev 0) +++ kos/kernel/libc/koslib/inet_ntop.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,58 @@ +/* KallistiOS ##version## + + inet_ntop.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> +#include <errno.h> + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { + char tmp[3]; + int i, part; + char *ch = tmp; + char *ch2 = dst; + struct in_addr *addr = (struct in_addr *)src; + + if(af != AF_INET) { + errno = EAFNOSUPPORT; + return NULL; + } + + /* Parse each 8 bits individually. */ + for(i = 0; i < 4; ++i) { + /* Treat the 32-bit address value as if it were an array of 8-bit + values. This works, regardless of the endianness of the host system + because the specs require the address passed in here to be in + network byte order (big endian). */ + part = ((uint8 *) &addr->s_addr)[i]; + + do { + *ch++ = '0' + (char)(part % 10); + part /= 10; + } while(part); + + /* tmp now contains the inverse of the number that is in the given + 8 bits. Reverse it for the final result, rewinding ch to the + beginning of tmp in the process. */ + while(ch != tmp && size) { + *ch2++ = *--ch; + --size; + } + + if(!size) { + errno = ENOSPC; + return NULL; + } + + *ch2++ = '.'; + --size; + } + + /* There's a trailing '.' at the end of the address, change it to the + required NUL character */ + *--ch2 = 0; + + return dst; +} Added: kos/kernel/libc/koslib/inet_pton.c =================================================================== --- kos/kernel/libc/koslib/inet_pton.c (rev 0) +++ kos/kernel/libc/koslib/inet_pton.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,51 @@ +/* KallistiOS ##version## + + inet_pton.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> +#include <errno.h> + +int inet_pton(int af, const char *src, void *dst) { + int parts[4] = { 0 }; + int count = 0; + struct in_addr *addr = (struct in_addr *)dst; + + if(af != AF_INET) { + errno = EAFNOSUPPORT; + return -1; + } + + for(; *src && count < 4; ++src) { + if(*src == '.') { + ++count; + } + /* Unlike inet_aton(), inet_pton() only supports decimal parts */ + else if(*src >= '0' && *src <= '9') { + parts[count] *= 10; + parts[count] += *src - '0'; + } + else { + /* Invalid digit, and not a dot... bail */ + return 0; + } + } + + if(count != 3) { + /* Not the right number of parts, bail */ + return 0; + } + + /* Validate each part, note that unlike inet_aton(), inet_pton() only + supports the standard xxx.xxx.xxx.xxx addresses. */ + if(parts[0] > 0xFF || parts[1] > 0xFF || + parts[2] > 0xFF || parts[3] > 0xFF) + return 0; + + addr->s_addr = htonl(parts[0] << 24 | parts[1] << 16 | + parts[2] << 8 | parts[3]); + + return 1; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |