Skip to content

Commit bf10abf

Browse files
committed
adopt libnx net util functions for lower footprint inet_pton
1 parent c5c371e commit bf10abf

File tree

3 files changed

+212
-27
lines changed

3 files changed

+212
-27
lines changed

libogc/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ add_library(ogc STATIC
88
lwpcompat/lwpc_mq.c
99

1010
ogc_sockets/soc_init.c
11-
ogc_sockets/soc_inet_pton.c
11+
ogc_sockets/soc_util.c
1212
ogc_sockets/soc_common.c
1313
ogc_sockets/soc_socket.c
14+
ogc_sockets/soc_select.c
1415
ogc_sockets/soc_bind.c
1516
ogc_sockets/soc_listen.c
1617
ogc_sockets/soc_send.c

libogc/ogc_sockets/soc_inet_pton.c

Lines changed: 0 additions & 26 deletions
This file was deleted.

libogc/ogc_sockets/soc_util.c

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
#include <stdint.h>
2+
#include <string.h>
3+
#include <errno.h>
4+
#include <ctype.h>
5+
6+
#include <arpa/inet.h>
7+
#include <sys/socket.h>
8+
9+
// Adapted from libctru
10+
static int _inetAtonDetail(int inBase, size_t *outNumBytes, const char *cp, struct in_addr *inp)
11+
{
12+
int base;
13+
uint32_t val;
14+
int c;
15+
char bytes[4];
16+
size_t num_bytes = 0;
17+
18+
c = *cp;
19+
for (;;)
20+
{
21+
if (!isdigit(c))
22+
return 0;
23+
24+
val = 0;
25+
base = inBase;
26+
if (!base)
27+
{
28+
base = 10;
29+
if (c == '0')
30+
{
31+
c = *++cp;
32+
if (c == 'x' || c == 'X')
33+
{
34+
base = 16;
35+
c = *++cp;
36+
} else
37+
base = 8;
38+
}
39+
}
40+
41+
for (;;)
42+
{
43+
if (isdigit(c))
44+
{
45+
if (base == 8 && c >= '8')
46+
return 0;
47+
val *= base;
48+
val += c - '0';
49+
c = *++cp;
50+
} else if (base == 16 && isxdigit(c))
51+
{
52+
val *= base;
53+
val += c + 10 - (islower(c) ? 'a' : 'A');
54+
c = *++cp;
55+
} else
56+
break;
57+
}
58+
59+
if (c == '.')
60+
{
61+
if (num_bytes > 3)
62+
return 0;
63+
if (val > 0xFF)
64+
return 0;
65+
bytes[num_bytes++] = val;
66+
c = *++cp;
67+
} else
68+
break;
69+
}
70+
71+
if (c != 0)
72+
{
73+
*outNumBytes = num_bytes;
74+
return 0;
75+
}
76+
77+
switch (num_bytes)
78+
{
79+
case 0:
80+
break;
81+
82+
case 1:
83+
if (val > 0xFFFFFF)
84+
return 0;
85+
val |= bytes[0] << 24;
86+
break;
87+
88+
case 2:
89+
if (val > 0xFFFF)
90+
return 0;
91+
val |= bytes[0] << 24;
92+
val |= bytes[1] << 16;
93+
break;
94+
95+
case 3:
96+
if (val > 0xFF)
97+
return 0;
98+
val |= bytes[0] << 24;
99+
val |= bytes[1] << 16;
100+
val |= bytes[2] << 8;
101+
break;
102+
}
103+
104+
if (inp)
105+
inp->s_addr = htonl(val);
106+
107+
*outNumBytes = num_bytes;
108+
109+
return 1;
110+
}
111+
112+
// Adapted from libctru
113+
static const char *inet_ntop4(const void *src, char *dst, socklen_t size)
114+
{
115+
const uint8_t *ip = src;
116+
117+
char *p;
118+
size_t i;
119+
unsigned int n;
120+
121+
if (size < INET_ADDRSTRLEN)
122+
{
123+
errno = ENOSPC;
124+
return NULL;
125+
}
126+
127+
for (p = dst, i = 0; i < 4; ++i)
128+
{
129+
if (i > 0)
130+
*p++ = '.';
131+
132+
n = ip[i];
133+
if (n >= 100)
134+
{
135+
*p++ = n / 100 + '0';
136+
n %= 100;
137+
}
138+
if (n >= 10 || ip[i] >= 100)
139+
{
140+
*p++ = n / 10 + '0';
141+
n %= 10;
142+
}
143+
*p++ = n + '0';
144+
}
145+
*p = 0;
146+
147+
return dst;
148+
}
149+
150+
static int inet_pton4(const char *src, void *dst)
151+
{
152+
size_t numBytes;
153+
154+
int ret = _inetAtonDetail(10, &numBytes, src, (struct in_addr *)dst);
155+
return (ret == 1 && numBytes == 3) ? 1 : 0;
156+
}
157+
158+
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
159+
{
160+
switch (af)
161+
{
162+
case AF_INET:
163+
return inet_ntop4(src, dst, size);
164+
default:
165+
errno = EAFNOSUPPORT;
166+
return NULL;
167+
}
168+
}
169+
170+
int inet_pton(int af, const char *src, void *dst)
171+
{
172+
switch (af)
173+
{
174+
case AF_INET:
175+
return inet_pton4(src, dst);
176+
default:
177+
errno = EAFNOSUPPORT;
178+
return -1;
179+
}
180+
}
181+
182+
char *inet_ntoa(struct in_addr in)
183+
{
184+
static char buffer[INET_ADDRSTRLEN];
185+
inet_ntop(AF_INET, &in.s_addr, buffer, INET_ADDRSTRLEN);
186+
return buffer;
187+
}
188+
189+
int inet_aton(const char *cp, struct in_addr *inp)
190+
{
191+
size_t numBytes;
192+
return _inetAtonDetail(0, &numBytes, cp, inp);
193+
}
194+
195+
/*
196+
* Ascii internet address interpretation routine.
197+
* The value returned is in network order.
198+
*/
199+
200+
/* inet_addr */
201+
in_addr_t inet_addr(const char *cp)
202+
{
203+
struct in_addr val;
204+
205+
if (inet_aton(cp, &val))
206+
{
207+
return (val.s_addr);
208+
}
209+
return (INADDR_NONE);
210+
}

0 commit comments

Comments
 (0)