summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2009-11-09 23:22:53 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2009-11-09 23:22:53 +0100
commit4ac7c8341c660db654821ed2dc0273645dc19645 (patch)
tree246c5cd54ab5a851a6f7a8397515e0e0f61fbbe7
parent3f22fa9e74c8643d3e4f7e3a7b4f2aa992ad09f5 (diff)
downloadbird-4ac7c8341c660db654821ed2dc0273645dc19645.tar
bird-4ac7c8341c660db654821ed2dc0273645dc19645.zip
Use IPv6 checksums in OSPFv3.
-rw-r--r--lib/socket.h4
-rw-r--r--proto/ospf/iface.c6
-rw-r--r--proto/ospf/packet.c1
-rw-r--r--sysdep/unix/io.c19
4 files changed, 28 insertions, 2 deletions
diff --git a/lib/socket.h b/lib/socket.h
index f44e8e8..c642bdf 100644
--- a/lib/socket.h
+++ b/lib/socket.h
@@ -60,6 +60,10 @@ int sk_setup_multicast(sock *s);
int sk_join_group(sock *s, ip_addr maddr);
int sk_leave_group(sock *s, ip_addr maddr);
+#ifdef IPV6
+int sk_set_ipv6_checksum(sock *s, int offset);
+#endif
+
static inline int
sk_send_buffer_empty(sock *sk)
{
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c
index 9b65961..e98414f 100644
--- a/proto/ospf/iface.c
+++ b/proto/ospf/iface.c
@@ -89,6 +89,12 @@ ospf_open_socket(struct ospf_iface *ifa, int mc)
if (sk_open(ipsk) != 0)
goto err;
+#ifdef OSPFv3
+ /* 12 is an offset of the checksum in an OSPF packet */
+ if (sk_set_ipv6_checksum(ipsk, 12) < 0)
+ goto err;
+#endif
+
if (mc)
{
if (sk_setup_multicast(ipsk) < 0)
diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c
index 9422a9f..94ec010 100644
--- a/proto/ospf/packet.c
+++ b/proto/ospf/packet.c
@@ -320,7 +320,6 @@ ospf_rx_hook(sock * sk, int size)
return 1;
}
- /* FIXME - handle checksums in OSPFv3 */
#ifdef OSPFv2
if ((ps->autype != htons(OSPF_AUTH_CRYPT)) &&
(!ipsum_verify(ps, 16, (void *) ps + sizeof(struct ospf_packet),
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index 3eb2e03..cd5c5db 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -782,13 +782,30 @@ int
sk_set_broadcast(sock *s, int enable)
{
if (setsockopt(s->fd, SOL_SOCKET, SO_BROADCAST, &enable, sizeof(enable)) < 0)
- log(L_ERR "sk_set_broadcast: SO_BROADCAST: %m");
+ {
+ log(L_ERR "sk_set_broadcast: SO_BROADCAST: %m");
+ return -1;
+ }
+
+ return 0;
}
#ifdef IPV6
int
+sk_set_ipv6_checksum(sock *s, int offset)
+{
+ if (setsockopt(s->fd, IPPROTO_IPV6, IPV6_CHECKSUM, &offset, sizeof(offset)) < 0)
+ {
+ log(L_ERR "sk_set_ipv6_checksum: IPV6_CHECKSUM: %m");
+ return -1;
+ }
+
+ return 0;
+}
+
+int
sk_setup_multicast(sock *s)
{
char *err;