1 #include <errno.h> 2 #include <sys/types.h> 3 #include <netinet/in.h> 4 5 #include "utils.h" 6 7 static __inline__ u_int16_t dn_ntohs(u_int16_t addr) 8 { 9 union { 10 u_int8_t byte[2]; 11 u_int16_t word; 12 } u; 13 14 u.word = addr; 15 return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8); 16 } 17 18 static __inline__ int do_digit(char *str, u_int16_t *addr, u_int16_t scale, size_t *pos, size_t len, int *started) 19 { 20 u_int16_t tmp = *addr / scale; 21 22 if (*pos == len) 23 return 1; 24 25 if (((tmp) > 0) || *started || (scale == 1)) { 26 *str = tmp + '0'; 27 *started = 1; 28 (*pos)++; 29 *addr -= (tmp * scale); 30 } 31 32 return 0; 33 } 34 35 36 static const char *dnet_ntop1(const struct dn_naddr *dna, char *str, size_t len) 37 { 38 u_int16_t addr = dn_ntohs(*(u_int16_t *)dna->a_addr); 39 u_int16_t area = addr >> 10; 40 size_t pos = 0; 41 int started = 0; 42 43 if (dna->a_len != 2) 44 return NULL; 45 46 addr &= 0x03ff; 47 48 if (len == 0) 49 return str; 50 51 if (do_digit(str + pos, &area, 10, &pos, len, &started)) 52 return str; 53 54 if (do_digit(str + pos, &area, 1, &pos, len, &started)) 55 return str; 56 57 if (pos == len) 58 return str; 59 60 *(str + pos) = '.'; 61 pos++; 62 started = 0; 63 64 if (do_digit(str + pos, &addr, 1000, &pos, len, &started)) 65 return str; 66 67 if (do_digit(str + pos, &addr, 100, &pos, len, &started)) 68 return str; 69 70 if (do_digit(str + pos, &addr, 10, &pos, len, &started)) 71 return str; 72 73 if (do_digit(str + pos, &addr, 1, &pos, len, &started)) 74 return str; 75 76 if (pos == len) 77 return str; 78 79 *(str + pos) = 0; 80 81 return str; 82 } 83 84 85 const char *dnet_ntop(int af, const void *addr, char *str, size_t len) 86 { 87 switch(af) { 88 case AF_DECnet: 89 errno = 0; 90 return dnet_ntop1((struct dn_naddr *)addr, str, len); 91 default: 92 errno = EAFNOSUPPORT; 93 } 94 95 return NULL; 96 } 97 98 99