summaryrefslogtreecommitdiff
path: root/libc/inet/addr.c
blob: 7751b6bc2a4726c72263da185de38ecf36d99d27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
 * This file is part of the Linux-8086 C library and is distributed
 * under the GNU Library General Public License.
 */

/*
 * Manuel Novoa III       Dec 2000
 *
 * Converted to use my new (un)signed long (long) to string routines, which
 * are smaller than the previous functions and don't require static buffers.
 * In the process, removed the reference to strcat and cut object size of
 * inet_ntoa in half (from 190 bytes down to 94).
 *
 * Manuel Novoa III       Feb 2002
 *
 * Changed to use _int10tostr.
 */

#define __FORCE_GLIBC
#include <features.h>
#define _STDIO_UTILITY			/* For _int10tostr. */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>

int inet_aton(const char *cp, struct in_addr *inp);

#ifdef L_inet_aton
int inet_aton(cp, inp)
const char *cp;
struct in_addr *inp;
{
	unsigned long addr;
	int value;
	int part;

	if (!inp)
		return 0;

	addr = 0;
	for (part = 1; part <= 4; part++) {

		if (!isdigit(*cp))
			return 0;

		value = 0;
		while (isdigit(*cp)) {
			value *= 10;
			value += *cp++ - '0';
			if (value > 255)
				return 0;
		}

		if (part < 4) {
			if (*cp++ != '.')
				return 0;
		} else {
			char c = *cp++;
			if (c != '\0' && !isspace(c))
			return 0;
		}

		addr <<= 8;
		addr |= value;
	}

	inp->s_addr = htonl(addr);

	return 1;
}
#endif

#ifdef L_inet_addr
unsigned long inet_addr(const char *cp)
{
	struct in_addr a;

	if (!inet_aton(cp, &a))
		return -1;
	else
		return a.s_addr;
}
#endif

#ifdef L_inet_ntoa
char *inet_ntoa_r(struct in_addr in, char buf[16])
{
	unsigned long addr = ntohl(in.s_addr);
	int i;
	char *p, *q;
   
	q = 0;
	p = buf + sizeof(buf) - 1;
	for (i=0 ; i < 4 ; i++ ) {
		p = _int10tostr(p, addr & 0xff) - 1;
		addr >>= 8;
		if (q) {
			*q = '.';
		}
		q = p;
	}

	return p+1;
}

char *inet_ntoa(struct in_addr in)
{
	static char buf[16];		/* max 12 digits + 3 '.'s + 1 nul */
	return(inet_ntoa_r(in, buf));
}
#endif

#ifdef L_inet_makeaddr
/*
 * Formulate an Internet address from network + host.  Used in
 * building addresses stored in the ifnet structure.
 */
struct in_addr inet_makeaddr(unsigned long net, unsigned long host)
{
        unsigned long addr;

        if (net < 128)
                addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
        else if (net < 65536)
                addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
        else if (net < 16777216L)
                addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
        else
                addr = net | host;
        addr = htonl(addr);
        return (*(struct in_addr *)&addr);
}

#endif

#ifdef L_inet_lnaof
/*
 * Return the local network address portion of an
 * internet address; handles class a/b/c network
 * number formats.
 */
unsigned long inet_lnaof(struct in_addr in)
{
	unsigned long i = ntohl(in.s_addr);

	if (IN_CLASSA(i))
		return ((i)&IN_CLASSA_HOST);
	else if (IN_CLASSB(i))
		return ((i)&IN_CLASSB_HOST);
	else
		return ((i)&IN_CLASSC_HOST);
}
#endif

#ifdef L_inet_netof

/*
 * Return the network number from an internet
 * address; handles class a/b/c network #'s.
 */
u_int32_t
inet_netof(struct in_addr in)
{
        u_int32_t i = ntohl(in.s_addr);

        if (IN_CLASSA(i))
                return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
        else if (IN_CLASSB(i))
                return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
        else
                return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
}

#endif