1 #include "first.h" 2 3 #include "sock_addr_cache.h" 4 5 #include "sys-socket.h" 6 #include <string.h> 7 8 #include "buffer.h" 9 #include "sock_addr.h" 10 11 12 int sock_addr_cache_inet_ntop_copy_buffer(buffer * const restrict b, const sock_addr * const restrict saddr) 13 { 14 #define NTOP_CACHE_MAX 4 15 static int ndx4; 16 static struct { struct in_addr ipv4; } ntop4_cache[NTOP_CACHE_MAX]; 17 static struct { char s[INET_ADDRSTRLEN+1]; } ntop4_strs[NTOP_CACHE_MAX]; 18 #ifdef HAVE_IPV6 19 static int ndx6; 20 static struct { struct in6_addr ipv6; } ntop6_cache[NTOP_CACHE_MAX]; 21 static struct { char s[INET6_ADDRSTRLEN+1]; } ntop6_strs[NTOP_CACHE_MAX]; 22 #endif 23 switch (saddr->plain.sa_family) { 24 case AF_INET: 25 for (int i = 0; i < NTOP_CACHE_MAX; ++i) { 26 if (ntop4_cache[i].ipv4.s_addr == saddr->ipv4.sin_addr.s_addr) { 27 buffer_copy_string(b, ntop4_strs[i].s); 28 return 0; 29 } 30 } 31 break; 32 #ifdef HAVE_IPV6 33 case AF_INET6: 34 for (int i = 0; i < NTOP_CACHE_MAX; ++i) { 35 if (0 == memcmp(ntop6_cache[i].ipv6.s6_addr, 36 saddr->ipv6.sin6_addr.s6_addr, 16)) { 37 buffer_copy_string(b, ntop6_strs[i].s); 38 return 0; 39 } 40 } 41 break; 42 #endif 43 default: 44 break; 45 } 46 47 if (0 != sock_addr_inet_ntop_copy_buffer(b, saddr)) { 48 buffer_string_set_length(b, 0); 49 return -1; 50 } 51 52 switch (saddr->plain.sa_family) { 53 case AF_INET: 54 ntop4_cache[ndx4].ipv4.s_addr = saddr->ipv4.sin_addr.s_addr; 55 memcpy(ntop4_strs+ndx4, b->ptr, buffer_string_length(b)+1); 56 if (++ndx4 == NTOP_CACHE_MAX) ndx4 = 0; 57 break; 58 #ifdef HAVE_IPV6 59 case AF_INET6: 60 memcpy(ntop6_cache[ndx6].ipv6.s6_addr,saddr->ipv6.sin6_addr.s6_addr,16); 61 memcpy(ntop6_strs+ndx6, b->ptr, buffer_string_length(b)+1); 62 if (++ndx6 == NTOP_CACHE_MAX) ndx6 = 0; 63 break; 64 #endif 65 default: 66 break; 67 } 68 return 0; 69 } 70