From 6b161fc12a15aba8824c84d1eb38e529aaf70769 Mon Sep 17 00:00:00 2001 From: CROSS Date: Mon, 26 Sep 2011 13:17:21 +0400 Subject: ospfd: CVE-2011-3326 (uknown LSA type segfault) This vulnerability (CERT-FI #514837) was reported by CROSS project. They have also suggested a fix to the problem, which was found acceptable. Quagga ospfd does not seem to handle unknown LSA types in a Link State Update message correctly. If LSA type is something else than one supported by Quagga, the default handling of unknown types leads to an error. * ospf_flood.c * ospf_flood(): check return value of ospf_lsa_install() --- ospfd/ospf_flood.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 77f2e161..004ed1a7 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -319,7 +319,8 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, procedure cannot overwrite the newly installed LSA until MinLSArrival seconds have elapsed. */ - new = ospf_lsa_install (ospf, nbr->oi, new); + if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) + return 0; /* unknown LSA type */ /* Acknowledge the receipt of the LSA by sending a Link State Acknowledgment packet back out the receiving interface. */ -- cgit v1.2.1 From 61ab0301606053192f45c188bc48afc837518770 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 26 Sep 2011 13:17:52 +0400 Subject: ospfd: CVE-2011-3325 part 1 (OSPF header underrun) This vulnerability (CERT-FI #514838) was reported by CROSS project. When only 14 first bytes of a Hello packet is delivered, ospfd crashes. * ospf_packet.c * ospf_read(): add size check --- ospfd/ospf_packet.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index be137d91..57278788 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2430,10 +2430,19 @@ ospf_read (struct thread *thread) return 0; } - /* Adjust size to message length. */ + /* Advance from IP header to OSPF header (iph->ip_hl has been verified + by ospf_recv_packet() to be correct). */ stream_forward_getp (ibuf, iph->ip_hl * 4); - - /* Get ospf packet header. */ + + /* Make sure the OSPF header is really there. */ + if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE) + { + zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header", + stream_get_endp (ibuf) - stream_get_getp (ibuf)); + return -1; + } + + /* Now it is safe to access all fields of OSPF packet header. */ ospfh = (struct ospf_header *) STREAM_PNT (ibuf); /* associate packet with ospf interface */ -- cgit v1.2.1 From 717750433839762d23a5f8d88fe0b4d57c8d490a Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 26 Sep 2011 13:18:02 +0400 Subject: ospfd: CVE-2011-3325 part 2 (OSPF pkt type segv) This vulnerability (CERT-FI #514838) was reported by CROSS project. The error is reproducible only when ospfd debugging is enabled: * debug ospf packet all * debug ospf zebra When incoming packet header type field is set to 0x0a, ospfd will crash. * ospf_packet.c * ospf_verify_header(): add type field check * ospf_read(): perform input checks early --- ospfd/ospf_packet.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 57278788..151ed328 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2321,6 +2321,13 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, return -1; } + /* Valid OSPFv2 packet types are 1 through 5 inclusive. */ + if (ospfh->type < 1 || ospfh->type > 5) + { + zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type); + return -1; + } + /* Check Area ID. */ if (!ospf_check_area_id (oi, ospfh)) { @@ -2448,6 +2455,17 @@ ospf_read (struct thread *thread) /* associate packet with ospf interface */ oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp); + /* Verify header fields before any further processing. */ + ret = ospf_verify_header (ibuf, oi, iph, ospfh); + if (ret < 0) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("ospf_read[%s]: Header check failed, " + "dropping.", + inet_ntoa (iph->ip_src)); + return ret; + } + /* If incoming interface is passive one, ignore it. */ if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) { @@ -2557,20 +2575,6 @@ ospf_read (struct thread *thread) zlog_debug ("-----------------------------------------------------"); } - /* Some header verification. */ - ret = ospf_verify_header (ibuf, oi, iph, ospfh); - if (ret < 0) - { - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - { - zlog_debug ("ospf_read[%s/%s]: Header check failed, " - "dropping.", - ospf_packet_type_str[ospfh->type], - inet_ntoa (iph->ip_src)); - } - return ret; - } - stream_forward_getp (ibuf, OSPF_HEADER_SIZE); /* Adjust size to message length. */ -- cgit v1.2.1 From 3c9cfcdebf680c1d2c0e6b69cb4e11885a049e05 Mon Sep 17 00:00:00 2001 From: Alexandre Chappuis Date: Tue, 2 Aug 2011 17:37:39 +0400 Subject: ospfd: remove useless RFC1583 check * ospf_route.c: Function ospf_asbr_route_cmp is called uniquely from ospf_route_cmp() when the flag OSPF_RFC1583_COMPATIBLE is not set. Therefore, the check that the flag is set doesn't make sense at all and it can consequently be removed without doing any harm. Signed-off-by: Alexandre Chappuis Signed-off-by: Roman Hoog Antink --- ospfd/ospf_route.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 267237b8..d77c7420 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -720,10 +720,6 @@ ospf_asbr_route_cmp (struct ospf *ospf, struct ospf_route *r1, r1_type = r1->path_type; r2_type = r2->path_type; - /* If RFC1583Compat flag is on -- all paths are equal. */ - if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) - return 0; - /* r1/r2 itself is backbone, and it's Inter-area path. */ if (OSPF_IS_AREA_ID_BACKBONE (r1->u.std.area_id)) r1_type = OSPF_PATH_INTER_AREA; -- cgit v1.2.1 From 69bf3a39931ce61a92fb04d8888b4655fd5620a2 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Thu, 18 Aug 2011 20:22:17 +0400 Subject: lib: simplify interface of setsockopt_multicast_ipv4(). * sockopt.[ch] (setsockopt_ipv4_multicast): ifindex is now mandatory (all non-ancient OSes can use it anyway), and if_addr parameter (the address of the interface) is now gone. (setsockopt_ipv4_multicast_if): IP_MULTICAST_IF processing moved to this new function * ospf_network.c (ospf_if_add_allspfrouters, ospf_if_drop_allspfrouters, ospf_if_add_alldrouters, ospf_if_drop_alldrouters, ospf_if_ipmulticast), rip_interface.c (ipv4_multicast_join, ipv4_multicast_leave, rip_interface_new): adapt to the new interface --- ospfd/ospf_network.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 1e2d44e6..3e326a8c 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -52,8 +52,8 @@ ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p, { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, + htonl (OSPF_ALLSPFROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -73,8 +73,8 @@ ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p, { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, + htonl (OSPF_ALLSPFROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -94,8 +94,8 @@ ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, unsigned int { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLDROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, + htonl (OSPF_ALLDROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -115,8 +115,8 @@ ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, unsigned int { int ret; - ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP, - p->u.prefix4, htonl (OSPF_ALLDROUTERS), + ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, + htonl (OSPF_ALLDROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -151,8 +151,7 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *p, unsigned int ifindex) zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", top->fd, safe_strerror (errno)); - ret = setsockopt_multicast_ipv4 (top->fd, IP_MULTICAST_IF, - p->u.prefix4, 0, ifindex); + ret = setsockopt_ipv4_multicast_if (top->fd, ifindex); if (ret < 0) zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, " "ifindex %u): %s", -- cgit v1.2.1 From 05b7709dad416146376cc4f41db0c866b3738f5b Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 23 Aug 2011 11:36:27 +0400 Subject: ospfd: sizing macros cleanup * ospf_spf.c * ROUTER_LSA_TOS_SIZE: prepend OSPF_ and move to ospf_lsa.h * ROUTER_LSA_MIN_SIZE: replace with existing OSPF_ROUTER_LSA_LINK_SIZE --- ospfd/ospf_lsa.h | 1 + ospfd/ospf_spf.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 72e2f8a5..bf3b083c 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -49,6 +49,7 @@ #define OSPF_LSA_HEADER_SIZE 20U #define OSPF_ROUTER_LSA_LINK_SIZE 12U +#define OSPF_ROUTER_LSA_TOS_SIZE 4U #define OSPF_MAX_LSA_SIZE 1500U /* AS-external-LSA refresh method. */ diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index ca200222..6dcf0b18 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -356,9 +356,6 @@ ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v) return -1; } -#define ROUTER_LSA_MIN_SIZE 12 -#define ROUTER_LSA_TOS_SIZE 4 - /* Find the next link after prev_link from v to w. If prev_link is * NULL, return the first link from v to w. Ignore stub and virtual links; * these link types will never be returned. @@ -380,8 +377,8 @@ ospf_get_next_link (struct vertex *v, struct vertex *w, else { p = (u_char *) prev_link; - p += (ROUTER_LSA_MIN_SIZE + - (prev_link->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (prev_link->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); } lim = ((u_char *) v->lsa) + ntohs (v->lsa->length); @@ -390,7 +387,7 @@ ospf_get_next_link (struct vertex *v, struct vertex *w, { l = (struct router_lsa_link *) p; - p += (ROUTER_LSA_MIN_SIZE + (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); if (l->m[0].type != lsa_type) continue; @@ -755,8 +752,8 @@ ospf_spf_next (struct vertex *v, struct ospf_area *area, { l = (struct router_lsa_link *) p; - p += (ROUTER_LSA_MIN_SIZE + - (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); /* (a) If this is a link to a stub network, examine the next link in V's LSA. Links to stub networks will be @@ -989,8 +986,8 @@ ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v, { l = (struct router_lsa_link *) p; - p += (ROUTER_LSA_MIN_SIZE + - (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE)); + p += (OSPF_ROUTER_LSA_LINK_SIZE + + (l->m[0].tos_count * OSPF_ROUTER_LSA_TOS_SIZE)); if (l->m[0].type == LSA_LINK_TYPE_STUB) ospf_intra_add_stub (rt, l, v, area, parent_is_root); -- cgit v1.2.1 From 171c9a996dd75a8b9aa596288c974f9ac0fbc5d6 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 10 Sep 2011 16:40:23 +0400 Subject: ospfd: use existing macro for consistency --- ospfd/ospf_vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 46e7ffa5..3c8df130 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -7902,9 +7902,9 @@ config_write_ospf_distribute (struct vty *vty, struct ospf *ospf) { /* distribute-list print. */ for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - if (ospf->dlist[type].name) + if (DISTRIBUTE_NAME (ospf, type)) vty_out (vty, " distribute-list %s out %s%s", - ospf->dlist[type].name, + DISTRIBUTE_NAME (ospf, type), zebra_route_string(type), VTY_NEWLINE); /* default-information print. */ -- cgit v1.2.1 From bcc6c59ac5e9c1e8cf9693b4768f6b8cad5e559a Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 10 Sep 2011 23:29:19 +0400 Subject: ospfd: spelling --- ospfd/ospf_zebra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 50ca85e1..bffa90db 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -670,7 +670,7 @@ ospf_external_lsa_originate_check (struct ospf *ospf, if (is_prefix_default (&ei->p)) if (ospf->default_originate == DEFAULT_ORIGINATE_NONE) { - zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-exntenal-LSA " + zlog_info ("LSA[Type5:0.0.0.0]: Not originate AS-external-LSA " "for default"); return 0; } -- cgit v1.2.1 From 52ecbbea36439758590f0c31a0ec147fec041d7a Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Thu, 15 Sep 2011 15:40:47 +0400 Subject: ospfd: remove unused macro --- ospfd/ospfd.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 0e57c452..7a56d163 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -72,10 +72,6 @@ #define OSPF_ALLSPFROUTERS 0xe0000005 /* 224.0.0.5 */ #define OSPF_ALLDROUTERS 0xe0000006 /* 224.0.0.6 */ -/* XXX Where is this used? And why it was used only if compiled with - * NSSA support. */ -#define OSPF_LOOPer 0x7f000000 /* 127.0.0.0 */ - #define OSPF_AREA_BACKBONE 0x00000000 /* 0.0.0.0 */ /* OSPF Authentication Type. */ -- cgit v1.2.1 From 3aad46bdaa0a2700e43252904b9481750c8cb45d Mon Sep 17 00:00:00 2001 From: YAMAMOTO Shigeru Date: Wed, 28 Sep 2011 21:00:14 +0400 Subject: ospfd: fix regression in recent commit commit '717750433839762d23a5f8d88fe0b4d57c8d490a' causes SEGV error, when 'oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp);' returns NULL. * ospf_packet.c * ospf_read(): change a place of calling 'ospf_verify_header()' --- ospfd/ospf_packet.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 151ed328..0f338d35 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2455,16 +2455,10 @@ ospf_read (struct thread *thread) /* associate packet with ospf interface */ oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp); - /* Verify header fields before any further processing. */ - ret = ospf_verify_header (ibuf, oi, iph, ospfh); - if (ret < 0) - { - if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("ospf_read[%s]: Header check failed, " - "dropping.", - inet_ntoa (iph->ip_src)); - return ret; - } + /* ospf_verify_header() relies on a valid "oi" and thus can be called only + after the passive/backbone/other checks below are passed. These checks + in turn access the fields of unverified "ospfh" structure for their own + purposes and must remain very accurate in doing this. */ /* If incoming interface is passive one, ignore it. */ if (oi && OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) @@ -2556,6 +2550,17 @@ ospf_read (struct thread *thread) return 0; } + /* Verify more OSPF header fields. */ + ret = ospf_verify_header (ibuf, oi, iph, ospfh); + if (ret < 0) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("ospf_read[%s]: Header check failed, " + "dropping.", + inet_ntoa (iph->ip_src)); + return ret; + } + /* Show debug receiving packet. */ if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) { -- cgit v1.2.1 From 4de148e5d6f6f7885b2c0952a236a3bc3ec36250 Mon Sep 17 00:00:00 2001 From: Thomas Ries Date: Thu, 27 Oct 2011 17:43:38 +0400 Subject: ospfd: improve fix to CVE-2011-3326 (BZ#586) Make ospf_flood() propagate error returned by ospf_lsa_install() further to properly discard the malformed LSA, not just prevent the immediate crash. --- ospfd/ospf_flood.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index 004ed1a7..2ebae89a 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -320,7 +320,7 @@ ospf_flood (struct ospf *ospf, struct ospf_neighbor *nbr, MinLSArrival seconds have elapsed. */ if (! (new = ospf_lsa_install (ospf, nbr->oi, new))) - return 0; /* unknown LSA type */ + return -1; /* unknown LSA type or any other error condition */ /* Acknowledge the receipt of the LSA by sending a Link State Acknowledgment packet back out the receiving interface. */ -- cgit v1.2.1 From fb01f87f4f50744206222343a780721af19fe56c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2011 14:46:42 +0400 Subject: ospfd: avoid redundant lookup in ospf_redistribute_withdraw The old algorithim looked up every node twice as it withdrew the entry. It looks up entry once in redistribute_withdraw, then looks it up again info_delete. Use result of first lookup to do the free directly. This may explain the slow performance observed in https://bugzilla.vyatta.com/show_bug.cgi?id=4421 --- ospfd/ospf_asbr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index c39efee1..a23b4f2b 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -284,6 +284,9 @@ ospf_redistribute_withdraw (struct ospf *ospf, u_char type) continue; ospf_external_lsa_flush (ospf, type, &ei->p, ei->ifindex /*, ei->nexthop */); - ospf_external_info_delete (type, ei->p); + + ospf_external_info_free (ei); + route_unlock_node (rn); + rn->info = NULL; } } -- cgit v1.2.1 From 075e12f57d6c0b115cd177c7b244d9810460e3ff Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 6 Dec 2011 23:54:17 +0400 Subject: ospfd: remove unused code The code for nssa_range and other bits that were written but never used. --- ospfd/ospf_abr.c | 45 -------------------------------------------- ospfd/ospf_route.c | 55 ------------------------------------------------------ ospfd/ospf_spf.c | 2 ++ ospfd/ospf_vty.c | 3 ++- ospfd/ospfd.c | 2 ++ 5 files changed, 6 insertions(+), 101 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 7a75194a..846b90df 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -613,15 +613,6 @@ set_metric (struct ospf_lsa *lsa, u_int32_t metric) memcpy(header->metric, mp, 3); } -static int -ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost, - struct ospf_area *area) -{ - /* The Type-7 is tested against the aggregated prefix and forwarded - for lsa installation and flooding */ - return 0; -} - /* ospf_abr_translate_nssa */ static int ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa) @@ -1576,42 +1567,6 @@ ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */ zlog_debug ("ospf_abr_send_nssa_aggregates(): Stop"); } -static void -ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */ -{ - struct listnode *node; - struct ospf_area *area; - - if (! IS_OSPF_ABR (ospf)) - return; - - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_announce_stub_defaults(): Start"); - - for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area)) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_announce_nssa_defaults(): looking at area %s", - inet_ntoa (area->area_id)); - - if (area->external_routing != OSPF_AREA_NSSA) - continue; - - if (OSPF_IS_AREA_BACKBONE (area)) - continue; /* Sanity Check */ - - /* if (!TranslatorRole continue V 1.0 look for "always" conf */ - if (area->NSSATranslatorState) - { - if (IS_DEBUG_OSPF_NSSA) - zlog_debug ("ospf_abr_announce_nssa_defaults(): " - "announcing 0.0.0.0/0 to this nssa"); - /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */ - /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/ - } - } -} - static void ospf_abr_announce_stub_defaults (struct ospf *ospf) { diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index d77c7420..d2e5e1e7 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -272,61 +272,6 @@ ospf_route_install (struct ospf *ospf, struct route_table *rt) } } -static void -ospf_intra_route_add (struct route_table *rt, struct vertex *v, - struct ospf_area *area) -{ - struct route_node *rn; - struct ospf_route *or; - struct prefix_ipv4 p; - struct ospf_path *path; - struct vertex_parent *parent; - struct listnode *node, *nnode; - - p.family = AF_INET; - p.prefix = v->id; - if (v->type == OSPF_VERTEX_ROUTER) - p.prefixlen = IPV4_MAX_BITLEN; - else - { - struct network_lsa *lsa = (struct network_lsa *) v->lsa; - p.prefixlen = ip_masklen (lsa->mask); - } - apply_mask_ipv4 (&p); - - rn = route_node_get (rt, (struct prefix *) &p); - if (rn->info) - { - zlog_warn ("Same routing information exists for %s", inet_ntoa (v->id)); - route_unlock_node (rn); - return; - } - - or = ospf_route_new (); - - if (v->type == OSPF_VERTEX_NETWORK) - { - or->type = OSPF_DESTINATION_NETWORK; - - for (ALL_LIST_ELEMENTS (v->parents, node, nnode, parent)) - { - path = ospf_path_new (); - path->nexthop = parent->nexthop->router; - listnode_add (or->paths, path); - } - } - else - or->type = OSPF_DESTINATION_ROUTER; - - or->id = v->id; - or->u.std.area_id = area->area_id; - or->u.std.external_routing= area->external_routing; - or->path_type = OSPF_PATH_INTRA_AREA; - or->cost = v->distance; - - rn->info = or; -} - /* RFC2328 16.1. (4). For "router". */ void ospf_intra_add_router (struct route_table *rt, struct vertex *v, diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 6dcf0b18..d7f9ba27 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -1042,6 +1042,7 @@ ospf_rtrs_free (struct route_table *rtrs) route_table_finish (rtrs); } +#if 0 static void ospf_rtrs_print (struct route_table *rtrs) { @@ -1101,6 +1102,7 @@ ospf_rtrs_print (struct route_table *rtrs) zlog_debug ("ospf_rtrs_print() end"); } +#endif /* Calculating the shortest-path tree for an area. */ static void diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 3c8df130..59f5fb67 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3761,7 +3761,7 @@ show_as_external_lsa_detail (struct vty *vty, struct ospf_lsa *lsa) return 0; } -/* N.B. This function currently seems to be unused. */ +#if 0 static int show_as_external_lsa_stdvty (struct ospf_lsa *lsa) { @@ -3785,6 +3785,7 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa) return 0; } +#endif /* Show AS-NSSA-LSA detail information. */ static int diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 0188ffda..e8405136 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -1204,6 +1204,7 @@ ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id, return 1; } +#if 0 /* XXX: unused? Leave for symmetry? */ static int ospf_area_nssa_translator_role_unset (struct ospf *ospf, @@ -1221,6 +1222,7 @@ ospf_area_nssa_translator_role_unset (struct ospf *ospf, return 1; } +#endif int ospf_area_export_list_set (struct ospf *ospf, -- cgit v1.2.1 From b51146856e660bcec723f535c17dc1c38b2f6efc Mon Sep 17 00:00:00 2001 From: Vyacheslav Trushkin Date: Fri, 25 Nov 2011 18:51:48 +0400 Subject: quagga: option "-z" ("--socket ") added All daemons modified to support custom path to zserv socket. lib: generalize a zclient connection zclient_socket_connect added. zclient_socket and zclient_socket_un were hidden under static expression. "zclient_serv_path_set" modified. --- ospfd/ospf_main.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 8b9a3458..bad674b6 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -38,6 +38,7 @@ #include "memory.h" #include "privs.h" #include "sigevent.h" +#include "zclient.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -80,6 +81,7 @@ struct option longopts[] = { "daemon", no_argument, NULL, 'd'}, { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, + { "socket", required_argument, NULL, 'z'}, { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, @@ -116,6 +118,7 @@ Daemon which manages OSPF.\n\n\ -d, --daemon Runs in daemon mode\n\ -f, --config_file Set configuration file name\n\ -i, --pid_file Set process identifier file name\n\ +-z, --socket Set path of zebra socket\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -u, --user User to run as\n\ @@ -191,30 +194,11 @@ main (int argc, char **argv) /* get program name */ progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); - /* Invoked by a priviledged user? -- endo. */ - if (geteuid () != 0) - { - errno = EPERM; - perror (progname); - exit (1); - } - - zlog_default = openzlog (progname, ZLOG_OSPF, - LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); - - /* OSPF master init. */ - ospf_master_init (); - -#ifdef SUPPORT_OSPF_API - /* OSPF apiserver is disabled by default. */ - ospf_apiserver_enable = 0; -#endif /* SUPPORT_OSPF_API */ - while (1) { int opt; - opt = getopt_long (argc, argv, "df:i:hA:P:u:g:avC", longopts, 0); + opt = getopt_long (argc, argv, "df:i:z:hA:P:u:g:avC", longopts, 0); if (opt == EOF) break; @@ -235,6 +219,9 @@ main (int argc, char **argv) case 'i': pid_file = optarg; break; + case 'z': + zclient_serv_path_set (optarg); + break; case 'P': /* Deal with atoi() returning 0 on failure, and ospfd not listening on ospfd port... */ @@ -274,6 +261,25 @@ main (int argc, char **argv) } } + /* Invoked by a priviledged user? -- endo. */ + if (geteuid () != 0) + { + errno = EPERM; + perror (progname); + exit (1); + } + + zlog_default = openzlog (progname, ZLOG_OSPF, + LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); + + /* OSPF master init. */ + ospf_master_init (); + +#ifdef SUPPORT_OSPF_API + /* OSPF apiserver is disabled by default. */ + ospf_apiserver_enable = 0; +#endif /* SUPPORT_OSPF_API */ + /* Initializations. */ master = om->master; -- cgit v1.2.1 From ad8d4802a3078de694539fa9bae12322fc82042f Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 2 Dec 2011 20:02:40 +0400 Subject: ospfd: spelling --- ospfd/ospf_lsa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 842df49c..a2d400fa 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -1637,7 +1637,7 @@ ospf_external_lsa_new (struct ospf *ospf, if (ei == NULL) { if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) - zlog_debug ("LSA[Type5]: External info is NULL, could not originated"); + zlog_debug ("LSA[Type5]: External info is NULL, can't originate"); return NULL; } @@ -2840,7 +2840,7 @@ ospf_maxage_lsa_remover (struct thread *thread) /* Remove LSA from the LSDB */ if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)) if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) - zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ", + zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ", lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa); if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) -- cgit v1.2.1 From 05e54ee3df973194f2a00e3ea0b1da7bebc71fd6 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sat, 3 Dec 2011 17:45:17 +0400 Subject: build: delete .cvsignore files --- ospfd/.cvsignore | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 ospfd/.cvsignore (limited to 'ospfd') diff --git a/ospfd/.cvsignore b/ospfd/.cvsignore deleted file mode 100644 index 6fce629e..00000000 --- a/ospfd/.cvsignore +++ /dev/null @@ -1,14 +0,0 @@ -Makefile -Makefile.in -*.o -ospfd -ospfd.conf -tags -TAGS -.deps -.nfs* -*.lo -*.la -*.libs -.arch-inventory -.arch-ids -- cgit v1.2.1 From e0ca5fde7be5b5ce90dae78c2477e8245aecb8e9 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 16 Sep 2009 01:52:42 +0200 Subject: lib: put route_types.txt to real use this replaces most occurences of routing protocol lists by preprocessor defines from route_types.h. the latter is autogenerated from route_types.txt by a perl script (previously awk). adding a routing protocol now is mostly a matter of changing route_types.txt and log.c. Conflicts: lib/route_types.awk --- ospfd/ospf_vty.c | 47 ++++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 31 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 59f5fb67..c928e819 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -92,29 +92,6 @@ ospf_str2area_id (const char *str, struct in_addr *area_id, int *format) } -static int -str2distribute_source (const char *str, int *source) -{ - /* Sanity check. */ - if (str == NULL) - return 0; - - if (strncmp (str, "k", 1) == 0) - *source = ZEBRA_ROUTE_KERNEL; - else if (strncmp (str, "c", 1) == 0) - *source = ZEBRA_ROUTE_CONNECT; - else if (strncmp (str, "s", 1) == 0) - *source = ZEBRA_ROUTE_STATIC; - else if (strncmp (str, "r", 1) == 0) - *source = ZEBRA_ROUTE_RIP; - else if (strncmp (str, "b", 1) == 0) - *source = ZEBRA_ROUTE_BGP; - else - return 0; - - return 1; -} - static int str2metric (const char *str, int *metric) { @@ -5825,7 +5802,8 @@ DEFUN (ospf_redistribute_source_metric_type, int metric = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -5886,7 +5864,8 @@ DEFUN (ospf_redistribute_source_type_metric, int metric = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -5950,7 +5929,8 @@ DEFUN (ospf_redistribute_source_metric_routemap, int metric = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -5983,7 +5963,8 @@ DEFUN (ospf_redistribute_source_type_routemap, int type = -1; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; /* Get metric value. */ @@ -6011,7 +5992,8 @@ DEFUN (ospf_redistribute_source_routemap, int source; /* Get distribute source. */ - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; if (argc == 2) @@ -6032,7 +6014,8 @@ DEFUN (no_ospf_redistribute_source, struct ospf *ospf = vty->index; int source; - if (!str2distribute_source (argv[0], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; ospf_routemap_unset (ospf, source); @@ -6051,7 +6034,8 @@ DEFUN (ospf_distribute_list_out, int source; /* Get distribute source. */ - if (!str2distribute_source (argv[1], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; return ospf_distribute_list_out_set (ospf, source, argv[0]); @@ -6069,7 +6053,8 @@ DEFUN (no_ospf_distribute_list_out, struct ospf *ospf = vty->index; int source; - if (!str2distribute_source (argv[1], &source)) + source = proto_redistnum(AFI_IP, argv[0]); + if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; return ospf_distribute_list_out_unset (ospf, source, argv[0]); -- cgit v1.2.1 From 223da1a912305f2cac6f72c3b480ce103a25d7d6 Mon Sep 17 00:00:00 2001 From: Jaroslav Fojtik Date: Sun, 11 Dec 2011 18:22:16 +0400 Subject: ospfd: more info in LSA checksum warning (BZ#685) --- ospfd/ospf_packet.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 0f338d35..f8887c5f 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -1568,8 +1568,13 @@ ospf_ls_upd_list_lsa (struct ospf_neighbor *nbr, struct stream *s, sum = lsah->checksum; if (sum != ospf_lsa_checksum (lsah)) { - zlog_warn ("Link State Update: LSA checksum error %x, %x.", - sum, lsah->checksum); + /* (bug #685) more details in a one-line message make it possible + * to identify problem source on the one hand and to have a better + * chance to compress repeated messages in syslog on the other */ + zlog_warn ("Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s", + sum, lsah->checksum, inet_ntoa (lsah->id), + inet_ntoa (nbr->src), inet_ntoa (nbr->router_id), + inet_ntoa (lsah->adv_router)); continue; } -- cgit v1.2.1 From de5ccb96023181765c9904ab40e645c397f536d6 Mon Sep 17 00:00:00 2001 From: Dmitrij Tejblum Date: Mon, 12 Dec 2011 20:30:10 +0400 Subject: ospfd: fix packet reception for FreeBSD 10. * ospf_packet.c (ospf_recv_packet): FreeBSD, starting from version 10, will not subtract the IP header size from ip_len. This is the patch from FreeBSD's ports/net/quagga/files/patch-ospfd__ospf_packet.c, by Boris Kovalenko. --- ospfd/ospf_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index f8887c5f..07050824 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2121,7 +2121,7 @@ ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf) ip_len = iph->ip_len; -#if !defined(GNU_LINUX) && (OpenBSD < 200311) +#if !defined(GNU_LINUX) && (OpenBSD < 200311) && (__FreeBSD_version < 1000000) /* * Kernel network code touches incoming IP header parameters, * before protocol specific processing. -- cgit v1.2.1 From 4e677f52db2276b92bcc201b4379a66a83d45caa Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 18 Dec 2011 16:27:02 +0400 Subject: ospfd: fix bug in NSSA ABR status check * ospf_abr.c * ospf_abr_nssa_am_elected(): feed "best" instead of "address of best" into IPV4_ADDR_CMP(), because "best" is a pointer; also, mean s_addr field of the structures to get better typed pointers --- ospfd/ospf_abr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 846b90df..b7cc20dd 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -384,7 +384,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area) if (best == NULL) best = &lsa->data->id; else - if ( IPV4_ADDR_CMP (&best, &lsa->data->id) < 0) + if (IPV4_ADDR_CMP (&best->s_addr, &lsa->data->id.s_addr) < 0) best = &lsa->data->id; } @@ -395,7 +395,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area) if (best == NULL) return 1; - if ( IPV4_ADDR_CMP (&best, &area->ospf->router_id) < 0) + if (IPV4_ADDR_CMP (&best->s_addr, &area->ospf->router_id.s_addr) < 0) return 1; else return 0; -- cgit v1.2.1 From 664711c1f4cc218073783ff6ce362093debd7b53 Mon Sep 17 00:00:00 2001 From: Ulrich Weber Date: Wed, 21 Dec 2011 02:24:11 +0400 Subject: lib: fix some strtoul() use cases ...otherwise 4294967295 is not a valid value on 32bit systems --- ospfd/ospf_vty.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index c928e819..97c8e8d6 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -80,8 +80,11 @@ ospf_str2area_id (const char *str, struct in_addr *area_id, int *format) /* match "<0-4294967295>". */ else { + if (*str == '-') + return -1; + errno = 0; ret = strtoul (str, &endptr, 10); - if (*endptr != '\0' || (ret == ULONG_MAX && errno == ERANGE)) + if (*endptr != '\0' || errno || ret > UINT32_MAX) return -1; area_id->s_addr = htonl (ret); -- cgit v1.2.1 From f63f06da2e7be6b17c72dd6110aae179f42f3700 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Fri, 8 Apr 2011 12:44:43 +0100 Subject: general: remove inline qualifiers and move in-header functions to objects * (general) Move functions in headers into files, to be compiled into shared object files. Remove inline qualifier from functions. Let the compiler do the work. --- ospfd/ospf_lsa.c | 2 +- ospfd/ospf_packet.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index a2d400fa..fa36a027 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -746,7 +746,7 @@ ospf_stub_router_timer (struct thread *t) return 0; } -inline static void +static void ospf_stub_router_check (struct ospf_area *area) { /* area must either be administratively configured to be stub diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 07050824..b714c27d 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -266,7 +266,7 @@ ospf_packet_dup (struct ospf_packet *op) } /* XXX inline */ -static inline unsigned int +static unsigned int ospf_packet_authspace (struct ospf_interface *oi) { int auth = 0; @@ -2213,7 +2213,7 @@ ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp, return NULL; } -static inline int +static int ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh) { /* Check match the Area ID of the receiving interface. */ -- cgit v1.2.1 From 72f062b6ebd7f279dc3f0b66acdb0b718ff42e40 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 28 Aug 2011 22:38:45 +0400 Subject: ospfd: address more trivial compiler warnings * ospf_ase.c * ospf_ase_complete_direct_routes(): dismiss unused variable --- ospfd/ospf_ase.c | 1 - 1 file changed, 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 3c199311..6a72e31d 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -135,7 +135,6 @@ ospf_ase_complete_direct_routes (struct ospf_route *ro, struct in_addr nexthop) { struct listnode *node; struct ospf_path *op; - struct interface *ifp; for (ALL_LIST_ELEMENTS_RO (ro->paths, node, op)) if (op->nexthop.s_addr == 0) -- cgit v1.2.1 From 8216f53b73d8eb375615ad4395deace11d1e22d6 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 3 Oct 2011 14:08:01 +0400 Subject: ospfd: justify ospf_default_originate_timer() The function is implemented in ospf_lsa.c, move its "extern" declaration to ospf_lsa.h for consistency. --- ospfd/ospf_lsa.h | 1 + ospfd/ospf_zebra.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index bf3b083c..f364840f 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -275,6 +275,7 @@ extern struct in_addr ospf_get_ip_from_ifp (struct ospf_interface *); extern struct ospf_lsa *ospf_external_lsa_originate (struct ospf *, struct external_info *); extern int ospf_external_lsa_originate_timer (struct thread *); +extern int ospf_default_originate_timer (struct thread *); extern struct ospf_lsa *ospf_lsa_lookup (struct ospf_area *, u_int32_t, struct in_addr, struct in_addr); extern struct ospf_lsa *ospf_lsa_lookup_by_id (struct ospf_area *, diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index 3efd8958..fbb34442 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -50,8 +50,6 @@ extern void ospf_zebra_delete (struct prefix_ipv4 *, struct ospf_route *); extern void ospf_zebra_add_discard (struct prefix_ipv4 *); extern void ospf_zebra_delete_discard (struct prefix_ipv4 *); -extern int ospf_default_originate_timer (struct thread *); - extern int ospf_redistribute_check (struct ospf *, struct external_info *, int *); extern int ospf_distribute_check_connected (struct ospf *, -- cgit v1.2.1 From ce3cdcfbed2ca65d0d3a12b926dd1103910a6056 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 24 Oct 2011 18:17:09 +0400 Subject: ospfd: use IS_LSA_SELF() where appropriate --- ospfd/ospf_lsa.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index fa36a027..d5959eb1 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -2838,7 +2838,7 @@ ospf_maxage_lsa_remover (struct thread *thread) OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0); /* Remove LSA from the LSDB */ - if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)) + if (IS_LSA_SELF (lsa)) if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ", lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa); @@ -3389,7 +3389,7 @@ ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa) /* This LSA is already checked. */ if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED)) - return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); + return IS_LSA_SELF (lsa); /* Make sure LSA is self-checked. */ SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED); @@ -3414,11 +3414,11 @@ ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa) { /* to make it easier later */ SET_FLAG (lsa->flags, OSPF_LSA_SELF); - return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); + return IS_LSA_SELF (lsa); } } - return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF); + return IS_LSA_SELF (lsa); } /* Get unique Link State ID. */ @@ -3541,6 +3541,7 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa) struct external_info *ei; struct ospf_lsa *new = NULL; assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); + assert (IS_LSA_SELF (lsa)); assert (lsa->lock > 0); switch (lsa->data->type) @@ -3589,7 +3590,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa) u_int16_t index, current_index; assert (lsa->lock > 0); - assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); + assert (IS_LSA_SELF (lsa)); if (lsa->refresh_list < 0) { @@ -3632,7 +3633,7 @@ void ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa) { assert (lsa->lock > 0); - assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF)); + assert (IS_LSA_SELF (lsa)); if (lsa->refresh_list >= 0) { struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list]; -- cgit v1.2.1 From b4e45f67057be22133b6bec88cdf285d5c8214db Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 5 Dec 2011 16:35:14 +0400 Subject: fix zebra protocol after MP-BGP changes The previous commits modified both zebra and bgpd for additional SAFI field, but not any other routing daemon, which led to zebra daemon crashing with failed assertion. --- ospfd/ospf_zebra.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'ospfd') diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index bffa90db..f8d1cb7c 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -358,6 +358,7 @@ ospf_zebra_add (struct prefix_ipv4 *p, struct ospf_route *or) stream_putc (s, ZEBRA_ROUTE_OSPF); stream_putc (s, flags); stream_putc (s, message); + stream_putw (s, SAFI_UNICAST); /* Put prefix information. */ psize = PSIZE (p->prefixlen); @@ -427,6 +428,7 @@ ospf_zebra_delete (struct prefix_ipv4 *p, struct ospf_route *or) api.type = ZEBRA_ROUTE_OSPF; api.flags = 0; api.message = 0; + api.safi = SAFI_UNICAST; api.ifindex_num = 0; api.nexthop_num = 0; @@ -483,6 +485,7 @@ ospf_zebra_add_discard (struct prefix_ipv4 *p) api.type = ZEBRA_ROUTE_OSPF; api.flags = ZEBRA_FLAG_BLACKHOLE; api.message = 0; + api.safi = SAFI_UNICAST; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 0; api.ifindex_num = 0; @@ -505,6 +508,7 @@ ospf_zebra_delete_discard (struct prefix_ipv4 *p) api.type = ZEBRA_ROUTE_OSPF; api.flags = ZEBRA_FLAG_BLACKHOLE; api.message = 0; + api.safi = SAFI_UNICAST; SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP); api.nexthop_num = 0; api.ifindex_num = 0; -- cgit v1.2.1 From 272ca1e33016b1cbf9c72038d5e631b0adb04dc9 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 15 Jan 2012 19:12:19 +0400 Subject: ospfd: use LOOKUP() for ospf_packet_type_str * ospf_packet.h: add proper str/max extern declarations * ospf_packet.c * ospf_packet_type_str: rewrite in "struct message", add max value * ospf_packet_add(): use LOOKUP() * ospf_write(): ditto * ospf_hello(): ditto * ospf_read(): ditto * ospf_dump.h: the declaration does not belong here * ospf_dump.c * ospf_header_dump(): use LOOKUP() * show_debugging_ospf(): ditto --- ospfd/ospf_dump.c | 8 ++++---- ospfd/ospf_dump.h | 1 - ospfd/ospf_packet.c | 25 +++++++++++++------------ ospfd/ospf_packet.h | 3 +++ 4 files changed, 20 insertions(+), 17 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index e65b2e33..8ace0957 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -661,7 +661,7 @@ ospf_header_dump (struct ospf_header *ospfh) zlog_debug ("Header"); zlog_debug (" Version %d", ospfh->version); zlog_debug (" Type %d (%s)", ospfh->type, - ospf_packet_type_str[ospfh->type]); + LOOKUP (ospf_packet_type_str, ospfh->type)); zlog_debug (" Packet Len %d", ntohs (ospfh->length)); zlog_debug (" Router ID %s", inet_ntoa (ospfh->router_id)); zlog_debug (" Area ID %s", inet_ntoa (ospfh->area_id)); @@ -1457,7 +1457,7 @@ DEFUN (show_debugging_ospf, if (IS_DEBUG_OSPF_PACKET (i, SEND) && IS_DEBUG_OSPF_PACKET (i, RECV)) { vty_out (vty, " OSPF packet %s%s debugging is on%s", - ospf_packet_type_str[i + 1], + LOOKUP (ospf_packet_type_str, i + 1), IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "", VTY_NEWLINE); } @@ -1465,12 +1465,12 @@ DEFUN (show_debugging_ospf, { if (IS_DEBUG_OSPF_PACKET (i, SEND)) vty_out (vty, " OSPF packet %s send%s debugging is on%s", - ospf_packet_type_str[i + 1], + LOOKUP (ospf_packet_type_str, i + 1), IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "", VTY_NEWLINE); if (IS_DEBUG_OSPF_PACKET (i, RECV)) vty_out (vty, " OSPF packet %s receive%s debugging is on%s", - ospf_packet_type_str[i + 1], + LOOKUP (ospf_packet_type_str, i + 1), IS_DEBUG_OSPF_PACKET (i, DETAIL) ? " detail" : "", VTY_NEWLINE); } diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index fb813719..455214f5 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -121,7 +121,6 @@ extern unsigned long term_debug_ospf_zebra; extern unsigned long term_debug_ospf_nssa; /* Message Strings. */ -extern const char *ospf_packet_type_str[]; extern char *ospf_lsa_type_str[]; /* Prototypes. */ diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index b714c27d..a8102da4 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -50,15 +50,16 @@ #include "ospfd/ospf_dump.h" /* Packet Type String. */ -const char *ospf_packet_type_str[] = -{ - "unknown", - "Hello", - "Database Description", - "Link State Request", - "Link State Update", - "Link State Acknowledgment", +const struct message ospf_packet_type_str[] = +{ + { OSPF_MSG_HELLO, "Hello" }, + { OSPF_MSG_DB_DESC, "Database Description" }, + { OSPF_MSG_LS_REQ, "Link State Request" }, + { OSPF_MSG_LS_UPD, "Link State Update" }, + { OSPF_MSG_LS_ACK, "Link State Acknowledgment" }, }; +const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) / + sizeof (ospf_packet_type_str[0]); /* OSPF authentication checking function */ static int @@ -201,7 +202,7 @@ ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op) "destination %s) called with NULL obuf, ignoring " "(please report this bug)!\n", IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state), - ospf_packet_type_str[stream_getc_from(op->s, 1)], + LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)), inet_ntoa (op->dst)); return; } @@ -755,7 +756,7 @@ ospf_write (struct thread *thread) } zlog_debug ("%s sent to [%s] via [%s].", - ospf_packet_type_str[type], inet_ntoa (op->dst), + LOOKUP (ospf_packet_type_str, type), inet_ntoa (op->dst), IF_NAME (oi)); if (IS_DEBUG_OSPF_PACKET (type - 1, DETAIL)) @@ -801,7 +802,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh, { zlog_debug ("ospf_header[%s/%s]: selforiginated, " "dropping.", - ospf_packet_type_str[ospfh->type], + LOOKUP (ospf_packet_type_str, ospfh->type), inet_ntoa (iph->ip_src)); } return; @@ -2576,7 +2577,7 @@ ospf_read (struct thread *thread) } zlog_debug ("%s received from [%s] via [%s]", - ospf_packet_type_str[ospfh->type], + LOOKUP (ospf_packet_type_str, ospfh->type), inet_ntoa (ospfh->router_id), IF_NAME (oi)); zlog_debug (" src [%s],", inet_ntoa (iph->ip_src)); zlog_debug (" dst [%s]", inet_ntoa (iph->ip_dst)); diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 9a472081..2115f111 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -163,4 +163,7 @@ extern int ospf_ls_ack_timer (struct thread *); extern int ospf_poll_timer (struct thread *); extern int ospf_hello_reply_timer (struct thread *); +extern const struct message ospf_packet_type_str[]; +extern const size_t ospf_packet_type_str_max; + #endif /* _ZEBRA_OSPF_PACKET_H */ -- cgit v1.2.1 From 7e0e2cb14ca16ce9eaca3b0300c1ffa92a6a104b Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 20 Jan 2012 22:32:10 +0400 Subject: ospfd: fix ospf_packet_add_top() to use LOOKUP() --- ospfd/ospf_packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index a8102da4..876320ee 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -223,7 +223,7 @@ ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op) "destination %s) called with NULL obuf, ignoring " "(please report this bug)!\n", IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state), - ospf_packet_type_str[stream_getc_from(op->s, 1)], + LOOKUP (ospf_packet_type_str, stream_getc_from(op->s, 1)), inet_ntoa (op->dst)); return; } -- cgit v1.2.1 From 75c8eabbb5d3dc8aa21b61e8700ab939ce272f5c Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 30 Jan 2012 15:41:39 +0400 Subject: ospfd: introduce ospf_packet_minlen[] (BZ#705) This commit ports some of the OSPFv3 packet reception checks to OSPFv2. * ospf_packet.c * ospf_packet_minlen[]: a direct equivalent of ospf6_packet_minlen[] * ospf_packet_examin(): new function designed after the first part of ospf6_packet_examin() * ospf_read(): verify received packet with ospf_packet_examin() * ospf_packet.h: add convenience macros --- ospfd/ospf_packet.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-------- ospfd/ospf_packet.h | 4 ++++ 2 files changed, 60 insertions(+), 9 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 876320ee..d52430a3 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -61,6 +61,18 @@ const struct message ospf_packet_type_str[] = const size_t ospf_packet_type_str_max = sizeof (ospf_packet_type_str) / sizeof (ospf_packet_type_str[0]); +/* Minimum (besides OSPF_HEADER_SIZE) lengths for OSPF packets of + particular types, offset is the "type" field of a packet. */ +static const u_int16_t ospf_packet_minlen[] = +{ + 0, + OSPF_HELLO_MIN_SIZE, + OSPF_DB_DESC_MIN_SIZE, + OSPF_LS_REQ_MIN_SIZE, + OSPF_LS_UPD_MIN_SIZE, + OSPF_LS_ACK_MIN_SIZE, +}; + /* OSPF authentication checking function */ static int ospf_auth_type (struct ospf_interface *oi) @@ -2314,6 +2326,47 @@ ospf_check_sum (struct ospf_header *ospfh) return 1; } +/* Verify a complete OSPF packet for proper sizing/alignment. */ +static unsigned +ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) +{ + u_int16_t bytesdeclared; + + /* Length, 1st approximation. */ + if (bytesonwire < OSPF_HEADER_SIZE) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: undersized (%u B) packet", __func__, bytesonwire); + return MSG_NG; + } + /* Now it is safe to access header fields. Performing length check, allow + * for possible extra bytes of crypto auth/padding, which are not counted + * in the OSPF header "length" field. */ + bytesdeclared = ntohs (oh->length); + if (bytesdeclared > bytesonwire) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: packet length error (%u real, %u declared)", + __func__, bytesonwire, bytesdeclared); + return MSG_NG; + } + /* Length, 2nd approximation. The type-specific constraint is checked + against declared length, not amount of bytes on wire. */ + if + ( + oh->type >= OSPF_MSG_HELLO && + oh->type <= OSPF_MSG_LS_ACK && + bytesdeclared < OSPF_HEADER_SIZE + ospf_packet_minlen[oh->type] + ) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: undersized (%u B) %s packet", __func__, + bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type)); + return MSG_NG; + } + return MSG_OK; +} + /* OSPF Header verification. */ static int ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, @@ -2409,10 +2462,10 @@ ospf_read (struct thread *thread) /* prepare for next packet. */ ospf->t_read = thread_add_read (master, ospf_read, ospf, ospf->fd); - /* read OSPF packet. */ stream_reset(ospf->ibuf); if (!(ibuf = ospf_recv_packet (ospf->fd, &ifp, ospf->ibuf))) return -1; + /* This raw packet is known to be at least as big as its IP header. */ /* Note that there should not be alignment problems with this assignment because this is at the beginning of the stream data buffer. */ @@ -2447,16 +2500,10 @@ ospf_read (struct thread *thread) by ospf_recv_packet() to be correct). */ stream_forward_getp (ibuf, iph->ip_hl * 4); - /* Make sure the OSPF header is really there. */ - if (stream_get_endp (ibuf) - stream_get_getp (ibuf) < OSPF_HEADER_SIZE) - { - zlog_debug ("ospf_read: ignored OSPF packet with undersized (%u bytes) header", - stream_get_endp (ibuf) - stream_get_getp (ibuf)); + ospfh = (struct ospf_header *) STREAM_PNT (ibuf); + if (MSG_OK != ospf_packet_examin (ospfh, stream_get_endp (ibuf) - stream_get_getp (ibuf))) return -1; - } - /* Now it is safe to access all fields of OSPF packet header. */ - ospfh = (struct ospf_header *) STREAM_PNT (ibuf); /* associate packet with ospf interface */ oi = ospf_if_lookup_recv_if (ospf, iph->ip_src, ifp); diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 2115f111..3cbe8897 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -46,6 +46,10 @@ #define OSPF_HELLO_REPLY_DELAY 1 +/* Return values of functions involved in packet verification, see ospf6d. */ +#define MSG_OK 0 +#define MSG_NG 1 + struct ospf_packet { struct ospf_packet *next; -- cgit v1.2.1 From e52591481ed64e4cf9f26a76ad682ed7e6b451e7 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 30 Jan 2012 16:07:18 +0400 Subject: ospfd: review ospf_check_auth() 1. The only purpose of "ibuf" argument was to get stream size, which was always equal to OSPF_MAX_PACKET_SIZE + 1, exactly as initialized in ospf_new(). 2. Fix the packet size check condition, which was incorrect for very large packets, at least in theory. --- ospfd/ospf_packet.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index d52430a3..b18117b5 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2260,8 +2260,7 @@ ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src) } static int -ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf, - struct ospf_header *ospfh) +ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh) { int ret = 0; struct crypt_key *ck; @@ -2287,7 +2286,7 @@ ospf_check_auth (struct ospf_interface *oi, struct stream *ibuf, /* This is very basic, the digest processing is elsewhere */ if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE && ospfh->u.crypt.key_id == ck->key_id && - ntohs (ospfh->length) + OSPF_AUTH_SIMPLE_SIZE <= stream_get_size (ibuf)) + ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE <= OSPF_MAX_PACKET_SIZE) ret = 1; else ret = 0; @@ -2411,7 +2410,7 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, return -1; } - if (! ospf_check_auth (oi, ibuf, ospfh)) + if (! ospf_check_auth (oi, ospfh)) { zlog_warn ("interface %s: ospf_read authentication failed.", IF_NAME (oi)); -- cgit v1.2.1 From 2d8223c5472129eba89d630dc4f2688ebeae1dd8 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 30 Jan 2012 20:32:39 +0400 Subject: ospfd: review ospf_check_md5_digest() Rewrite some pointer arithmetics without the additional variables and move byte order conversion inside the function. --- ospfd/ospf_packet.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index b18117b5..15ec3733 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -304,24 +304,14 @@ ospf_packet_max (struct ospf_interface *oi) static int -ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s, - u_int16_t length) +ospf_check_md5_digest (struct ospf_interface *oi, struct ospf_header *ospfh) { - unsigned char *ibuf; MD5_CTX ctx; unsigned char digest[OSPF_AUTH_MD5_SIZE]; - unsigned char *pdigest; struct crypt_key *ck; - struct ospf_header *ospfh; struct ospf_neighbor *nbr; + u_int16_t length = ntohs (ospfh->length); - - ibuf = STREAM_PNT (s); - ospfh = (struct ospf_header *) ibuf; - - /* Get pointer to the end of the packet. */ - pdigest = ibuf + length; - /* Get secret key. */ ck = ospf_crypt_key_lookup (OSPF_IF_PARAM (oi, auth_crypt), ospfh->u.crypt.key_id); @@ -347,12 +337,12 @@ ospf_check_md5_digest (struct ospf_interface *oi, struct stream *s, /* Generate a digest for the ospf packet - their digest + our digest. */ memset(&ctx, 0, sizeof(ctx)); MD5Init(&ctx); - MD5Update(&ctx, ibuf, length); + MD5Update(&ctx, ospfh, length); MD5Update(&ctx, ck->auth_key, OSPF_AUTH_MD5_SIZE); MD5Final(digest, &ctx); /* compare the two */ - if (memcmp (pdigest, digest, OSPF_AUTH_MD5_SIZE)) + if (memcmp ((caddr_t)ospfh + length, digest, OSPF_AUTH_MD5_SIZE)) { zlog_warn ("interface %s: ospf_check_md5 checksum mismatch", IF_NAME (oi)); @@ -2431,7 +2421,7 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, { if (ospfh->checksum != 0) return -1; - if (ospf_check_md5_digest (oi, ibuf, ntohs (ospfh->length)) == 0) + if (ospf_check_md5_digest (oi, ospfh) == 0) { zlog_warn ("interface %s: ospf_read md5 authentication failed.", IF_NAME (oi)); -- cgit v1.2.1 From 4e31de792ec5e48a97360b5b86196b4fa02996a3 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Fri, 17 Feb 2012 16:20:50 +0400 Subject: ospfd: introduce ospf_lsa_minlen[] (BZ#705) This commit ports more packet checks to OSPFv2, in particular, LSA size verification and Router-LSA link blocks verification. * ospf_lsa.h: add LSA size macros * ospf_packet.h: add struct ospf_ls_update * ospf_packet.c * ospf_lsa_minlen[]: a direct equivalent of ospf6_lsa_minlen[] * ospf_router_lsa_links_examin(): new function, verifies trailing part of a Router-LSA * ospf_lsa_examin(): new function like ospf6_lsa_examin() * ospf_lsaseq_examin(): new function like ospf6_lsaseq_examin() * ospf_packet_examin(): add type-specific deeper level checks --- ospfd/ospf_lsa.h | 4 + ospfd/ospf_packet.c | 260 +++++++++++++++++++++++++++++++++++++++++++++++++++- ospfd/ospf_packet.h | 4 + 3 files changed, 267 insertions(+), 1 deletion(-) (limited to 'ospfd') diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index f364840f..297cd984 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -153,6 +153,7 @@ struct router_lsa_link }; /* OSPF Router-LSAs structure. */ +#define OSPF_ROUTER_LSA_MIN_SIZE 16U /* w/1 link descriptor */ struct router_lsa { struct lsa_header header; @@ -170,6 +171,7 @@ struct router_lsa }; /* OSPF Network-LSAs structure. */ +#define OSPF_NETWORK_LSA_MIN_SIZE 8U /* w/1 router-ID */ struct network_lsa { struct lsa_header header; @@ -178,6 +180,7 @@ struct network_lsa }; /* OSPF Summary-LSAs structure. */ +#define OSPF_SUMMARY_LSA_MIN_SIZE 8U /* w/1 TOS metric block */ struct summary_lsa { struct lsa_header header; @@ -187,6 +190,7 @@ struct summary_lsa }; /* OSPF AS-external-LSAs structure. */ +#define OSPF_AS_EXTERNAL_LSA_MIN_SIZE 16U /* w/1 TOS forwarding block */ struct as_external_lsa { struct lsa_header header; diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 15ec3733..68c25790 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -73,6 +73,24 @@ static const u_int16_t ospf_packet_minlen[] = OSPF_LS_ACK_MIN_SIZE, }; +/* Minimum (besides OSPF_LSA_HEADER_SIZE) lengths for LSAs of particular + types, offset is the "LSA type" field. */ +static const u_int16_t ospf_lsa_minlen[] = +{ + 0, + OSPF_ROUTER_LSA_MIN_SIZE, + OSPF_NETWORK_LSA_MIN_SIZE, + OSPF_SUMMARY_LSA_MIN_SIZE, + OSPF_SUMMARY_LSA_MIN_SIZE, + OSPF_AS_EXTERNAL_LSA_MIN_SIZE, + 0, + OSPF_AS_EXTERNAL_LSA_MIN_SIZE, + 0, + 0, + 0, + 0, +}; + /* OSPF authentication checking function */ static int ospf_auth_type (struct ospf_interface *oi) @@ -2315,11 +2333,199 @@ ospf_check_sum (struct ospf_header *ospfh) return 1; } +/* Verify, that given link/TOS records are properly sized/aligned and match + Router-LSA "# links" and "# TOS" fields as specified in RFC2328 A.4.2. */ +static unsigned +ospf_router_lsa_links_examin +( + struct router_lsa_link * link, + u_int16_t linkbytes, + const u_int16_t num_links +) +{ + unsigned counted_links = 0, thislinklen; + + while (linkbytes) + { + thislinklen = OSPF_ROUTER_LSA_LINK_SIZE + 4 * link->m[0].tos_count; + if (thislinklen > linkbytes) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: length error in link block #%u", __func__, counted_links); + return MSG_NG; + } + link = (struct router_lsa_link *)((caddr_t) link + thislinklen); + linkbytes -= thislinklen; + counted_links++; + } + if (counted_links != num_links) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: %u link blocks declared, %u present", + __func__, num_links, counted_links); + return MSG_NG; + } + return MSG_OK; +} + +/* Verify, that the given LSA is properly sized/aligned (including type-specific + minimum length constraint). */ +static unsigned +ospf_lsa_examin (struct lsa_header * lsah, const u_int16_t lsalen, const u_char headeronly) +{ + unsigned ret; + struct router_lsa * rlsa; + if + ( + lsah->type < OSPF_MAX_LSA && + ospf_lsa_minlen[lsah->type] && + lsalen < OSPF_LSA_HEADER_SIZE + ospf_lsa_minlen[lsah->type] + ) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: undersized (%u B) %s", + __func__, lsalen, LOOKUP (ospf_lsa_type_msg, lsah->type)); + return MSG_NG; + } + switch (lsah->type) + { + case OSPF_ROUTER_LSA: + /* RFC2328 A.4.2, LSA header + 4 bytes followed by N>=1 (12+)-byte link blocks */ + if (headeronly) + { + ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_ROUTER_LSA_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; + break; + } + rlsa = (struct router_lsa *) lsah; + ret = ospf_router_lsa_links_examin + ( + (struct router_lsa_link *) rlsa->link, + lsalen - OSPF_LSA_HEADER_SIZE - 4, /* skip: basic header, "flags", 0, "# links" */ + ntohs (rlsa->links) /* 16 bits */ + ); + break; + case OSPF_AS_EXTERNAL_LSA: + /* RFC2328 A.4.5, LSA header + 4 bytes followed by N>=1 12-bytes long blocks */ + case OSPF_AS_NSSA_LSA: + /* RFC3101 C, idem */ + ret = (lsalen - OSPF_LSA_HEADER_SIZE - OSPF_AS_EXTERNAL_LSA_MIN_SIZE) % 12 ? MSG_NG : MSG_OK; + break; + /* Following LSA types are considered OK length-wise as soon as their minimum + * length constraint is met and length of the whole LSA is a multiple of 4 + * (basic LSA header size is already a multiple of 4). */ + case OSPF_NETWORK_LSA: + /* RFC2328 A.4.3, LSA header + 4 bytes followed by N>=1 router-IDs */ + case OSPF_SUMMARY_LSA: + case OSPF_ASBR_SUMMARY_LSA: + /* RFC2328 A.4.4, LSA header + 4 bytes followed by N>=1 4-bytes TOS blocks */ +#ifdef HAVE_OPAQUE_LSA + case OSPF_OPAQUE_LINK_LSA: + case OSPF_OPAQUE_AREA_LSA: + case OSPF_OPAQUE_AS_LSA: + /* RFC5250 A.2, "some number of octets (of application-specific + * data) padded to 32-bit alignment." This is considered equivalent + * to 4-byte alignment of all other LSA types, see OSPF-ALIGNMENT.txt + * file for the detailed analysis of this passage. */ +#endif + ret = lsalen % 4 ? MSG_NG : MSG_OK; + break; + default: + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: unsupported LSA type 0x%02x", __func__, lsah->type); + return MSG_NG; + } + if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: alignment error in %s", + __func__, LOOKUP (ospf_lsa_type_msg, lsah->type)); + return ret; +} + +/* Verify if the provided input buffer is a valid sequence of LSAs. This + includes verification of LSA blocks length/alignment and dispatching + of deeper-level checks. */ +static unsigned +ospf_lsaseq_examin +( + struct lsa_header *lsah, /* start of buffered data */ + size_t length, + const u_char headeronly, + /* When declared_num_lsas is not 0, compare it to the real number of LSAs + and treat the difference as an error. */ + const u_int32_t declared_num_lsas +) +{ + u_int32_t counted_lsas = 0; + + while (length) + { + u_int16_t lsalen; + if (length < OSPF_LSA_HEADER_SIZE) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: undersized (%zu B) trailing (#%u) LSA header", + __func__, length, counted_lsas); + return MSG_NG; + } + /* save on ntohs() calls here and in the LSA validator */ + lsalen = ntohs (lsah->length); + if (lsalen < OSPF_LSA_HEADER_SIZE) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: malformed LSA header #%u, declared length is %u B", + __func__, counted_lsas, lsalen); + return MSG_NG; + } + if (headeronly) + { + /* less checks here and in ospf_lsa_examin() */ + if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 1)) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: malformed header-only LSA #%u", __func__, counted_lsas); + return MSG_NG; + } + lsah = (struct lsa_header *) ((caddr_t) lsah + OSPF_LSA_HEADER_SIZE); + length -= OSPF_LSA_HEADER_SIZE; + } + else + { + /* make sure the input buffer is deep enough before further checks */ + if (lsalen > length) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: anomaly in LSA #%u: declared length is %u B, buffered length is %zu B", + __func__, counted_lsas, lsalen, length); + return MSG_NG; + } + if (MSG_OK != ospf_lsa_examin (lsah, lsalen, 0)) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: malformed LSA #%u", __func__, counted_lsas); + return MSG_NG; + } + lsah = (struct lsa_header *) ((caddr_t) lsah + lsalen); + length -= lsalen; + } + counted_lsas++; + } + + if (declared_num_lsas && counted_lsas != declared_num_lsas) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: #LSAs declared (%u) does not match actual (%u)", + __func__, declared_num_lsas, counted_lsas); + return MSG_NG; + } + return MSG_OK; +} + /* Verify a complete OSPF packet for proper sizing/alignment. */ static unsigned ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) { u_int16_t bytesdeclared; + unsigned ret; + struct ospf_ls_update * lsupd; /* Length, 1st approximation. */ if (bytesonwire < OSPF_HEADER_SIZE) @@ -2353,7 +2559,59 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) bytesdeclared, LOOKUP (ospf_packet_type_str, oh->type)); return MSG_NG; } - return MSG_OK; + switch (oh->type) + { + case OSPF_MSG_HELLO: + /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed + by N>=0 router-IDs. */ + ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; + break; + case OSPF_MSG_DB_DESC: + /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed + by N>=0 header-only LSAs. */ + ret = ospf_lsaseq_examin + ( + (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE), + bytesonwire - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE, + 1, /* header-only LSAs */ + 0 + ); + break; + case OSPF_MSG_LS_REQ: + /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */ + ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) % + OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK; + break; + case OSPF_MSG_LS_UPD: + /* RFC2328 A.3.5, packet header + OSPF_LS_UPD_MIN_SIZE bytes followed + by N>=0 full LSAs (with N declared beforehand). */ + lsupd = (struct ospf_ls_update *) ((caddr_t) oh + OSPF_HEADER_SIZE); + ret = ospf_lsaseq_examin + ( + (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE), + bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE, + 0, /* full LSAs */ + ntohl (lsupd->num_lsas) /* 32 bits */ + ); + break; + case OSPF_MSG_LS_ACK: + /* RFC2328 A.3.6, packet header followed by N>=0 header-only LSAs. */ + ret = ospf_lsaseq_examin + ( + (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE), + bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE, + 1, /* header-only LSAs */ + 0 + ); + break; + default: + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: invalid packet type 0x%02x", __func__, oh->type); + return MSG_NG; + } + if (ret != MSG_OK && IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: malformed %s packet", __func__, LOOKUP (ospf_packet_type_str, oh->type)); + return ret; } /* OSPF Header verification. */ diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 3cbe8897..337686ad 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -121,6 +121,10 @@ struct ospf_db_desc u_int32_t dd_seqnum; }; +struct ospf_ls_update +{ + u_int32_t num_lsas; +}; /* Macros. */ /* XXX Perhaps obsolete; function in ospf_packet.c */ -- cgit v1.2.1 From b29adf9c3e69f298f748564a20abdf7274bbc549 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Mon, 20 Feb 2012 23:08:10 +0400 Subject: ospfd: fix packet length check for auth/LLS cases An OSPFv2 packet with trailing data blocks (authentication and/or link-local signaling) failed the recently implemented packet length check, because trailing data length isn't counted in the packet header "length" field. This commit fixes respective check conditions. * ospf_packet.c * ospf_packet_examin(): use "bytesdeclared" instead of "bytesonwire" --- ospfd/ospf_packet.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 68c25790..3d827296 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2564,7 +2564,7 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) case OSPF_MSG_HELLO: /* RFC2328 A.3.2, packet header + OSPF_HELLO_MIN_SIZE bytes followed by N>=0 router-IDs. */ - ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; + ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_HELLO_MIN_SIZE) % 4 ? MSG_NG : MSG_OK; break; case OSPF_MSG_DB_DESC: /* RFC2328 A.3.3, packet header + OSPF_DB_DESC_MIN_SIZE bytes followed @@ -2572,14 +2572,14 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) ret = ospf_lsaseq_examin ( (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_DB_DESC_MIN_SIZE), - bytesonwire - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE, + bytesdeclared - OSPF_HEADER_SIZE - OSPF_DB_DESC_MIN_SIZE, 1, /* header-only LSAs */ 0 ); break; case OSPF_MSG_LS_REQ: /* RFC2328 A.3.4, packet header followed by N>=0 12-bytes request blocks. */ - ret = (bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) % + ret = (bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_REQ_MIN_SIZE) % OSPF_LSA_KEY_SIZE ? MSG_NG : MSG_OK; break; case OSPF_MSG_LS_UPD: @@ -2589,7 +2589,7 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) ret = ospf_lsaseq_examin ( (struct lsa_header *) ((caddr_t) lsupd + OSPF_LS_UPD_MIN_SIZE), - bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE, + bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_UPD_MIN_SIZE, 0, /* full LSAs */ ntohl (lsupd->num_lsas) /* 32 bits */ ); @@ -2599,7 +2599,7 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) ret = ospf_lsaseq_examin ( (struct lsa_header *) ((caddr_t) oh + OSPF_HEADER_SIZE + OSPF_LS_ACK_MIN_SIZE), - bytesonwire - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE, + bytesdeclared - OSPF_HEADER_SIZE - OSPF_LS_ACK_MIN_SIZE, 1, /* header-only LSAs */ 0 ); -- cgit v1.2.1 From ef1b78cbcd8ade0c5444f3ff9dd00a40e760ec92 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 26 Feb 2012 17:00:57 +0400 Subject: ospfd: introduce ospf_auth_type_str[] --- ospfd/ospf_dump.c | 15 +++++++++++++-- ospfd/ospf_dump.h | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index 8ace0957..7e11e251 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -115,6 +115,16 @@ const struct message ospf_network_type_msg[] = }; const int ospf_network_type_msg_max = OSPF_IFTYPE_MAX; +/* AuType */ +const struct message ospf_auth_type_str[] = +{ + { OSPF_AUTH_NULL, "Null" }, + { OSPF_AUTH_SIMPLE, "Simple" }, + { OSPF_AUTH_CRYPTOGRAPHIC, "Cryptographic" }, +}; +const size_t ospf_auth_type_str_max = sizeof (ospf_auth_type_str) / + sizeof (ospf_auth_type_str[0]); + /* Configuration debug option variables. */ unsigned long conf_debug_ospf_packet[5] = {0, 0, 0, 0, 0}; unsigned long conf_debug_ospf_event = 0; @@ -657,6 +667,7 @@ static void ospf_header_dump (struct ospf_header *ospfh) { char buf[9]; + u_int16_t auth_type = ntohs (ospfh->auth_type); zlog_debug ("Header"); zlog_debug (" Version %d", ospfh->version); @@ -666,9 +677,9 @@ ospf_header_dump (struct ospf_header *ospfh) zlog_debug (" Router ID %s", inet_ntoa (ospfh->router_id)); zlog_debug (" Area ID %s", inet_ntoa (ospfh->area_id)); zlog_debug (" Checksum 0x%x", ntohs (ospfh->checksum)); - zlog_debug (" AuType %d", ntohs (ospfh->auth_type)); + zlog_debug (" AuType %s", LOOKUP (ospf_auth_type_str, auth_type)); - switch (ntohs (ospfh->auth_type)) + switch (auth_type) { case OSPF_AUTH_NULL: break; diff --git a/ospfd/ospf_dump.h b/ospfd/ospf_dump.h index 455214f5..a2d5e8ba 100644 --- a/ospfd/ospf_dump.h +++ b/ospfd/ospf_dump.h @@ -122,6 +122,8 @@ extern unsigned long term_debug_ospf_nssa; /* Message Strings. */ extern char *ospf_lsa_type_str[]; +extern const struct message ospf_auth_type_str[]; +extern const size_t ospf_auth_type_str_max; /* Prototypes. */ extern const char *ospf_area_name_string (struct ospf_area *); -- cgit v1.2.1 From bd5651f0ec7aa94627a2a6868dd458f016750a35 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Sun, 26 Feb 2012 17:59:43 +0400 Subject: ospfd: bring ospf_check_auth() into focus The old ospf_check_auth() function did two different jobs depending on AuType. For Null and Simple cases it actually authenticated the packet, but for Cryptographic case it only checked declared packet size (not taking the actual number of bytes on wire into account). The calling function, ospf_verify_header(), had its own set of MD5/checksum checks dispatched depending on AuType. This commit makes the packet size check work against the real number of bytes and moves it to ospf_packet_examine(). All MD5/checksum verification is now performed in ospf_check_auth() function. * ospf_packet.c * ospf_packet_examin(): check length with MD5 bytes in mind * ospf_verify_header(): remove all AuType-specific code * ospf_check_auth(): completely rewrite --- ospfd/ospf_packet.c | 170 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 100 insertions(+), 70 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 3d827296..4842c4e2 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -91,6 +91,9 @@ static const u_int16_t ospf_lsa_minlen[] = 0, }; +/* for ospf_check_auth() */ +static int ospf_check_sum (struct ospf_header *); + /* OSPF authentication checking function */ static int ospf_auth_type (struct ospf_interface *oi) @@ -2267,44 +2270,91 @@ ospf_check_network_mask (struct ospf_interface *oi, struct in_addr ip_src) return 0; } +/* Return 1, if the packet is properly authenticated and checksummed, + 0 otherwise. In particular, check that AuType header field is valid and + matches the locally configured AuType, and that D.5 requirements are met. */ static int ospf_check_auth (struct ospf_interface *oi, struct ospf_header *ospfh) { - int ret = 0; struct crypt_key *ck; + u_int16_t iface_auth_type; + u_int16_t pkt_auth_type = ntohs (ospfh->auth_type); - switch (ntohs (ospfh->auth_type)) + switch (pkt_auth_type) + { + case OSPF_AUTH_NULL: /* RFC2328 D.5.1 */ + if (OSPF_AUTH_NULL != (iface_auth_type = ospf_auth_type (oi))) { - case OSPF_AUTH_NULL: - ret = 1; - break; - case OSPF_AUTH_SIMPLE: - if (!memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE)) - ret = 1; - else - ret = 0; - break; - case OSPF_AUTH_CRYPTOGRAPHIC: - if ((ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) == NULL) - { - ret = 0; - break; - } - - /* This is very basic, the digest processing is elsewhere */ - if (ospfh->u.crypt.auth_data_len == OSPF_AUTH_MD5_SIZE && - ospfh->u.crypt.key_id == ck->key_id && - ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE <= OSPF_MAX_PACKET_SIZE) - ret = 1; - else - ret = 0; - break; - default: - ret = 0; - break; + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Null", + IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type)); + return 0; } - - return ret; + if (! ospf_check_sum (ospfh)) + { + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: Null auth OK, but checksum error, Router-ID %s", + IF_NAME (oi), inet_ntoa (ospfh->router_id)); + return 0; + } + return 1; + case OSPF_AUTH_SIMPLE: /* RFC2328 D.5.2 */ + if (OSPF_AUTH_SIMPLE != (iface_auth_type = ospf_auth_type (oi))) + { + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Simple", + IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type)); + return 0; + } + if (memcmp (OSPF_IF_PARAM (oi, auth_simple), ospfh->u.auth_data, OSPF_AUTH_SIMPLE_SIZE)) + { + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: Simple auth failed", IF_NAME (oi)); + return 0; + } + if (! ospf_check_sum (ospfh)) + { + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: Simple auth OK, checksum error, Router-ID %s", + IF_NAME (oi), inet_ntoa (ospfh->router_id)); + return 0; + } + return 1; + case OSPF_AUTH_CRYPTOGRAPHIC: /* RFC2328 D.5.3 */ + if (OSPF_AUTH_CRYPTOGRAPHIC != (iface_auth_type = ospf_auth_type (oi))) + { + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: auth-type mismatch, local %s, rcvd Cryptographic", + IF_NAME (oi), LOOKUP (ospf_auth_type_str, iface_auth_type)); + return 0; + } + if (ospfh->checksum) + { + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: OSPF header checksum is not 0", IF_NAME (oi)); + return 0; + } + /* only MD5 crypto method can pass ospf_packet_examin() */ + if + ( + NULL == (ck = listgetdata (listtail(OSPF_IF_PARAM (oi,auth_crypt)))) || + ospfh->u.crypt.key_id != ck->key_id || + /* Condition above uses the last key ID on the list, which is + different from what ospf_crypt_key_lookup() does. A bug? */ + ! ospf_check_md5_digest (oi, ospfh) + ) + { + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: MD5 auth failed", IF_NAME (oi)); + return 0; + } + return 1; + default: + if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + zlog_warn ("interface %s: invalid packet auth-type (%02x)", + IF_NAME (oi), pkt_auth_type); + return 0; + } } static int @@ -2523,7 +2573,7 @@ ospf_lsaseq_examin static unsigned ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) { - u_int16_t bytesdeclared; + u_int16_t bytesdeclared, bytesauth; unsigned ret; struct ospf_ls_update * lsupd; @@ -2538,11 +2588,24 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) * for possible extra bytes of crypto auth/padding, which are not counted * in the OSPF header "length" field. */ bytesdeclared = ntohs (oh->length); - if (bytesdeclared > bytesonwire) + if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) + bytesauth = 0; + else + { + if (oh->u.crypt.auth_data_len != OSPF_AUTH_MD5_SIZE) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: unsupported crypto auth length (%u B)", + __func__, oh->u.crypt.auth_data_len); + return MSG_NG; + } + bytesauth = OSPF_AUTH_MD5_SIZE; + } + if (bytesdeclared + bytesauth > bytesonwire) { if (IS_DEBUG_OSPF_PACKET (0, RECV)) - zlog_debug ("%s: packet length error (%u real, %u declared)", - __func__, bytesonwire, bytesdeclared); + zlog_debug ("%s: packet length error (%u real, %u+%u declared)", + __func__, bytesonwire, bytesdeclared, bytesauth); return MSG_NG; } /* Length, 2nd approximation. The type-specific constraint is checked @@ -2650,42 +2713,9 @@ ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, return -1; } - /* Check authentication. */ - if (ospf_auth_type (oi) != ntohs (ospfh->auth_type)) - { - zlog_warn ("interface %s: auth-type mismatch, local %d, rcvd %d", - IF_NAME (oi), ospf_auth_type (oi), ntohs (ospfh->auth_type)); - return -1; - } - + /* Check authentication. The function handles logging actions, where required. */ if (! ospf_check_auth (oi, ospfh)) - { - zlog_warn ("interface %s: ospf_read authentication failed.", - IF_NAME (oi)); - return -1; - } - - /* if check sum is invalid, packet is discarded. */ - if (ntohs (ospfh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) - { - if (! ospf_check_sum (ospfh)) - { - zlog_warn ("interface %s: ospf_read packet checksum error %s", - IF_NAME (oi), inet_ntoa (ospfh->router_id)); - return -1; - } - } - else - { - if (ospfh->checksum != 0) - return -1; - if (ospf_check_md5_digest (oi, ospfh) == 0) - { - zlog_warn ("interface %s: ospf_read md5 authentication failed.", - IF_NAME (oi)); - return -1; - } - } + return -1; return 0; } -- cgit v1.2.1 From aee567450eaf32877d00f47c4cc5d05c5fb85a51 Mon Sep 17 00:00:00 2001 From: Denis Ovsienko Date: Tue, 28 Feb 2012 15:15:29 +0400 Subject: ospfd: reduce ospf_verify_header() Protocol version checks fits ospf_packet_examin() better (like it is implemented in ospf6d), and packet type check is already there. --- ospfd/ospf_packet.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'ospfd') diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 4842c4e2..351fb210 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2587,6 +2587,12 @@ ospf_packet_examin (struct ospf_header * oh, const unsigned bytesonwire) /* Now it is safe to access header fields. Performing length check, allow * for possible extra bytes of crypto auth/padding, which are not counted * in the OSPF header "length" field. */ + if (oh->version != OSPF_VERSION) + { + if (IS_DEBUG_OSPF_PACKET (0, RECV)) + zlog_debug ("%s: invalid (%u) protocol version", __func__, oh->version); + return MSG_NG; + } bytesdeclared = ntohs (oh->length); if (ntohs (oh->auth_type) != OSPF_AUTH_CRYPTOGRAPHIC) bytesauth = 0; @@ -2682,21 +2688,6 @@ static int ospf_verify_header (struct stream *ibuf, struct ospf_interface *oi, struct ip *iph, struct ospf_header *ospfh) { - /* check version. */ - if (ospfh->version != OSPF_VERSION) - { - zlog_warn ("interface %s: ospf_read version number mismatch.", - IF_NAME (oi)); - return -1; - } - - /* Valid OSPFv2 packet types are 1 through 5 inclusive. */ - if (ospfh->type < 1 || ospfh->type > 5) - { - zlog_warn ("interface %s: invalid packet type %u", IF_NAME (oi), ospfh->type); - return -1; - } - /* Check Area ID. */ if (!ospf_check_area_id (oi, ospfh)) { -- cgit v1.2.1