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