diff options
Diffstat (limited to 'ripd')
-rw-r--r-- | ripd/rip_interface.c | 100 | ||||
-rw-r--r-- | ripd/ripd.c | 4 | ||||
-rw-r--r-- | ripd/ripd.h | 2 |
3 files changed, 104 insertions, 2 deletions
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index b4725225..2668e7dc 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -396,6 +396,106 @@ rip_if_ipv4_address_check (struct interface *ifp) return count; } + + + + +/* Does this address belongs to me ? */ +int +if_check_address (struct in_addr addr) +{ + listnode node; + + for (node = listhead (iflist); node; nextnode (node)) + { + listnode cnode; + struct interface *ifp; + + ifp = getdata (node); + + for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) + { + struct connected *connected; + struct prefix_ipv4 *p; + + connected = getdata (cnode); + p = (struct prefix_ipv4 *) connected->address; + + if (p->family != AF_INET) + continue; + + if (IPV4_ADDR_CMP (&p->prefix, &addr) == 0) + return 1; + } + } + return 0; +} + +/* is this address from a valid neighbor? (RFC2453 - Sec. 3.9.2) */ +int +if_valid_neighbor (struct in_addr addr) +{ + listnode node; + struct connected *connected = NULL; + struct prefix_ipv4 *p; + + for (node = listhead (iflist); node; nextnode (node)) + { + listnode cnode; + struct interface *ifp; + + ifp = getdata (node); + + for (cnode = listhead (ifp->connected); cnode; nextnode (cnode)) + { + struct prefix *pxn = NULL; /* Prefix of the neighbor */ + struct prefix *pxc = NULL; /* Prefix of the connected network */ + + connected = getdata (cnode); + + if (if_is_pointopoint (ifp)) + { + p = (struct prefix_ipv4 *) connected->address; + + if (p && p->family == AF_INET) + { + if (IPV4_ADDR_SAME (&p->prefix, &addr)) + return 1; + + p = (struct prefix_ipv4 *) connected->destination; + if (p && IPV4_ADDR_SAME (&p->prefix, &addr)) + return 1; + } + } + else + { + p = (struct prefix_ipv4 *) connected->address; + + if (p->family != AF_INET) + continue; + + pxn = prefix_new(); + pxn->family = AF_INET; + pxn->prefixlen = 32; + pxn->u.prefix4 = addr; + + pxc = prefix_new(); + prefix_copy(pxc, (struct prefix *) p); + apply_mask(pxc); + + if (prefix_match (pxc, pxn)) + { + prefix_free (pxn); + prefix_free (pxc); + return 1; + } + prefix_free(pxc); + prefix_free(pxn); + } + } + } + return 0; +} /* Inteface link down message processing. */ int diff --git a/ripd/ripd.c b/ripd/ripd.c index d2a6b4d4..68f49ac2 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1017,7 +1017,7 @@ rip_response_process (struct rip_packet *packet, int size, /* The datagram's IPv4 source address should be checked to see whether the datagram is from a valid neighbor; the source of the datagram must be on a directly connected network */ - if (if_lookup_address (from->sin_addr) == NULL) + if (! if_valid_neighbor (from->sin_addr)) { zlog_info ("This datagram doesn't came from a valid neighbor: %s", inet_ntoa (from->sin_addr)); @@ -1602,7 +1602,7 @@ rip_read (struct thread *t) } /* Check is this packet comming from myself? */ - if (if_lookup_exact_address (from.sin_addr)) + if (if_check_address (from.sin_addr)) { if (IS_RIP_DEBUG_PACKET) zlog_warn ("ignore packet comes from myself"); diff --git a/ripd/ripd.h b/ripd/ripd.h index c414c76d..dc2f64d0 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -374,6 +374,8 @@ void rip_zclient_init (); void rip_zclient_start (); void rip_zclient_reset (); void rip_offset_init (); +int if_check_address (struct in_addr addr); +int if_valid_neighbor (struct in_addr addr); int rip_request_send (struct sockaddr_in *, struct interface *, u_char); int rip_neighbor_lookup (struct sockaddr_in *); |