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