diff --git a/ip2net/ip2net.c b/ip2net/ip2net.c
index b026795..77d7139 100644
--- a/ip2net/ip2net.c
+++ b/ip2net/ip2net.c
@@ -225,6 +225,28 @@ static void exithelp(void)
 #define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
 #endif
 
+enum opt_indices {
+	IDX_HELP,
+	IDX_H,
+	IDX_4,
+	IDX_6,
+	IDX_PREFIX_LENGTH,
+	IDX_V4_THRESHOLD,
+	IDX_V6_THRESHOLD,
+	IDX_LAST,
+};
+
+static const struct option long_options[] = {
+	[IDX_HELP] = {"help", no_argument, 0, 0},
+	[IDX_H] = {"h", no_argument, 0, 0},
+	[IDX_4] = {"4", no_argument, 0, 0},
+	[IDX_6] = {"6", no_argument, 0, 0},
+	[IDX_PREFIX_LENGTH] = {"prefix-length", required_argument, 0, 0},
+	[IDX_V4_THRESHOLD] = {"v4-threshold", required_argument, 0, 0},
+	[IDX_V6_THRESHOLD] = {"v6-threshold", required_argument, 0, 0},
+	[IDX_LAST] = {NULL, 0, NULL, 0},
+};
+
 static void parse_params(int argc, char *argv[])
 {
 	int option_index = 0;
@@ -236,33 +258,23 @@ static void parse_params(int argc, char *argv[])
 	params.pctdiv = DEFAULT_PCTDIV;
 	params.v6_threshold = DEFAULT_V6_THRESHOLD;
 
-	const struct option long_options[] = {
-		{ "help",no_argument,0,0 },// optidx=0
-		{ "h",no_argument,0,0 },// optidx=1
-		{ "4",no_argument,0,0 },// optidx=2
-		{ "6",no_argument,0,0 },// optidx=3
-		{ "prefix-length",required_argument,0,0 },// optidx=4
-		{ "v4-threshold",required_argument,0,0 },// optidx=5
-		{ "v6-threshold",required_argument,0,0 },// optidx=6
-		{ NULL,0,NULL,0 }
-	};
 	while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
 	{
 		if (v) exithelp();
 		switch (option_index)
 		{
-		case 0:
-		case 1:
+		case IDX_HELP:
+		case IDX_H:
 			PRINT_VER;
 			exithelp();
 			break;
-		case 2:
+		case IDX_4:
 			params.ipv6 = false;
 			break;
-		case 3:
+		case IDX_6:
 			params.ipv6 = true;
 			break;
-		case 4:
+		case IDX_PREFIX_LENGTH:
 			i = sscanf(optarg,"%u-%u",&plen1,&plen2);
 			if (i == 1) plen2 = plen1;
 			if (i<=0 || plen2<plen1 || !plen1 || !plen2)
@@ -271,7 +283,7 @@ static void parse_params(int argc, char *argv[])
 				exit(1);
 			}
 			break;
-		case 5:
+		case IDX_V4_THRESHOLD:
 			i = sscanf(optarg, "%u/%u", &params.pctmult, &params.pctdiv);
 			if (i!=2 || params.pctdiv<2 || params.pctmult<1 || params.pctmult>=params.pctdiv)
 			{
@@ -279,7 +291,7 @@ static void parse_params(int argc, char *argv[])
 				exit(1);
 			}
 			break;
-		case 6:
+		case IDX_V6_THRESHOLD:
 			i = sscanf(optarg, "%u", &params.v6_threshold);
 			if (i != 1 || params.v6_threshold<1)
 			{
diff --git a/mdig/mdig.c b/mdig/mdig.c
index 1856356..b2447f6 100644
--- a/mdig/mdig.c
+++ b/mdig/mdig.c
@@ -467,25 +467,38 @@ static void exithelp(void)
 #define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
 #endif
 
+enum opt_indices {
+	IDX_HELP,
+	IDX_THREADS,
+	IDX_FAMILY,
+	IDX_VERBOSE,
+	IDX_STATS,
+	IDX_LOG_RESOLVED,
+	IDX_LOG_FAILED,
+	IDX_DNS_MAKE_QUERY,
+	IDX_DNS_PARSE_QUERY,
+	IDX_LAST,
+};
+
+static const struct option long_options[] = {
+	[IDX_HELP] = {"help", no_argument, 0, 0},
+	[IDX_THREADS] = {"threads", required_argument, 0, 0},
+	[IDX_FAMILY] = {"family", required_argument, 0, 0},
+	[IDX_VERBOSE] = {"verbose", no_argument, 0, 0},
+	[IDX_STATS] = {"stats", required_argument, 0, 0},
+	[IDX_LOG_RESOLVED] = {"log-resolved", required_argument, 0, 0},
+	[IDX_LOG_FAILED] = {"log-failed", required_argument, 0, 0},
+	[IDX_DNS_MAKE_QUERY] = {"dns-make-query", required_argument, 0, 0},
+	[IDX_DNS_PARSE_QUERY] = {"dns-parse-query", no_argument, 0, 0},
+	[IDX_LAST] = {NULL, 0, NULL, 0},
+};
+
 int main(int argc, char **argv)
 {
 	int r, v, option_index = 0;
 	char fn1[256],fn2[256];
 	char dom[256];
 
-	static const struct option long_options[] = {
-			{"help",no_argument,0,0},			// optidx=0
-			{"threads",required_argument,0,0},		// optidx=1
-			{"family",required_argument,0,0},		// optidx=2
-			{"verbose",no_argument,0,0},			// optidx=3
-			{"stats",required_argument,0,0},		// optidx=4
-			{"log-resolved",required_argument,0,0},		// optidx=5
-			{"log-failed",required_argument,0,0},		// optidx=6
-			{"dns-make-query",required_argument,0,0},	// optidx=7
-			{"dns-parse-query",no_argument,0,0},		// optidx=8
-			{NULL,0,NULL,0}
-	};
-
 	memset(&glob, 0, sizeof(glob));
 	*fn1 = *fn2 = *dom = 0;
 	glob.family = FAMILY4;
@@ -495,11 +508,11 @@ int main(int argc, char **argv)
 		if (v) exithelp();
 		switch (option_index)
 		{
-		case 0: /* help */
+		case IDX_HELP:
 			PRINT_VER;
 			exithelp();
 			break;
-		case 1: /* threads */
+		case IDX_THREADS:
 			glob.threads = optarg ? atoi(optarg) : 0;
 			if (glob.threads <= 0 || glob.threads > 100)
 			{
@@ -507,7 +520,7 @@ int main(int argc, char **argv)
 				return 1;
 			}
 			break;
-		case 2: /* family */
+		case IDX_FAMILY:
 			if (!strcmp(optarg, "4"))
 				glob.family = FAMILY4;
 			else if (!strcmp(optarg, "6"))
@@ -520,25 +533,25 @@ int main(int argc, char **argv)
 				return 1;
 			}
 			break;
-		case 3: /* verbose */
+		case IDX_VERBOSE:
 			glob.verbose = '\1';
 			break;
-		case 4: /* stats */
+		case IDX_STATS:
 			glob.stats_every = optarg ? atoi(optarg) : 0;
 			break;
-		case 5: /* log-resolved */
+		case IDX_LOG_RESOLVED:
 			strncpy(fn1,optarg,sizeof(fn1));
 			fn1[sizeof(fn1)-1] = 0;
 			break;
-		case 6: /* log-failed */
+		case IDX_LOG_FAILED:
 			strncpy(fn2,optarg,sizeof(fn2));
 			fn2[sizeof(fn2)-1] = 0;
 			break;
-		case 7: /* dns-make-query */
+		case IDX_DNS_MAKE_QUERY:
 			strncpy(dom,optarg,sizeof(dom));
 			dom[sizeof(dom)-1] = 0;
 			break;
-		case 8: /* dns-parse-query */
+		case IDX_DNS_PARSE_QUERY:
 			return dns_parse_query();
 		}
 	}
diff --git a/nfq/nfqws.c b/nfq/nfqws.c
index 31f49ed..5bdfc15 100644
--- a/nfq/nfqws.c
+++ b/nfq/nfqws.c
@@ -1530,6 +1530,206 @@ void check_dp(const struct desync_profile *dp)
 #define PRINT_VER printf("self-built version %s %s\n\n", __DATE__, __TIME__)
 #endif
 
+enum opt_indices {
+	IDX_DEBUG,
+	IDX_DRY_RUN,
+	IDX_VERSION,
+	IDX_COMMENT,
+#ifdef __linux__
+	IDX_QNUM,
+#elif defined(BSD)
+	IDX_PORT,
+#endif
+	IDX_DAEMON,
+	IDX_PIDFILE,
+#ifndef __CYGWIN__
+	IDX_USER,
+	IDX_UID,
+#endif
+	IDX_WSIZE,
+	IDX_WSSIZE,
+	IDX_WSSIZE_CUTOFF,
+	IDX_CTRACK_TIMEOUTS,
+	IDX_HOSTCASE,
+	IDX_HOSTSPELL,
+	IDX_HOSTNOSPACE,
+	IDX_DOMCASE,
+	IDX_METHODEOL,
+	IDX_DPI_DESYNC,
+#ifdef __linux__
+	IDX_DPI_DESYNC_FWMARK,
+#elif defined(SO_USER_COOKIE)
+	IDX_DPI_DESYNC_SOCKARG,
+#endif
+	IDX_DPI_DESYNC_TTL,
+	IDX_DPI_DESYNC_TTL6,
+	IDX_DPI_DESYNC_AUTOTTL,
+	IDX_DPI_DESYNC_AUTOTTL6,
+	IDX_DPI_DESYNC_FOOLING,
+	IDX_DPI_DESYNC_REPEATS,
+	IDX_DPI_DESYNC_SKIP_NOSNI,
+	IDX_DPI_DESYNC_SPLIT_POS,
+	IDX_DPI_DESYNC_SPLIT_HTTP_REQ,
+	IDX_DPI_DESYNC_SPLIT_TLS,
+	IDX_DPI_DESYNC_SPLIT_SEQOVL,
+	IDX_DPI_DESYNC_SPLIT_SEQOVL_PATTERN,
+	IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN,
+	IDX_DPI_DESYNC_IPFRAG_POS_TCP,
+	IDX_DPI_DESYNC_IPFRAG_POS_UDP,
+	IDX_DPI_DESYNC_BADSEQ_INCREMENT,
+	IDX_DPI_DESYNC_BADACK_INCREMENT,
+	IDX_DPI_DESYNC_ANY_PROTOCOL,
+	IDX_DPI_DESYNC_FAKE_HTTP,
+	IDX_DPI_DESYNC_FAKE_TLS,
+	IDX_DPI_DESYNC_FAKE_TLS_MOD,
+	IDX_DPI_DESYNC_FAKE_UNKNOWN,
+	IDX_DPI_DESYNC_FAKE_SYNDATA,
+	IDX_DPI_DESYNC_FAKE_QUIC,
+	IDX_DPI_DESYNC_FAKE_WIREGUARD,
+	IDX_DPI_DESYNC_FAKE_DHT,
+	IDX_DPI_DESYNC_FAKE_DISCORD,
+	IDX_DPI_DESYNC_FAKE_STUN,
+	IDX_DPI_DESYNC_FAKE_UNKNOWN_UDP,
+	IDX_DPI_DESYNC_UDPLEN_INCREMENT,
+	IDX_DPI_DESYNC_UDPLEN_PATTERN,
+	IDX_DPI_DESYNC_CUTOFF,
+	IDX_DPI_DESYNC_START,
+	IDX_HOSTLIST,
+	IDX_HOSTLIST_DOMAINS,
+	IDX_HOSTLIST_EXCLUDE,
+	IDX_HOSTLIST_EXCLUDE_DOMAINS,
+	IDX_HOSTLIST_AUTO,
+	IDX_HOSTLIST_AUTO_FAIL_THRESHOLD,
+	IDX_HOSTLIST_AUTO_FAIL_TIME,
+	IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD,
+	IDX_HOSTLIST_AUTO_DEBUG,
+	IDX_NEW,
+	IDX_SKIP,
+	IDX_FILTER_L3,
+	IDX_FILTER_TCP,
+	IDX_FILTER_UDP,
+	IDX_FILTER_L7,
+	IDX_IPSET,
+	IDX_IPSET_IP,
+	IDX_IPSET_EXCLUDE,
+	IDX_IPSET_EXCLUDE_IP,
+#ifdef __linux__
+	IDX_BIND_FIX4,
+	IDX_BIND_FIX6,
+#elif defined(__CYGWIN__),
+	IDX_WF_IFACE,
+	IDX_WF_L3,
+	IDX_WF_TCP,
+	IDX_WF_UDP,
+	IDX_WF_RAW,
+	IDX_WF_SAVE,
+	IDX_SSID_FILTER,
+	IDX_NLM_FILTER,
+	IDX_NLM_LIST,
+#endif
+	IDX_LAST,
+};
+
+static const struct option long_options[] = {
+	[IDX_DEBUG] = {"debug", optional_argument, 0, 0},
+	[IDX_DRY_RUN] = {"dry-run", no_argument, 0, 0},
+	[IDX_VERSION] = {"version", no_argument, 0, 0},
+	[IDX_COMMENT] = {"comment", optional_argument, 0, 0},
+#ifdef __linux__
+	[IDX_QNUM] = {"qnum", required_argument, 0, 0},
+#elif defined(BSD)
+	[IDX_PORT] = {"port", required_argument, 0, 0},
+#endif
+	[IDX_DAEMON] = {"daemon", no_argument, 0, 0},
+	[IDX_PIDFILE] = {"pidfile", required_argument, 0, 0},
+#ifndef __CYGWIN__
+	[IDX_USER] = {"user", required_argument, 0, 0},
+	[IDX_UID] = {"uid", required_argument, 0, 0},
+#endif
+	[IDX_WSIZE] = {"wsize", required_argument, 0, 0},
+	[IDX_WSSIZE] = {"wssize", required_argument, 0, 0},
+	[IDX_WSSIZE_CUTOFF] = {"wssize-cutoff", required_argument, 0, 0},
+	[IDX_CTRACK_TIMEOUTS] = {"ctrack-timeouts", required_argument, 0, 0},
+	[IDX_HOSTCASE] = {"hostcase", no_argument, 0, 0},
+	[IDX_HOSTSPELL] = {"hostspell", required_argument, 0, 0},
+	[IDX_HOSTNOSPACE] = {"hostnospace", no_argument, 0, 0},
+	[IDX_DOMCASE] = {"domcase", no_argument, 0, 0},
+	[IDX_METHODEOL] = {"methodeol", no_argument, 0, 0},
+	[IDX_DPI_DESYNC] = {"dpi-desync", required_argument, 0, 0},
+#ifdef __linux__
+	[IDX_DPI_DESYNC_FWMARK] = {"dpi-desync-fwmark", required_argument, 0, 0},
+#elif defined(SO_USER_COOKIE)
+	[IDX_DPI_DESYNC_SOCKARG] = {"dpi-desync-sockarg", required_argument, 0, 0},
+#endif
+	[IDX_DPI_DESYNC_TTL] = {"dpi-desync-ttl", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_TTL6] = {"dpi-desync-ttl6", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_AUTOTTL] = {"dpi-desync-autottl", optional_argument, 0, 0},
+	[IDX_DPI_DESYNC_AUTOTTL6] = {"dpi-desync-autottl6", optional_argument, 0, 0},
+	[IDX_DPI_DESYNC_FOOLING] = {"dpi-desync-fooling", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_REPEATS] = {"dpi-desync-repeats", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_SKIP_NOSNI] = {"dpi-desync-skip-nosni", optional_argument, 0, 0},
+	[IDX_DPI_DESYNC_SPLIT_POS] = {"dpi-desync-split-pos", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_SPLIT_HTTP_REQ] = {"dpi-desync-split-http-req", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_SPLIT_TLS] = {"dpi-desync-split-tls", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_SPLIT_SEQOVL] = {"dpi-desync-split-seqovl", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_SPLIT_SEQOVL_PATTERN] = {"dpi-desync-split-seqovl-pattern", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN] = {"dpi-desync-fakedsplit-pattern", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_IPFRAG_POS_TCP] = {"dpi-desync-ipfrag-pos-tcp", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_IPFRAG_POS_UDP] = {"dpi-desync-ipfrag-pos-udp", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_BADSEQ_INCREMENT] = {"dpi-desync-badseq-increment", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_BADACK_INCREMENT] = {"dpi-desync-badack-increment", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_ANY_PROTOCOL] = {"dpi-desync-any-protocol", optional_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_HTTP] = {"dpi-desync-fake-http", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_TLS] = {"dpi-desync-fake-tls", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_TLS_MOD] = {"dpi-desync-fake-tls-mod", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_UNKNOWN] = {"dpi-desync-fake-unknown", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_SYNDATA] = {"dpi-desync-fake-syndata", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_QUIC] = {"dpi-desync-fake-quic", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_WIREGUARD] = {"dpi-desync-fake-wireguard", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_DHT] = {"dpi-desync-fake-dht", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_DISCORD] = {"dpi-desync-fake-discord", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_STUN] = {"dpi-desync-fake-stun", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_FAKE_UNKNOWN_UDP] = {"dpi-desync-fake-unknown-udp", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_UDPLEN_INCREMENT] = {"dpi-desync-udplen-increment", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_UDPLEN_PATTERN] = {"dpi-desync-udplen-pattern", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_CUTOFF] = {"dpi-desync-cutoff", required_argument, 0, 0},
+	[IDX_DPI_DESYNC_START] = {"dpi-desync-start", required_argument, 0, 0},
+	[IDX_HOSTLIST] = {"hostlist", required_argument, 0, 0},
+	[IDX_HOSTLIST_DOMAINS] = {"hostlist-domains", required_argument, 0, 0},
+	[IDX_HOSTLIST_EXCLUDE] = {"hostlist-exclude", required_argument, 0, 0},
+	[IDX_HOSTLIST_EXCLUDE_DOMAINS] = {"hostlist-exclude-domains", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO] = {"hostlist-auto", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO_FAIL_THRESHOLD] = {"hostlist-auto-fail-threshold", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO_FAIL_TIME] = {"hostlist-auto-fail-time", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD] = {"hostlist-auto-retrans-threshold", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO_DEBUG] = {"hostlist-auto-debug", required_argument, 0, 0},
+	[IDX_NEW] = {"new", no_argument, 0, 0},
+	[IDX_SKIP] = {"skip", no_argument, 0, 0},
+	[IDX_FILTER_L3] = {"filter-l3", required_argument, 0, 0},
+	[IDX_FILTER_TCP] = {"filter-tcp", required_argument, 0, 0},
+	[IDX_FILTER_UDP] = {"filter-udp", required_argument, 0, 0},
+	[IDX_FILTER_L7] = {"filter-l7", required_argument, 0, 0},
+	[IDX_IPSET] = {"ipset", required_argument, 0, 0},
+	[IDX_IPSET_IP] = {"ipset-ip", required_argument, 0, 0},
+	[IDX_IPSET_EXCLUDE] = {"ipset-exclude", required_argument, 0, 0},
+	[IDX_IPSET_EXCLUDE_IP] = {"ipset-exclude-ip", required_argument, 0, 0},
+#ifdef __linux__
+	[IDX_BIND_FIX4] = {"bind-fix4", no_argument, 0, 0},
+	[IDX_BIND_FIX6] = {"bind-fix6", no_argument, 0, 0},
+#elif defined(__CYGWIN__)
+	[IDX_WF_IFACE] = {"wf-iface", required_argument, 0, 0},
+	[IDX_WF_L3] = {"wf-l3", required_argument, 0, 0},
+	[IDX_WF_TCP] = {"wf-tcp", required_argument, 0, 0},
+	[IDX_WF_UDP] = {"wf-udp", required_argument, 0, 0},
+	[IDX_WF_RAW] = {"wf-raw", required_argument, 0, 0},
+	[IDX_WF_SAVE] = {"wf-save", required_argument, 0, 0},
+	[IDX_SSID_FILTER] = {"ssid-filter", required_argument, 0, 0},
+	[IDX_NLM_FILTER] = {"nlm-filter", required_argument, 0, 0},
+	[IDX_NLM_LIST] = {"nlm-list", optional_argument, 0, 0},
+#endif
+	[IDX_LAST] = {NULL, 0, NULL, 0},
+};
+
 int main(int argc, char **argv)
 {
 	set_console_io_buffering();
@@ -1610,112 +1810,6 @@ int main(int argc, char **argv)
 	}
 #endif
 
-	const struct option long_options[] = {
-		{"debug",optional_argument,0,0},	// optidx=0
-		{"dry-run",no_argument,0,0},		// optidx=1
-		{"version",no_argument,0,0},		// optidx=2
-		{"comment",optional_argument,0,0},	// optidx=3
-#ifdef __linux__
-		{"qnum",required_argument,0,0},		// optidx=4
-#elif defined(BSD)
-		{"port",required_argument,0,0},		// optidx=4
-#else
-		{"disabled_argument_1",no_argument,0,0},// optidx=4
-#endif
-		{"daemon",no_argument,0,0},		// optidx=5
-		{"pidfile",required_argument,0,0},	// optidx=6
-#ifndef __CYGWIN__
-		{"user",required_argument,0,0 },	// optidx=7
-		{"uid",required_argument,0,0 },		// optidx=8
-#else
-		{"disabled_argument_2",no_argument,0,0},	// optidx=7
-		{"disabled_argument_3",no_argument,0,0},	// optidx=8
-#endif
-		{"wsize",required_argument,0,0},	// optidx=9
-		{"wssize",required_argument,0,0},	// optidx=10
-		{"wssize-cutoff",required_argument,0,0},// optidx=11
-		{"ctrack-timeouts",required_argument,0,0},// optidx=12
-		{"hostcase",no_argument,0,0},		// optidx=13
-		{"hostspell",required_argument,0,0},	// optidx=14
-		{"hostnospace",no_argument,0,0},	// optidx=15
-		{"domcase",no_argument,0,0 },		// optidx=16
-		{"methodeol",no_argument,0,0 },		// optidx=17
-		{"dpi-desync",required_argument,0,0},		// optidx=18
-#ifdef __linux__
-		{"dpi-desync-fwmark",required_argument,0,0},	// optidx=18
-#elif defined(SO_USER_COOKIE)
-		{"dpi-desync-sockarg",required_argument,0,0},	// optidx=18
-#else
-		{"disabled_argument_4",no_argument,0,0},	// optidx=18
-#endif
-		{"dpi-desync-ttl",required_argument,0,0},	// optidx=20
-		{"dpi-desync-ttl6",required_argument,0,0},	// optidx=21
-		{"dpi-desync-autottl",optional_argument,0,0},	// optidx=22
-		{"dpi-desync-autottl6",optional_argument,0,0},	// optidx=23
-		{"dpi-desync-fooling",required_argument,0,0},	// optidx=24
-		{"dpi-desync-repeats",required_argument,0,0},	// optidx=25
-		{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=26
-		{"dpi-desync-split-pos",required_argument,0,0},// optidx=27
-		{"dpi-desync-split-http-req",required_argument,0,0 },// optidx=28
-		{"dpi-desync-split-tls",required_argument,0,0 },// optidx=29
-		{"dpi-desync-split-seqovl",required_argument,0,0 },// optidx=30
-		{"dpi-desync-split-seqovl-pattern",required_argument,0,0 },// optidx=31
-		{"dpi-desync-fakedsplit-pattern",required_argument,0,0 },// optidx=32
-		{"dpi-desync-ipfrag-pos-tcp",required_argument,0,0},// optidx=33
-		{"dpi-desync-ipfrag-pos-udp",required_argument,0,0},// optidx=34
-		{"dpi-desync-badseq-increment",required_argument,0,0},// optidx=35
-		{"dpi-desync-badack-increment",required_argument,0,0},// optidx=36
-		{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=37
-		{"dpi-desync-fake-http",required_argument,0,0},// optidx=38
-		{"dpi-desync-fake-tls",required_argument,0,0},// optidx=39
-		{"dpi-desync-fake-tls-mod",required_argument,0,0},// optidx=40
-		{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=41
-		{"dpi-desync-fake-syndata",required_argument,0,0},// optidx=42
-		{"dpi-desync-fake-quic",required_argument,0,0},// optidx=43
-		{"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=44
-		{"dpi-desync-fake-dht",required_argument,0,0},// optidx=45
-		{"dpi-desync-fake-discord",required_argument,0,0},// optidx=46
-		{"dpi-desync-fake-stun",required_argument,0,0},// optidx=47
-		{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=48
-		{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=49
-		{"dpi-desync-udplen-pattern",required_argument,0,0},// optidx=50
-		{"dpi-desync-cutoff",required_argument,0,0},// optidx=51
-		{"dpi-desync-start",required_argument,0,0},// optidx=52
-		{"hostlist",required_argument,0,0},		// optidx=53
-		{"hostlist-domains",required_argument,0,0},// optidx=54
-		{"hostlist-exclude",required_argument,0,0},	// optidx=55
-		{"hostlist-exclude-domains",required_argument,0,0},// optidx=56
-		{"hostlist-auto",required_argument,0,0},	// optidx=57
-		{"hostlist-auto-fail-threshold",required_argument,0,0},	// optidx=58
-		{"hostlist-auto-fail-time",required_argument,0,0},	// optidx=59
-		{"hostlist-auto-retrans-threshold",required_argument,0,0},	// optidx=60
-		{"hostlist-auto-debug",required_argument,0,0},	// optidx=61
-		{"new",no_argument,0,0},	// optidx=62
-		{"skip",no_argument,0,0},	// optidx=63
-		{"filter-l3",required_argument,0,0},	// optidx=64
-		{"filter-tcp",required_argument,0,0},	// optidx=65
-		{"filter-udp",required_argument,0,0},	// optidx=66
-		{"filter-l7",required_argument,0,0},	// optidx=67
-		{"ipset",required_argument,0,0},	// optidx=68
-		{"ipset-ip",required_argument,0,0},	// optidx=69
-		{"ipset-exclude",required_argument,0,0},// optidx=70
-		{"ipset-exclude-ip",required_argument,0,0},	// optidx=71
-#ifdef __linux__
-		{"bind-fix4",no_argument,0,0},		// optidx=72
-		{"bind-fix6",no_argument,0,0},		// optidx=73
-#elif defined(__CYGWIN__)
-		{"wf-iface",required_argument,0,0},	// optidx=72
-		{"wf-l3",required_argument,0,0},	// optidx=73
-		{"wf-tcp",required_argument,0,0},	// optidx=74
-		{"wf-udp",required_argument,0,0},	// optidx=75
-		{"wf-raw",required_argument,0,0},	// optidx=76
-		{"wf-save",required_argument,0,0},	// optidx=77
-		{"ssid-filter",required_argument,0,0},	// optidx=78
-		{"nlm-filter",required_argument,0,0},	// optidx=79
-		{"nlm-list",optional_argument,0,0},	// optidx=80
-#endif
-		{NULL,0,NULL,0}
-	};
 	if (argc < 2) exithelp_clean();
 	while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
 	{
@@ -1728,7 +1822,7 @@ int main(int argc, char **argv)
 		}
 		switch (option_index)
 		{
-		case 0: /* debug */
+		case IDX_DEBUG:
 			if (optarg)
 			{
 				if (*optarg=='@')
@@ -1762,23 +1856,25 @@ int main(int argc, char **argv)
 				params.debug_target = LOG_TARGET_CONSOLE;
 			}
 			break;
-		case 1: /* dry-run */
+		case IDX_DRY_RUN:
 			bDry=true;
 			break;
-		case 2: /* version */
+		case IDX_VERSION:
 			exit_clean(0);
 			break;
-		case 3: /* comment */
+		case IDX_COMMENT:
 			break;
-		case 4: /* qnum or port */
 #ifdef __linux__
+		case IDX_QNUM:
 			params.qnum = atoi(optarg);
 			if (params.qnum < 0 || params.qnum>65535)
 			{
 				DLOG_ERR("bad qnum\n");
 				exit_clean(1);
 			}
+			break;
 #elif defined(BSD)
+		case IDX_PORT:
 			{
 				int i = atoi(optarg);
 				if (i <= 0 || i > 65535)
@@ -1788,18 +1884,17 @@ int main(int argc, char **argv)
 				}
 				params.port = (uint16_t)i;
 			}
-#endif
 			break;
-		case 5: /* daemon */
+#endif
+		case IDX_DAEMON:
 			daemon = true;
 			break;
-		case 6: /* pidfile */
+		case IDX_PIDFILE:
 			strncpy(pidfile, optarg, sizeof(pidfile));
 			pidfile[sizeof(pidfile) - 1] = '\0';
 			break;
 #ifndef __CYGWIN__
-		case 7: /* user */
-		{
+		case IDX_USER:
 			struct passwd *pwd = getpwnam(optarg);
 			if (!pwd)
 			{
@@ -1810,8 +1905,7 @@ int main(int argc, char **argv)
 			params.gid = pwd->pw_gid;
 			params.droproot = true;
 			break;
-		}
-		case 8: /* uid */
+		case IDX_UID:
 			params.gid = 0x7FFFFFFF; // default gid. drop gid=0
 			params.droproot = true;
 			if (sscanf(optarg, "%u:%u", &params.uid, &params.gid)<1)
@@ -1821,32 +1915,32 @@ int main(int argc, char **argv)
 			}
 			break;
 #endif
-		case 9: /* wsize */
+		case IDX_WSIZE:
 			if (!parse_ws_scale_factor(optarg,&dp->wsize,&dp->wscale))
 				exit_clean(1);
 			break;
-		case 10: /* wssize */
+		case IDX_WSSIZE:
 			if (!parse_ws_scale_factor(optarg,&dp->wssize,&dp->wsscale))
 				exit_clean(1);
 			break;
-		case 11: /* wssize-cutoff */
+		case IDX_WSSIZE_CUTOFF:
 			if (!parse_cutoff(optarg, &dp->wssize_cutoff, &dp->wssize_cutoff_mode))
 			{
 				DLOG_ERR("invalid wssize-cutoff value\n");
 				exit_clean(1);
 			}
 			break;
-		case 12: /* ctrack-timeouts */
+		case IDX_CTRACK_TIMEOUTS:
 			if (sscanf(optarg, "%u:%u:%u:%u", &params.ctrack_t_syn, &params.ctrack_t_est, &params.ctrack_t_fin, &params.ctrack_t_udp)<3)
 			{
 				DLOG_ERR("invalid ctrack-timeouts value\n");
 				exit_clean(1);
 			}
 			break;
-		case 13: /* hostcase */
+		case IDX_HOSTCASE:
 			dp->hostcase = true;
 			break;
-		case 14: /* hostspell */
+		case IDX_HOSTSPELL:
 			if (strlen(optarg) != 4)
 			{
 				DLOG_ERR("hostspell must be exactly 4 chars long\n");
@@ -1855,7 +1949,7 @@ int main(int argc, char **argv)
 			dp->hostcase = true;
 			memcpy(dp->hostspell, optarg, 4);
 			break;
-		case 15: /* hostnospace */
+		case IDX_HOSTNOSPACE:
 			if (dp->methodeol)
 			{
 				DLOG_ERR("--hostnospace and --methodeol are incompatible\n");
@@ -1863,10 +1957,10 @@ int main(int argc, char **argv)
 			}
 			dp->hostnospace = true;
 			break;
-		case 16: /* domcase */
+		case IDX_DOMCASE:
 			dp->domcase = true;
 			break;
-		case 17: /* methodeol */
+		case IDX_METHODEOL:
 			if (dp->hostnospace)
 			{
 				DLOG_ERR("--hostnospace and --methodeol are incompatible\n");
@@ -1874,7 +1968,7 @@ int main(int argc, char **argv)
 			}
 			dp->methodeol = true;
 			break;
-		case 18: /* dpi-desync */
+		case IDX_DPI_DESYNC:
 			{
 				char *mode=optarg,*mode2,*mode3;
 				mode2 = mode ? strchr(mode,',') : NULL;
@@ -1919,8 +2013,11 @@ int main(int argc, char **argv)
 				#endif
 			}
 			break;
-#ifndef __CYGWIN__
-		case 19: /* dpi-desync-fwmark/dpi-desync-sockarg */
+#if defined(__linux__)
+		case IDX_DPI_DESYNC_FWMARK:
+#elif defined(SO_USER_COOKIE)
+		case IDX_DPI_DESYNC_SOCKARG:
+#endif
 #if defined(__linux__) || defined(SO_USER_COOKIE)
 			params.desync_fwmark = 0;
 			if (sscanf(optarg, "0x%X", &params.desync_fwmark)<=0) sscanf(optarg, "%u", &params.desync_fwmark);
@@ -1929,33 +2026,29 @@ int main(int argc, char **argv)
 				DLOG_ERR("fwmark/sockarg should be decimal or 0xHEX and should not be zero\n");
 				exit_clean(1);
 			}
-#else
-			DLOG_ERR("fmwark/sockarg not supported in this OS\n");
-			exit_clean(1);
-#endif
 			break;
 #endif
-		case 20: /* dpi-desync-ttl */
+		case IDX_DPI_DESYNC_TTL:
 			dp->desync_ttl = (uint8_t)atoi(optarg);
 			break;
-		case 21: /* dpi-desync-ttl6 */
+		case IDX_DPI_DESYNC_TTL6:
 			dp->desync_ttl6 = (uint8_t)atoi(optarg);
 			break;
-		case 22: /* dpi-desync-autottl */
+		case IDX_DPI_DESYNC_AUTOTTL:
 			if (!parse_autottl(optarg, &dp->desync_autottl))
 			{
 				DLOG_ERR("dpi-desync-autottl value error\n");
 				exit_clean(1);
 			}
 			break;
-		case 23: /* dpi-desync-autottl6 */
+		case IDX_DPI_DESYNC_AUTOTTL6:
 			if (!parse_autottl(optarg, &dp->desync_autottl6))
 			{
 				DLOG_ERR("dpi-desync-autottl6 value error\n");
 				exit_clean(1);
 			}
 			break;
-		case 24: /* dpi-desync-fooling */
+		case IDX_DPI_DESYNC_FOOLING:
 			{
 				char *e,*p = optarg;
 				while (p)
@@ -1990,17 +2083,17 @@ int main(int argc, char **argv)
 				}
 			}
 			break;
-		case 25: /* dpi-desync-repeats */
+		case IDX_DPI_DESYNC_REPEATS:
 			if (sscanf(optarg,"%u",&dp->desync_repeats)<1 || !dp->desync_repeats || dp->desync_repeats>20)
 			{
 				DLOG_ERR("dpi-desync-repeats must be within 1..20\n");
 				exit_clean(1);
 			}
 			break;
-		case 26: /* dpi-desync-skip-nosni */
+		case IDX_DPI_DESYNC_SKIP_NOSNI:
 			dp->desync_skip_nosni = !optarg || atoi(optarg);
 			break;
-		case 27: /* dpi-desync-split-pos */
+		case IDX_DPI_DESYNC_SPLIT_POS:
 			{
 				int ct;
 				if (!parse_split_pos_list(optarg,dp->splits+dp->split_count,MAX_SPLITS-dp->split_count,&ct))
@@ -2011,7 +2104,7 @@ int main(int argc, char **argv)
 				dp->split_count += ct;
 			}
 			break;
-		case 28: /* dpi-desync-split-http-req */
+		case IDX_DPI_DESYNC_SPLIT_HTTP_REQ:
 			// obsolete arg
 			DLOG_CONDUP("WARNING ! --dpi-desync-split-http-req is deprecated. use --dpi-desync-split-pos with markers.\n",MAX_SPLITS);
 			if (dp->split_count>=MAX_SPLITS)
@@ -2026,7 +2119,7 @@ int main(int argc, char **argv)
 			}
 			dp->split_count++;
 			break;
-		case 29: /* dpi-desync-split-tls */
+		case IDX_DPI_DESYNC_SPLIT_TLS:
 			// obsolete arg
 			DLOG_CONDUP("WARNING ! --dpi-desync-split-tls is deprecated. use --dpi-desync-split-pos with markers.\n",MAX_SPLITS);
 			if (dp->split_count>=MAX_SPLITS)
@@ -2041,7 +2134,7 @@ int main(int argc, char **argv)
 			}
 			dp->split_count++;
 			break;
-		case 30: /* dpi-desync-split-seqovl */
+		case IDX_DPI_DESYNC_SPLIT_SEQOVL:
 			if (!strcmp(optarg,"0"))
 			{
 				// allow zero = disable seqovl
@@ -2054,7 +2147,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 31: /* dpi-desync-split-seqovl-pattern */
+		case IDX_DPI_DESYNC_SPLIT_SEQOVL_PATTERN:
 			{
 				char buf[sizeof(dp->seqovl_pattern)];
 				size_t sz=sizeof(buf);
@@ -2062,7 +2155,7 @@ int main(int argc, char **argv)
 				fill_pattern(dp->seqovl_pattern,sizeof(dp->seqovl_pattern),buf,sz);
 			}
 			break;
-		case 32: /* dpi-desync-fakedsplit-pattern */
+		case IDX_DPI_DESYNC_FAKEDSPLIT_PATTERN:
 			{
 				char buf[sizeof(dp->fsplit_pattern)];
 				size_t sz=sizeof(buf);
@@ -2070,7 +2163,7 @@ int main(int argc, char **argv)
 				fill_pattern(dp->fsplit_pattern,sizeof(dp->fsplit_pattern),buf,sz);
 			}
 			break;
-		case 33: /* dpi-desync-ipfrag-pos-tcp */
+		case IDX_DPI_DESYNC_IPFRAG_POS_TCP:
 			if (sscanf(optarg,"%u",&dp->desync_ipfrag_pos_tcp)<1 || dp->desync_ipfrag_pos_tcp<1 || dp->desync_ipfrag_pos_tcp>DPI_DESYNC_MAX_FAKE_LEN)
 			{
 				DLOG_ERR("dpi-desync-ipfrag-pos-tcp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
@@ -2082,7 +2175,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 34: /* dpi-desync-ipfrag-pos-udp */
+		case IDX_DPI_DESYNC_IPFRAG_POS_UDP:
 			if (sscanf(optarg,"%u",&dp->desync_ipfrag_pos_udp)<1 || dp->desync_ipfrag_pos_udp<1 || dp->desync_ipfrag_pos_udp>DPI_DESYNC_MAX_FAKE_LEN)
 			{
 				DLOG_ERR("dpi-desync-ipfrag-pos-udp must be within 1..%u range\n",DPI_DESYNC_MAX_FAKE_LEN);
@@ -2094,27 +2187,27 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 35: /* dpi-desync-badseq-increments */
+		case IDX_DPI_DESYNC_BADSEQ_INCREMENT:
 			if (!parse_badseq_increment(optarg,&dp->desync_badseq_increment))
 			{
 				DLOG_ERR("dpi-desync-badseq-increment should be signed decimal or signed 0xHEX\n");
 				exit_clean(1);
 			}
 			break;
-		case 36: /* dpi-desync-badack-increment */
+		case IDX_DPI_DESYNC_BADACK_INCREMENT:
 			if (!parse_badseq_increment(optarg,&dp->desync_badseq_ack_increment))
 			{
 				DLOG_ERR("dpi-desync-badack-increment should be signed decimal or signed 0xHEX\n");
 				exit_clean(1);
 			}
 			break;
-		case 37: /* dpi-desync-any-protocol */
+		case IDX_DPI_DESYNC_ANY_PROTOCOL:
 			dp->desync_any_proto = !optarg || atoi(optarg);
 			break;
-		case 38: /* dpi-desync-fake-http */
+		case IDX_DPI_DESYNC_FAKE_HTTP:
 			load_blob_to_collection(optarg, &dp->fake_http, FAKE_MAX_TCP,0);
 			break;
-		case 39: /* dpi-desync-fake-tls */
+		case IDX_DPI_DESYNC_FAKE_TLS:
 			{
 				dp->tls_fake_last = load_blob_to_collection(optarg, &dp->fake_tls, FAKE_MAX_TCP,4+sizeof(dp->tls_mod_last.sni));
 				if (!(dp->tls_fake_last->extra2 = malloc(sizeof(struct fake_tls_mod))))
@@ -2127,7 +2220,7 @@ int main(int argc, char **argv)
 				tls_mod->mod |= FAKE_TLS_MOD_CUSTOM_FAKE;
 			}
 			break;
-		case 40: /* dpi-desync-fake-tls-mod */
+		case IDX_DPI_DESYNC_FAKE_TLS_MOD:
 			if (!parse_tlsmod_list(optarg,&dp->tls_mod_last))
 			{
 				DLOG_ERR("Invalid tls mod : %s\n",optarg);
@@ -2136,39 +2229,39 @@ int main(int argc, char **argv)
 			if (dp->tls_fake_last)
 				*(struct fake_tls_mod*)dp->tls_fake_last->extra2 = dp->tls_mod_last;
 			break;
-		case 41: /* dpi-desync-fake-unknown */
+		case IDX_DPI_DESYNC_FAKE_UNKNOWN:
 			load_blob_to_collection(optarg, &dp->fake_unknown, FAKE_MAX_TCP, 0);
 			break;
-		case 42: /* dpi-desync-fake-syndata */
+		case IDX_DPI_DESYNC_FAKE_SYNDATA:
 			dp->fake_syndata_size = sizeof(dp->fake_syndata);
 			load_file_or_exit(optarg,dp->fake_syndata,&dp->fake_syndata_size);
 			break;
-		case 43: /* dpi-desync-fake-quic */
+		case IDX_DPI_DESYNC_FAKE_QUIC:
 			load_blob_to_collection(optarg, &dp->fake_quic, FAKE_MAX_UDP, 0);
 			break;
-		case 44: /* dpi-desync-fake-wireguard */
+		case IDX_DPI_DESYNC_FAKE_WIREGUARD:
 			load_blob_to_collection(optarg, &dp->fake_wg, FAKE_MAX_UDP, 0);
 			break;
-		case 45: /* dpi-desync-fake-dht */
+		case IDX_DPI_DESYNC_FAKE_DHT:
 			load_blob_to_collection(optarg, &dp->fake_dht, FAKE_MAX_UDP, 0);
 			break;
-		case 46: /* dpi-desync-fake-discord */
+		case IDX_DPI_DESYNC_FAKE_DISCORD:
 			load_blob_to_collection(optarg, &dp->fake_discord, FAKE_MAX_UDP, 0);
 			break;
-		case 47: /* dpi-desync-fake-stun */
+		case IDX_DPI_DESYNC_FAKE_STUN:
 			load_blob_to_collection(optarg, &dp->fake_stun, FAKE_MAX_UDP, 0);
 			break;
-		case 48: /* dpi-desync-fake-unknown-udp */
+		case IDX_DPI_DESYNC_FAKE_UNKNOWN_UDP:
 			load_blob_to_collection(optarg, &dp->fake_unknown_udp, FAKE_MAX_UDP, 0);
 			break;
-		case 49: /* dpi-desync-udplen-increment */
+		case IDX_DPI_DESYNC_UDPLEN_INCREMENT:
 			if (sscanf(optarg,"%d",&dp->udplen_increment)<1 || dp->udplen_increment>0x7FFF || dp->udplen_increment<-0x8000)
 			{
 				DLOG_ERR("dpi-desync-udplen-increment must be integer within -32768..32767 range\n");
 				exit_clean(1);
 			}
 			break;
-		case 50: /* dpi-desync-udplen-pattern */
+		case IDX_DPI_DESYNC_UDPLEN_PATTERN:
 			{
 				char buf[sizeof(dp->udplen_pattern)];
 				size_t sz=sizeof(buf);
@@ -2176,21 +2269,21 @@ int main(int argc, char **argv)
 				fill_pattern(dp->udplen_pattern,sizeof(dp->udplen_pattern),buf,sz);
 			}
 			break;
-		case 51: /* desync-cutoff */
+		case IDX_DPI_DESYNC_CUTOFF:
 			if (!parse_cutoff(optarg, &dp->desync_cutoff, &dp->desync_cutoff_mode))
 			{
 				DLOG_ERR("invalid desync-cutoff value\n");
 				exit_clean(1);
 			}
 			break;
-		case 52: /* desync-start */
+		case IDX_DPI_DESYNC_START:
 			if (!parse_cutoff(optarg, &dp->desync_start, &dp->desync_start_mode))
 			{
 				DLOG_ERR("invalid desync-start value\n");
 				exit_clean(1);
 			}
 			break;
-		case 53: /* hostlist */
+		case IDX_HOSTLIST:
 			if (bSkip) break;
 			if (!RegisterHostlist(dp, false, optarg))
 			{
@@ -2198,7 +2291,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 54: /* hostlist-domains */
+		case IDX_HOSTLIST_DOMAINS:
 			if (bSkip) break;
 			if (!anon_hl && !(anon_hl=RegisterHostlist(dp, false, NULL)))
 			{
@@ -2211,7 +2304,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 55: /* hostlist-exclude */
+		case IDX_HOSTLIST_EXCLUDE:
 			if (bSkip) break;
 			if (!RegisterHostlist(dp, true, optarg))
 			{
@@ -2219,7 +2312,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 56: /* hostlist-exclude-domains */
+		case IDX_HOSTLIST_EXCLUDE_DOMAINS:
 			if (bSkip) break;
 			if (!anon_hl_exclude && !(anon_hl_exclude=RegisterHostlist(dp, true, NULL)))
 			{
@@ -2232,7 +2325,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 57: /* hostlist-auto */
+		case IDX_HOSTLIST_AUTO:
 			if (bSkip) break;
 			if (dp->hostlist_auto)
 			{
@@ -2260,7 +2353,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 58: /* hostlist-auto-fail-threshold */
+		case IDX_HOSTLIST_AUTO_FAIL_THRESHOLD:
 			dp->hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
 			if (dp->hostlist_auto_fail_threshold<1 || dp->hostlist_auto_fail_threshold>20)
 			{
@@ -2268,7 +2361,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 59: /* hostlist-auto-fail-time */
+		case IDX_HOSTLIST_AUTO_FAIL_TIME:
 			dp->hostlist_auto_fail_time = (uint8_t)atoi(optarg);
 			if (dp->hostlist_auto_fail_time<1)
 			{
@@ -2276,7 +2369,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 60: /* hostlist-auto-retrans-threshold */
+		case IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD:
 			dp->hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg);
 			if (dp->hostlist_auto_retrans_threshold<2 || dp->hostlist_auto_retrans_threshold>10)
 			{
@@ -2284,7 +2377,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 61: /* hostlist-auto-debug */
+		case IDX_HOSTLIST_AUTO_DEBUG:
 			{
 				FILE *F = fopen(optarg,"a+t");
 				if (!F)
@@ -2298,7 +2391,7 @@ int main(int argc, char **argv)
 			}
 			break;
 
-		case 62: /* new */
+		case IDX_NEW:
 			if (bSkip)
 			{
 				dp_clear(dp);
@@ -2320,18 +2413,18 @@ int main(int argc, char **argv)
 			anon_hl = anon_hl_exclude = NULL;
 			anon_ips = anon_ips_exclude = NULL;
 			break;
-		case 63: /* skip */
+		case IDX_SKIP:
 			bSkip = true;
 			break;
 
-		case 64: /* filter-l3 */
+		case IDX_FILTER_L3:
 			if (!wf_make_l3(optarg,&dp->filter_ipv4,&dp->filter_ipv6))
 			{
 				DLOG_ERR("bad value for --filter-l3\n");
 				exit_clean(1);
 			}
 			break;
-		case 65: /* filter-tcp */
+		case IDX_FILTER_TCP:
 			if (!parse_pf_list(optarg,&dp->pf_tcp))
 			{
 				DLOG_ERR("Invalid port filter : %s\n",optarg);
@@ -2341,7 +2434,7 @@ int main(int argc, char **argv)
 			if (!port_filters_deny_if_empty(&dp->pf_udp))
 				exit_clean(1);
 			break;
-		case 66: /* filter-udp */
+		case IDX_FILTER_UDP:
 			if (!parse_pf_list(optarg,&dp->pf_udp))
 			{
 				DLOG_ERR("Invalid port filter : %s\n",optarg);
@@ -2351,14 +2444,14 @@ int main(int argc, char **argv)
 			if (!port_filters_deny_if_empty(&dp->pf_tcp))
 				exit_clean(1);
 			break;
-		case 67: /* filter-l7 */
+		case IDX_FILTER_L7:
 			if (!parse_l7_list(optarg,&dp->filter_l7))
 			{
 				DLOG_ERR("Invalid l7 filter : %s\n",optarg);
 				exit_clean(1);
 			}
 			break;
-		case 68: /* ipset */
+		case IDX_IPSET:
 			if (bSkip) break;
 			if (!RegisterIpset(dp, false, optarg))
 			{
@@ -2366,7 +2459,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 69: /* ipset-ip */
+		case IDX_IPSET_IP:
 			if (bSkip) break;
 			if (!anon_ips && !(anon_ips=RegisterIpset(dp, false, NULL)))
 			{
@@ -2379,7 +2472,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 70: /* ipset-exclude */
+		case IDX_IPSET_EXCLUDE:
 			if (bSkip) break;
 			if (!RegisterIpset(dp, true, optarg))
 			{
@@ -2387,7 +2480,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 71: /* ipset-exclude-ip */
+		case IDX_IPSET_EXCLUDE_IP:
 			if (bSkip) break;
 			if (!anon_ips_exclude && !(anon_ips_exclude=RegisterIpset(dp, true, NULL)))
 			{
@@ -2403,28 +2496,28 @@ int main(int argc, char **argv)
 
 
 #ifdef __linux__
-		case 72: /* bind-fix4 */
+		case IDX_BIND_FIX4:
 			params.bind_fix4 = true;
 			break;
-		case 73: /* bind-fix6 */
+		case IDX_BIND_FIX6:
 			params.bind_fix6 = true;
 			break;
 #elif defined(__CYGWIN__)
-		case 72: /* wf-iface */
+		case IDX_WF_IFACE:
 			if (!sscanf(optarg,"%u.%u",&IfIdx,&SubIfIdx))
 			{
 				DLOG_ERR("bad value for --wf-iface\n");
 				exit_clean(1);
 			}
 			break;
-		case 73: /* wf-l3 */
+		case IDX_WF_L3:
 			if (!wf_make_l3(optarg,&wf_ipv4,&wf_ipv6))
 			{
 				DLOG_ERR("bad value for --wf-l3\n");
 				exit_clean(1);
 			}
 			break;
-		case 74: /* wf-tcp */
+		case IDX_WF_TCP:
 			hash_wf_tcp=hash_jen(optarg,strlen(optarg));
 			if (!wf_make_pf(optarg,"tcp","SrcPort",wf_pf_tcp_src,sizeof(wf_pf_tcp_src)) ||
 				!wf_make_pf(optarg,"tcp","DstPort",wf_pf_tcp_dst,sizeof(wf_pf_tcp_dst)))
@@ -2433,7 +2526,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 75: /* wf-udp */
+		case IDX_WF_UDP:
 			hash_wf_udp=hash_jen(optarg,strlen(optarg));
 			if (!wf_make_pf(optarg,"udp","SrcPort",wf_pf_udp_src,sizeof(wf_pf_udp_src)) ||
 				!wf_make_pf(optarg,"udp","DstPort",wf_pf_udp_dst,sizeof(wf_pf_udp_dst)))
@@ -2442,7 +2535,7 @@ int main(int argc, char **argv)
 				exit_clean(1);
 			}
 			break;
-		case 76: /* wf-raw */
+		case IDX_WF_RAW:
 			hash_wf_raw=hash_jen(optarg,strlen(optarg));
 			if (optarg[0]=='@')
 			{
@@ -2456,11 +2549,11 @@ int main(int argc, char **argv)
 				windivert_filter[sizeof(windivert_filter) - 1] = '\0';
 			}
 			break;
-		case 77: /* wf-save */
+		case IFX_WF_SAVE:
 			strncpy(wf_save_file, optarg, sizeof(wf_save_file));
 			wf_save_file[sizeof(wf_save_file) - 1] = '\0';
 			break;
-		case 78: /* ssid-filter */
+		case IDX_SSID_FILTER:
 			hash_ssid_filter=hash_jen(optarg,strlen(optarg));
 			{
 				char *e,*p = optarg;
@@ -2478,7 +2571,7 @@ int main(int argc, char **argv)
 				}
 			}
 			break;
-		case 79: /* nlm-filter */
+		case IDX_NLM_FILTER:
 			hash_nlm_filter=hash_jen(optarg,strlen(optarg));
 			{
 				char *e,*p = optarg;
@@ -2496,7 +2589,7 @@ int main(int argc, char **argv)
 				}
 			}
 			break;
-		case 80: /* nlm-list */
+		case IDX_NLM_LIST:
 			if (!nlm_list(optarg && !strcmp(optarg,"all")))
 			{
 				DLOG_ERR("could not get list of NLM networks\n");
diff --git a/tpws/tpws.c b/tpws/tpws.c
index 0256f42..fe630d1 100644
--- a/tpws/tpws.c
+++ b/tpws/tpws.c
@@ -610,6 +610,188 @@ static bool check_oob_disorder(const struct desync_profile *dp)
 }
 #endif
 
+enum opt_indices {
+	IDX_HELP,
+	IDX_H,
+	IDX_BIND_ADDR,
+	IDX_BIND_IFACE4,
+	IDX_BIND_IFACE6,
+	IDX_BIND_LINKLOCAL,
+	IDX_BIND_WAIT_IFUP,
+	IDX_BIND_WAIT_IP,
+	IDX_BIND_WAIT_IP_LINKLOCAL,
+	IDX_BIND_WAIT_ONLY,
+	IDX_PORT,
+	IDX_DAEMON,
+	IDX_USER,
+	IDX_UID,
+	IDX_MAXCONN,
+	IDX_MAXFILES,
+	IDX_MAX_ORPHAN_TIME,
+	IDX_HOSTCASE,
+	IDX_HOSTSPELL,
+	IDX_HOSTDOT,
+	IDX_HOSTNOSPACE,
+	IDX_HOSTPAD,
+	IDX_DOMCASE,
+	IDX_SPLIT_HTTP_REQ,
+	IDX_SPLIT_TLS,
+	IDX_SPLIT_POS,
+	IDX_SPLIT_ANY_PROTOCOL,
+	IDX_DISORDER,
+	IDX_OOB,
+	IDX_OOB_DATA,
+	IDX_METHODSPACE,
+	IDX_METHODEOL,
+	IDX_HOSTTAB,
+	IDX_UNIXEOL,
+	IDX_TLSREC,
+	IDX_TLSREC_POS,
+	IDX_HOSTLIST,
+	IDX_HOSTLIST_DOMAINS,
+	IDX_HOSTLIST_EXCLUDE,
+	IDX_HOSTLIST_EXCLUDE_DOMAINS,
+	IDX_HOSTLIST_AUTO,
+	IDX_HOSTLIST_AUTO_FAIL_THRESHOLD,
+	IDX_HOSTLIST_AUTO_FAIL_TIME,
+	IDX_HOSTLIST_AUTO_DEBUG,
+	IDX_PIDFILE,
+	IDX_DEBUG,
+	IDX_DEBUG_LEVEL,
+	IDX_DRY_RUN,
+	IDX_VERSION,
+	IDX_COMMENT,
+	IDX_LOCAL_RCVBUF,
+	IDX_LOCAL_SNDBUF,
+	IDX_REMOTE_RCVBUF,
+	IDX_REMOTE_SNDBUF,
+	IDX_SOCKS,
+	IDX_NO_RESOLVE,
+	IDX_RESOLVER_THREADS,
+	IDX_SKIP_NODELAY,
+	IDX_TAMPER_START,
+	IDX_TAMPER_CUTOFF,
+	IDX_CONNECT_BIND_ADDR,
+
+	IDX_NEW,
+	IDX_SKIP,
+	IDX_FILTER_L3,
+	IDX_FILTER_TCP,
+	IDX_FILTER_L7,
+	IDX_IPSET,
+	IDX_IPSET_IP,
+	IDX_IPSET_EXCLUDE,
+	IDX_IPSET_EXCLUDE_IP,
+
+#if defined(__FreeBSD__)
+	IDX_ENABLE_PF,
+#elif defined(__APPLE__)
+	IDX_LOCAL_TCP_USER_TIMEOUT,
+	IDX_REMOTE_TCP_USER_TIMEOUT,
+#elif defined(__linux__)
+	IDX_LOCAL_TCP_USER_TIMEOUT,
+	IDX_REMOTE_TCP_USER_TIMEOUT,
+	IDX_MSS,
+	IDX_FIX_SEG,
+#ifdef SPLICE_PRESENT
+	IDX_NOSPLICE,
+#endif
+#endif
+	IDX_HOSTLIST_AUTO_RETRANS_TRESHOLD, // ignored. for nfqws command line compatibility
+	IDX_LAST,
+};
+
+static const struct option long_options[] = {
+	[IDX_HELP] = {"help", no_argument, 0, 0},
+	[IDX_H] = {"h", no_argument, 0, 0},
+	[IDX_BIND_ADDR] = {"bind-addr", required_argument, 0, 0},
+	[IDX_BIND_IFACE4] = {"bind-iface4", required_argument, 0, 0},
+	[IDX_BIND_IFACE6] = {"bind-iface6", required_argument, 0, 0},
+	[IDX_BIND_LINKLOCAL] = {"bind-linklocal", required_argument, 0, 0},
+	[IDX_BIND_WAIT_IFUP] = {"bind-wait-ifup", required_argument, 0, 0},
+	[IDX_BIND_WAIT_IP] = {"bind-wait-ip", required_argument, 0, 0},
+	[IDX_BIND_WAIT_IP_LINKLOCAL] = {"bind-wait-ip-linklocal", required_argument, 0, 0},
+	[IDX_BIND_WAIT_ONLY] = {"bind-wait-only", no_argument, 0, 0},
+	[IDX_PORT] = {"port", required_argument, 0, 0},
+	[IDX_DAEMON] = {"daemon", no_argument, 0, 0},
+	[IDX_USER] = {"user", required_argument, 0, 0},
+	[IDX_UID] = {"uid", required_argument, 0, 0},
+	[IDX_MAXCONN] = {"maxconn", required_argument, 0, 0},
+	[IDX_MAXFILES] = {"maxfiles", required_argument, 0, 0},
+	[IDX_MAX_ORPHAN_TIME] = {"max-orphan-time", required_argument, 0, 0},
+	[IDX_HOSTCASE] = {"hostcase", no_argument, 0, 0},
+	[IDX_HOSTSPELL] = {"hostspell", required_argument, 0, 0},
+	[IDX_HOSTDOT] = {"hostdot", no_argument, 0, 0},
+	[IDX_HOSTNOSPACE] = {"hostnospace", no_argument, 0, 0},
+	[IDX_HOSTPAD] = {"hostpad", required_argument, 0, 0},
+	[IDX_DOMCASE] = {"domcase", no_argument, 0, 0},
+	[IDX_SPLIT_HTTP_REQ] = {"split-http-req", required_argument, 0, 0},
+	[IDX_SPLIT_TLS] = {"split-tls", required_argument, 0, 0},
+	[IDX_SPLIT_POS] = {"split-pos", required_argument, 0, 0},
+	[IDX_SPLIT_ANY_PROTOCOL] = {"split-any-protocol", optional_argument, 0, 0},
+	[IDX_DISORDER] = {"disorder", optional_argument, 0, 0},
+	[IDX_OOB] = {"oob", optional_argument, 0, 0},
+	[IDX_OOB_DATA] = {"oob-data", required_argument, 0, 0},
+	[IDX_METHODSPACE] = {"methodspace", no_argument, 0, 0},
+	[IDX_METHODEOL] = {"methodeol", no_argument, 0, 0},
+	[IDX_HOSTTAB] = {"hosttab", no_argument, 0, 0},
+	[IDX_UNIXEOL] = {"unixeol", no_argument, 0, 0},
+	[IDX_TLSREC] = {"tlsrec", required_argument, 0, 0},
+	[IDX_TLSREC_POS] = {"tlsrec-pos", required_argument, 0, 0},
+	[IDX_HOSTLIST] = {"hostlist", required_argument, 0, 0},
+	[IDX_HOSTLIST_DOMAINS] = {"hostlist-domains", required_argument, 0, 0},
+	[IDX_HOSTLIST_EXCLUDE] = {"hostlist-exclude", required_argument, 0, 0},
+	[IDX_HOSTLIST_EXCLUDE_DOMAINS] = {"hostlist-exclude-domains", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO] = {"hostlist-auto", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO_FAIL_THRESHOLD] = {"hostlist-auto-fail-threshold", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO_FAIL_TIME] = {"hostlist-auto-fail-time", required_argument, 0, 0},
+	[IDX_HOSTLIST_AUTO_DEBUG] = {"hostlist-auto-debug", required_argument, 0, 0},
+	[IDX_PIDFILE] = {"pidfile", required_argument, 0, 0},
+	[IDX_DEBUG] = {"debug", optional_argument, 0, 0},
+	[IDX_DEBUG_LEVEL] = {"debug-level", required_argument, 0, 0},
+	[IDX_DRY_RUN] = {"dry-run", no_argument, 0, 0},
+	[IDX_VERSION] = {"version", no_argument, 0, 0},
+	[IDX_COMMENT] = {"comment", optional_argument, 0, 0},
+	[IDX_LOCAL_RCVBUF] = {"local-rcvbuf", required_argument, 0, 0},
+	[IDX_LOCAL_SNDBUF] = {"local-sndbuf", required_argument, 0, 0},
+	[IDX_REMOTE_RCVBUF] = {"remote-rcvbuf", required_argument, 0, 0},
+	[IDX_REMOTE_SNDBUF] = {"remote-sndbuf", required_argument, 0, 0},
+	[IDX_SOCKS] = {"socks", no_argument, 0, 0},
+	[IDX_NO_RESOLVE] = {"no-resolve", no_argument, 0, 0},
+	[IDX_RESOLVER_THREADS] = {"resolver-threads", required_argument, 0, 0},
+	[IDX_SKIP_NODELAY] = {"skip-nodelay", no_argument, 0, 0},
+	[IDX_TAMPER_START] = {"tamper-start", required_argument, 0, 0},
+	[IDX_TAMPER_CUTOFF] = {"tamper-cutoff", required_argument, 0, 0},
+	[IDX_CONNECT_BIND_ADDR] = {"connect-bind-addr", required_argument, 0, 0},
+
+	[IDX_NEW] = {"new", no_argument, 0, 0},
+	[IDX_SKIP] = {"skip", no_argument, 0, 0},
+	[IDX_FILTER_L3] = {"filter-l3", required_argument, 0, 0},
+	[IDX_FILTER_TCP] = {"filter-tcp", required_argument, 0, 0},
+	[IDX_FILTER_L7] = {"filter-l7", required_argument, 0, 0},
+	[IDX_IPSET] = {"ipset", required_argument, 0, 0},
+	[IDX_IPSET_IP] = {"ipset-ip", required_argument, 0, 0},
+	[IDX_IPSET_EXCLUDE] = {"ipset-exclude", required_argument, 0, 0},
+	[IDX_IPSET_EXCLUDE_IP] = {"ipset-exclude-ip", required_argument, 0, 0},
+
+#if defined(__FreeBSD__)
+	[IDX_ENABLE_PF] = {"enable-pf", no_argument, 0, 0},
+#elif defined(__APPLE__)
+	[IDX_LOCAL_TCP_USER_TIMEOUT] = {"local-tcp-user-timeout", required_argument, 0, 0},
+	[IDX_REMOTE_TCP_USER_TIMEOUT] = {"remote-tcp-user-timeout", required_argument, 0, 0},
+#elif defined(__linux__)
+	[IDX_LOCAL_TCP_USER_TIMEOUT] = {"local-tcp-user-timeout", required_argument, 0, 0},
+	[IDX_REMOTE_TCP_USER_TIMEOUT] = {"remote-tcp-user-timeout", required_argument, 0, 0},
+	[IDX_MSS] = {"mss", required_argument, 0, 0},
+	[IDX_FIX_SEG] = {"fix-seg", optional_argument, 0, 0},
+#ifdef SPLICE_PRESENT
+	[IDX_NOSPLICE] = {"nosplice", no_argument, 0, 0},
+#endif
+#endif
+	[IDX_HOSTLIST_AUTO_RETRANS_TRESHOLD] = {"hostlist-auto-retrans-threshold", optional_argument, 0, 0},
+	[IDX_LAST] = {NULL, 0, NULL, 0},
+};
+
 void parse_params(int argc, char *argv[])
 {
 	int option_index = 0;
@@ -664,96 +846,6 @@ void parse_params(int argc, char *argv[])
 	}
 #endif
 	
-	const struct option long_options[] = {
-		{ "help",no_argument,0,0 },// optidx=0
-		{ "h",no_argument,0,0 },// optidx=1
-		{ "bind-addr",required_argument,0,0 },// optidx=2
-		{ "bind-iface4",required_argument,0,0 },// optidx=3
-		{ "bind-iface6",required_argument,0,0 },// optidx=4
-		{ "bind-linklocal",required_argument,0,0 },// optidx=5
-		{ "bind-wait-ifup",required_argument,0,0 },// optidx=6
-		{ "bind-wait-ip",required_argument,0,0 },// optidx=7
-		{ "bind-wait-ip-linklocal",required_argument,0,0 },// optidx=8
-		{ "bind-wait-only",no_argument,0,0 },// optidx=9
-		{ "port",required_argument,0,0 },// optidx=10
-		{ "daemon",no_argument,0,0 },// optidx=11
-		{ "user",required_argument,0,0 },// optidx=12
-		{ "uid",required_argument,0,0 },// optidx=13
-		{ "maxconn",required_argument,0,0 },// optidx=14
-		{ "maxfiles",required_argument,0,0 },// optidx=15
-		{ "max-orphan-time",required_argument,0,0 },// optidx=16
-		{ "hostcase",no_argument,0,0 },// optidx=17
-		{ "hostspell",required_argument,0,0 },// optidx=18
-		{ "hostdot",no_argument,0,0 },// optidx=19
-		{ "hostnospace",no_argument,0,0 },// optidx=20
-		{ "hostpad",required_argument,0,0 },// optidx=21
-		{ "domcase",no_argument,0,0 },// optidx=22
-		{ "split-http-req",required_argument,0,0 },// optidx=23
-		{ "split-tls",required_argument,0,0 },// optidx=24
-		{ "split-pos",required_argument,0,0 },// optidx=25
-		{ "split-any-protocol",optional_argument,0,0},// optidx=26
-		{ "disorder",optional_argument,0,0 },// optidx=27
-		{ "oob",optional_argument,0,0 },// optidx=28
-		{ "oob-data",required_argument,0,0 },// optidx=29
-		{ "methodspace",no_argument,0,0 },// optidx=30
-		{ "methodeol",no_argument,0,0 },// optidx=31
-		{ "hosttab",no_argument,0,0 },// optidx=32
-		{ "unixeol",no_argument,0,0 },// optidx=33
-		{ "tlsrec",required_argument,0,0 },// optidx=34
-		{ "tlsrec-pos",required_argument,0,0 },// optidx=35
-		{ "hostlist",required_argument,0,0 },// optidx=36
-		{ "hostlist-domains",required_argument,0,0 },// optidx=37
-		{ "hostlist-exclude",required_argument,0,0 },// optidx=38
-		{ "hostlist-exclude-domains",required_argument,0,0 },// optidx=39
-		{ "hostlist-auto",required_argument,0,0}, // optidx=40
-		{ "hostlist-auto-fail-threshold",required_argument,0,0}, // optidx=41
-		{ "hostlist-auto-fail-time",required_argument,0,0},	// optidx=42
-		{ "hostlist-auto-debug",required_argument,0,0}, // optidx=43
-		{ "pidfile",required_argument,0,0 },// optidx=44
-		{ "debug",optional_argument,0,0 },// optidx=45
-		{ "debug-level",required_argument,0,0 },// optidx=46
-		{ "dry-run",no_argument,0,0 },// optidx=47
-		{ "version",no_argument,0,0 },// optidx=48
-		{ "comment",optional_argument,0,0 },// optidx=49
-		{ "local-rcvbuf",required_argument,0,0 },// optidx=50
-		{ "local-sndbuf",required_argument,0,0 },// optidx=51
-		{ "remote-rcvbuf",required_argument,0,0 },// optidx=52
-		{ "remote-sndbuf",required_argument,0,0 },// optidx=53
-		{ "socks",no_argument,0,0 },// optidx=54
-		{ "no-resolve",no_argument,0,0 },// optidx=55
-		{ "resolver-threads",required_argument,0,0 },// optidx=56
-		{ "skip-nodelay",no_argument,0,0 },// optidx=57
-		{ "tamper-start",required_argument,0,0 },// optidx=58
-		{ "tamper-cutoff",required_argument,0,0 },// optidx=59
-		{ "connect-bind-addr",required_argument,0,0 },// optidx=60
-
-		{ "new",no_argument,0,0 },				// optidx=61
-		{ "skip",no_argument,0,0 },				// optidx=62
-		{ "filter-l3",required_argument,0,0 },			// optidx=63
-		{ "filter-tcp",required_argument,0,0 },			// optidx=64
-		{ "filter-l7",required_argument,0,0 },			// optidx=65
-		{ "ipset",required_argument,0,0 },			// optidx=66
-		{ "ipset-ip",required_argument,0,0 },			// optidx=67
-		{ "ipset-exclude",required_argument,0,0 },		// optidx=68
-		{ "ipset-exclude-ip",required_argument,0,0 },		// optidx=69
-
-#if defined(__FreeBSD__)
-		{ "enable-pf",no_argument,0,0 },// optidx=69
-#elif defined(__APPLE__)
-		{ "local-tcp-user-timeout",required_argument,0,0 },	// optidx=79
-		{ "remote-tcp-user-timeout",required_argument,0,0 },	// optidx=71
-#elif defined(__linux__)
-		{ "local-tcp-user-timeout",required_argument,0,0 },	// optidx=70
-		{ "remote-tcp-user-timeout",required_argument,0,0 },	// optidx=71
-		{ "mss",required_argument,0,0 },			// optidx=72
-		{ "fix-seg",optional_argument,0,0 },			// optidx=73
-#ifdef SPLICE_PRESENT
-		{ "nosplice",no_argument,0,0 },				// optidx=74
-#endif
-#endif
-		{ "hostlist-auto-retrans-threshold",optional_argument,0,0}, // ignored. for nfqws command line compatibility
-		{ NULL,0,NULL,0 }
-	};
 	while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
 	{
 		if (v)
@@ -765,11 +857,11 @@ void parse_params(int argc, char *argv[])
 		}
 		switch (option_index)
 		{
-		case 0:
-		case 1:
+		case IDX_HELP:
+		case IDX_H:
 			exithelp_clean();
 			break;
-		case 2: /* bind-addr */
+		case IDX_BIND_ADDR:
 			nextbind_clean();
 			{
 				char *p = strchr(optarg,'%');
@@ -782,19 +874,19 @@ void parse_params(int argc, char *argv[])
 			}
 			params.binds[params.binds_last].bindaddr[sizeof(params.binds[params.binds_last].bindaddr) - 1] = 0;
 			break;
-		case 3: /* bind-iface4 */
+		case IDX_BIND_IFACE4:
 			nextbind_clean();
 			params.binds[params.binds_last].bind_if6=false;
 			strncpy(params.binds[params.binds_last].bindiface, optarg, sizeof(params.binds[params.binds_last].bindiface));
 			params.binds[params.binds_last].bindiface[sizeof(params.binds[params.binds_last].bindiface) - 1] = 0;
 			break;
-		case 4: /* bind-iface6 */
+		case IDX_BIND_IFACE6:
 			nextbind_clean();
 			params.binds[params.binds_last].bind_if6=true;
 			strncpy(params.binds[params.binds_last].bindiface, optarg, sizeof(params.binds[params.binds_last].bindiface));
 			params.binds[params.binds_last].bindiface[sizeof(params.binds[params.binds_last].bindiface) - 1] = 0;
 			break;
-		case 5: /* bind-linklocal */
+		case IDX_BIND_LINKLOCAL:
 			checkbind_clean();
 			params.binds[params.binds_last].bindll = true;
 			if (!strcmp(optarg, "no"))
@@ -811,22 +903,22 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 6: /* bind-wait-ifup */
+		case IDX_BIND_WAIT_IFUP:
 			checkbind_clean();
 			params.binds[params.binds_last].bind_wait_ifup = atoi(optarg);
 			break;
-		case 7: /* bind-wait-ip */
+		case IDX_BIND_WAIT_IP:
 			checkbind_clean();
 			params.binds[params.binds_last].bind_wait_ip = atoi(optarg);
 			break;
-		case 8: /* bind-wait-ip-linklocal */
+		case IDX_BIND_WAIT_IP_LINKLOCAL:
 			checkbind_clean();
 			params.binds[params.binds_last].bind_wait_ip_ll = atoi(optarg);
 			break;
-		case 9: /* bind-wait-only */
+		case IDX_BIND_WAIT_ONLY:
 			params.bind_wait_only = true;
 			break;
-		case 10: /* port */
+		case IDX_PORT:
 			i = atoi(optarg);
 			if (i <= 0 || i > 65535)
 			{
@@ -835,10 +927,10 @@ void parse_params(int argc, char *argv[])
 			}
 			params.port = (uint16_t)i;
 			break;
-		case 11: /* daemon */
+		case IDX_DAEMON:
 			params.daemon = true;
 			break;
-		case 12: /* user */
+		case IDX_USER:
 		{
 			struct passwd *pwd = getpwnam(optarg);
 			if (!pwd)
@@ -851,7 +943,7 @@ void parse_params(int argc, char *argv[])
 			params.droproot = true;
 			break;
 		}
-		case 13: /* uid */
+		case IDX_UID:
 			params.gid=0x7FFFFFFF; // default git. drop gid=0
 			params.droproot = true;
 			if (sscanf(optarg,"%u:%u",&params.uid,&params.gid)<1)
@@ -860,7 +952,7 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 14: /* maxconn */
+		case IDX_MAXCONN:
 			params.maxconn = atoi(optarg);
 			if (params.maxconn <= 0 || params.maxconn > 10000)
 			{
@@ -868,7 +960,7 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 15: /* maxfiles */
+		case IDX_MAXFILES:
 			params.maxfiles = atoi(optarg);
 			if (params.maxfiles < 0)
 			{
@@ -876,7 +968,7 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 16: /* max-orphan-time */
+		case IDX_MAX_ORPHAN_TIME:
 			params.max_orphan_time = atoi(optarg);
 			if (params.max_orphan_time < 0)
 			{
@@ -884,11 +976,11 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 17: /* hostcase */
+		case IDX_HOSTCASE:
 			dp->hostcase = true;
 			params.tamper = true;
 			break;
-		case 18: /* hostspell */
+		case IDX_HOSTSPELL:
 			if (strlen(optarg) != 4)
 			{
 				DLOG_ERR("hostspell must be exactly 4 chars long\n");
@@ -898,23 +990,23 @@ void parse_params(int argc, char *argv[])
 			memcpy(dp->hostspell, optarg, 4);
 			params.tamper = true;
 			break;
-		case 19: /* hostdot */
+		case IDX_HOSTDOT:
 			dp->hostdot = true;
 			params.tamper = true;
 			break;
-		case 20: /* hostnospace */
+		case IDX_HOSTNOSPACE:
 			dp->hostnospace = true;
 			params.tamper = true;
 			break;
-		case 21: /* hostpad */
+		case IDX_HOSTPAD:
 			dp->hostpad = atoi(optarg);
 			params.tamper = true;
 			break;
-		case 22: /* domcase */
+		case IDX_DOMCASE:
 			dp->domcase = true;
 			params.tamper = true;
 			break;
-		case 23: /* split-http-req */
+		case IDX_SPLIT_HTTP_REQ:
 			DLOG_CONDUP("WARNING ! --split-http-req is deprecated. use --split-pos with markers.\n",MAX_SPLITS);
 			if (dp->split_count>=MAX_SPLITS)
 			{
@@ -929,7 +1021,7 @@ void parse_params(int argc, char *argv[])
 			dp->split_count++;
 			params.tamper = true;
 			break;
-		case 24: /* split-tls */
+		case IDX_SPLIT_TLS:
 			// obsolete arg
 			DLOG_CONDUP("WARNING ! --split-tls is deprecated. use --split-pos with markers.\n",MAX_SPLITS);
 			if (dp->split_count>=MAX_SPLITS)
@@ -945,7 +1037,7 @@ void parse_params(int argc, char *argv[])
 			dp->split_count++;
 			params.tamper = true;
 			break;
-		case 25: /* split-pos */
+		case IDX_SPLIT_POS:
 			{
 				int ct;
 				if (!parse_split_pos_list(optarg,dp->splits+dp->split_count,MAX_SPLITS-dp->split_count,&ct))
@@ -957,10 +1049,10 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 26: /* split-any-protocol */
+		case IDX_SPLIT_ANY_PROTOCOL:
 			dp->split_any_protocol = true;
 			break;
-		case 27: /* disorder */
+		case IDX_DISORDER:
 			if (optarg)
 			{
 				if (!strcmp(optarg,"http")) dp->disorder_http=true;
@@ -981,7 +1073,7 @@ void parse_params(int argc, char *argv[])
 			}
 #endif
 			break;
-		case 28: /* oob */
+		case IDX_OOB:
 			if (optarg)
 			{
 				if (!strcmp(optarg,"http")) dp->oob_http=true;
@@ -1002,7 +1094,7 @@ void parse_params(int argc, char *argv[])
 			}
 #endif
 			break;
-		case 29: /* oob-data */
+		case IDX_OOB_DATA:
 			{
 				size_t l = strlen(optarg);
 				unsigned int bt;
@@ -1015,23 +1107,23 @@ void parse_params(int argc, char *argv[])
 				else dp->oob_byte = (uint8_t)bt;
 			}
 			break;
-		case 30: /* methodspace */
+		case IDX_METHODSPACE:
 			dp->methodspace = true;
 			params.tamper = true;
 			break;
-		case 31: /* methodeol */
+		case IDX_METHODEOL:
 			dp->methodeol = true;
 			params.tamper = true;
 			break;
-		case 32: /* hosttab */
+		case IDX_HOSTTAB:
 			dp->hosttab = true;
 			params.tamper = true;
 			break;
-		case 33: /* unixeol */
+		case IDX_UNIXEOL:
 			dp->unixeol = true;
 			params.tamper = true;
 			break;
-		case 34: /* tlsrec */
+		case IDX_TLSREC:
 			if (!parse_split_pos(optarg, &dp->tlsrec) && !parse_tlspos(optarg, &dp->tlsrec))
 			{
 				DLOG_ERR("Invalid argument for tlsrec\n");
@@ -1039,7 +1131,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 35: /* tlsrec-pos */
+		case IDX_TLSREC_POS:
 			// obsolete arg
 			i = atoi(optarg);
 			dp->tlsrec.marker = PM_ABS;
@@ -1051,7 +1143,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 36: /* hostlist */
+		case IDX_HOSTLIST:
 			if (bSkip) break;
 			if (!RegisterHostlist(dp, false, optarg))
 			{
@@ -1060,7 +1152,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 37: /* hostlist-domains */
+		case IDX_HOSTLIST_DOMAINS:
 			if (bSkip) break;
 			if (!anon_hl && !(anon_hl=RegisterHostlist(dp, false, NULL)))
 			{
@@ -1074,7 +1166,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 38: /* hostlist-exclude */
+		case IDX_HOSTLIST_EXCLUDE:
 			if (bSkip) break;
 			if (!RegisterHostlist(dp, true, optarg))
 			{
@@ -1083,7 +1175,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 39: /* hostlist-exclude-domains */
+		case IDX_HOSTLIST_EXCLUDE_DOMAINS:
 			if (bSkip) break;
 			if (!anon_hl_exclude && !(anon_hl_exclude=RegisterHostlist(dp, true, NULL)))
 			{
@@ -1097,7 +1189,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 40: /* hostlist-auto */
+		case IDX_HOSTLIST_AUTO:
 			if (bSkip) break;
 			if (dp->hostlist_auto)
 			{
@@ -1126,7 +1218,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true; // need to detect blocks and update autohostlist. cannot just slice.
 			break;
-		case 41: /* hostlist-auto-fail-threshold */
+		case IDX_HOSTLIST_AUTO_FAIL_THRESHOLD:
 			dp->hostlist_auto_fail_threshold = (uint8_t)atoi(optarg);
 			if (dp->hostlist_auto_fail_threshold<1 || dp->hostlist_auto_fail_threshold>20)
 			{
@@ -1134,7 +1226,7 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 42: /* hostlist-auto-fail-time */
+		case IDX_HOSTLIST_AUTO_FAIL_TIME:
 			dp->hostlist_auto_fail_time = (uint8_t)atoi(optarg);
 			if (dp->hostlist_auto_fail_time<1)
 			{
@@ -1142,7 +1234,7 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 43: /* hostlist-auto-debug */
+		case IDX_HOSTLIST_AUTO_DEBUG:
 			{
 				FILE *F = fopen(optarg,"a+t");
 				if (!F)
@@ -1155,11 +1247,11 @@ void parse_params(int argc, char *argv[])
 				params.hostlist_auto_debuglog[sizeof(params.hostlist_auto_debuglog) - 1] = '\0';
 			}
 			break;
-		case 44: /* pidfile */
+		case IDX_PIDFILE:
 			strncpy(params.pidfile,optarg,sizeof(params.pidfile));
 			params.pidfile[sizeof(params.pidfile)-1]='\0';
 			break;
-		case 45: /* debug */
+		case IDX_DEBUG:
 			if (optarg)
 			{
 				if (*optarg=='@')
@@ -1193,52 +1285,52 @@ void parse_params(int argc, char *argv[])
 				params.debug_target = LOG_TARGET_CONSOLE;
 			}
 			break;
-		case 46: /* debug-level */
+		case IDX_DEBUG_LEVEL:
 			params.debug = atoi(optarg);
 			break;
-		case 47: /* dry-run */
+		case IDX_DRY_RUN:
 			bDry = true;
 			break;
-		case 48: /* version */
+		case IDX_VERSION:
 			exit_clean(0);
 			break;
-		case 49: /* comment */
+		case IDX_COMMENT:
 			break;
-		case 50: /* local-rcvbuf */
+		case IDX_LOCAL_RCVBUF:
 #ifdef __linux__
 			params.local_rcvbuf = atoi(optarg)/2;
 #else
 			params.local_rcvbuf = atoi(optarg);
 #endif
 			break;
-		case 51: /* local-sndbuf */
+		case IDX_LOCAL_SNDBUF:
 #ifdef __linux__
 			params.local_sndbuf = atoi(optarg)/2;
 #else
 			params.local_sndbuf = atoi(optarg);
 #endif
 			break;
-		case 52: /* remote-rcvbuf */
+		case IDX_REMOTE_RCVBUF:
 #ifdef __linux__
 			params.remote_rcvbuf = atoi(optarg)/2;
 #else
 			params.remote_rcvbuf = atoi(optarg);
 #endif
 			break;
-		case 53: /* remote-sndbuf */
+		case IDX_REMOTE_SNDBUF:
 #ifdef __linux__
 			params.remote_sndbuf = atoi(optarg)/2;
 #else
 			params.remote_sndbuf = atoi(optarg);
 #endif
 			break;
-		case 54: /* socks */
+		case IDX_SOCKS:
 			params.proxy_type = CONN_TYPE_SOCKS;
 			break;
-		case 55: /* no-resolve */
+		case IDX_NO_RESOLVE:
 			params.no_resolve = true;
 			break;
-		case 56: /* resolver-threads */
+		case IDX_RESOLVER_THREADS:
 			params.resolver_threads = atoi(optarg);
 			if (params.resolver_threads<1 || params.resolver_threads>300)
 			{
@@ -1246,10 +1338,10 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 57: /* skip-nodelay */
+		case IDX_SKIP_NODELAY:
 			params.skip_nodelay = true;
 			break;
-		case 58: /* tamper-start */
+		case IDX_TAMPER_START:
 			{
 				const char *p=optarg;
 				if (*p=='n')
@@ -1263,7 +1355,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper_lim = true;
 			break;
-		case 59: /* tamper-cutoff */
+		case IDX_TAMPER_CUTOFF:
 			{
 				const char *p=optarg;
 				if (*p=='n')
@@ -1277,7 +1369,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper_lim = true;
 			break;
-		case 60: /* connect-bind-addr */
+		case IDX_CONNECT_BIND_ADDR:
 			{
 				char *p = strchr(optarg,'%');
 				if (p) *p++=0;
@@ -1305,7 +1397,7 @@ void parse_params(int argc, char *argv[])
 			break;
 
 
-		case 61: /* new */
+		case IDX_NEW:
 			if (bSkip)
 			{
 				dp_clear(dp);
@@ -1326,31 +1418,31 @@ void parse_params(int argc, char *argv[])
 			anon_hl = anon_hl_exclude = NULL;
 			anon_ips = anon_ips_exclude = NULL;
 			break;
-		case 62: /* skip */
+		case IDX_SKIP:
 			bSkip = true;
 			break;
-		case 63: /* filter-l3 */
+		case IDX_FILTER_L3:
 			if (!wf_make_l3(optarg,&dp->filter_ipv4,&dp->filter_ipv6))
 			{
 				DLOG_ERR("bad value for --filter-l3\n");
 				exit_clean(1);
 			}
 			break;
-		case 64: /* filter-tcp */
+		case IDX_FILTER_TCP:
 			if (!parse_pf_list(optarg,&dp->pf_tcp))
 			{
 				DLOG_ERR("Invalid port filter : %s\n",optarg);
 				exit_clean(1);
 			}
 			break;
-		case 65: /* filter-l7 */
+		case IDX_FILTER_L7:
 			if (!parse_l7_list(optarg,&dp->filter_l7))
 			{
 				DLOG_ERR("Invalid l7 filter : %s\n",optarg);
 				exit_clean(1);
 			}
 			break;
-		case 66: /* ipset */
+		case IDX_IPSET:
 			if (bSkip) break;
 			if (!RegisterIpset(dp, false, optarg))
 			{
@@ -1359,7 +1451,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 67: /* ipset-ip */
+		case IDX_IPSET_IP:
 			if (bSkip) break;
 			if (!anon_ips && !(anon_ips=RegisterIpset(dp, false, NULL)))
 			{
@@ -1373,7 +1465,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 68: /* ipset-exclude */
+		case IDX_IPSET_EXCLUDE:
 			if (bSkip) break;
 			if (!RegisterIpset(dp, true, optarg))
 			{
@@ -1382,7 +1474,7 @@ void parse_params(int argc, char *argv[])
 			}
 			params.tamper = true;
 			break;
-		case 69: /* ipset-exclude-ip */
+		case IDX_IPSET_EXCLUDE_IP:
 			if (bSkip) break;
 			if (!anon_ips_exclude && !(anon_ips_exclude=RegisterIpset(dp, true, NULL)))
 			{
@@ -1398,11 +1490,11 @@ void parse_params(int argc, char *argv[])
 			break;
 
 #if defined(__FreeBSD__)
-		case 70: /* enable-pf */
+		case IDX_ENABLE_PF:
 			params.pf_enable = true;
 			break;
 #elif defined(__linux__) || defined(__APPLE__)
-		case 70: /* local-tcp-user-timeout */
+		case IDX_LOCAL_TCP_USER_TIMEOUT:
 			params.tcp_user_timeout_local = atoi(optarg);
 			if (params.tcp_user_timeout_local<0 || params.tcp_user_timeout_local>86400)
 			{
@@ -1410,7 +1502,7 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 71: /* remote-tcp-user-timeout */
+		case IDX_REMOTE_TCP_USER_TIMEOUT:
 			params.tcp_user_timeout_remote = atoi(optarg);
 			if (params.tcp_user_timeout_remote<0 || params.tcp_user_timeout_remote>86400)
 			{
@@ -1421,7 +1513,7 @@ void parse_params(int argc, char *argv[])
 #endif
 
 #if defined(__linux__)
-		case 72: /* mss */
+		case IDX_MSS:
 			// this option does not work in any BSD and MacOS. OS may accept but it changes nothing
 			dp->mss = atoi(optarg);
 			if (dp->mss<88 || dp->mss>32767)
@@ -1430,7 +1522,7 @@ void parse_params(int argc, char *argv[])
 				exit_clean(1);
 			}
 			break;
-		case 73: /* fix-seg */
+		case IDX_FIX_SEG:
 			if (!params.fix_seg_avail)
 			{
 				DLOG_ERR("--fix-seg is supported since kernel 4.6\n");
@@ -1450,7 +1542,7 @@ void parse_params(int argc, char *argv[])
 				params.fix_seg = FIX_SEG_DEFAULT_MAX_WAIT;
 			break;
 #ifdef SPLICE_PRESENT
-		case 74: /* nosplice */
+		case IDX_NOSPLICE:
 			params.nosplice = true;
 			break;
 #endif