|
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.
|