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