mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Add inet_pton and inet_ntop
This commit is contained in:
parent
545c29763e
commit
7826c14c05
4
src/cc3k/include/inet_ntop.h
Normal file
4
src/cc3k/include/inet_ntop.h
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef __INET_NTOP_H
|
||||
#define __INET_NTOP_H
|
||||
char *inet_ntop(int af, const void *addr, char *buf, size_t size);
|
||||
#endif /* __INET_NTOP_H */
|
||||
4
src/cc3k/include/inet_pton.h
Normal file
4
src/cc3k/include/inet_pton.h
Normal file
@ -0,0 +1,4 @@
|
||||
#ifndef __INET_PTON_H
|
||||
#define __INET_PTON_H
|
||||
int inet_pton(int, const char *, void *);
|
||||
#endif /* __INET_PTON_H */
|
||||
195
src/cc3k/src/inet_ntop.c
Normal file
195
src/cc3k/src/inet_ntop.c
Normal file
@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <std.h>
|
||||
#include <string.h>
|
||||
#include "cc3000_common.h"
|
||||
#include "socket.h"
|
||||
#include "inet_ntop.h"
|
||||
|
||||
#define IN6ADDRSZ 16
|
||||
#define INADDRSZ 4
|
||||
#define INT16SZ 2
|
||||
|
||||
#define ENOSPC (28)
|
||||
#define EAFNOSUPPORT (106)
|
||||
#define SET_ERRNO(err) (errno=-err)
|
||||
|
||||
/*
|
||||
* Format an IPv4 address, more or less like inet_ntoa().
|
||||
*
|
||||
* Returns `dst' (as a const)
|
||||
* Note:
|
||||
* - uses no statics
|
||||
* - takes a unsigned char* not an in_addr as input
|
||||
*/
|
||||
static char *inet_ntop4 (const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
size_t len;
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
tmp[0] = '\0';
|
||||
(void)snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d",
|
||||
((int)((unsigned char)src[0])) & 0xff,
|
||||
((int)((unsigned char)src[1])) & 0xff,
|
||||
((int)((unsigned char)src[2])) & 0xff,
|
||||
((int)((unsigned char)src[3])) & 0xff);
|
||||
|
||||
len = strlen(tmp);
|
||||
if(len == 0 || len >= size)
|
||||
{
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return dst;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/*
|
||||
* Convert IPv6 binary address into presentation (printable) format.
|
||||
*/
|
||||
static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
|
||||
char *tp;
|
||||
struct {
|
||||
long base;
|
||||
long len;
|
||||
} best, cur;
|
||||
unsigned long words[IN6ADDRSZ / INT16SZ];
|
||||
int i;
|
||||
|
||||
/* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof(words));
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i/2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
best.len = 0;
|
||||
cur.len = 0;
|
||||
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
if(words[i] == 0)
|
||||
{
|
||||
if(cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
}
|
||||
else if(cur.base != -1)
|
||||
{
|
||||
if(best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
if((cur.base != -1) && (best.base == -1 || cur.len > best.len))
|
||||
best = cur;
|
||||
if(best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
|
||||
{
|
||||
/* Are we inside the best run of 0x00's?
|
||||
*/
|
||||
if(best.base != -1 && i >= best.base && i < (best.base + best.len))
|
||||
{
|
||||
if(i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Are we following an initial run of 0x00s or any real hex?
|
||||
*/
|
||||
if(i != 0)
|
||||
*tp++ = ':';
|
||||
|
||||
/* Is this address an encapsulated IPv4?
|
||||
*/
|
||||
if(i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||
{
|
||||
if(!inet_ntop4(src+12, tp, sizeof(tmp) - (tp - tmp)))
|
||||
{
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += snprintf(tp, 5, "%lx", words[i]);
|
||||
}
|
||||
|
||||
/* Was it a trailing run of 0x00's?
|
||||
*/
|
||||
if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if((size_t)(tp - tmp) > size)
|
||||
{
|
||||
SET_ERRNO(ENOSPC);
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return dst;
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
|
||||
/*
|
||||
* Convert a network format address to presentation format.
|
||||
*
|
||||
* Returns pointer to presentation format address (`buf').
|
||||
* Returns NULL on error and errno set with the specific
|
||||
* error, EAFNOSUPPORT or ENOSPC.
|
||||
*
|
||||
* On Windows we store the error in the thread errno, not
|
||||
* in the winsock error code. This is to avoid loosing the
|
||||
* actual last winsock error. So use macro ERRNO to fetch the
|
||||
* errno this funtion sets when returning NULL, not SOCKERRNO.
|
||||
*/
|
||||
char *inet_ntop(int af, const void *src, char *buf, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return inet_ntop4((const unsigned char*)src, buf, size);
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
return inet_ntop6((const unsigned char*)src, buf, size);
|
||||
#endif
|
||||
default:
|
||||
SET_ERRNO(EAFNOSUPPORT);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
216
src/cc3k/src/inet_pton.c
Normal file
216
src/cc3k/src/inet_pton.c
Normal file
@ -0,0 +1,216 @@
|
||||
/* This is from the BIND 4.9.4 release, modified to compile by itself */
|
||||
|
||||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "cc3000_common.h"
|
||||
#include "socket.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
#define IN6ADDRSZ 16
|
||||
#define INADDRSZ 4
|
||||
#define INT16SZ 2
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
#ifdef ENABLE_IPV6
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
#endif
|
||||
|
||||
#define EAFNOSUPPORT (106)
|
||||
#define SET_ERRNO(err) (errno=-err)
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* notice:
|
||||
* On Windows we store the error in the thread errno, not
|
||||
* in the winsock error code. This is to avoid loosing the
|
||||
* actual last winsock error. So use macro ERRNO to fetch the
|
||||
* errno this funtion sets when returning (-1), not SOCKERRNO.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, (unsigned char *)dst));
|
||||
#ifdef ENABLE_IPV6
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, (unsigned char *)dst));
|
||||
#endif
|
||||
default:
|
||||
SET_ERRNO(EAFNOSUPPORT);
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int inet_pton4(const char *src, unsigned char *dst)
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
tp = tmp;
|
||||
*tp = 0;
|
||||
while((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if((pch = strchr(digits, ch)) != NULL) {
|
||||
unsigned int val = *tp * 10 + (unsigned int)(pch - digits);
|
||||
|
||||
if(saw_digit && *tp == 0)
|
||||
return (0);
|
||||
if(val > 255)
|
||||
return (0);
|
||||
*tp = (unsigned char)val;
|
||||
if(! saw_digit) {
|
||||
if(++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
}
|
||||
else if(ch == '.' && saw_digit) {
|
||||
if(octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
if(octets < 4)
|
||||
return (0);
|
||||
memcpy(dst, tmp, INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int inet_pton6(const char *src, unsigned char *dst)
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
unsigned int val;
|
||||
|
||||
memset((tp = tmp), 0, IN6ADDRSZ);
|
||||
endp = tp + IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if(*src == ':')
|
||||
if(*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if(pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if(++saw_xdigit > 4)
|
||||
return (0);
|
||||
continue;
|
||||
}
|
||||
if(ch == ':') {
|
||||
curtok = src;
|
||||
if(!saw_xdigit) {
|
||||
if(colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if(tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if(ch == '.' && ((tp + INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if(saw_xdigit) {
|
||||
if(tp + INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
}
|
||||
if(colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const long n = tp - colonp;
|
||||
long i;
|
||||
|
||||
if(tp == endp)
|
||||
return (0);
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if(tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
#endif /* ENABLE_IPV6 */
|
||||
Loading…
Reference in New Issue
Block a user