]>
Commit | Line | Data |
---|---|---|
0a0a289a MT |
1 | /* |
2 | libloc - A library to determine the location of someone on the Internet | |
3 | ||
4 | Copyright (C) 2022 IPFire Development Team <info@ipfire.org> | |
5 | ||
6 | This library is free software; you can redistribute it and/or | |
7 | modify it under the terms of the GNU Lesser General Public | |
8 | License as published by the Free Software Foundation; either | |
9 | version 2.1 of the License, or (at your option) any later version. | |
10 | ||
11 | This library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | Lesser General Public License for more details. | |
15 | */ | |
16 | ||
17 | #include <arpa/inet.h> | |
18 | #include <netinet/in.h> | |
19 | #include <stddef.h> | |
20 | ||
21 | #include <libloc/address.h> | |
22 | ||
23 | #define LOC_ADDRESS_BUFFERS 6 | |
24 | #define LOC_ADDRESS_BUFFER_LENGTH INET6_ADDRSTRLEN | |
25 | ||
b0f572df | 26 | static char __loc_address_buffers[LOC_ADDRESS_BUFFERS][LOC_ADDRESS_BUFFER_LENGTH + 1]; |
0a0a289a MT |
27 | static int __loc_address_buffer_idx = 0; |
28 | ||
29 | static const char* __loc_address6_str(const struct in6_addr* address, char* buffer, size_t length) { | |
30 | return inet_ntop(AF_INET6, address, buffer, length); | |
31 | } | |
32 | ||
33 | static const char* __loc_address4_str(const struct in6_addr* address, char* buffer, size_t length) { | |
34 | struct in_addr address4 = { | |
35 | .s_addr = address->s6_addr32[3], | |
36 | }; | |
37 | ||
38 | return inet_ntop(AF_INET, &address4, buffer, length); | |
39 | } | |
40 | ||
41 | const char* loc_address_str(const struct in6_addr* address) { | |
42 | if (!address) | |
43 | return NULL; | |
44 | ||
45 | // Select buffer | |
46 | char* buffer = __loc_address_buffers[__loc_address_buffer_idx++]; | |
47 | ||
48 | // Prevent index from overflow | |
49 | __loc_address_buffer_idx %= LOC_ADDRESS_BUFFERS; | |
50 | ||
51 | if (IN6_IS_ADDR_V4MAPPED(address)) | |
52 | return __loc_address4_str(address, buffer, LOC_ADDRESS_BUFFER_LENGTH); | |
53 | else | |
54 | return __loc_address6_str(address, buffer, LOC_ADDRESS_BUFFER_LENGTH); | |
55 | } |