pkgsrc/net/quagga/patches/patch-ab

178 lines
4.9 KiB
Text
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

$NetBSD: patch-ab,v 1.3 2008/05/13 22:30:47 tonnerre Exp $
--- bgpd/bgp_attr.c
+++ bgpd/bgp_attr.c
@@ -39,7 +39,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "bgpd/bgp_ecommunity.h"
/* Attribute strings for logging. */
-struct message attr_str [] =
+static struct message attr_str [] =
{
{ BGP_ATTR_ORIGIN, "ORIGIN" },
{ BGP_ATTR_AS_PATH, "AS_PATH" },
@@ -58,6 +58,7 @@ struct message attr_str [] =
{ BGP_ATTR_MP_UNREACH_NLRI, "MP_UNREACH_NLRI" },
{ 0, NULL }
};
+int attr_str_max = sizeof(attr_str)/sizeof(attr_str[0]);
struct hash *cluster_hash;
@@ -922,24 +923,30 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
{
u_int16_t afi;
u_char safi;
- u_char snpa_num;
- u_char snpa_len;
- u_char *lim;
bgp_size_t nlri_len;
+ size_t start;
int ret;
struct stream *s;
/* Set end of packet. */
- s = peer->ibuf;
- lim = stream_pnt (s) + length;
-
+ s = BGP_INPUT(peer);
+ start = stream_get_getp(s);
+
+ /* safe to read statically sized header? */
+#define BGP_MP_REACH_MIN_SIZE 5
+ if ((length > STREAM_READABLE(s)) || (length < BGP_MP_REACH_MIN_SIZE))
+ return -1;
+
/* Load AFI, SAFI. */
afi = stream_getw (s);
safi = stream_getc (s);
/* Get nexthop length. */
attr->mp_nexthop_len = stream_getc (s);
-
+
+ if (STREAM_READABLE(s) < attr->mp_nexthop_len)
+ return -1;
+
/* Nexthop length check. */
switch (attr->mp_nexthop_len)
{
@@ -986,31 +993,28 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
break;
}
- snpa_num = stream_getc (s);
-
- while (snpa_num--)
- {
- snpa_len = stream_getc (s);
- stream_forward (s, (snpa_len + 1) >> 1);
- }
+ if (!STREAM_READABLE(s))
+ return -1;
+
+ {
+ u_char val;
+ if ((val = stream_getc (s)))
+ zlog_warn ("%s sent non-zero value, %u, for defunct SNPA-length field",
+ peer->host, val);
+ }
+
+ /* must have nrli_len, what is left of the attribute */
+ nlri_len = length - (stream_get_getp(s) - start);
+ if ((!nlri_len) || (nlri_len > STREAM_READABLE(s)))
+ return -1;
- /* If peer is based on old draft-00. I read NLRI length from the
- packet. */
- if (peer->version == BGP_VERSION_MP_4_DRAFT_00)
- {
- bgp_size_t nlri_total_len;
- nlri_total_len = stream_getw (s);
- }
-
- nlri_len = lim - stream_pnt (s);
-
if (safi != BGP_SAFI_VPNV4)
{
ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), nlri_len);
if (ret < 0)
return -1;
}
-
+
mp_update->afi = afi;
mp_update->safi = safi;
mp_update->nlri = stream_pnt (s);
@@ -1023,24 +1027,26 @@ bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr,
/* Multiprotocol unreachable parse */
int
-bgp_mp_unreach_parse (struct peer *peer, int length,
+bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length,
struct bgp_nlri *mp_withdraw)
{
struct stream *s;
u_int16_t afi;
u_char safi;
- u_char *lim;
u_int16_t withdraw_len;
int ret;
s = peer->ibuf;
- lim = stream_pnt (s) + length;
+#define BGP_MP_UNREACH_MIN_SIZE 3
+ if ((length > STREAM_READABLE(s)) || (length < BGP_MP_UNREACH_MIN_SIZE))
+ return -1;
+
afi = stream_getw (s);
safi = stream_getc (s);
-
- withdraw_len = lim - stream_pnt (s);
-
+
+ withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
+
if (safi != BGP_SAFI_VPNV4)
{
ret = bgp_nlri_sanity_check (peer, afi, stream_pnt (s), withdraw_len);
@@ -1271,13 +1277,23 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
/* If error occured immediately return to the caller. */
if (ret < 0)
- return ret;
+ {
+ zlog (peer->log, LOG_WARNING,
+ "%s: Attribute %s, parse error",
+ peer->host,
+ LOOKUP (attr_str, type));
+ bgp_notify_send (peer,
+ BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_MAL_ATTR);
+ return ret;
+ }
/* Check the fetched length. */
if (BGP_INPUT_PNT (peer) != attr_endp)
{
zlog (peer->log, LOG_WARNING,
- "%s BGP attribute fetch error", peer->host);
+ "%s: BGP attribute %s, fetch error",
+ peer->host, LOOKUP (attr_str, type));
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
@@ -1289,7 +1305,8 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
if (BGP_INPUT_PNT (peer) != endp)
{
zlog (peer->log, LOG_WARNING,
- "%s BGP attribute length mismatch", peer->host);
+ "%s BGP attribute %s, length mismatch",
+ peer->host, LOOKUP (attr_str, type));
bgp_notify_send (peer,
BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_ATTR_LENG_ERR);
diff --git a/doc/quagga.info b/doc/quagga.info
diff --git a/lib/stream.h b/lib/stream.h
index f7a94ea..a85e413 100644