diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c index 3d8ec50a..54dd71fe 100644 --- a/proto/ospf/dbdes.c +++ b/proto/ospf/dbdes.c @@ -182,26 +182,11 @@ ospf_dbdes_reqladd(struct ospf_dbdes_packet *ps, struct ospf_neighbor *n) void ospf_dbdes_receive(struct ospf_dbdes_packet *ps, - struct ospf_iface *ifa, u16 size) + struct ospf_iface *ifa, struct ospf_neighbor *n) { struct proto *p = (struct proto *) ifa->proto; - u32 nrid, myrid = p->cf->global->router_id; - struct ospf_neighbor *n; - - nrid = ntohl(((struct ospf_packet *) ps)->routerid); - - - if ((n = find_neigh(ifa, nrid)) == NULL) - { - OSPF_TRACE(D_PACKETS, "Received dbdes from unknown neigbor! %I.", nrid); - return; - } - - if (ifa->iface->mtu < size) - { - OSPF_TRACE(D_PACKETS, "Received dbdes larger than MTU from %I!", n->ip); - return; - } + u32 myrid = p->cf->global->router_id; + unsigned int size = ntohs(ps->ospf_packet.length); OSPF_TRACE(D_PACKETS, "Received dbdes from %I via %s.", n->ip, ifa->iface->name); diff --git a/proto/ospf/dbdes.h b/proto/ospf/dbdes.h index b332ecb2..c5ffe590 100644 --- a/proto/ospf/dbdes.h +++ b/proto/ospf/dbdes.h @@ -12,6 +12,6 @@ void ospf_dbdes_send(struct ospf_neighbor *n); void ospf_dbdes_receive(struct ospf_dbdes_packet *ps, - struct ospf_iface *ifa, u16 size); + struct ospf_iface *ifa, struct ospf_neighbor *n); #endif /* _BIRD_OSPF_DBDES_H_ */ diff --git a/proto/ospf/hello.c b/proto/ospf/hello.c index 6e1fa92a..a318a674 100644 --- a/proto/ospf/hello.c +++ b/proto/ospf/hello.c @@ -10,18 +10,14 @@ void ospf_hello_receive(struct ospf_hello_packet *ps, - struct ospf_iface *ifa, int size, ip_addr faddr) + struct ospf_iface *ifa, struct ospf_neighbor *n, ip_addr faddr) { - u32 nrid, *pnrid; - struct ospf_neighbor *n; - u8 i, twoway, oldpriority; + u32 *pnrid; ip_addr olddr, oldbdr; ip_addr mask; char *beg = "Bad OSPF hello packet from ", *rec = " received: "; - int eligible = 0; struct proto *p = (struct proto *) ifa->proto; - - nrid = ntohl(((struct ospf_packet *) ps)->routerid); + unsigned int size = ntohs(ps->ospf_packet.length), i, twoway, oldpriority, eligible = 0; OSPF_TRACE(D_PACKETS, "Received hello from %I via %s", faddr, ifa->iface->name); @@ -30,7 +26,7 @@ ospf_hello_receive(struct ospf_hello_packet *ps, if ((unsigned) ipa_mklen(mask) != ifa->iface->addr->pxlen) { - log(L_ERR, "%s%I%sbad netmask %I.", beg, nrid, rec, mask); + log(L_ERR "%s%I%sbad netmask %I.", beg, faddr, rec, mask); return; } @@ -54,7 +50,7 @@ ospf_hello_receive(struct ospf_hello_packet *ps, return; } - if ((n = find_neigh(ifa, nrid)) == NULL) + if (!n) { if ((ifa->type == OSPF_IT_NBMA)) { @@ -92,7 +88,7 @@ ospf_hello_receive(struct ospf_hello_packet *ps, n = ospf_neighbor_new(ifa); - n->rid = nrid; + n->rid = ntohl(((struct ospf_packet *) ps)->routerid); n->ip = faddr; n->dr = ps->dr; ipa_ntoh(n->dr); diff --git a/proto/ospf/hello.h b/proto/ospf/hello.h index 5b41857c..d5359352 100644 --- a/proto/ospf/hello.h +++ b/proto/ospf/hello.h @@ -11,7 +11,7 @@ #define _BIRD_OSPF_HELLO_H_ void ospf_hello_receive(struct ospf_hello_packet *ps, - struct ospf_iface *ifa, int size, ip_addr faddr); -void ospf_hello_send(timer * timer, int poll, struct ospf_neighbor *dirn); + struct ospf_iface *ifa, struct ospf_neighbor *n, ip_addr faddr); +void ospf_hello_send(timer *timer, int poll, struct ospf_neighbor *dirn); #endif /* _BIRD_OSPF_HELLO_H_ */ diff --git a/proto/ospf/lsack.c b/proto/ospf/lsack.c index 3a4e9652..7d7238c2 100644 --- a/proto/ospf/lsack.c +++ b/proto/ospf/lsack.c @@ -119,25 +119,13 @@ ospf_lsack_send(struct ospf_neighbor *n, int queue) void ospf_lsack_receive(struct ospf_lsack_packet *ps, - struct ospf_iface *ifa, u16 size) + struct ospf_iface *ifa, struct ospf_neighbor *n) { - u32 nrid, myrid; - struct ospf_neighbor *n; struct ospf_lsa_header lsa, *plsa; - u16 nolsa, i; + u16 nolsa; struct top_hash_entry *en; - u16 lenn = ntohs(ps->ospf_packet.length); struct proto *p = (struct proto *) ifa->proto; - - nrid = ntohl(ps->ospf_packet.routerid); - - myrid = p->cf->global->router_id; - - if ((n = find_neigh(ifa, nrid)) == NULL) - { - OSPF_TRACE(D_PACKETS, "Received LS ack from unknown neigbor! (%I)", nrid); - return; - } + unsigned int size = ntohs(ps->ospf_packet.length), i; OSPF_TRACE(D_PACKETS, "Received LS ack from %I", n->ip); ospf_neigh_sm(n, INM_HELLOREC); @@ -145,10 +133,10 @@ ospf_lsack_receive(struct ospf_lsack_packet *ps, if (n->state < NEIGHBOR_EXCHANGE) return; - nolsa = (lenn - sizeof(struct ospf_lsack_packet)) / + nolsa = (size - sizeof(struct ospf_lsack_packet)) / sizeof(struct ospf_lsa_header); - if ((nolsa < 1) || ((lenn - sizeof(struct ospf_lsack_packet)) != + if ((nolsa < 1) || ((size - sizeof(struct ospf_lsack_packet)) != (nolsa * sizeof(struct ospf_lsa_header)))) { log(L_ERR "Received corrupted LS ack from %I", n->ip); diff --git a/proto/ospf/lsack.h b/proto/ospf/lsack.h index d56abc54..05cc22f0 100644 --- a/proto/ospf/lsack.h +++ b/proto/ospf/lsack.h @@ -17,7 +17,7 @@ struct lsah_n }; void ospf_lsack_receive(struct ospf_lsack_packet *ps, - struct ospf_iface *ifa, u16 size); + struct ospf_iface *ifa, struct ospf_neighbor *n); void ospf_lsack_send(struct ospf_neighbor *n, int queue); void ospf_lsack_enqueue(struct ospf_neighbor *n, struct ospf_lsa_header *h, int queue); diff --git a/proto/ospf/lsreq.c b/proto/ospf/lsreq.c index 046e1495..98d2d06c 100644 --- a/proto/ospf/lsreq.c +++ b/proto/ospf/lsreq.c @@ -66,36 +66,27 @@ ospf_lsreq_send(struct ospf_neighbor *n) void ospf_lsreq_receive(struct ospf_lsreq_packet *ps, - struct ospf_iface *ifa, u16 size) + struct ospf_iface *ifa, struct ospf_neighbor *n) { - u32 nrid; - struct ospf_neighbor *n; struct ospf_lsreq_header *lsh; struct l_lsr_head *llsh; list uplist; slab *upslab; - int length, i, lsano; + unsigned int size = ntohs(ps->ospf_packet.length); + int i, lsano; struct proto *p = (struct proto *) ifa->proto; - nrid = ntohl(ps->ospf_packet.routerid); - - if ((n = find_neigh(ifa, nrid)) == NULL) - { - OSPF_TRACE(D_PACKETS, "Received lsreq from unknown neighbor! (%I)", nrid); - return; - } if (n->state < NEIGHBOR_EXCHANGE) return; OSPF_TRACE(D_EVENTS, "Received LS req from neighbor: %I", n->ip); ospf_neigh_sm(n, INM_HELLOREC); - length = ntohs(ps->ospf_packet.length); lsh = (void *) (ps + 1); init_list(&uplist); upslab = sl_new(n->pool, sizeof(struct l_lsr_head)); - lsano = (length - sizeof(struct ospf_lsreq_packet)) / + lsano = (size - sizeof(struct ospf_lsreq_packet)) / sizeof(struct ospf_lsreq_header); for (i = 0; i < lsano; lsh++, i++) { diff --git a/proto/ospf/lsreq.h b/proto/ospf/lsreq.h index 90a4e82b..f917f05c 100644 --- a/proto/ospf/lsreq.h +++ b/proto/ospf/lsreq.h @@ -12,6 +12,6 @@ void ospf_lsreq_send(struct ospf_neighbor *n); void ospf_lsreq_receive(struct ospf_lsreq_packet *ps, - struct ospf_iface *ifa, u16 size); + struct ospf_iface *ifa, struct ospf_neighbor *n); #endif /* _BIRD_OSPF_LSREQ_H_ */ diff --git a/proto/ospf/lsupd.c b/proto/ospf/lsupd.c index 52531bf5..2211891f 100644 --- a/proto/ospf/lsupd.c +++ b/proto/ospf/lsupd.c @@ -283,24 +283,15 @@ ospf_lsupd_send_list(struct ospf_neighbor *n, list * l) void ospf_lsupd_receive(struct ospf_lsupd_packet *ps, - struct ospf_iface *ifa, u16 size) + struct ospf_iface *ifa, struct ospf_neighbor *n) { - u32 area, nrid; - struct ospf_neighbor *n, *ntmp; + u32 area; + struct ospf_neighbor *ntmp; struct ospf_lsa_header *lsa; struct ospf_area *oa; struct proto_ospf *po = ifa->proto; struct proto *p = (struct proto *) po; - u8 i; - int sendreq = 1; - - nrid = ntohl(ps->ospf_packet.routerid); - - if ((n = find_neigh(ifa, nrid)) == NULL) - { - OSPF_TRACE(D_PACKETS, "Received lsupd from unknown neighbor! (%I)", nrid); - return; - } + unsigned int i, sendreq = 1, size = ntohs(ps->ospf_packet.length); if (n->state < NEIGHBOR_EXCHANGE) { @@ -329,8 +320,8 @@ ospf_lsupd_receive(struct ospf_lsupd_packet *ps, { struct ospf_lsa_header lsatmp; struct top_hash_entry *lsadb; - int diff = ((u8 *) lsa) - ((u8 *) ps); - u16 chsum, lenn = ntohs(lsa->length); + unsigned diff = ((u8 *) lsa) - ((u8 *) ps), lenn = ntohs(lsa->length); + u16 chsum; if (((diff + sizeof(struct ospf_lsa_header)) >= size) || ((lenn + diff) > size)) diff --git a/proto/ospf/lsupd.h b/proto/ospf/lsupd.h index 8c046759..64d9aeff 100644 --- a/proto/ospf/lsupd.h +++ b/proto/ospf/lsupd.h @@ -12,7 +12,7 @@ void ospf_lsupd_send_list(struct ospf_neighbor *n, list * l); void ospf_lsupd_receive(struct ospf_lsupd_packet *ps, - struct ospf_iface *ifa, u16 size); + struct ospf_iface *ifa, struct ospf_neighbor *n); int ospf_lsupd_flood(struct ospf_neighbor *n, struct ospf_lsa_header *hn, struct ospf_lsa_header *hh, struct ospf_iface *iff, struct ospf_area *oa, int rtl); diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 714ca806..ef3066ed 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -84,6 +84,8 @@ ospf_rx_hook(sock * sk, int size) struct ospf_packet *ps; struct ospf_iface *ifa = (struct ospf_iface *) (sk->data); struct proto *p = (struct proto *) (ifa->proto); + struct ospf_neighbor *n; + char *mesg = "Bad OSPF packet from "; if (ifa->stub) return (1); @@ -93,65 +95,71 @@ ospf_rx_hook(sock * sk, int size) ps = (struct ospf_packet *) ipv4_skip_header(sk->rbuf, &size); if (ps == NULL) { - log("%s: Bad OSPF packet received: bad IP header", p->name); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - bad IP header", mesg, sk->faddr); + return 1; } if ((unsigned) size < sizeof(struct ospf_packet)) { - log("%s: Bad OSPF packet received: too short (%u bytes)", p->name, size); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - too short (%u bytes)", mesg, sk->faddr, size); + return 1; } if ((ntohs(ps->length) != size) || (size != (4 * (size / 4)))) { - log("%s: Bad OSPF packet received: size field does not match", p->name); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - size field does not match", mesg, sk->faddr); + return 1; } if (ps->version != OSPF_VERSION) { - log("%s: Bad OSPF packet received: version %u", p->name, ps->version); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - version %u", mesg, sk->faddr, ps->version); + return 1; } if (!ipsum_verify(ps, 16, (void *) ps + sizeof(struct ospf_packet), ntohs(ps->length) - sizeof(struct ospf_packet), NULL)) { - log("%s: Bad OSPF packet received: bad checksum", p->name); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - bad checksum", mesg, sk->faddr); + return 1; } if (!ospf_rx_authenticate(ifa, ps)) { - log("%s: Bad OSPF packet received: bad password", p->name); - return (1); + log(L_ERR "%s%I - bad password", mesg, sk->faddr); + return 1; } if (ntohl(ps->areaid) != ifa->an) { - log("%s: Bad OSPF packet received: other area %ld", p->name, ps->areaid); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - other area %ld", mesg, sk->faddr, ps->areaid); + return 1; } if (ntohl(ps->routerid) == p->cf->global->router_id) { - log("%s: Bad OSPF packet received: received my own router ID!", p->name); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - received my own router ID!", mesg, sk->faddr); + return 1; } if (ntohl(ps->routerid) == 0) { - log("%s: Bad OSPF packet received: Id 0.0.0.0 is not allowed.", p->name); - log("%s: Discarding", p->name); - return (1); + log(L_ERR "%s%I - router id = 0.0.0.0", mesg, sk->faddr); + return 1; + } + + if ((unsigned) size > ifa->iface->mtu) + { + log(L_ERR "%s%I - received larger packet than MTU", mesg, sk->faddr); + return 1; + } + + n = find_neigh(ifa, ntohl(((struct ospf_packet *) ps)->routerid)); + + if(!n && (ps->type != HELLO_P)) + { + OSPF_TRACE(D_PACKETS, "Received non-hello packet from uknown neighbor (%I)", sk->faddr); + return 1; } /* Dump packet @@ -166,30 +174,29 @@ ospf_rx_hook(sock * sk, int size) { case HELLO_P: DBG("%s: Hello received.\n", p->name); - ospf_hello_receive((struct ospf_hello_packet *) ps, ifa, size, sk->faddr); + ospf_hello_receive((struct ospf_hello_packet *) ps, ifa, n, sk->faddr); break; case DBDES_P: DBG("%s: Database description received.\n", p->name); - ospf_dbdes_receive((struct ospf_dbdes_packet *) ps, ifa, size); + ospf_dbdes_receive((struct ospf_dbdes_packet *) ps, ifa, n); break; case LSREQ_P: DBG("%s: Link state request received.\n", p->name); - ospf_lsreq_receive((struct ospf_lsreq_packet *) ps, ifa, size); + ospf_lsreq_receive((struct ospf_lsreq_packet *) ps, ifa, n); break; case LSUPD_P: DBG("%s: Link state update received.\n", p->name); - ospf_lsupd_receive((struct ospf_lsupd_packet *) ps, ifa, size); + ospf_lsupd_receive((struct ospf_lsupd_packet *) ps, ifa, n); break; case LSACK_P: DBG("%s: Link state ack received.\n", p->name); - ospf_lsack_receive((struct ospf_lsack_packet *) ps, ifa, size); + ospf_lsack_receive((struct ospf_lsack_packet *) ps, ifa, n); break; default: - log("%s: Bad packet received: wrong type %u", p->name, ps->type); - log("%s: Discarding\n", p->name); - return (1); + log(L_ERR "%s%I - wrong type %u", mesg, sk->faddr, ps->type); + return 1; }; - return (1); + return 1; } void