From 4b493784abab0f7e7e3a9b2d59cf78d09098a4bb Mon Sep 17 00:00:00 2001
From: Christophe Massiot <massiot@videolan.org>
Date: Wed, 21 Dec 2016 17:33:36 +0000
Subject: [PATCH] FreeBSD has it's own structures for IP and UDP headers,
 handled them properly

commit e7e736d85ca80bb6e5b9c9694a1c002d1875b5c0
Author: Dmitry Marakasov <amdmi3@amdmi3.ru>
Date:   Fri Oct 7 17:22:59 2016 +0300
---
 multicat.c |  2 +-
 util.c     | 32 +++++++++++++++++++++++++-------
 util.h     | 10 +++++++---
 3 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/multicat.c b/multicat.c
index cf273af..003f077 100644
--- a/multicat.c
+++ b/multicat.c
@@ -281,7 +281,7 @@ static ssize_t raw_Write( const void *p_buf, size_t i_len )
     ssize_t i_ret;
     struct iovec iov[2];
 
-    #ifdef __FAVOR_BSD
+    #if defined(__FreeBSD__)
     pktheader.udph.uh_ulen
     #else
     pktheader.udph.len
diff --git a/util.c b/util.c
index 25b6ab8..ea3a9d3 100644
--- a/util.c
+++ b/util.c
@@ -451,7 +451,11 @@ static void RawFillHeaders(struct udprawpkt *dgram,
                         uint8_t ttl, uint8_t tos, uint16_t len)
 {
 #ifndef __APPLE__
+#if defined(__FreeBSD__)
+    struct ip *iph = &(dgram->iph);
+#else
     struct iphdr *iph = &(dgram->iph);
+#endif
     struct udphdr *udph = &(dgram->udph);
 
 #ifdef DEBUG_SOCKET
@@ -464,6 +468,26 @@ static void RawFillHeaders(struct udprawpkt *dgram,
     printf("Filling raw header (%p) (%s:%u -> %s:%u)\n", dgram, ipsrc_str, portsrc, ipdst_str, portdst);
 #endif
 
+#if defined(__FreeBSD__)
+    // Fill ip header
+    iph->ip_hl    = 5;              // ip header with no specific option
+    iph->ip_v     = 4;
+    iph->ip_tos   = tos;
+    iph->ip_len   = sizeof(struct udprawpkt) + len; // auto-htoned ?
+    iph->ip_id    = htons(0);       // auto-generated if frag_off (flags) = 0 ?
+    iph->ip_off   = 0;
+    iph->ip_ttl   = ttl;
+    iph->ip_p     = IPPROTO_UDP;
+    iph->ip_sum   = 0;
+    iph->ip_src.s_addr = ipsrc;
+    iph->ip_dst.s_addr = ipdst;
+
+    // Fill udp header
+    udph->uh_sport = htons(portsrc);
+    udph->uh_dport = htons(portdst);
+    udph->uh_ulen  = htons(sizeof(struct udphdr) + len);
+    udph->uh_sum   = 0;
+#else
     // Fill ip header
     iph->ihl      = 5;              // ip header with no specific option
     iph->version  = 4;
@@ -478,17 +502,11 @@ static void RawFillHeaders(struct udprawpkt *dgram,
     iph->daddr    = ipdst;
 
     // Fill udp header
-    #ifdef __FAVOR_BSD
-    udph->uh_sport = htons(portsrc);
-    udph->uh_dport = htons(portdst);
-    udph->uh_ulen  = htons(sizeof(struct udphdr) + len);
-    udph->uh_sum   = 0;
-    #else
     udph->source = htons(portsrc);
     udph->dest   = htons(portdst);
     udph->len    = htons(sizeof(struct udphdr) + len);
     udph->check  = 0;
-    #endif
+#endif
 
     // Compute ip header checksum. Computed by kernel when frag_off = 0 ?
     //iph->check = csum((unsigned short *)iph, sizeof(struct iphdr));
diff --git a/util.h b/util.h
index 528f6ac..f7d86c6 100644
--- a/util.h
+++ b/util.h
@@ -24,7 +24,7 @@
 #include <netinet/udp.h>
 #include <netinet/ip.h>
 
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__FreeBSD__)
 #define POLLRDHUP 0
 /* uClibc may does not have clock_nanosleep() */
 #elif !defined (__UCLIBC__) || \
@@ -58,11 +58,15 @@ typedef union
  * Raw udp packet structure with flexible-array payload
  *****************************************************************************/
 struct udprawpkt {
-#ifndef __APPLE__
+#if !defined(__APPLE__)
+#if defined(__FreeBSD__)
+    struct  ip iph;
+#else
     struct  iphdr iph;
+#endif
     struct  udphdr udph;
-    uint8_t payload[];
 #endif
+    uint8_t payload[];
 } __attribute__((packed));
 
 
-- 
GitLab