From 8a62d1b05b74792d16f9448e24881af5319a6866 Mon Sep 17 00:00:00 2001
From: Jerome Duval <jerome.duval@gmail.com>
Date: Sat, 8 Oct 2016 14:45:19 +0000
Subject: Haiku patch


diff --git a/gtests/net/packetdrill/Makefile.Haiku b/gtests/net/packetdrill/Makefile.Haiku
new file mode 100644
index 0000000..7d332d0
--- /dev/null
+++ b/gtests/net/packetdrill/Makefile.Haiku
@@ -0,0 +1,2 @@
+packetdrill-ext-libs := -lnetwork -lpcap
+include Makefile.common
diff --git a/gtests/net/packetdrill/Makefile.common b/gtests/net/packetdrill/Makefile.common
index 0ec741f..a98ffa8 100644
--- a/gtests/net/packetdrill/Makefile.common
+++ b/gtests/net/packetdrill/Makefile.common
@@ -1,6 +1,6 @@
 all: binaries
 
-CFLAGS = -g -Wall -Werror
+CFLAGS += -g -Wall -Werror
 
 parser.o: parser.y
 	bison --output=parser.c --defines=parser.h --report=state parser.y
@@ -19,6 +19,7 @@ packetdrill-lib := \
          symbols_freebsd.o \
          symbols_openbsd.o \
          symbols_netbsd.o \
+         symbols_haiku.o \
          gre_packet.o icmp_packet.o ip_packet.o tcp_packet.o udp_packet.o \
          mpls_packet.o \
          run.o run_command.o run_packet.o run_system_call.o \
diff --git a/gtests/net/packetdrill/link_layer.c b/gtests/net/packetdrill/link_layer.c
index 45f5b66..db38bbf 100644
--- a/gtests/net/packetdrill/link_layer.c
+++ b/gtests/net/packetdrill/link_layer.c
@@ -66,7 +66,7 @@ void get_hw_address(const char *name, struct ether_addr *hw_address)
 
 #else
 
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) 
 #include <net/if_types.h>
 #include <net/if_dl.h>
 #include <sys/types.h>
diff --git a/gtests/net/packetdrill/netdev.c b/gtests/net/packetdrill/netdev.c
index aeca2da..393c23d 100644
--- a/gtests/net/packetdrill/netdev.c
+++ b/gtests/net/packetdrill/netdev.c
@@ -307,7 +307,7 @@ static void local_netdev_free(struct netdev *a_netdev)
 	free(netdev);
 }
 
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
 /* According to `man 4 tun` on OpenBSD: "Each packet read or written
  * is prefixed with a tunnel header consisting of a 4-byte network
  * byte order integer containing the address family in the case of
@@ -352,7 +352,7 @@ static int local_netdev_send(struct netdev *a_netdev,
 
 	DEBUGP("local_netdev_send\n");
 
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
 	bsd_tun_write(netdev, packet);
 #endif /* defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) */
 
diff --git a/gtests/net/packetdrill/packet_socket_pcap.c b/gtests/net/packetdrill/packet_socket_pcap.c
index 9b22101..1f9b629 100644
--- a/gtests/net/packetdrill/packet_socket_pcap.c
+++ b/gtests/net/packetdrill/packet_socket_pcap.c
@@ -37,7 +37,7 @@
 
 #if defined(__FreeBSD__)
 #include <pcap/pcap.h>
-#elif defined(__OpenBSD__) || defined(__NetBSD__)
+#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
 #include <pcap.h>
 #endif
 
