]>
git.proxmox.com Git - mirror_frr.git/blob - lib/ntop.c
2 * optimized ntop, about 10x faster than libc versions [as of 2019]
4 * Copyright (c) 2019 David Lamparter, for NetDEF, Inc.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
35 static inline void putbyte(uint8_t bytex
, char **posx
)
36 __attribute__((always_inline
)) OPTIMIZE
;
38 static inline void putbyte(uint8_t bytex
, char **posx
)
41 int byte
= bytex
, tmp
, a
, b
;
43 if ((tmp
= byte
- 200) >= 0) {
47 } else if ((tmp
= byte
- 100) >= 0) {
53 /* make sure the compiler knows the value range of "byte" */
54 assume(byte
< 100 && byte
>= 0);
65 static inline void puthex(uint16_t word
, char **posx
)
66 __attribute__((always_inline
)) OPTIMIZE
;
68 static inline void puthex(uint16_t word
, char **posx
)
70 const char *digits
= "0123456789abcdef";
72 *pos
++ = digits
[(word
>> 12) & 0xf];
74 *pos
++ = digits
[(word
>> 8) & 0xf];
76 *pos
++ = digits
[(word
>> 4) & 0xf];
77 *pos
++ = digits
[word
& 0xf];
82 const char *frr_inet_ntop(int af
, const void * restrict src
,
83 char * restrict dst
, socklen_t size
)
84 __attribute__((flatten
)) OPTIMIZE
;
86 const char *frr_inet_ntop(int af
, const void * restrict src
,
87 char * restrict dst
, socklen_t size
)
89 const uint8_t *b
= src
;
90 /* 8 * "abcd:" for IPv6
91 * note: the IPv4-embedded IPv6 syntax is only used for ::A.B.C.D,
92 * which isn't longer than 40 chars either. even with ::ffff:A.B.C.D
95 char buf
[8 * 5], *o
= buf
;
96 size_t best
= 0, bestlen
= 0, curlen
= 0, i
;
111 for (i
= 0; i
< 8; i
++) {
112 if (b
[i
* 2] || b
[i
* 2 + 1]) {
113 if (curlen
&& curlen
> bestlen
) {
122 if (curlen
&& curlen
> bestlen
) {
126 /* do we want ::ffff:A.B.C.D? */
127 if (best
== 0 && bestlen
== 6) {
136 for (i
= 0; i
< 8; i
++) {
137 if (bestlen
&& i
== best
) {
143 if (i
> best
&& i
< best
+ bestlen
) {
146 puthex((b
[i
* 2] << 8) | b
[i
* 2 + 1], &o
);
160 /* compiler might inline memcpy if it knows the length is short,
161 * although neither gcc nor clang actually do this currently [2019]
168 #if !defined(INET_NTOP_NO_OVERRIDE) && !defined(__APPLE__)
169 /* we want to override libc inet_ntop, but make sure it shows up in backtraces
170 * as frr_inet_ntop (to avoid confusion while debugging)
172 const char *inet_ntop(int af
, const void *src
, char *dst
, socklen_t size
)
173 __attribute__((alias ("frr_inet_ntop")));