]>
Commit | Line | Data |
---|---|---|
aba5acdf SH |
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 |