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.
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index fb8d0ab..a6ac1fc 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 67609b3..6060435 100644
--- a/zebra/irdp_packet.c
+++ b/zebra/irdp_packet.c
@@ -82,79 +82,88 @@
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 (icmp->code != 0)
+ {
+ zlog_warn ("IRDP: RX packet type %d from %s. Bad ICMP type code,"
+ " silently ignored",
+ icmp->type, inet_ntoa (src));
+ return;
+ }
- if(ip->ip_dst.s_addr == INADDR_BROADCAST &&
- irdp->flags & IF_BROADCAST);
+ 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");
- 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");
-
- zlog_warn ("IRDP: Please correct settings\n");
- return;
- }
+ zlog_warn ("IRDP: Please correct settings\n");
+ return;
+ }
switch (icmp->type)
{
@@ -182,7 +191,6 @@
{
struct msghdr msg;
struct iovec iov;
- struct cmsghdr *ptr;
char adata[CMSG_SPACE( SOPT_SIZE_CMSG_PKTINFO_IPV4() )];
int ret;
@@ -255,10 +263,12 @@
}
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 @@
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 @@
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 @@
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));
}