Module Name:    src
Committed By:   kefren
Date:           Tue Jul 16 02:54:33 UTC 2013

Modified Files:
        src/usr.sbin/ldpd: label.c ldp_command.c ldp_errors.c mpls_routes.c
            mpls_routes.h

Log Message:
retire union_ntoa, replace it with satos
check for valid sizes on PF_ROUTE socket
minor comment update


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/ldpd/label.c
cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/ldpd/ldp_command.c
cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/ldpd/ldp_errors.c
cvs rdiff -u -r1.14 -r1.15 src/usr.sbin/ldpd/mpls_routes.c
cvs rdiff -u -r1.4 -r1.5 src/usr.sbin/ldpd/mpls_routes.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/ldpd/label.c
diff -u src/usr.sbin/ldpd/label.c:1.6 src/usr.sbin/ldpd/label.c:1.7
--- src/usr.sbin/ldpd/label.c:1.6	Thu Jul 11 10:46:19 2013
+++ src/usr.sbin/ldpd/label.c	Tue Jul 16 02:54:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: label.c,v 1.6 2013/07/11 10:46:19 kefren Exp $ */
+/* $NetBSD: label.c,v 1.7 2013/07/16 02:54:32 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -85,9 +85,9 @@ label_add(const union sockunion * so_des
 
 	SLIST_INSERT_HEAD(&label_head, l, labels);
 
-	strlcpy(spreftmp, union_ntoa(so_pref), INET_ADDRSTRLEN);
+	strlcpy(spreftmp, satos(&so_pref->sa), INET_ADDRSTRLEN);
 	warnp("[label_add] added binding %d for %s/%s\n", l->binding,
-	    union_ntoa(so_dest), spreftmp);
+	    satos(&so_dest->sa), spreftmp);
 
 	send_label_tlv_to_all(&(so_dest->sa),
 	    from_union_to_cidr(so_pref), l->binding);
@@ -99,7 +99,7 @@ void 
 label_del(struct label * l)
 {
 	warnp("[label_del] deleted binding %d for %s\n", l->binding,
-	   union_ntoa(&l->so_dest));
+	   satos(&l->so_dest.sa));
 	SLIST_REMOVE(&label_head, l, label, labels);
 	free(l);
 }

Index: src/usr.sbin/ldpd/ldp_command.c
diff -u src/usr.sbin/ldpd/ldp_command.c:1.10 src/usr.sbin/ldpd/ldp_command.c:1.11
--- src/usr.sbin/ldpd/ldp_command.c:1.10	Mon Jan 28 21:08:14 2013
+++ src/usr.sbin/ldpd/ldp_command.c	Tue Jul 16 02:54:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_command.c,v 1.10 2013/01/28 21:08:14 kefren Exp $ */
+/* $NetBSD: ldp_command.c,v 1.11 2013/07/16 02:54:32 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -513,9 +513,9 @@ show_bindings(int s, char *recvspace)
 	writestr(s, sendspace);
 	SLIST_FOREACH (l, &label_head, labels) {
 		snprintf(sendspace, MAXSEND, "%d\t\t%s/", l->binding,
-		    union_ntoa(&l->so_dest));
+		    satos(&l->so_dest.sa));
 		writestr(s, sendspace);
-		snprintf(sendspace, MAXSEND, "%s", union_ntoa(&l->so_pref));
+		snprintf(sendspace, MAXSEND, "%s", satos(&l->so_pref.sa));
 		writestr(s, sendspace);
 		if (l->p)
 			snprintf(sendspace, MAXSEND, "\t%s:%d\n",

Index: src/usr.sbin/ldpd/ldp_errors.c
diff -u src/usr.sbin/ldpd/ldp_errors.c:1.3 src/usr.sbin/ldpd/ldp_errors.c:1.4
--- src/usr.sbin/ldpd/ldp_errors.c:1.3	Sat Jan 26 17:29:55 2013
+++ src/usr.sbin/ldpd/ldp_errors.c	Tue Jul 16 02:54:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_errors.c,v 1.3 2013/01/26 17:29:55 kefren Exp $ */
+/* $NetBSD: ldp_errors.c,v 1.4 2013/07/16 02:54:32 kefren Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,10 +30,12 @@
  */
 
 #include <arpa/inet.h>
