diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-02-04 07:38:05 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2005-02-04 07:38:05 +0000 |
commit | 47b54aab6153617df6f6bef7de33837d490e5b75 (patch) | |
tree | de605c78347167ec0949114fcb36230e4e00c015 | |
parent | 355734ac497c277d6e8a1fe6c1f3e5293efcb20a (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.h | 21 | ||||
-rw-r--r-- | usr.sbin/ospfd/rde_lsdb.c | 52 |
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; |