aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-11-02 12:50:00 +0000
committerIgor Sysoev <igor@sysoev.ru>2009-11-02 12:50:00 +0000
commit5a76cbbbc6fb36cf0c29f38c04d3ebdeea68e244 (patch)
treebcd0deec33e3db5ac1113762b7c3b9b0a6cb3f9c /src
parent19811dbdded93bc57e536cbcf7b067aee6d8ef26 (diff)
downloadnginx-5a76cbbbc6fb36cf0c29f38c04d3ebdeea68e244.tar.gz
nginx-5a76cbbbc6fb36cf0c29f38c04d3ebdeea68e244.zip
ngx_inet6_addr()
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_inet.c120
-rw-r--r--src/core/ngx_inet.h3
2 files changed, 123 insertions, 0 deletions
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index 5702dbaa6..9b039f5dd 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -59,6 +59,126 @@ ngx_inet_addr(u_char *text, size_t len)
}
+#if (NGX_HAVE_INET6)
+
+ngx_int_t
+ngx_inet6_addr(u_char *p, size_t len, u_char *addr)
+{
+ u_char c, *zero, *digit, *s, *d;
+ size_t len4;
+ ngx_uint_t n, nibbles, word;
+
+ if (len == 0) {
+ return NGX_ERROR;
+ }
+
+ zero = NULL;
+ digit = NULL;
+ len4 = 0;
+ nibbles = 0;
+ word = 0;
+ n = 8;
+
+ if (p[0] == ':') {
+ p++;
+ len--;
+ }
+
+ for (/* void */; len; len--) {
+ c = *p++;
+
+ if (c == ':') {
+ if (nibbles) {
+ digit = p;
+ len4 = len;
+ *addr++ = (u_char) (word >> 8);
+ *addr++ = (u_char) (word & 0xff);
+
+ if (--n) {
+ nibbles = 0;
+ word = 0;
+ continue;
+ }
+
+ } else {
+ if (zero == NULL) {
+ digit = p;
+ len4 = len;
+ zero = addr;
+ continue;
+ }
+ }
+
+ return NGX_ERROR;
+ }
+
+ if (c == '.' && nibbles) {
+ if (n < 2) {
+ return NGX_ERROR;
+ }
+
+ word = ngx_inet_addr(digit, len4 - 1);
+ if (word == INADDR_NONE) {
+ return NGX_ERROR;
+ }
+
+ word = ntohl(word);
+ *addr++ = (u_char) ((word >> 24) & 0xff);
+ *addr++ = (u_char) ((word >> 16) & 0xff);
+ n--;
+ break;
+ }
+
+ if (++nibbles > 4) {
+ return NGX_ERROR;
+ }
+
+ if (c >= '0' && c <= '9') {
+ word = word * 16 + (c - '0');
+ continue;
+ }
+
+ c |= 0x20;
+
+ if (c >= 'a' && c <= 'f') {
+ word = word * 16 + (c - 'a') + 10;
+ continue;
+ }
+
+ return NGX_ERROR;
+ }
+
+ if (nibbles == 0 && zero == NULL) {
+ return NGX_ERROR;
+ }
+
+ *addr++ = (u_char) (word >> 8);
+ *addr++ = (u_char) (word & 0xff);
+
+ if (--n) {
+ if (zero) {
+ n *= 2;
+ s = addr - 1;
+ d = s + n;
+ while (s >= zero) {
+ *d-- = *s--;
+ }
+ ngx_memzero(zero, n);
+ return NGX_OK;
+ }
+
+ } else {
+ if (zero == NULL) {
+ return NGX_OK;
+ }
+ }
+
+ return NGX_ERROR;
+}
+
+#endif
+
+
size_t
ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len, ngx_uint_t port)
{
diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h
index 3db74551b..f3bf9e4e1 100644
--- a/src/core/ngx_inet.h
+++ b/src/core/ngx_inet.h
@@ -102,6 +102,9 @@ typedef struct {
in_addr_t ngx_inet_addr(u_char *text, size_t len);
+#if (NGX_HAVE_INET6)
+ngx_int_t ngx_inet6_addr(u_char *p, size_t len, u_char *addr);
+#endif
size_t ngx_sock_ntop(struct sockaddr *sa, u_char *text, size_t len,
ngx_uint_t port);
size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);