@@ -71,8 +71,11 @@ extern void die_pcap_perror(pcap_t *pcap, char *message)
 
 static void packet_socket_setup(struct packet_socket *psock)
 {
+#ifndef __HAIKU__
 	int data_link = -1, bpf_fd = -1, val = -1;
-
+#else
+	int data_link = -1, bpf_fd = -1;
+#endif
 	DEBUGP("calling pcap_create() with %s\n", psock->name);
 	psock->pcap = pcap_create(psock->name, psock->pcap_error);
 	if (psock->pcap == NULL)
@@ -96,9 +99,11 @@ static void packet_socket_setup(struct packet_socket *psock)
 	 * force the BPF device to return the first packet
 	 * immediately.
 	 */
+#ifndef __HAIKU__
 	val = 1;
 	if (ioctl(bpf_fd, BIOCIMMEDIATE, &val) < 0)
 		die_perror("ioctl BIOCIMMEDIATE on bpf fd");
+#endif
 
 	/* Find data link type. */
 	data_link = pcap_datalink(psock->pcap);
@@ -252,7 +257,7 @@ int packet_socket_receive(struct packet_socket *psock,
 	       (u32)pkt_header->ts.tv_sec,
 	       (u32)pkt_header->ts.tv_usec);
 
-#if defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
 	packet->time_usecs = timeval_to_usecs(&pkt_header->ts);
 #elif defined(__OpenBSD__)
 	packet->time_usecs = bpf_timeval_to_usecs(&pkt_header->ts);
diff --git a/gtests/net/packetdrill/platforms.h b/gtests/net/packetdrill/platforms.h
index 5fdda2c..b322dff 100644
--- a/gtests/net/packetdrill/platforms.h
+++ b/gtests/net/packetdrill/platforms.h
@@ -92,5 +92,26 @@
 
 #endif  /* __NetBSD__ */
 
+/* ------------------------- Haiku --------------------- */
+
+#if defined(__HAIKU__)
+
+#include <sys/param.h>
+#include <sys/sockio.h>
+#define USE_LIBPCAP             1
+#define TUN_PATH                "/dev/tun0"
+#define TUN_DEV                 "tun0"
+#define IFF_RUNNING 0
+#define IPPROTO_IPIP  4
+#define IPPROTO_GRE  47
+
+#define HAVE_FMEMOPEN           1
+#define HAVE_OPEN_MEMSTREAM     1
+#include "fmemopen.h"
+
+#define __always_inline
+
+#endif  /* __HAIKU__ */
+
 
 #endif /* __PLATFORMS_H__ */
diff --git a/gtests/net/packetdrill/run.c b/gtests/net/packetdrill/run.c
index a326019..e5a6b99 100644
--- a/gtests/net/packetdrill/run.c
+++ b/gtests/net/packetdrill/run.c
@@ -407,7 +407,7 @@ void set_scheduling_priority(void)
 	if (num_cpus <= 1)
 		return;
 
-#if !defined(__OpenBSD__)
+#if !defined(__OpenBSD__) && !defined(__HAIKU__)
 	/* Chose a real-time policy, but use SCHED_RR instead of
 	 * SCHED_FIFO, so that we round-robin among real-time threads
 	 * of the same priority. In practice this shouldn't matter,
@@ -434,8 +434,10 @@ void set_scheduling_priority(void)
  */
 void lock_memory(void)
 {
+#ifndef __HAIKU__
 	if (mlockall(MCL_CURRENT | MCL_FUTURE))
 		die_perror("lockall(MCL_CURRENT | MCL_FUTURE)");
+#endif
 }
 
 /* Wait for and return the wall time at which we should start the
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index dcc57c3..535afe8 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -37,10 +37,14 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#ifndef __HAIKU__
 #include <sys/syscall.h>
+#endif
 #include <sys/types.h>
 #include <sys/uio.h>
+#ifndef __HAIKU__
 #include <sys/sendfile.h>
+#endif
 #include <time.h>
 #include <unistd.h>
 #include "logging.h"
@@ -56,7 +60,7 @@ static pid_t gettid(void)
 #ifdef linux
 	return syscall(__NR_gettid);
 #endif
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
 	/* TODO(ncardwell): Implement me. XXX */
 	return 0;
 #endif /* defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)*/
@@ -1740,8 +1744,12 @@ static int syscall_sendfile(struct state *state, struct syscall_spec *syscall,
 	int live_outfd, script_outfd;
 	int live_infd, script_infd;
 	int script_offset = 0;
+#ifndef __HAIKU__
 	off_t live_offset;
 	int count, result;
+#else
+	int count;
+#endif
 	int status = STATUS_ERR;
 
 	if (check_arg_count(args, 4, error))
@@ -1759,6 +1767,7 @@ static int syscall_sendfile(struct state *state, struct syscall_spec *syscall,
 	if (s32_arg(args, 3, &count, error))
 		return STATUS_ERR;
 
+#ifndef __HAIKU__
 	live_offset = script_offset;
 
 	begin_syscall(state, syscall);
@@ -1766,6 +1775,7 @@ static int syscall_sendfile(struct state *state, struct syscall_spec *syscall,
 	result = sendfile(live_outfd, live_infd, &live_offset, count);
 
 	status = end_syscall(state, syscall, CHECK_EXACT, result, error);
+#endif
 
 	return status;
 }
@@ -1885,7 +1895,7 @@ static int yield(void)
 #elif defined(__FreeBSD__) || defined(__OpenBSD__)
 	pthread_yield();
 	return 0;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__HAIKU__)
 	return sched_yield();
 #endif  /* defined(__NetBSD__) */
 }
diff --git a/gtests/net/packetdrill/symbols_haiku.c b/gtests/net/packetdrill/symbols_haiku.c
new file mode 100644
index 0000000..e3d8768
--- /dev/null
+++ b/gtests/net/packetdrill/symbols_haiku.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+/*
+ * Definitions of strace-style symbols for HAIKU.
+ * Allows us to map from symbolic strings to integers for system call inputs.
+ */
+
+#if defined(__HAIKU__)
+
+#include "symbols.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/udp.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "tcp.h"
+
+/* A table of platform-specific string->int mappings. */
+struct int_symbol platform_symbols_table[] = {
+
+	/* /usr/include/sys/socket.h */
+	{ SO_DEBUG,                         "SO_DEBUG"                        },
+	{ SO_ACCEPTCONN,                    "SO_ACCEPTCONN"                   },
+	{ SO_REUSEADDR,                     "SO_REUSEADDR"                    },
+	{ SO_KEEPALIVE,                     "SO_KEEPALIVE"                    },
+	{ SO_DONTROUTE,                     "SO_DONTROUTE"                    },
+	{ SO_BROADCAST,                     "SO_BROADCAST"                    },
+	{ SO_USELOOPBACK,                   "SO_USELOOPBACK"                  },
+	{ SO_LINGER,                        "SO_LINGER"                       },
+	{ SO_OOBINLINE,                     "SO_OOBINLINE"                    },
+	{ SO_REUSEPORT,                     "SO_REUSEPORT"                    },
+	{ SO_SNDBUF,                        "SO_SNDBUF"                       },
+	{ SO_RCVBUF,                        "SO_RCVBUF"                       },
+	{ SO_SNDLOWAT,                      "SO_SNDLOWAT"                     },
+	{ SO_RCVLOWAT,                      "SO_RCVLOWAT"                     },
+	{ SO_SNDTIMEO,                      "SO_SNDTIMEO"                     },
+	{ SO_RCVTIMEO,                      "SO_RCVTIMEO"                     },
+	{ SO_ERROR,                         "SO_ERROR"                        },
+	{ SO_TYPE,                          "SO_TYPE"                         },
+
+	/* /usr/include/netinet/tcp.h */
+	{ TCP_NODELAY,                      "TCP_NODELAY"                     },
+	{ TCP_MAXSEG,                       "TCP_MAXSEG"                      },
+	{ TCP_NOPUSH,                       "TCP_NOPUSH"                      },
+	{ TCP_NOOPT,                        "TCP_NOOPT"                       },
+
+	/* /usr/include/sys/fcntl.h */
+	{ O_RDONLY,                         "O_RDONLY"                        },
+	{ O_WRONLY,                         "O_WRONLY"                        },
+	{ O_RDWR,                           "O_RDWR"                          },
+	{ O_ACCMODE,                        "O_ACCMODE"                       },
+	{ O_NONBLOCK,                       "O_NONBLOCK"                      },
+	{ O_APPEND,                         "O_APPEND"                        },
+	{ O_SYNC,                           "O_SYNC"                          },
+	{ O_NOFOLLOW,                       "O_NOFOLLOW"                      },
+	{ O_CREAT,                          "O_CREAT"                         },
+	{ O_TRUNC,                          "O_TRUNC"                         },
+	{ O_EXCL,                           "O_EXCL"                          },
+	{ O_NOCTTY,                         "O_NOCTTY"                        },
+	{ O_DIRECT,                         "O_DIRECT"                        },
+	{ O_DIRECTORY,                      "O_DIRECTORY"                     },
+	{ O_CLOEXEC,                        "O_CLOEXEC"                       },
+	{ O_NDELAY,                         "O_NDELAY"                        },
+	{ AT_FDCWD,                         "AT_FDCWD"                        },
+	{ AT_EACCESS,                       "AT_EACCESS"                      },
+	{ AT_SYMLINK_NOFOLLOW,              "AT_SYMLINK_NOFOLLOW"             },
+	{ AT_SYMLINK_FOLLOW,                "AT_SYMLINK_FOLLOW"               },
+	{ AT_REMOVEDIR,                     "AT_REMOVEDIR"                    },
+	{ F_DUPFD,                          "F_DUPFD"                         },
+	{ F_GETFD,                          "F_GETFD"                         },
+	{ F_SETFD,                          "F_SETFD"                         },
+	{ F_GETFL,                          "F_GETFL"                         },
+	{ F_SETFL,                          "F_SETFL"                         },
+	{ F_GETLK,                          "F_GETLK"                         },
+	{ F_SETLK,                          "F_SETLK"                         },
+	{ F_SETLKW,                         "F_SETLKW"                        },
+	{ FD_CLOEXEC,                       "FD_CLOEXEC"                      },
+	{ F_RDLCK,                          "F_RDLCK"                         },
+	{ F_UNLCK,                          "F_UNLCK"                         },
+	{ F_WRLCK,                          "F_WRLCK"                         },
+
+	/* /usr/include/sys/unistd.h */
+	{ SEEK_SET,                         "SEEK_SET"                        },
+	{ SEEK_CUR,                         "SEEK_CUR"                        },
+	{ SEEK_END,                         "SEEK_END"                        },
+
+	/* /usr/include/sys/socket.h */
+	{ MSG_OOB,                          "MSG_OOB"                         },
+	{ MSG_PEEK,                         "MSG_PEEK"                        },
+	{ MSG_DONTROUTE,                    "MSG_DONTROUTE"                   },
+	{ MSG_EOR,                          "MSG_EOR"                         },
+	{ MSG_TRUNC,                        "MSG_TRUNC"                       },
+	{ MSG_CTRUNC,                       "MSG_CTRUNC"                      },
+	{ MSG_WAITALL,                      "MSG_WAITALL"                     },
+	{ MSG_DONTWAIT,                     "MSG_DONTWAIT"                    },
+	{ MSG_EOF,                          "MSG_EOF"                         },
+	{ MSG_NOSIGNAL,                     "MSG_NOSIGNAL"                    },
+
+	/* /usr/include/sys/filio.h */
+	{ FIONREAD,                         "FIONREAD"                        },
+	{ FIONBIO,                          "FIONBIO"                         },
+
+	/* /usr/include/sys/poll.h */
+	{ POLLIN,                           "POLLIN"                          },
+	{ POLLPRI,                          "POLLPRI"                         },
+	{ POLLOUT,                          "POLLOUT"                         },
+	{ POLLRDNORM,                       "POLLRDNORM"                      },
+	{ POLLWRNORM,                       "POLLWRNORM"                      },
+	{ POLLRDBAND,                       "POLLRDBAND"                      },
+	{ POLLWRBAND,                       "POLLWRBAND"                      },
+	{ POLLERR,                          "POLLERR"                         },
+	{ POLLHUP,                          "POLLHUP"                         },
+	{ POLLNVAL,                         "POLLNVAL"                        },
+
+	/* /usr/include/sys/errno.h */
+	{ EPERM,                            "EPERM"                           },
+	{ ENOENT,                           "ENOENT"                          },
+	{ ESRCH,                            "ESRCH"                           },
+	{ EINTR,                            "EINTR"                           },
+	{ EIO,                              "EIO"                             },
+	{ ENXIO,                            "ENXIO"                           },
+	{ E2BIG,                            "E2BIG"                           },
+	{ ENOEXEC,                          "ENOEXEC"                         },
+	{ EBADF,                            "EBADF"                           },
+	{ ECHILD,                           "ECHILD"                          },
+	{ EDEADLK,                          "EDEADLK"                         },
+	{ ENOMEM,                           "ENOMEM"                          },
+	{ EACCES,                           "EACCES"                          },
+	{ EFAULT,                           "EFAULT"                          },
+	{ EBUSY,                            "EBUSY"                           },
+	{ EEXIST,                           "EEXIST"                          },
+	{ EXDEV,                            "EXDEV"                           },
+	{ ENODEV,                           "ENODEV"                          },
+	{ ENOTDIR,                          "ENOTDIR"                         },
+	{ EISDIR,                           "EISDIR"                          },
+	{ EINVAL,                           "EINVAL"                          },
+	{ ENFILE,                           "ENFILE"                          },
+	{ EMFILE,                           "EMFILE"                          },
+	{ ENOTTY,                           "ENOTTY"                          },
+	{ ETXTBSY,                          "ETXTBSY"                         },
+	{ EFBIG,                            "EFBIG"                           },
+	{ ENOSPC,                           "ENOSPC"                          },
+	{ ESPIPE,                           "ESPIPE"                          },
+	{ EROFS,                            "EROFS"                           },
+	{ EMLINK,                           "EMLINK"                          },
+	{ EPIPE,                            "EPIPE"                           },
+	{ EDOM,                             "EDOM"                            },
+	{ ERANGE,                           "ERANGE"                          },
+	{ EAGAIN,                           "EAGAIN"                          },
+	{ EWOULDBLOCK,                      "EWOULDBLOCK"                     },
+	{ EINPROGRESS,                      "EINPROGRESS"                     },
+	{ EALREADY,                         "EALREADY"                        },
+	{ ENOTSOCK,                         "ENOTSOCK"                        },
+	{ EDESTADDRREQ,                     "EDESTADDRREQ"                    },
+	{ EMSGSIZE,                         "EMSGSIZE"                        },
+	{ EPROTOTYPE,                       "EPROTOTYPE"                      },
+	{ ENOPROTOOPT,                      "ENOPROTOOPT"                     },
+	{ EPROTONOSUPPORT,                  "EPROTONOSUPPORT"                 },
+	{ EOPNOTSUPP,                       "EOPNOTSUPP"                      },
+	{ ENOTSUP,                          "ENOTSUP"                         },
+	{ EPFNOSUPPORT,                     "EPFNOSUPPORT"                    },
+	{ EAFNOSUPPORT,                     "EAFNOSUPPORT"                    },
+	{ EADDRINUSE,                       "EADDRINUSE"                      },
+	{ EADDRNOTAVAIL,                    "EADDRNOTAVAIL"                   },
+	{ ENETDOWN,                         "ENETDOWN"                        },
+	{ ENETUNREACH,                      "ENETUNREACH"                     },
+	{ ENETRESET,                        "ENETRESET"                       },
+	{ ECONNABORTED,                     "ECONNABORTED"                    },
+	{ ECONNRESET,                       "ECONNRESET"                      },
+	{ ENOBUFS,                          "ENOBUFS"                         },
+	{ EISCONN,                          "EISCONN"                         },
+	{ ENOTCONN,                         "ENOTCONN"                        },
+	{ ESHUTDOWN,                        "ESHUTDOWN"                       },
+	{ ETIMEDOUT,                        "ETIMEDOUT"                       },
+	{ ECONNREFUSED,                     "ECONNREFUSED"                    },
+	{ ELOOP,                            "ELOOP"                           },
+	{ ENAMETOOLONG,                     "ENAMETOOLONG"                    },
+	{ EHOSTDOWN,                        "EHOSTDOWN"                       },
+	{ EHOSTUNREACH,                     "EHOSTUNREACH"                    },
+	{ ENOTEMPTY,                        "ENOTEMPTY"                       },
+	{ EDQUOT,                           "EDQUOT"                          },
+	{ ESTALE,                           "ESTALE"                          },
+	{ ENOLCK,                           "ENOLCK"                          },
+	{ ENOSYS,                           "ENOSYS"                          },
+	{ EIDRM,                            "EIDRM"                           },
+	{ ENOMSG,                           "ENOMSG"                          },
+	{ EOVERFLOW,                        "EOVERFLOW"                       },
+	{ ECANCELED,                        "ECANCELED"                       },
+	{ EILSEQ,                           "EILSEQ"                          },
+	{ ENOATTR,                          "ENOATTR"                         },
+	{ EBADMSG,                          "EBADMSG"                         },
+	{ EMULTIHOP,                        "EMULTIHOP"                       },
+	{ ENOLINK,                          "ENOLINK"                         },
+	{ EPROTO,                           "EPROTO"                          },
+
+	/* Sentinel marking the end of the table. */
+	{ 0, NULL },
+};
+
+struct int_symbol *platform_symbols(void)
+{
+	return platform_symbols_table;
+}
+
+#endif  /* __HAIKU__ */
diff --git a/gtests/net/packetdrill/tcp.h b/gtests/net/packetdrill/tcp.h
index b29bfb6..a4f81e5 100644
--- a/gtests/net/packetdrill/tcp.h
+++ b/gtests/net/packetdrill/tcp.h
@@ -35,7 +35,7 @@
 
 #include <netinet/tcp.h>
 
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) 
 #define SOL_TCP IPPROTO_TCP
 #endif /* defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) */
 
-- 
2.2.2