+#include <netmpls/mpls.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 #include <syslog.h>
 #include <unistd.h>
 
@@ -45,6 +47,7 @@ int	debug_f = 0, warn_f = 0, syslog_f = 
 static void do_syslog(int, const char*, va_list) __printflike(2, 0);
 static char satos_str[INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN :
 		INET_ADDRSTRLEN];
+static char *mpls_ntoa(const struct sockaddr_mpls *smpls);
 
 void 
 debugp(const char *fmt, ...)
@@ -134,8 +137,33 @@ satos(const struct sockaddr *sa)
 				return "INET6 ERROR";
 			break;
 		}
+		case AF_LINK:
+		{
+			strlcpy(satos_str,
+			    link_ntoa((const struct sockaddr_dl *)sa),
+			    sizeof(satos_str));
+			break;
+		}
+		case AF_MPLS:
+		{
+			strlcpy(satos_str,
+			    mpls_ntoa((const struct sockaddr_mpls *)sa),
+			    sizeof(satos_str));
+			break;
+		}
 		default:
 			return "UNKNOWN AF";
 	}
 	return satos_str;
 }
+
+static char *
+mpls_ntoa(const struct sockaddr_mpls *smpls)
+{
+	static char ret[10];
+	union mpls_shim ms2;
+
+	ms2.s_addr = ntohl(smpls->smpls_addr.s_addr);
+	snprintf(ret, sizeof(ret), "%d", ms2.shim.label);
+	return ret;
+}

Index: src/usr.sbin/ldpd/mpls_routes.c
diff -u src/usr.sbin/ldpd/mpls_routes.c:1.14 src/usr.sbin/ldpd/mpls_routes.c:1.15
--- src/usr.sbin/ldpd/mpls_routes.c:1.14	Fri Jul 12 08:55:52 2013
+++ src/usr.sbin/ldpd/mpls_routes.c	Tue Jul 16 02:54:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.c,v 1.14 2013/07/12 08:55:52 kefren Exp $ */
+/* $NetBSD: mpls_routes.c,v 1.15 2013/07/16 02:54:32 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -68,7 +68,6 @@ int             replay_index = 0;
 static int read_route_socket(char *, int);
 void	mask_addr(union sockunion *);
 int	compare_sockunion(const union sockunion *, const union sockunion *);
-char *	mpls_ntoa(union mpls_shim);
 static int check_if_addr_updown(struct rt_msg *, uint);
 
 extern struct sockaddr mplssockaddr;
@@ -79,9 +78,25 @@ extern struct sockaddr mplssockaddr;
 	do { l = RT_ROUNDUP(u->sa.sa_len); memcpy(cp, u, l); cp += l;} while(0);
 #define NEXTADDR2(u) \
 	do { l = RT_ROUNDUP(u.sa_len); memcpy(cp, &u, l); cp += l; } while(0);
-#define GETNEXT(sunion) \
-	(union sockunion *) ((char *) (sunion)  + \
-	RT_ROUNDUP((sunion)->sa.sa_len))
+
+#define CHECK_LEN(sunion) \
+	if (size_cp + sunion->sa.sa_len > rlen) \
+		return LDP_E_ROUTE_ERROR; \
+	else \
+		size_cp += sunion->sa.sa_len;
+
+#define CHECK_MINSA \
+	if (size_cp + sizeof(sa_family_t) + sizeof(uint8_t) > rlen) \
+		return LDP_E_ROUTE_ERROR;
+
+#define GETNEXT(dstunion, origunion) \
+	do { \
+	CHECK_MINSA \
+	dstunion = (union sockunion *) ((char *) (origunion)  + \
+	RT_ROUNDUP((origunion)->sa.sa_len)); \
+	CHECK_LEN(dstunion) \
+	} while (0);
+
 
 static int 
 read_route_socket(char *s, int max)
@@ -267,35 +282,6 @@ from_cidr_to_mask(uint8_t prefixlen, cha
 	    (a << 16) >> 24, (a << 24) >> 24);  
 }
 
-char *
-mpls_ntoa(const union mpls_shim ms)
-{
-	static char     ret[255];
-	union mpls_shim ms2;
-
-	ms2.s_addr = ntohl(ms.s_addr);
-	snprintf(ret, sizeof(ret), "%d", ms2.shim.label);
-	return ret;
-}
-
-char *
-union_ntoa(const union sockunion * so)
-{
-	static char defret[] = "Unknown family address";
-
-	switch (so->sa.sa_family) {
-	case AF_INET:
-		return inet_ntoa(so->sin.sin_addr);
-	case AF_LINK:
-		return link_ntoa(&so->sdl);
-	case AF_MPLS:
-		return mpls_ntoa(so->smpls.smpls_addr);
-	}
-	fatalp("Unknown family address in union_ntoa: %d\n",
-	       so->sa.sa_family);
-	return defret;
-}
-
 /* From src/sbin/route/route.c */
 static const char *
 route_strerror(int error)
