xref: /aosp_15_r20/external/iproute2/lib/mpls_pton.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 #include <linux/mpls.h>
6*de1e4e89SAndroid Build Coastguard Worker 
7*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
8*de1e4e89SAndroid Build Coastguard Worker 
9*de1e4e89SAndroid Build Coastguard Worker 
mpls_pton1(const char * name,struct mpls_label * addr,unsigned int maxlabels)10*de1e4e89SAndroid Build Coastguard Worker static int mpls_pton1(const char *name, struct mpls_label *addr,
11*de1e4e89SAndroid Build Coastguard Worker 		      unsigned int maxlabels)
12*de1e4e89SAndroid Build Coastguard Worker {
13*de1e4e89SAndroid Build Coastguard Worker 	char *endp;
14*de1e4e89SAndroid Build Coastguard Worker 	unsigned count;
15*de1e4e89SAndroid Build Coastguard Worker 
16*de1e4e89SAndroid Build Coastguard Worker 	for (count = 0; count < maxlabels; count++) {
17*de1e4e89SAndroid Build Coastguard Worker 		unsigned long label;
18*de1e4e89SAndroid Build Coastguard Worker 
19*de1e4e89SAndroid Build Coastguard Worker 		label = strtoul(name, &endp, 0);
20*de1e4e89SAndroid Build Coastguard Worker 		/* Fail when the label value is out or range */
21*de1e4e89SAndroid Build Coastguard Worker 		if (label >= (1 << 20))
22*de1e4e89SAndroid Build Coastguard Worker 			return 0;
23*de1e4e89SAndroid Build Coastguard Worker 
24*de1e4e89SAndroid Build Coastguard Worker 		if (endp == name) /* no digits */
25*de1e4e89SAndroid Build Coastguard Worker 			return 0;
26*de1e4e89SAndroid Build Coastguard Worker 
27*de1e4e89SAndroid Build Coastguard Worker 		addr->entry = htonl(label << MPLS_LS_LABEL_SHIFT);
28*de1e4e89SAndroid Build Coastguard Worker 		if (*endp == '\0') {
29*de1e4e89SAndroid Build Coastguard Worker 			addr->entry |= htonl(1 << MPLS_LS_S_SHIFT);
30*de1e4e89SAndroid Build Coastguard Worker 			return 1;
31*de1e4e89SAndroid Build Coastguard Worker 		}
32*de1e4e89SAndroid Build Coastguard Worker 
33*de1e4e89SAndroid Build Coastguard Worker 		/* Bad character in the address */
34*de1e4e89SAndroid Build Coastguard Worker 		if (*endp != '/')
35*de1e4e89SAndroid Build Coastguard Worker 			return 0;
36*de1e4e89SAndroid Build Coastguard Worker 
37*de1e4e89SAndroid Build Coastguard Worker 		name = endp + 1;
38*de1e4e89SAndroid Build Coastguard Worker 		addr += 1;
39*de1e4e89SAndroid Build Coastguard Worker 	}
40*de1e4e89SAndroid Build Coastguard Worker 	/* The address was too long */
41*de1e4e89SAndroid Build Coastguard Worker 	fprintf(stderr, "Error: too many labels.\n");
42*de1e4e89SAndroid Build Coastguard Worker 	return 0;
43*de1e4e89SAndroid Build Coastguard Worker }
44*de1e4e89SAndroid Build Coastguard Worker 
mpls_pton(int af,const char * src,void * addr,size_t alen)45*de1e4e89SAndroid Build Coastguard Worker int mpls_pton(int af, const char *src, void *addr, size_t alen)
46*de1e4e89SAndroid Build Coastguard Worker {
47*de1e4e89SAndroid Build Coastguard Worker 	unsigned int maxlabels = alen / sizeof(struct mpls_label);
48*de1e4e89SAndroid Build Coastguard Worker 	int err;
49*de1e4e89SAndroid Build Coastguard Worker 
50*de1e4e89SAndroid Build Coastguard Worker 	switch(af) {
51*de1e4e89SAndroid Build Coastguard Worker 	case AF_MPLS:
52*de1e4e89SAndroid Build Coastguard Worker 		errno = 0;
53*de1e4e89SAndroid Build Coastguard Worker 		err = mpls_pton1(src, (struct mpls_label *)addr, maxlabels);
54*de1e4e89SAndroid Build Coastguard Worker 		break;
55*de1e4e89SAndroid Build Coastguard Worker 	default:
56*de1e4e89SAndroid Build Coastguard Worker 		errno = EAFNOSUPPORT;
57*de1e4e89SAndroid Build Coastguard Worker 		err = -1;
58*de1e4e89SAndroid Build Coastguard Worker 	}
59*de1e4e89SAndroid Build Coastguard Worker 
60*de1e4e89SAndroid Build Coastguard Worker 	return err;
61*de1e4e89SAndroid Build Coastguard Worker }
62