Home | History | Annotate | Download | only in lib
      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