summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2007-10-09 06:26:48 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2007-10-09 06:26:48 +0000
commit055eb141dc8359bab78fff9bd129b0fc5f07eddf (patch)
tree375fbb17b6cf399cf4dac6de8eb7ced1f74bdf34
parentc9f9203edf9f32a6ebf3f0f1407751437b1ac315 (diff)
Remaining bit of last night work. Make packet reception use all the goodies
introduced (checksumming is no longer needed, no IP header checking is needed, get a in6_pktinfo with the ifindex and dest addr, cleanup and remove a lot of other code). With this ospf6d is able to send and receive first hello packets. OK norby@
-rw-r--r--usr.sbin/ospf6d/hello.c10
-rw-r--r--usr.sbin/ospf6d/ospfe.h4
-rw-r--r--usr.sbin/ospf6d/packet.c125
3 files changed, 49 insertions, 90 deletions
diff --git a/usr.sbin/ospf6d/hello.c b/usr.sbin/ospf6d/hello.c
index 4e3f3d42710..fa872a3f9af 100644
--- a/usr.sbin/ospf6d/hello.c
+++ b/usr.sbin/ospf6d/hello.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hello.c,v 1.1 2007/10/08 10:44:50 norby Exp $ */
+/* $OpenBSD: hello.c,v 1.2 2007/10/09 06:26:47 claudio Exp $ */
/*
* Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
@@ -121,7 +121,7 @@ fail:
}
void
-recv_hello(struct iface *iface, struct in6_addr src, u_int32_t rtr_id,
+recv_hello(struct iface *iface, struct in6_addr *src, u_int32_t rtr_id,
char *buf, u_int16_t len)
{
struct hello_hdr hello;
@@ -157,7 +157,7 @@ XXX
return;
}
- if (ntohl(hello.rtr_dead_interval) != iface->dead_interval) {
+ if (ntohs(hello.rtr_dead_interval) != iface->dead_interval) {
log_warnx("recv_hello: invalid router-dead-interval %d, "
"interface %s", ntohl(hello.rtr_dead_interval),
iface->name);
@@ -190,7 +190,7 @@ XXX
if (nbr == iface->self)
continue;
//XXX if (nbr->addr.s_addr == src.s_addr)
- if (IN6_ARE_ADDR_EQUAL(&nbr->addr, &src))
+ if (IN6_ARE_ADDR_EQUAL(&nbr->addr, src))
break;
}
break;
@@ -209,7 +209,7 @@ XXX
/* actually the neighbor address shouldn't be stored on virtual links */
//XXX nbr->addr.s_addr = src.s_addr;
- nbr->addr = src;
+ nbr->addr = *src;
nbr->options = hello.opts3; /* XXX */
nbr_fsm(nbr, NBR_EVT_HELLO_RCVD);
diff --git a/usr.sbin/ospf6d/ospfe.h b/usr.sbin/ospf6d/ospfe.h
index 6629dd07a4b..903d982f17c 100644
--- a/usr.sbin/ospf6d/ospfe.h
+++ b/usr.sbin/ospf6d/ospfe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ospfe.h,v 1.2 2007/10/09 06:17:40 claudio Exp $ */
+/* $OpenBSD: ospfe.h,v 1.3 2007/10/09 06:26:47 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -105,7 +105,7 @@ void stop_db_tx_timer(struct nbr *);
/* hello.c */
int send_hello(struct iface *);
-void recv_hello(struct iface *, struct in6_addr, u_int32_t,
+void recv_hello(struct iface *, struct in6_addr *, u_int32_t,
char *, u_int16_t);
/* ospfe.c */
diff --git a/usr.sbin/ospf6d/packet.c b/usr.sbin/ospf6d/packet.c
index 2e833c48c27..a872050f665 100644
--- a/usr.sbin/ospf6d/packet.c
+++ b/usr.sbin/ospf6d/packet.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: packet.c,v 1.1 2007/10/08 10:44:50 norby Exp $ */
+/* $OpenBSD: packet.c,v 1.2 2007/10/09 06:26:47 claudio Exp $ */
/*
* Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -38,9 +38,10 @@
#include "ospfe.h"
int ip_hdr_sanity_check(const struct ip6_hdr *, u_int16_t);
-int ospf_hdr_sanity_check(const struct ip6_hdr *,
- struct ospf_hdr *, u_int16_t, const struct iface *);
-struct iface *find_iface(struct ospfd_conf *, unsigned int, struct in6_addr);
+int ospf_hdr_sanity_check(struct ospf_hdr *, u_int16_t,
+ const struct iface *, struct in6_addr *);
+struct iface *find_iface(struct ospfd_conf *, unsigned int,
+ struct in6_addr *);
int
gen_ospf_hdr(struct buf *buf, struct iface *iface, u_int8_t type)
@@ -71,8 +72,7 @@ upd_ospf_hdr(struct buf *buf, struct iface *iface)
if (buf->wpos > USHRT_MAX)
fatalx("upd_ospf_hdr: resulting ospf packet too big");
ospf_hdr->len = htons((u_int16_t)buf->wpos);
-
- ospf_hdr->chksum = in_cksum(buf->buf, buf->wpos); /* XXX */
+ ospf_hdr->chksum = 0; /* calculated via IPV6_CHECKSUM */
return (0);
}
@@ -101,10 +101,8 @@ send_packet(struct iface *iface, void *pkt, size_t len,
return (-1);
}
-
- log_debug("send_packet: iface %d addr %s", iface->ifindex,
- log_in6addr(&iface->addr));
- log_debug("send_packet: dest %s", log_in6addr(&dst->sin6_addr));
+ log_debug("send_packet: iface %d addr %s dest %s", iface->ifindex,
+ log_in6addr(&iface->addr), log_in6addr(&dst->sin6_addr));
if (sendmsg(iface->fd, &msg, MSG_DONTROUTE) == -1) {
log_warn("send_packet: error sending packet on interface %s",
iface->name);
@@ -117,11 +115,11 @@ send_packet(struct iface *iface, void *pkt, size_t len,
void
recv_packet(int fd, short event, void *bula)
{
- char cbuf[CMSG_SPACE(sizeof(struct sockaddr_dl))];
+ char cbuf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
struct msghdr msg;
struct iovec iov;
- struct ip6_hdr ip_hdr;
- struct in6_addr addr;
+ struct in6_addr addr, dest;
+ struct sockaddr_in6 src;
struct ospfd_conf *xconf = bula;
struct ospf_hdr *ospf_hdr;
struct iface *iface;
@@ -140,6 +138,8 @@ recv_packet(int fd, short event, void *bula)
bzero(&msg, sizeof(msg));
iov.iov_base = buf = pkt_ptr;
iov.iov_len = READ_BUF_SIZE;
+ msg.msg_name = &src;
+ msg.msg_namelen = sizeof(src);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cbuf;
@@ -154,32 +154,20 @@ recv_packet(int fd, short event, void *bula)
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == IPPROTO_IPV6 &&
- cmsg->cmsg_type == IP_RECVIF) {
- ifindex = ((struct sockaddr_dl *)
- CMSG_DATA(cmsg))->sdl_index;
+ cmsg->cmsg_type == IPV6_PKTINFO) {
+ ifindex = ((struct in6_pktinfo *)
+ CMSG_DATA(cmsg))->ipi6_ifindex;
+ dest = ((struct in6_pktinfo *)
+ CMSG_DATA(cmsg))->ipi6_addr;
break;
}
}
- len = (u_int16_t)r;
-
- /* IP header sanity checks */
- if (len < sizeof(ip_hdr)) {
- log_warnx("recv_packet: bad packet size");
- return;
- }
- memcpy(&ip_hdr, buf, sizeof(ip_hdr));
- if ((l = ip_hdr_sanity_check(&ip_hdr, len)) == -1)
- return;
- buf += l;
- len -= l;
-
/* find a matching interface */
- if ((iface = find_iface(xconf, ifindex, ip_hdr.ip6_src)) == NULL) {
+ if ((iface = find_iface(xconf, ifindex, &src.sin6_addr)) == NULL) {
/* XXX add a counter here */
return;
}
-#if 1
/*
* Packet needs to be sent to AllSPFRouters or AllDRouters
* or to the address of the interface itself.
@@ -187,19 +175,19 @@ recv_packet(int fd, short event, void *bula)
*/
inet_pton(AF_INET6, AllSPFRouters, &addr);
- if (!IN6_ARE_ADDR_EQUAL(&ip_hdr.ip6_dst, &addr)) {
+ if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) {
inet_pton(AF_INET6, AllDRouters, &addr);
- if (!IN6_ARE_ADDR_EQUAL(&ip_hdr.ip6_dst, &addr)) {
- if (!IN6_ARE_ADDR_EQUAL(&ip_hdr.ip6_dst,
- &iface->addr)) {
+ if (!IN6_ARE_ADDR_EQUAL(&dest, &addr)) {
+ if (!IN6_ARE_ADDR_EQUAL(&dest, &iface->addr)) {
log_debug("recv_packet: packet sent to wrong "
"address %s, interface %s",
- log_in6addr(&ip_hdr.ip6_dst), iface->name);
+ log_in6addr(&dest), iface->name);
return;
}
}
}
-#endif
+
+ len = (u_int16_t)r;
/* OSPF header sanity checks */
if (len < sizeof(*ospf_hdr)) {
log_debug("recv_packet: bad packet size");
@@ -207,7 +195,7 @@ recv_packet(int fd, short event, void *bula)
}
ospf_hdr = (struct ospf_hdr *)buf;
- if ((l = ospf_hdr_sanity_check(&ip_hdr, ospf_hdr, len, iface)) == -1)
+ if ((l = ospf_hdr_sanity_check(ospf_hdr, len, iface, &dest)) == -1)
return;
nbr = nbr_find_id(iface, ospf_hdr->rtr_id);
@@ -216,12 +204,6 @@ recv_packet(int fd, short event, void *bula)
return;
}
- if (in_cksum(buf, len)) {
- log_warnx("recv_packet: invalid checksum, "
- "interface %s", iface->name);
- return;
- }
-
buf += sizeof(*ospf_hdr);
len = l - sizeof(*ospf_hdr);
@@ -229,13 +211,13 @@ recv_packet(int fd, short event, void *bula)
switch (ospf_hdr->type) {
case PACKET_TYPE_HELLO:
inet_pton(AF_INET6, AllDRouters, &addr);
- if (IN6_ARE_ADDR_EQUAL(&ip_hdr.ip6_dst, &addr)) {
+ if (IN6_ARE_ADDR_EQUAL(&dest, &addr)) {
log_debug("recv_packet: invalid destination IP "
"address");
break;
}
- recv_hello(iface, ip_hdr.ip6_src, ospf_hdr->rtr_id, buf, len);
+ recv_hello(iface, &src.sin6_addr, ospf_hdr->rtr_id, buf, len);
break;
case PACKET_TYPE_DD:
recv_db_description(nbr, buf, len);
@@ -256,25 +238,8 @@ recv_packet(int fd, short event, void *bula)
}
int
-ip_hdr_sanity_check(const struct ip6_hdr *ip_hdr, u_int16_t len)
-{
- if (ntohs(ip_hdr->ip6_plen) != len) {
- log_debug("recv_packet: invalid IP packet length %u",
- ntohs(ip_hdr->ip6_plen));
- return (-1);
- }
-
- if (ip_hdr->ip6_nxt != IPPROTO_OSPF)
- /* this is enforced by the socket itself */
- fatalx("recv_packet: invalid IP proto");
-
-//XXX return (ip_hdr->ip_hl << 2);
- return (sizeof(struct ip6_hdr));
-}
-
-int
-ospf_hdr_sanity_check(const struct ip6_hdr *ip_hdr, struct ospf_hdr *ospf_hdr,
- u_int16_t len, const struct iface *iface)
+ospf_hdr_sanity_check(struct ospf_hdr *ospf_hdr, u_int16_t len,
+ const struct iface *iface, struct in6_addr *dst)
{
struct in6_addr addr;
struct in_addr id;
@@ -311,7 +276,7 @@ ospf_hdr_sanity_check(const struct ip6_hdr *ip_hdr, struct ospf_hdr *ospf_hdr,
if (iface->type == IF_TYPE_BROADCAST || iface->type == IF_TYPE_NBMA) {
if (inet_pton(AF_INET6, AllDRouters, &addr) == 0)
fatalx("recv_packet: inet_pton");
- if (IN6_ARE_ADDR_EQUAL(&ip_hdr->ip6_dst, &addr) &&
+ if (IN6_ARE_ADDR_EQUAL(dst, &addr) &&
(iface->state & IF_STA_DRORBDR) == 0) {
log_debug("recv_packet: invalid destination IP in "
"state %s, interface %s",
@@ -324,38 +289,32 @@ ospf_hdr_sanity_check(const struct ip6_hdr *ip_hdr, struct ospf_hdr *ospf_hdr,
}
struct iface *
-find_iface(struct ospfd_conf *xconf, unsigned int ifindex, struct in6_addr src)
+find_iface(struct ospfd_conf *xconf, unsigned int ifindex, struct in6_addr *src)
{
- struct area *area = NULL;
- struct iface *iface = NULL;
+ struct area *area;
+ struct iface *iface, *match = NULL;
- /* returned interface needs to be active */
+ /*
+ * Returned interface needs to be active.
+ * Virtual-Links have higher precedence so the full interface
+ * list needs to be scanned for possible matches.
+ */
LIST_FOREACH(area, &xconf->area_list, entry) {
LIST_FOREACH(iface, &area->iface_list, entry) {
switch (iface->type) {
case IF_TYPE_VIRTUALLINK:
- if (IN6_ARE_ADDR_EQUAL(&src, &iface->dst) &&
- !iface->passive)
- return (iface);
- break;
- case IF_TYPE_POINTOPOINT:
- if (ifindex == iface->ifindex &&
- IN6_ARE_ADDR_EQUAL(&iface->dst, &src) &&
+ if (IN6_ARE_ADDR_EQUAL(src, &iface->dst) &&
!iface->passive)
return (iface);
break;
default:
-#if 0
if (ifindex == iface->ifindex &&
- (iface->addr.s_addr & iface->mask.s_addr) ==
- (src.s_addr & iface->mask.s_addr) &&
!iface->passive)
- return (iface);
-#endif
+ match = iface;
break;
}
}
}
- return (NULL);
+ return (match);
}