summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2005-02-04 07:38:05 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2005-02-04 07:38:05 +0000
commit47b54aab6153617df6f6bef7de33837d490e5b75 (patch)
treede605c78347167ec0949114fcb36230e4e00c015
parent355734ac497c277d6e8a1fe6c1f3e5293efcb20a (diff)
Add sanity checks for AS-external LSA. Refine some other checks to be as
strict as possible. OK norby@
-rw-r--r--usr.sbin/ospfd/ospf.h21
-rw-r--r--usr.sbin/ospfd/rde_lsdb.c52
2 files changed, 45 insertions, 28 deletions
diff --git a/usr.sbin/ospfd/ospf.h b/usr.sbin/ospfd/ospf.h
index 479e0f85b4b..969c8924de9 100644
--- a/usr.sbin/ospfd/ospf.h
+++ b/usr.sbin/ospfd/ospf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospf.h,v 1.4 2005/02/02 19:47:20 norby Exp $ */
+/* $OpenBSD: ospf.h,v 1.5 2005/02/04 07:38:04 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -34,7 +34,7 @@
#define DEFAULT_METRIC 1
#define MIN_METRIC 1
-#define MAX_METRIC 65535
+#define MAX_METRIC 65535 /* sum & as-ext lsa use 24bit metrics */
#define DEFAULT_PRIORITY 0 /* XXX force to 0 for now */
#define MIN_PRIORITY 0
@@ -156,6 +156,9 @@ struct ls_upd_hdr {
#define LINK_TYPE_VIRTUAL 4
/* LSA headers */
+#define LSA_METRIC_MASK 0x00ffffff /* only for sum & as-ext */
+#define LSA_ASEXT_E_FLAG 0x80000000
+
struct lsa_rtr {
u_int8_t flags;
u_int8_t dummy;
@@ -180,6 +183,13 @@ struct lsa_sum {
u_int32_t metric; /* only lower 24 bit */
};
+struct lsa_asext {
+ u_int32_t mask;
+ u_int32_t metric; /* lower 24 bit plus E bit */
+ u_int32_t fw_addr;
+ u_int32_t ext_tag;
+};
+
struct lsa_hdr {
u_int16_t age;
u_int8_t opts;
@@ -196,9 +206,10 @@ struct lsa_hdr {
struct lsa {
struct lsa_hdr hdr;
union {
- struct lsa_rtr rtr;
- struct lsa_net net;
- struct lsa_sum sum;
+ struct lsa_rtr rtr;
+ struct lsa_net net;
+ struct lsa_sum sum;
+ struct lsa_asext asext;
} data;
};
diff --git a/usr.sbin/ospfd/rde_lsdb.c b/usr.sbin/ospfd/rde_lsdb.c
index 1ac7f437793..3b3f662160a 100644
--- a/usr.sbin/ospfd/rde_lsdb.c
+++ b/usr.sbin/ospfd/rde_lsdb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_lsdb.c,v 1.3 2005/02/02 19:29:15 henning Exp $ */
+/* $OpenBSD: rde_lsdb.c,v 1.4 2005/02/04 07:38:04 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Claudio Jeker <claudio@openbsd.org>
@@ -30,7 +30,6 @@
struct vertex *vertex_get(struct lsa *, struct rde_nbr *);
int lsa_router_check(struct lsa *, u_int16_t);
-int lsa_asext_check(struct area *, struct lsa *, u_int16_t);
void lsa_age(struct vertex *);
void lsa_timeout(int, short, void *);
void lsa_refresh(struct vertex *);
@@ -146,31 +145,32 @@ int
lsa_check(struct rde_nbr *nbr, struct lsa *lsa, u_int16_t len)
{
struct area *area = nbr->area;
+ u_int32_t metric;
if (len < sizeof(lsa->hdr)) {
- log_warnx("lsa_check: invalid packet size");
+ log_warnx("lsa_check: bad packet size");
return (0);
}
if (ntohs(lsa->hdr.len) != len) {
- log_warnx("lsa_check: invalid packet size");
+ log_warnx("lsa_check: bad packet size");
return (0);
}
if (iso_cksum(lsa, len, 0)) {
- log_warnx("lsa_check: invalid packet checksum");
+ log_warnx("lsa_check: bad packet checksum");
return (0);
}
/* invalid ages */
if ((ntohs(lsa->hdr.age) < 1 && !nbr->self) ||
ntohs(lsa->hdr.age) > MAX_AGE) {
- log_debug("lsa_check: invalid age");
+ log_debug("lsa_check: bad age");
return (0);
}
/* invalid sequence number */
if (ntohl(lsa->hdr.seq_num) == 0x80000000) {
- log_debug("ls_check: invalid seq num");
+ log_debug("ls_check: bad seq num");
return (0);
}
@@ -180,21 +180,38 @@ lsa_check(struct rde_nbr *nbr, struct lsa *lsa, u_int16_t len)
return (0);
break;
case LSA_TYPE_NETWORK:
- if ((len & 0x03) ||
+ if ((len % sizeof(u_int32_t)) ||
len < sizeof(lsa->hdr) + sizeof(u_int32_t)) {
- log_warnx("lsa_check: invalid LSA network packet");
+ log_warnx("lsa_check: bad LSA network packet");
return (0);
}
break;
case LSA_TYPE_SUM_NETWORK:
case LSA_TYPE_SUM_ROUTER:
- if (len != sizeof(struct lsa_hdr) + sizeof(struct lsa_sum)) {
- log_warnx("lsa_check: invalid LSA summary packet");
+ if ((len % sizeof(u_int32_t)) ||
+ len < sizeof(lsa->hdr) + sizeof(lsa->data.sum)) {
+ log_warnx("lsa_check: bad LSA summary packet");
+ return (0);
+ }
+ metric = ntohl(lsa->data.sum.metric);
+ if (metric & ~LSA_METRIC_MASK) {
+ log_warnx("lsa_check: bad LSA summary metric");
return (0);
}
break;
case LSA_TYPE_EXTERNAL:
- if (!lsa_asext_check(area, lsa, len))
+ if ((len % (3 * sizeof(u_int32_t))) ||
+ len < sizeof(lsa->hdr) + sizeof(lsa->data.asext)) {
+ log_warnx("lsa_check: bad LSA as-external packet");
+ return (0);
+ }
+ metric = ntohl(lsa->data.asext.metric);
+ if (metric & ~(LSA_METRIC_MASK | LSA_ASEXT_E_FLAG)) {
+ log_warnx("lsa_check: bad LSA as-external metric");
+ return (0);
+ }
+ /* AS-external-LSA are silently discarded in stub areas */
+ if (area->stub)
return (0);
break;
default:
@@ -254,17 +271,6 @@ lsa_router_check(struct lsa *lsa, u_int16_t len)
}
int
-lsa_asext_check(struct area *area, struct lsa *lsa, u_int16_t len)
-{
- if (area->stub)
- /* AS-external-LSA are discarded in stub areas */
- return (0);
-
- /* XXX check size */
- return (1);
-}
-
-int
lsa_self(struct rde_nbr *nbr, struct lsa *new, struct vertex *v)
{
struct iface *iface;