1dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman#include <errno.h>
2dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman#include <string.h>
3dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman#include <sys/types.h>
4dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman#include <netinet/in.h>
5dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman#include <linux/mpls.h>
6dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
7dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman#include "utils.h"
8dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
9dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biedermanstatic const char *mpls_ntop1(const struct mpls_label *addr, char *buf, size_t buflen)
10dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman{
11dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	size_t destlen = buflen;
12dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	char *dest = buf;
13dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	int count;
14dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
15dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	for (count = 0; count < MPLS_MAX_LABELS; count++) {
16dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		uint32_t entry = ntohl(addr[count].entry);
17dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		uint32_t label = (entry & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT;
18dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		int len = snprintf(dest, destlen, "%u", label);
19dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
20dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		/* Is this the end? */
21dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		if (entry & MPLS_LS_S_MASK)
22dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			return buf;
23dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
24dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
25dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		dest += len;
26dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		destlen -= len;
27dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		if (destlen) {
28dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			*dest = '/';
29dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			dest++;
30dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman			destlen--;
31dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		}
32dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	}
33dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	errno = -E2BIG;
34dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	return NULL;
35dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman}
36dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
37dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biedermanconst char *mpls_ntop(int af, const void *addr, char *buf, size_t buflen)
38dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman{
39dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	switch(af) {
40dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	case AF_MPLS:
41dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		errno = 0;
42dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		return mpls_ntop1((struct mpls_label *)addr, buf, buflen);
43dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	default:
44dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman		errno = EAFNOSUPPORT;
45dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	}
46dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman
47dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman	return NULL;
48dacc5d4197c1f8ac12938a594f7e4131cb937cb2Eric W. Biederman}
49