@@ -386,11 +372,11 @@ add_route(union sockunion *so_dest, unio
 
 	if ((rlen = write(route_socket, (char *) &rm, l)) < l) {
 		warnp("Error adding a route: %s\n", route_strerror(errno));
-		warnp("Destination was: %s\n", union_ntoa(so_dest));
+		warnp("Destination was: %s\n", satos(&so_dest->sa));
 		if (so_prefix)
-			warnp("Prefix was: %s\n", union_ntoa(so_prefix));
+			warnp("Prefix was: %s\n", satos(&so_prefix->sa));
 		if (so_gate)
-			warnp("Gateway was: %s\n", union_ntoa(so_gate));
+			warnp("Gateway was: %s\n", satos(&so_gate->sa));
 		rv = LDP_E_ROUTE_ERROR;
 	}
 	if (fr == FREESO) {
@@ -461,11 +447,11 @@ delete_route(union sockunion * so_dest, 
 		strlcpy(spreftmp, inet_ntoa(so_pref->sin.sin_addr),
 		    INET_ADDRSTRLEN);
 		warnp("Error deleting route(%s): %s/%s",
-		    route_strerror(errno), union_ntoa(so_dest),
+		    route_strerror(errno), satos(&so_dest->sa),
 		    spreftmp);
 	    } else
 		warnp("Error deleting route(%s) : %s",
-		    route_strerror(errno), union_ntoa(so_dest));
+		    route_strerror(errno), satos(&so_dest->sa));
 	    return LDP_E_NO_SUCH_ROUTE;
 	}
 	return LDP_E_OK;
