summaryrefslogtreecommitdiff
path: root/sysdep/bsd
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2014-02-06 17:46:01 +0100
committerOndrej Zajicek <santiago@crfreenet.org>2014-02-06 17:46:01 +0100
commit48e5f32db676645640f84ab3d630cce975aa6b20 (patch)
treeb940fc8156b3e0c18aab6c339a066bdb7a9ec1e0 /sysdep/bsd
parentf48fa14214301382b2e6b134788a7506b61b664f (diff)
Many changes in I/O and OSPF sockets and packet handling.
I/O: - BSD: specify src addr on IP sockets by IP_HDRINCL - BSD: specify src addr on UDP sockets by IP_SENDSRCADDR - Linux: specify src addr on IP/UDP sockets by IP_PKTINFO - IPv6: specify src addr on IP/UDP sockets by IPV6_PKTINFO - Alternative SKF_BIND flag for binding to IP address - Allows IP/UDP sockets without tx_hook, on these sockets a packet is discarded when TX queue is full - Use consistently SOL_ for socket layer values. OSPF: - Packet src addr is always explicitly set - Support for secondary addresses in BSD - Dynamic RX/TX buffers - Fixes some minor buffer overruns - Interface option 'tx length' - Names for vlink pseudoifaces (vlinkX) - Vlinks use separate socket for TX - Vlinks do not use fixed associated iface - Fixes TTL for direct unicast packets - Fixes DONTROUTE for OSPF sockets - Use ifa->ifname instead of ifa->iface->name
Diffstat (limited to 'sysdep/bsd')
-rw-r--r--sysdep/bsd/sysio.h53
1 files changed, 31 insertions, 22 deletions
diff --git a/sysdep/bsd/sysio.h b/sysdep/bsd/sysio.h
index cf049a0b..e45deb6f 100644
--- a/sysdep/bsd/sysio.h
+++ b/sysdep/bsd/sysio.h
@@ -38,18 +38,13 @@ get_inaddr(ip_addr *a, struct in6_addr *ia)
ipa_ntoh(*a);
}
-static inline char *
-sysio_bind_to_iface(sock *s)
-{
- /* Unfortunately not available */
- return NULL;
-}
-
#else
#include <net/if.h>
#include <net/if_dl.h>
+#include <netinet/in_systm.h> // Workaround for some BSDs
+#include <netinet/ip.h>
static inline void
set_inaddr(struct in_addr * ia, ip_addr a)
@@ -93,7 +88,7 @@ sysio_setup_multicast(sock *s)
static inline char *
sysio_join_group(sock *s, ip_addr maddr)
{
- struct ip_mreq mreq;
+ struct ip_mreq mreq;
bzero(&mreq, sizeof(mreq));
set_inaddr(&mreq.imr_interface, s->iface->addr->ip);
@@ -152,7 +147,7 @@ sysio_register_cmsgs(sock *s)
return NULL;
}
-static void
+static inline void
sysio_process_rx_cmsgs(sock *s, struct msghdr *msg)
{
struct cmsghdr *cm;
@@ -190,26 +185,17 @@ sysio_process_rx_cmsgs(sock *s, struct msghdr *msg)
}
/* Unfortunately, IP_SENDSRCADDR does not work for raw IP sockets on BSD kernels */
-/*
-static void
+
+static inline void
sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
{
+#ifdef IP_SENDSRCADDR
struct cmsghdr *cm;
struct in_addr *sa;
- if (!(s->flags & SKF_LADDR_TX))
- return;
-
msg->msg_control = cbuf;
msg->msg_controllen = cbuflen;
- if (s->iface)
- {
- struct in_addr m;
- set_inaddr(&m, s->saddr);
- setsockopt(s->fd, IPPROTO_IP, IP_MULTICAST_IF, &m, sizeof(m));
- }
-
cm = CMSG_FIRSTHDR(msg);
cm->cmsg_level = IPPROTO_IP;
cm->cmsg_type = IP_SENDSRCADDR;
@@ -219,8 +205,31 @@ sysio_prepare_tx_cmsgs(sock *s, struct msghdr *msg, void *cbuf, size_t cbuflen)
set_inaddr(sa, s->saddr);
msg->msg_controllen = cm->cmsg_len;
+#endif
+}
+
+
+static void
+fill_ip_header(sock *s, void *hdr, int dlen)
+{
+ struct ip *ip = hdr;
+
+ bzero(ip, 20);
+
+ ip->ip_v = 4;
+ ip->ip_hl = 5;
+ ip->ip_tos = (s->tos < 0) ? 0 : s->tos;
+ ip->ip_len = 20 + dlen;
+ ip->ip_ttl = (s->ttl < 0) ? 64 : s->ttl;
+ ip->ip_p = s->dport;
+ set_inaddr(&ip->ip_src, s->saddr);
+ set_inaddr(&ip->ip_dst, s->daddr);
+
+#ifdef __OpenBSD__
+ /* OpenBSD expects ip_len in network order, other BSDs expect host order */
+ ip->ip_len = htons(ip->ip_len);
+#endif
}
-*/
#endif