Plan 9 from Bell Labs’s /usr/web/sources/patch/ape-erik/inet_pton.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#define _SUSV2_SOURCE
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define nil ((void*)0)
typedef unsigned char uchar;

int classnetbytes[] = {1, 1, 2, 3, };

static char*
parseip4(uchar *u, char *s)
{
	char *v;
	int i, d, b, n;

	for(i = 0; i < 4; i++){
		v = s;
		d = strtoul(s, &s, 0);
		if(d > 255)
			return nil;
		u[i] = d;
		if(*s == '.')
			s++;
		else if(s == v)
			break;
	}
	if(i < 4 && i > (b = classnetbytes[u[0]>>6])){
		n = i - b;
		memmove(u+4-n, u+b, n);
		memset(u+b, 0, 4-(b+n));
		i = 4;
	}
	if(i != 4)
		return nil;
	return s;
}

static char*
parseip6(uchar *u, char *s)
{
	char *v;
	int i, d, cc, is4;

	is4 = 1;
	cc = -1;
	for(i = 0; i < 16;){
		v = s;
		d = strtoul(s, &s, 16);
		switch(*s){
		case '.':
			if(i + 4 > 16)
				return nil;
			s = parseip4(u+i, v);
			if(s == nil)
				return nil;
			i += 4;
			break;
		case ':':
			is4 = 0;
			s++;
		default:
			if(d > 0xffff)
				return nil;
			u[i++] = d>>8;
			u[i++] = d;
			if(*s == ':'){
				if(cc != -1)
					return nil;
				cc = i;
				s++;
			}
			if(s == v)
				i -= 2;
			break;
		}
		if(s == v)
			break;
	}
	if(is4 && i == 4){
		memmove(u+12, u, 4);
		memset(u, 0, 4);
		memset(u+10, 0xff, 2);
	}
	else if(cc != -1 && i < 16){
		memmove(u+cc+(16-i), u+cc, i-cc);
		memset(u+cc, 0, 16-i);
	}
	else if(i != 16)
		return nil;
	return s;
}

int
inet_pton(int af, const char *src, void *dst)
{
	uchar u[16];
	struct in_addr *ia;
	struct in6_addr *ia6;

	memset(u, 0, sizeof u);
	switch(af){
	default:
		errno = EAFNOSUPPORT;
		return -1;
	case AF_INET:
		if(parseip4(u, src) == nil)
			return 0;
		ia = (struct in_addr*)dst;
		memmove(&ia->s_addr, u, 4);
		return 1;
	case AF_INET6:
		if(parseip6(u, src) == nil)
			return 0;
		ia6 = (struct in6_addr*)dst;
		memmove(ia6->s6_addr, u, 16);
		return 1;
	}
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].