blob: c71d4d4f744ca1c6f15d2328330d80fb5a252203 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
2 * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
3 *
4 * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
5 */
6
7/*
8 * Manuel Novoa III Dec 2000
9 *
10 * Converted to use my new (un)signed long (long) to string routines, which
11 * are smaller than the previous functions and don't require static buffers.
12 * In the process, removed the reference to strcat and cut object size of
13 * inet_ntoa in half (from 190 bytes down to 94).
14 *
15 * Manuel Novoa III Feb 2002
16 *
17 * Changed to use _int10tostr.
18 */
19
20#define __FORCE_GLIBC
21#include <features.h>
22#include <stdio.h>
23#include <string.h>
24#include <ctype.h>
25#include <netinet/in.h>
26#include <arpa/inet.h>
27#include <bits/uClibc_uintmaxtostr.h>
28
29#ifdef L_inet_aton
30/*
31 * More undocumented inet_aton features.
32 * (read: uclibc doesnt support but glibc does)
33 * http://www.mkssoftware.com/docs/man3/inet_aton.3.asp
34 *
35 * *cp can take the form of:
36 * a.b.c.d - {a,b,c,d} -> 1 byte
37 * a.b.c - {a,b} -> 1 byte {c} -> 2 bytes
38 * a.b - {a} -> 1 byte {b} -> 3 bytes
39 * a - {a} -> 4 bytes
40 *
41 * Each part may be decimal, octal, or hexadecimal as in ISO C.
42 * 0x or 0X -> hexadecimal
43 * leading 0 -> octal
44 * all else -> decimal
45 */
46int inet_aton(const char *cp, struct in_addr *addrptr)
47{
48 in_addr_t addr;
49 int value;
50 int part;
51
52 if (cp == NULL) {
53 return 0;
54 }
55
56 addr = 0;
57 for (part = 1; part <= 4; part++) {
58
59 if (!isdigit(*cp))
60 return 0;
61
62 value = 0;
63 while (isdigit(*cp)) {
64 value *= 10;
65 value += *cp++ - '0';
66 if (value > 255)
67 return 0;
68 }
69
70 if (part < 4) {
71 if (*cp++ != '.')
72 return 0;
73 } else {
74 char c = *cp++;
75 if (c != '\0' && !isspace(c))
76 return 0;
77 }
78
79 addr <<= 8;
80 addr |= value;
81 }
82
83 /* W. Richard Stevens in his book UNIX Network Programming,
84 * Volume 1, second edition, on page 71 says:
85 *
86 * An undocumented feature of inet_aton is that if addrptr is
87 * a null pointer, the function still performs it validation
88 * of the input string, but does not store the result.
89 */
90 if (addrptr) {
91 addrptr->s_addr = htonl(addr);
92 }
93
94 return 1;
95}
96libc_hidden_def(inet_aton)
97#endif
98
99#ifdef L_inet_addr
100
101in_addr_t inet_addr(const char *cp)
102{
103 struct in_addr a;
104
105 if (!inet_aton(cp, &a))
106 return INADDR_NONE;
107 else
108 return a.s_addr;
109}
110libc_hidden_def(inet_addr)
111#endif
112
113#ifdef L_inet_ntoa
114
115#define INET_NTOA_MAX_LEN 16 /* max 12 digits + 3 '.'s + 1 nul */
116
117char *inet_ntoa_r(struct in_addr in, char buf[INET_NTOA_MAX_LEN])
118{
119 in_addr_t addr = ntohl(in.s_addr);
120 int i;
121 char *p, *q;
122
123 q = 0;
124 p = buf + INET_NTOA_MAX_LEN - 1; /* cannot use sizeof(buf) here */
125 for (i = 0; i < 4; i++ ) {
126 p = _int10tostr(p, addr & 0xff) - 1;
127 addr >>= 8;
128 if (q) {
129 *q = '.';
130 }
131 q = p;
132 }
133
134 return p+1;
135}
136libc_hidden_def(inet_ntoa_r)
137
138char *inet_ntoa(struct in_addr in)
139{
140 static char buf[INET_NTOA_MAX_LEN];
141 return inet_ntoa_r(in, buf);
142}
143libc_hidden_def(inet_ntoa)
144#endif
145
146#ifdef L_inet_makeaddr
147
148/* for some reason it does not remove the jump relocation */
149
150/*
151 * Formulate an Internet address from network + host. Used in
152 * building addresses stored in the ifnet structure.
153 */
154struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host)
155{
156 in_addr_t addr;
157
158 if (net < 128)
159 addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
160 else if (net < 65536)
161 addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
162 else if (net < 16777216UL)
163 addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
164 else
165 addr = net | host;
166 addr = htonl(addr);
167 return *(struct in_addr *)&addr;
168}
169libc_hidden_def(inet_makeaddr)
170#endif
171
172#ifdef L_inet_lnaof
173/*
174 * Return the local network address portion of an
175 * internet address; handles class a/b/c network
176 * number formats.
177 */
178in_addr_t inet_lnaof(struct in_addr in)
179{
180 in_addr_t i = ntohl(in.s_addr);
181
182 if (IN_CLASSA(i))
183 return (i & IN_CLASSA_HOST);
184 else if (IN_CLASSB(i))
185 return (i & IN_CLASSB_HOST);
186 else
187 return (i & IN_CLASSC_HOST);
188}
189#endif
190
191#ifdef L_inet_netof
192
193/*
194 * Return the network number from an internet
195 * address; handles class a/b/c network #'s.
196 */
197in_addr_t
198inet_netof(struct in_addr in)
199{
200 in_addr_t i = ntohl(in.s_addr);
201
202 if (IN_CLASSA(i))
203 return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
204 else if (IN_CLASSB(i))
205 return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
206 else
207 return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
208}
209libc_hidden_def(inet_netof)
210#endif