]>
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
;
57 /* make sure the compiler knows the value range of "byte" */
58 assume(byte
< 100 && byte
>= 0);
69 static inline void puthex(uint16_t word
, char **posx
)
70 __attribute__((always_inline
)) OPTIMIZE
;
72 static inline void puthex(uint16_t word
, char **posx
)
74 const char *digits
= "0123456789abcdef";
76 *pos
++ = digits
[(word
>> 12) & 0xf];
78 *pos
++ = digits
[(word
>> 8) & 0xf];
80 *pos
++ = digits
[(word
>> 4) & 0xf];
81 *pos
++ = digits
[word
& 0xf];
86 const char *frr_inet_ntop(int af
, const void * restrict src
,
87 char * restrict dst
, socklen_t size
)
88 __attribute__((flatten
)) OPTIMIZE
;
90 const char *frr_inet_ntop(int af
, const void * restrict src
,
91 char * restrict dst
, socklen_t size
)
93 const uint8_t *b
= src
;
94 /* 8 * "abcd:" for IPv6
95 * note: the IPv4-embedded IPv6 syntax is only used for ::A.B.C.D,
96 * which isn't longer than 40 chars either. even with ::ffff:A.B.C.D
99 char buf
[8 * 5], *o
= buf
;
100 size_t best
= 0, bestlen
= 0, curlen
= 0, i
;
115 for (i
= 0; i
< 8; i
++) {
116 if (b
[i
* 2] || b
[i
* 2 + 1]) {
117 if (curlen
&& curlen
> bestlen
) {
126 if (curlen
&& curlen
> bestlen
) {
130 /* do we want ::ffff:A.B.C.D? */
131 if (best
== 0 && bestlen
== 6) {
140 for (i
= 0; i
< 8; i
++) {
141 if (bestlen
&& i
== best
) {
147 if (i
> best
&& i
< best
+ bestlen
) {
150 puthex((b
[i
* 2] << 8) | b
[i
* 2 + 1], &o
);
164 /* compiler might inline memcpy if it knows the length is short,
165 * although neither gcc nor clang actually do this currently [2019]
172 #if !defined(INET_NTOP_NO_OVERRIDE) && !defined(__APPLE__)
173 /* we want to override libc inet_ntop, but make sure it shows up in backtraces
174 * as frr_inet_ntop (to avoid confusion while debugging)
176 const char *inet_ntop(int af
, const void *src
, char *dst
, socklen_t size
)
177 __attribute__((alias ("frr_inet_ntop")));