struct expr *osf_expr_alloc(const struct location *loc);
#endif /* NFTABLES_OSF_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index ed3640e..e569029 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -57,6 +57,7 @@ libnftables_la_SOURCES = \
services.c \
mergesort.c \
osf.c \
+ nfnl_osf.c \
tcpopt.c \
socket.c \
libnftables.c
diff --git a/src/nfnl_osf.c b/src/nfnl_osf.c
new file mode 100644
index 0000000..07bf682
--- /dev/null
+++ b/src/nfnl_osf.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2005 Evgeniy Polyakov <johnpol@xxxxxxxxxx>
+ *
+ *
+ * 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.
+ */
+
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+
+#include <linux/unistd.h>
+
+#include <libmnl/libmnl.h>
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/nfnetlink_osf.h>
+#include <mnl.h>
+#include <nfnl_osf.h>
+
+#define OPTDEL ','
+#define OSFPDEL ':'
+#define MAXOPTSTRLEN 128
+
+static struct nf_osf_opt IANA_opts[] = {
+ { .kind = 0, .length = 1,},
+ { .kind=1, .length=1,},
+ { .kind=2, .length=4,},
+ { .kind=3, .length=3,},
+ { .kind=4, .length=2,},
+ { .kind=5, .length=1,}, /* SACK length is not defined */
+ { .kind=6, .length=6,},
+ { .kind=7, .length=6,},
+ { .kind=8, .length=10,},
+ { .kind=9, .length=2,},
+ { .kind=10, .length=3,},
+ { .kind=11, .length=1,}, /* CC: Suppose 1 */
+ { .kind=12, .length=1,}, /* the same */
+ { .kind=13, .length=1,}, /* and here too */
+ { .kind=14, .length=3,},
+ { .kind=15, .length=1,}, /* TCP Alternate Checksum Data. Length is not defined */
+ { .kind=16, .length=1,},
+ { .kind=17, .length=1,},
+ { .kind=18, .length=3,},
+ { .kind=19, .length=18,},
+ { .kind=20, .length=1,},
+ { .kind=21, .length=1,},
+ { .kind=22, .length=1,},
+ { .kind=23, .length=1,},
+ { .kind=24, .length=1,},
+ { .kind=25, .length=1,},
+ { .kind=26, .length=1,},
+};
+
+static void uloga(const char *f, struct netlink_ctx *ctx, ...)
+{
+ if (!(ctx->debug_mask & NFT_DEBUG_NETLINK))
+ return;
+
+ nft_print(ctx->octx, "%s", f);
+}