diff options
Diffstat (limited to 'proto')
-rw-r--r-- | proto/ospf/config.Y | 6 | ||||
-rw-r--r-- | proto/ospf/iface.c | 5 | ||||
-rw-r--r-- | proto/ospf/ospf.h | 4 | ||||
-rw-r--r-- | proto/ospf/packet.c | 6 | ||||
-rw-r--r-- | proto/rip/config.Y | 13 | ||||
-rw-r--r-- | proto/rip/rip.c | 13 | ||||
-rw-r--r-- | proto/rip/rip.h | 2 |
7 files changed, 40 insertions, 9 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index d9379a7c..f042e1aa 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -127,8 +127,8 @@ CF_KEYWORDS(OSPF, AREA, OSPF_METRIC1, OSPF_METRIC2, OSPF_TAG, OSPF_ROUTER_ID) CF_KEYWORDS(NEIGHBORS, RFC1583COMPAT, STUB, TICK, COST, COST2, RETRANSMIT) CF_KEYWORDS(HELLO, TRANSMIT, PRIORITY, DEAD, TYPE, BROADCAST, BCAST) CF_KEYWORDS(NONBROADCAST, NBMA, POINTOPOINT, PTP, POINTOMULTIPOINT, PTMP) -CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC) -CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK) +CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC, TTL, SECURITY) +CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK, ONLY) CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL) CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY) CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF, INSTANCE, REAL, NETMASK, TX, PRIORITY) @@ -307,6 +307,8 @@ ospf_iface_item: | RX BUFFER expr { OSPF_PATT->rxbuf = $3 ; if (($3 < OSPF_RXBUF_MINSIZE) || ($3 > OSPF_MAX_PKT_SIZE)) cf_error("Buffer size must be in range 256-65535"); } | TX tos { OSPF_PATT->tx_tos = $2; } | TX PRIORITY expr { OSPF_PATT->tx_priority = $3; } + | TTL SECURITY bool { OSPF_PATT->ttl_security = $3; } + | TTL SECURITY TX ONLY { OSPF_PATT->ttl_security = 2; } | password_list ; diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c index bc3b1ef6..698ef620 100644 --- a/proto/ospf/iface.c +++ b/proto/ospf/iface.c @@ -86,7 +86,7 @@ ospf_sk_open(struct ospf_iface *ifa) sk->rbsize = rxbufsize(ifa); sk->tbsize = rxbufsize(ifa); sk->data = (void *) ifa; - sk->flags = SKF_LADDR_RX; + sk->flags = SKF_LADDR_RX | (ifa->check_ttl ? SKF_TTL_RX : 0); if (sk_open(sk) != 0) goto err; @@ -131,7 +131,7 @@ ospf_sk_open(struct ospf_iface *ifa) else { ifa->all_routers = AllSPFRouters; - sk->ttl = 1; /* Hack, this will affect just multicast packets */ + sk->ttl = ifa->cf->ttl_security ? 255 : 1; if (sk_setup_multicast(sk) < 0) goto err; @@ -534,6 +534,7 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i ifa->rxbuf = ip->rxbuf; ifa->check_link = ip->check_link; ifa->ecmp_weight = ip->ecmp_weight; + ifa->check_ttl = (ip->ttl_security == 1); #ifdef OSPFv2 ifa->autype = ip->autype; diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h index 56ebcd31..f1409af3 100644 --- a/proto/ospf/ospf.h +++ b/proto/ospf/ospf.h @@ -275,6 +275,7 @@ struct ospf_iface u8 check_link; /* Whether iface link change is used */ u8 ecmp_weight; /* Weight used for ECMP */ u8 ptp_netmask; /* Send real netmask for P2P */ + u8 check_ttl; /* Check incoming packets for TTL 255 */ }; struct ospf_md5 @@ -815,7 +816,8 @@ struct ospf_iface_patt u8 check_link; u8 ecmp_weight; u8 real_bcast; /* Not really used in OSPFv3 */ - u8 ptp_netmask; /* bool but 2 for unspecified */ + u8 ptp_netmask; /* bool + 2 for unspecified */ + u8 ttl_security; /* bool + 2 for TX only */ #ifdef OSPFv2 list *passwords; diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index 241a58f7..4338bc1a 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -309,6 +309,12 @@ ospf_rx_hook(sock *sk, int size) return 1; } + if (ifa->check_ttl && (sk->ttl < 255)) + { + log(L_ERR "%s%I - TTL %d (< 255)", mesg, sk->faddr, sk->ttl); + return 1; + } + if ((unsigned) size < sizeof(struct ospf_packet)) { log(L_ERR "%s%I - too short (%u bytes)", mesg, sk->faddr, size); diff --git a/proto/rip/config.Y b/proto/rip/config.Y index ec82aa3d..791c43a2 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -22,12 +22,18 @@ CF_DEFINES #define RIP_CFG ((struct rip_proto_config *) this_proto) #define RIP_IPATT ((struct rip_patt *) this_ipatt) +#ifdef IPV6 +#define RIP_DEFAULT_TTL_SECURITY 2 +#else +#define RIP_DEFAULT_TTL_SECURITY 0 +#endif + CF_DECLS CF_KEYWORDS(RIP, INFINITY, METRIC, PORT, PERIOD, GARBAGE, TIMEOUT, MODE, BROADCAST, MULTICAST, QUIET, NOLISTEN, VERSION1, - AUTHENTICATION, NONE, PLAINTEXT, MD5, - HONOR, NEVER, NEIGHBOR, ALWAYS, TX, PRIORITY, + AUTHENTICATION, NONE, PLAINTEXT, MD5, TTL, SECURITY, + HONOR, NEVER, NEIGHBOR, ALWAYS, TX, PRIORITY, ONLY, RIP_METRIC, RIP_TAG) %type <i> rip_mode rip_auth @@ -78,6 +84,8 @@ rip_iface_item: | MODE rip_mode { RIP_IPATT->mode |= $2; } | TX tos { RIP_IPATT->tx_tos = $2; } | TX PRIORITY expr { RIP_IPATT->tx_priority = $3; } + | TTL SECURITY bool { RIP_IPATT->ttl_security = $3; } + | TTL SECURITY TX ONLY { RIP_IPATT->ttl_security = 2; } ; rip_iface_opts: @@ -98,6 +106,7 @@ rip_iface_init: RIP_IPATT->metric = 1; RIP_IPATT->tx_tos = IP_PREC_INTERNET_CONTROL; RIP_IPATT->tx_priority = sk_priority_control; + RIP_IPATT->ttl_security = RIP_DEFAULT_TTL_SECURITY; } ; diff --git a/proto/rip/rip.c b/proto/rip/rip.c index c09eae79..3ec070b3 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -480,6 +480,14 @@ rip_rx(sock *s, int size) iface = i->iface; #endif + if (i->check_ttl && (s->ttl < 255)) + { + log( L_REMOTE "%s: Discarding packet with TTL %d (< 255) from %I on %s", + p->name, s->ttl, s->faddr, i->iface->name); + return 1; + } + + CHK_MAGIC; DBG( "RIP: message came: %d bytes from %I via %s\n", size, s->faddr, i->iface ? i->iface->name : "(dummy)" ); size -= sizeof( struct rip_packet_heading ); @@ -686,6 +694,7 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_ rif->mode = PATT->mode; rif->metric = PATT->metric; rif->multicast = (!(PATT->mode & IM_BROADCAST)) && (flags & IF_MULTICAST); + rif->check_ttl = (PATT->ttl_security == 1); } /* lookup multicasts over unnumbered links - no: rip is not defined over unnumbered links */ @@ -706,10 +715,10 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_ rif->sock->dport = P_CF->port; if (new) { - rif->sock->ttl = 1; rif->sock->tos = PATT->tx_tos; rif->sock->priority = PATT->tx_priority; - rif->sock->flags = SKF_LADDR_RX; + rif->sock->ttl = PATT->ttl_security ? 255 : 1; + rif->sock->flags = SKF_LADDR_RX | (rif->check_ttl ? SKF_TTL_RX : 0); } if (new) { diff --git a/proto/rip/rip.h b/proto/rip/rip.h index 2cce8c81..6e0d5aad 100644 --- a/proto/rip/rip.h +++ b/proto/rip/rip.h @@ -114,6 +114,7 @@ struct rip_interface { struct rip_connection *busy; int metric; /* You don't want to put struct rip_patt *patt here -- think about reconfigure */ int mode; + int check_ttl; /* Check incoming packets for TTL 255 */ int triggered; struct object_lock *lock; int multicast; @@ -130,6 +131,7 @@ struct rip_patt { #define IM_VERSION1 16 int tx_tos; int tx_priority; + int ttl_security; /* bool + 2 for TX only (send, but do not check on RX) */ }; struct rip_proto_config { |