Home | History | Annotate | Download | only in lib
      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