summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/ChangeLog13
-rw-r--r--zebra/irdp_packet.c137
2 files changed, 89 insertions, 61 deletions
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index fb8d0ab1..a6ac1fc3 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -1,3 +1,16 @@
+2004-10-05 Paul Jakma <paul@dishone.st>
+
+ * irdp_packet.c: (parse_irdp_packet) style issues.
+ Use sockopt_iphdrincl_swab_systoh.
+ Try unbork the code. Checksum the ICMP data and actually
+ compare it to received checksum. Check data length against
+ claimed length in header.
+ Always use ntoh.. when accessing addresses, even when the
+ comparison happens to be endian-safe.
+ (send_packet) minor style isues. Use
+ sockopt_iphdrincl_swab_htosys.
+ (irdp_iph_hton/ntoh) IP header to/from network/host order.
+
2004-10-03 Gilad Arnold <gilad.arnold at terayon.com>
* interface.c, interface.h: A new prefix tree of connected subnets is
diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c
index 67609b31..60604353 100644
--- a/zebra/irdp_packet.c
+++ b/zebra/irdp_packet.c
@@ -82,79 +82,88 @@ void parse_irdp_packet(char *p,
struct ip *ip = (struct ip *)p ;
struct icmphdr *icmp;
struct in_addr src;
- int ip_hlen, ip_len;
+ int ip_hlen, iplen, datalen;
struct zebra_if *zi;
struct irdp_interface *irdp;
zi = ifp->info;
- if(!zi) return;
+ if (!zi)
+ return;
irdp = &zi->irdp;
- if(!irdp) return;
+ if (!irdp)
+ return;
- ip_hlen = ip->ip_hl*4;
- ip_len = ntohs(ip->ip_len);
- len = len - ip_hlen;
+ ip_hlen = ip->ip_hl << 2;
+
+ sockopt_iphdrincl_swab_systoh (ip);
+
+ iplen = ip->ip_len;
+ datalen = len - ip_hlen;
src = ip->ip_src;
- if(ip_len < ICMP_MINLEN) {
- zlog_err ("IRDP: RX ICMP packet too short from %s\n",
- inet_ntoa (src));
- return;
- }
+ if (len != iplen)
+ {
+ zlog_err ("IRDP: RX length doesnt match IP length");
+ return;
+ }
+ if (iplen < ICMP_MINLEN)
+ {
+ zlog_err ("IRDP: RX ICMP packet too short from %s\n",
+ inet_ntoa (src));
+ return;
+ }
+
+ /* XXX: RAW doesnt receive link-layer, surely? ??? */
/* Check so we don't checksum packets longer than oure RX_BUF - (ethlen +
len of IP-header) 14+20 */
-
- if(ip_len > IRDP_RX_BUF-34) {
- zlog_err ("IRDP: RX ICMP packet too long from %s\n",
- inet_ntoa (src));
- return;
- }
-
-
- if (in_cksum (ip, ip_len)) {
- zlog_warn ("IRDP: RX ICMP packet from %s. Bad checksum, silently ignored",
- inet_ntoa (src));
- return;
- }
+ if (iplen > IRDP_RX_BUF-34)
+ {
+ zlog_err ("IRDP: RX ICMP packet too long from %s\n",
+ inet_ntoa (src));
+ return;
+ }
icmp = (struct icmphdr *) (p+ip_hlen);
-
+ /* check icmp checksum */
+ if (in_cksum (icmp, datalen) != icmp->checksum)
+ {
+ zlog_warn ("IRDP: RX ICMP packet from %s. Bad checksum, silently ignored",
+ inet_ntoa (src));
+ return;
+ }
+
/* Handle just only IRDP */
-
- if( icmp->type == ICMP_ROUTERADVERT);
- else if( icmp->type == ICMP_ROUTERSOLICIT);
- else return;
-
-
- if (icmp->code != 0) {
- zlog_warn ("IRDP: RX packet type %d from %s. Bad ICMP type code, silently ignored",
- icmp->type,
- inet_ntoa (src));
+ if (!(icmp->type == ICMP_ROUTERADVERT
+ || icmp->type == ICMP_ROUTERSOLICIT))
return;
- }
-
- if(ip->ip_dst.s_addr == INADDR_BROADCAST &&
- irdp->flags & IF_BROADCAST);
-
- else if ( ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP &&
- ! (irdp->flags & IF_BROADCAST));
-
- else { /* ERROR */
-
- zlog_warn ("IRDP: RX illegal from %s to %s while %s operates in %s\n",
- inet_ntoa (src),
- ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP?
- "multicast" : inet_ntoa(ip->ip_dst),
- ifp->name,
- irdp->flags & IF_BROADCAST?
- "broadcast" : "multicast");
+
+ if (icmp->code != 0)
+ {
+ zlog_warn ("IRDP: RX packet type %d from %s. Bad ICMP type code,"
+ " silently ignored",
+ icmp->type, inet_ntoa (src));
+ return;
+ }
- zlog_warn ("IRDP: Please correct settings\n");
- return;
- }
+ if (! ((ntohl (ip->ip_dst.s_addr) == INADDR_BROADCAST)
+ && (irdp->flags & IF_BROADCAST))
+ ||
+ (ntohl (ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP
+ && !(irdp->flags & IF_BROADCAST)))
+ {
+ zlog_warn ("IRDP: RX illegal from %s to %s while %s operates in %s\n",
+ inet_ntoa (src),
+ ntohl (ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP ?
+ "multicast" : inet_ntoa (ip->ip_dst),
+ ifp->name,
+ irdp->flags & IF_BROADCAST ? "broadcast" : "multicast");
+
+ zlog_warn ("IRDP: Please correct settings\n");
+ return;
+ }
switch (icmp->type)
{
@@ -182,7 +191,6 @@ int irdp_recvmsg (int sock, u_char *buf, int size, int *ifindex)
{
struct msghdr msg;
struct iovec iov;
- struct cmsghdr *ptr;
char adata[CMSG_SPACE( SOPT_SIZE_CMSG_PKTINFO_IPV4() )];
int ret;
@@ -255,10 +263,12 @@ int irdp_read_raw(struct thread *r)
}
parse_irdp_packet(buf, ret, ifp);
+
return ret;
}
-void send_packet(struct interface *ifp,
+void
+send_packet(struct interface *ifp,
struct stream *s,
u_int32_t dst,
struct prefix *p,
@@ -276,10 +286,13 @@ void send_packet(struct interface *ifp,
u_long src;
int on;
- if (! (ifp->flags & IFF_UP)) return;
+ if (!(ifp->flags & IFF_UP))
+ return;
- if(!p) src = ntohl(p->u.prefix4.s_addr);
- else src = 0; /* Is filled in */
+ if (!p)
+ src = ntohl(p->u.prefix4.s_addr);
+ else
+ src = 0; /* Is filled in */
ip = (struct ip *) buf;
ip->ip_hl = sizeof(struct ip) >> 2;
@@ -290,7 +303,7 @@ void send_packet(struct interface *ifp,
ip->ip_ttl = ttl;
ip->ip_src.s_addr = src;
ip->ip_dst.s_addr = dst;
- icmp = (struct icmphdr *) (buf + 20);
+ icmp = (struct icmphdr *) (buf + sizeof (struct ip));
/* Merge IP header with icmp packet */
@@ -343,6 +356,8 @@ void send_packet(struct interface *ifp,
msg->msg_control = cmsg;
msg->msg_controllen = cmsg->cmsg_len;
+ sockopt_iphdrincl_swab_htosys (ip);
+
if (sendmsg(irdp_sock, msg, 0) < 0) {
zlog_warn("sendto %s", strerror (errno));
}