1
2
3#include <errno.h>
4#include <string.h>
5#include <sys/types.h>
6#include <netinet/in.h>
7#include <linux/mpls.h>
8
9#include "utils.h"
10
11
12static int mpls_pton1(const char *name, struct mpls_label *addr,
13 unsigned int maxlabels)
14{
15 char *endp;
16 unsigned count;
17
18 for (count = 0; count < maxlabels; count++) {
19 unsigned long label;
20
21 label = strtoul(name, &endp, 0);
22
23 if (label >= (1 << 20))
24 return 0;
25
26 if (endp == name)
27 return 0;
28
29 addr->entry = htonl(label << MPLS_LS_LABEL_SHIFT);
30 if (*endp == '\0') {
31 addr->entry |= htonl(1 << MPLS_LS_S_SHIFT);
32 return 1;
33 }
34
35
36 if (*endp != '/')
37 return 0;
38
39 name = endp + 1;
40 addr += 1;
41 }
42
43 fprintf(stderr, "Error: too many labels.\n");
44 return 0;
45}
46
47int mpls_pton(int af, const char *src, void *addr, size_t alen)
48{
49 unsigned int maxlabels = alen / sizeof(struct mpls_label);
50 int err;
51
52 switch(af) {
53 case AF_MPLS:
54 errno = 0;
55 err = mpls_pton1(src, (struct mpls_label *)addr, maxlabels);
56 break;
57 default:
58 errno = EAFNOSUPPORT;
59 err = -1;
60 }
61
62 return err;
63}
64