]>
git.proxmox.com Git - mirror_frr.git/blob - lib/ntop.c
1 // SPDX-License-Identifier: ISC
3 * optimized ntop, about 10x faster than libc versions [as of 2019]
5 * Copyright (c) 2019 David Lamparter, for NetDEF, Inc.
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
24 static inline void putbyte(uint8_t bytex
, char **posx
)
25 __attribute__((always_inline
)) OPTIMIZE
;
27 static inline void putbyte(uint8_t bytex
, char **posx
)
30 int byte
= bytex
, tmp
, a
, b
;
46 /* make sure the compiler knows the value range of "byte" */
47 assume(byte
< 100 && byte
>= 0);
58 static inline void puthex(uint16_t word
, char **posx
)
59 __attribute__((always_inline
)) OPTIMIZE
;
61 static inline void puthex(uint16_t word
, char **posx
)
63 const char *digits
= "0123456789abcdef";
65 *pos
++ = digits
[(word
>> 12) & 0xf];
67 *pos
++ = digits
[(word
>> 8) & 0xf];
69 *pos
++ = digits
[(word
>> 4) & 0xf];
70 *pos
++ = digits
[word
& 0xf];
75 const char *frr_inet_ntop(int af
, const void * restrict src
,
76 char * restrict dst
, socklen_t size
)
77 __attribute__((flatten
)) OPTIMIZE
;
79 const char *frr_inet_ntop(int af
, const void * restrict src
,
80 char * restrict dst
, socklen_t size
)
82 const uint8_t *b
= src
;
83 /* 8 * "abcd:" for IPv6
84 * note: the IPv4-embedded IPv6 syntax is only used for ::A.B.C.D,
85 * which isn't longer than 40 chars either. even with ::ffff:A.B.C.D
88 char buf
[8 * 5], *o
= buf
;
89 size_t best
= 0, bestlen
= 0, curlen
= 0, i
;
104 for (i
= 0; i
< 8; i
++) {
105 if (b
[i
* 2] || b
[i
* 2 + 1]) {
106 if (curlen
&& curlen
> bestlen
) {
115 if (curlen
&& curlen
> bestlen
) {
119 /* do we want ::ffff:A.B.C.D? */
120 if (best
== 0 && bestlen
== 6) {
129 for (i
= 0; i
< 8; i
++) {
130 if (bestlen
&& i
== best
) {
136 if (i
> best
&& i
< best
+ bestlen
) {
139 puthex((b
[i
* 2] << 8) | b
[i
* 2 + 1], &o
);
153 /* compiler might inline memcpy if it knows the length is short,
154 * although neither gcc nor clang actually do this currently [2019]
161 #if !defined(INET_NTOP_NO_OVERRIDE) && !defined(__APPLE__)
162 /* we want to override libc inet_ntop, but make sure it shows up in backtraces
163 * as frr_inet_ntop (to avoid confusion while debugging)
165 const char *inet_ntop(int af
, const void *src
, char *dst
, socklen_t size
)
166 __attribute__((alias ("frr_inet_ntop")));