1#include <errno.h>
2#include <string.h>
3#include <sys/types.h>
4#include <netinet/in.h>
5
6#include "utils.h"
7
8static u_int32_t hexget(char c)
9{
10	if (c >= 'A' && c <= 'F')
11		return c - 'A' + 10;
12	if (c >= 'a' && c <= 'f')
13		return c - 'a' + 10;
14	if (c >= '0' && c <= '9')
15		return c - '0';
16
17	return 0xf0;
18}
19
20static int ipx_getnet(u_int32_t *net, const char *str)
21{
22	int i;
23	u_int32_t tmp;
24
25	for(i = 0; *str && (i < 8); i++) {
26
27		if ((tmp = hexget(*str)) & 0xf0) {
28			if (*str == '.')
29				return 0;
30			else
31				return -1;
32		}
33
34		str++;
35		(*net) <<= 4;
36		(*net) |= tmp;
37	}
38
39	if (*str == 0)
40		return 0;
41
42	return -1;
43}
44
45static int ipx_getnode(u_int8_t *node, const char *str)
46{
47	int i;
48	u_int32_t tmp;
49
50	for(i = 0; i < 6; i++) {
51		if ((tmp = hexget(*str++)) & 0xf0)
52			return -1;
53		node[i] = (u_int8_t)tmp;
54		node[i] <<= 4;
55		if ((tmp = hexget(*str++)) & 0xf0)
56			return -1;
57		node[i] |= (u_int8_t)tmp;
58		if (*str == ':')
59			str++;
60	}
61
62	return 0;
63}
64
65static int ipx_pton1(const char *src, struct ipx_addr *addr)
66{
67	char *sep = (char *)src;
68	int no_node = 0;
69
70	memset(addr, 0, sizeof(struct ipx_addr));
71
72	while(*sep && (*sep != '.'))
73		sep++;
74
75	if (*sep != '.')
76		no_node = 1;
77
78	if (ipx_getnet(&addr->ipx_net, src))
79		return 0;
80
81	addr->ipx_net = htonl(addr->ipx_net);
82
83	if (no_node)
84		return 1;
85
86	if (ipx_getnode(addr->ipx_node, sep + 1))
87		return 0;
88
89	return 1;
90}
91
92int ipx_pton(int af, const char *src, void *addr)
93{
94	int err;
95
96	switch (af) {
97	case AF_IPX:
98		errno = 0;
99		err = ipx_pton1(src, (struct ipx_addr *)addr);
100		break;
101	default:
102		errno = EAFNOSUPPORT;
103		err = -1;
104	}
105
106	return err;
107}
108