]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - lib/dnet_ntop.c
(Logical change 1.3)
[mirror_iproute2.git] / lib / dnet_ntop.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..9500df86d691302b1e18aa0d4d134a6d005a2584 100644 (file)
@@ -0,0 +1,98 @@
+#include <errno.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+
+#include "utils.h"
+
+static __inline__ u_int16_t dn_ntohs(u_int16_t addr)
+{
+       union {
+               u_int8_t byte[2];
+               u_int16_t word;
+       } u;
+
+       u.word = addr;
+       return ((u_int16_t)u.byte[0]) | (((u_int16_t)u.byte[1]) << 8);
+}
+
+static __inline__ int do_digit(char *str, u_int16_t *addr, u_int16_t scale, size_t *pos, size_t len, int *started)
+{
+       u_int16_t tmp = *addr / scale;
+
+       if (*pos == len)
+               return 1;
+
+       if (((tmp) > 0) || *started || (scale == 1)) {
+               *str = tmp + '0';
+               *started = 1;
+               (*pos)++;
+               *addr -= (tmp * scale);
+       }
+
+       return 0;
+}
+
+
+static const char *dnet_ntop1(const struct dn_naddr *dna, char *str, size_t len)
+{
+       u_int16_t addr = dn_ntohs(*(u_int16_t *)dna->a_addr);
+       u_int16_t area = addr >> 10;
+       size_t pos = 0;
+       int started = 0;
+
+       if (dna->a_len != 2)
+               return NULL;
+
+       addr &= 0x03ff;
+
+       if (len == 0)
+               return str;
+
+       if (do_digit(str + pos, &area, 10, &pos, len, &started))
+               return str;
+
+       if (do_digit(str + pos, &area, 1, &pos, len, &started))
+               return str;
+
+       if (pos == len)
+               return str;
+
+       *(str + pos) = '.';
+       pos++;
+       started = 0;
+
+       if (do_digit(str + pos, &addr, 1000, &pos, len, &started))
+               return str;
+
+       if (do_digit(str + pos, &addr, 100, &pos, len, &started))
+               return str;
+
+       if (do_digit(str + pos, &addr, 10, &pos, len, &started))
+               return str;
+
+       if (do_digit(str + pos, &addr, 1, &pos, len, &started))
+               return str;
+
+       if (pos == len)
+               return str;
+
+       *(str + pos) = 0;
+
+       return str;
+}
+
+
+const char *dnet_ntop(int af, const void *addr, char *str, size_t len)
+{
+       switch(af) {
+               case AF_DECnet:
+                       errno = 0;
+                       return dnet_ntop1((struct dn_naddr *)addr, str, len);
+               default:
+                       errno = EAFNOSUPPORT;
+       }
+
+       return NULL;
+}
+
+