@@ -559,8 +545,8 @@ get_route(struct rt_msg * rg, const unio
 	if (exact_match) {
 		su = (union sockunion*)(rg->m_space);
 		if (compare_sockunion(so_dest, su)) {
-			debugp("Dest %s ", union_ntoa(so_dest));
-			debugp("not like %s\n", union_ntoa(su));
+			debugp("Dest %s ", satos(&so_dest->sa));
+			debugp("not like %s\n", satos(&su->sa));
 			return LDP_E_NO_SUCH_ROUTE;
 		}
 	}
@@ -575,6 +561,7 @@ check_route(struct rt_msg * rg, uint rle
 	union sockunion *so_dest = NULL, *so_gate = NULL, *so_pref = NULL;
 	int             so_pref_allocated = 0;
 	int             prefixlen;
+	size_t		size_cp;
 	struct peer_map *pm;
 	struct label	*lab;
 	char            dest[50], gate[50], pref[50], oper[50];
@@ -589,8 +576,8 @@ check_route(struct rt_msg * rg, uint rle
 	    rg->m_rtm.rtm_type == RTM_DELADDR)
 		return check_if_addr_updown(rg, rlen);
 
-	if (rlen < sizeof(struct rt_msghdr))
-		return LDP_E_ROUTE_ERROR;
+	size_cp = sizeof(struct rt_msghdr);
+	CHECK_MINSA;
 
 	if (rg->m_rtm.rtm_pid == getpid() ||
 	    ((rg->m_rtm.rtm_flags & RTF_DONE) == 0))
@@ -603,8 +590,10 @@ check_route(struct rt_msg * rg, uint rle
 	if (so_dest->sa.sa_family != AF_INET)
 		return LDP_E_OK;/* We don't care about non-IP changes */
 
+	CHECK_LEN(so_dest);
+
 	if (rg->m_rtm.rtm_addrs & RTA_GATEWAY) {
-		so_gate = GETNEXT(so_dest);
+		GETNEXT(so_gate, so_dest);
 		if ((so_gate->sa.sa_family != AF_INET) &&
 		    (so_gate->sa.sa_family != AF_MPLS))
 			return LDP_E_OK;
@@ -614,7 +603,7 @@ check_route(struct rt_msg * rg, uint rle
 			so_pref = so_gate;
 		else
 			so_pref = so_dest;
-		so_pref = GETNEXT(so_pref);
+		GETNEXT(so_pref, so_pref);
 	}
 	if (!(rg->m_rtm.rtm_flags & RTF_GATEWAY)) {
 		if (rg->m_rtm.rtm_addrs & RTA_GENMASK) {
@@ -673,7 +662,7 @@ check_route(struct rt_msg * rg, uint rle
 			}
 		} else	/* We already know about this prefix */
 			debugp("Binding already there for prefix %s/%d !\n",
-			      union_ntoa(so_dest), prefixlen);
+			      satos(&so_dest->sa), prefixlen);
 		break;
 	case RTM_DELETE:
 		if (!so_gate)
@@ -701,11 +690,11 @@ check_route(struct rt_msg * rg, uint rle
 	/* Rest is just for debug */
 
 	if (so_dest)
-		strlcpy(dest, union_ntoa(so_dest), 16);
+		strlcpy(dest, satos(&so_dest->sa), sizeof(dest));
 	if (so_pref)
-		snprintf(pref, 3, "%d", prefixlen);
+		snprintf(pref, sizeof(pref), "%d", prefixlen);
 	if (so_gate)
-		strlcpy(gate, union_ntoa(so_gate), 16);
+		strlcpy(gate, satos(&so_gate->sa), sizeof(gate));
 
 	switch (rg->m_rtm.rtm_type) {
 	case RTM_ADD:
@@ -755,20 +744,25 @@ check_if_addr_updown(struct rt_msg * rg,
 	struct ldp_peer *p;
 	struct address_list_tlv al_tlv;
 	struct ifa_msghdr *msghdr = (struct ifa_msghdr *)&rg->m_rtm;
+	size_t size_cp = sizeof(struct ifa_msghdr);
 
 	if (rlen < sizeof(struct ifa_msghdr) ||
 	    (msghdr->ifam_addrs & RTA_NETMASK) == 0 ||
 	    (msghdr->ifam_addrs & RTA_IFA) == 0)
 		return LDP_E_ROUTE_ERROR;
 
+	CHECK_MINSA;
+
 	/* we should have RTA_NETMASK, RTA_IFP, RTA_IFA and RTA_BRD */
 	ifa = netmask = (union sockunion *)(msghdr + 1);
 	if (netmask->sa.sa_family != AF_INET)
 		return LDP_E_OK;
+	CHECK_LEN(netmask);
 
 	if (msghdr->ifam_addrs & RTA_IFP)
-		ifa = GETNEXT(ifa);
-	ifa = GETNEXT(ifa);
+		GETNEXT(ifa, ifa);
+
+	GETNEXT(ifa, ifa);
 
 	if (ifa->sa.sa_family != AF_INET ||
 	    ntohl(ifa->sin.sin_addr.s_addr) >> 24 == IN_LOOPBACKNET)
@@ -794,11 +788,12 @@ check_if_addr_updown(struct rt_msg * rg,
 int 
 bind_current_routes()
 {
-	size_t          needed;
+	size_t          needed, size_cp;
 	int             mib[6];
 	char           *buf, *next, *lim;
 	struct rt_msghdr *rtmes;
 	union sockunion *so_dst, *so_pref, *so_gate;
+	uint rlen;
 
 	mib[0] = CTL_NET;
 	mib[1] = PF_ROUTE;
@@ -819,8 +814,10 @@ bind_current_routes()
 	}
 	lim = buf + needed;
 
-	for (next = buf; next < lim; next += rtmes->rtm_msglen) {
+	for (next = buf; next < lim; next += rlen) {
 		rtmes = (struct rt_msghdr *) next;
+		rlen = rtmes->rtm_msglen;
+		size_cp = sizeof(struct rt_msghdr);
 		so_pref = NULL;
 		so_gate = NULL;
 		if (rtmes->rtm_flags & RTF_LLINFO)	/* No need for arps */
@@ -830,8 +827,9 @@ bind_current_routes()
 			continue;
 		}
 
+		CHECK_MINSA;
 		so_dst = (union sockunion *) & rtmes[1];
-
+		CHECK_LEN(so_dst);
 		/*
 		 * This function is called only at startup, so use
 		 * this ocassion to delete all MPLS routes
@@ -851,22 +849,22 @@ bind_current_routes()
 		if (so_dst->sin.sin_addr.s_addr == 0 && no_default_route != 0)
 			continue;
 
-		/* XXX: Check if it's loopback */
+		/* Check if it's loopback */
 		if ((ntohl(so_dst->sin.sin_addr.s_addr) >> 24)==IN_LOOPBACKNET)
 			continue;
 
 		/* Get Gateway */
 		if (rtmes->rtm_addrs & RTA_GATEWAY)
-			so_gate = GETNEXT(so_dst);
+			GETNEXT(so_gate, so_dst);
 
 		/* Get prefix */
 		if (rtmes->rtm_flags & RTF_HOST) {
 			if ((so_pref = from_cidr_to_union(32)) == NULL)
 				return LDP_E_MEMORY;
-		} else if (rtmes->rtm_addrs & RTA_GATEWAY)
-			so_pref = GETNEXT(so_gate);
-		else
-			so_pref = GETNEXT(so_dst);
+		} else if (rtmes->rtm_addrs & RTA_GATEWAY) {
+			GETNEXT(so_pref, so_gate);
+		} else
+			GETNEXT(so_pref, so_dst);
 
 		so_pref->sa.sa_family = AF_INET;
 		so_pref->sa.sa_len = sizeof(struct sockaddr_in);
@@ -895,9 +893,10 @@ bind_current_routes()
 int 
 flush_mpls_routes()
 {
-	size_t          needed;
-	int             mib[6];
-	char           *buf, *next, *lim;
+	size_t needed, size_cp;
+	int mib[6];
+	uint rlen;
+	char *buf, *next, *lim;
 	struct rt_msghdr *rtm;
 	union sockunion *so_dst, *so_pref, *so_gate;
 
@@ -921,8 +920,10 @@ flush_mpls_routes()
 	}
 	lim = buf + needed;
 
-	for (next = buf; next < lim; next += rtm->rtm_msglen) {
+	for (next = buf; next < lim; next += rlen) {
 		rtm = (struct rt_msghdr *) next;
+		size_cp = sizeof(struct rt_msghdr);
+		rlen = rtm->rtm_msglen;
 		so_pref = NULL;
 		so_gate = NULL;
 		if (rtm->rtm_flags & RTF_LLINFO)	/* No need for arps */
@@ -940,10 +941,10 @@ flush_mpls_routes()
 		}
 
 		if (rtm->rtm_addrs & RTA_GATEWAY) {
-			so_gate = GETNEXT(so_dst);
-			so_pref = GETNEXT(so_gate);
+			GETNEXT(so_gate, so_dst);
+			GETNEXT(so_pref, so_gate);
 		} else
-			so_pref = GETNEXT(so_dst);
+			GETNEXT(so_pref, so_dst);
 
 		if (so_gate->sa.sa_family == AF_MPLS) {
 			if (so_dst->sa.sa_family == AF_INET)

Index: src/usr.sbin/ldpd/mpls_routes.h
diff -u src/usr.sbin/ldpd/mpls_routes.h:1.4 src/usr.sbin/ldpd/mpls_routes.h:1.5
--- src/usr.sbin/ldpd/mpls_routes.h:1.4	Thu Jul 11 10:46:19 2013
+++ src/usr.sbin/ldpd/mpls_routes.h	Tue Jul 16 02:54:32 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.h,v 1.4 2013/07/11 10:46:19 kefren Exp $ */
+/* $NetBSD: mpls_routes.h,v 1.5 2013/07/16 02:54:32 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -73,7 +73,6 @@ int	get_route(struct rt_msg *, const uni
 int	bind_current_routes(void);
 int	flush_mpls_routes(void);
 int	check_route(struct rt_msg *, uint);
-char*	union_ntoa(const union sockunion *);
 uint8_t	from_union_to_cidr(const union sockunion *);
 union sockunion *	from_cidr_to_union(uint8_t);
 

Reply via email to