1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-02 08:42:48 +00:00

tcp: add TH_AE capabilities to ppp and pf

Add support for the AE Flag in the TCP header to pf and ppp.
Commonalize to the use of "E"(ECE), "W"(CWR) and "e"(AE)
for the TCP header flags, in line with tcpdump.

Reviewers: kp, cc, tuexen, cy, #transport!
Sponsored by: NetApp, Inc.
Differential Revision: https://reviews.freebsd.org/D47106
This commit is contained in:
Richard Scheffenegger 2024-11-29 09:50:24 +01:00
parent 0fc7bdc978
commit 347dd0539f
23 changed files with 108 additions and 88 deletions

View File

@ -178,7 +178,7 @@ typedef int (* copyfunc_t)(void *, void *, size_t);
extern char thishost[MAXHOSTNAMELEN];
extern char flagset[];
extern u_char flags[];
extern uint16_t flags[];
extern struct ipopt_names ionames[];
extern struct ipopt_names secclass[];
extern char *icmpcodes[MAX_ICMPCODE + 1];
@ -330,7 +330,7 @@ extern int remove_hash(struct iphtable_s *, ioctlfunc_t);
extern int remove_hashnode(int, char *, struct iphtent_s *, ioctlfunc_t);
extern int remove_pool(ip_pool_t *, ioctlfunc_t);
extern int remove_poolnode(int, char *, ip_pool_node_t *, ioctlfunc_t);
extern u_char tcpflags(char *);
extern uint16_t tcpflags(char *);
extern void printc(struct frentry *);
extern void printC(int);
extern void emit(int, int, void *, struct frentry *);

View File

@ -533,10 +533,10 @@ When matching TCP flags, it is normal to just list the flag that you
wish to be set. By default the set of flags it is compared against
is "FSRPAU". Rules that say "flags S" will be displayed by ipfstat(8)
as having "flags S/FSRPAU". This is normal.
The last two flags, "C" and "E", are optional - they
The last three flags, "E", "W" and "e", are optional - they
may or may not be used by an end host and have no bearing on either
the acceptance of data nor control of the connection. Masking them
out with "flags S/FSRPAUCE" may cause problems for remote hosts
out with "flags S/FSRPAUEWe" may cause problems for remote hosts
making a successful connection.
.PP
.nf

View File

@ -125,7 +125,7 @@ This is the default if no \fB\-F\fP argument is specified.
The format used is as follows:
.nf
"in"|"out" "on" if ["tcp"|"udp"|"icmp"]
srchost[,srcport] dsthost[,destport] [FSRPAU]
srchost[,srcport] dsthost[,destport] [FSRPAUEWe]
.fi
.PP
This allows for a packet going "in" or "out" of an interface (if) to be

View File

@ -1045,9 +1045,9 @@ void set_tcpsum(char **arg)
void set_tcpflags(char **arg)
{
static char flags[] = "ASURPF";
static char flags[] = "ASURPFEWe";
static int flagv[] = { TH_ACK, TH_SYN, TH_URG, TH_RST, TH_PUSH,
TH_FIN } ;
TH_FIN, TH_ECE, TH_CWR, TH_AE } ;
char *s, *t;
for (s = *arg; *s; s++)
@ -1056,10 +1056,10 @@ void set_tcpflags(char **arg)
fprintf(stderr, "unknown TCP flag %c\n", *s);
break;
}
tcp->th_flags = strtol(*arg, NULL, 0);
__tcp_set_flags(tcp, strtol(*arg, NULL, 0));
break;
} else
tcp->th_flags |= flagv[t - flags];
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | flagv[t - flags]);
free(*arg);
*arg = NULL;
}

View File

@ -77,7 +77,8 @@ struct flags tcpfl[] = {
{ TH_URG, 'U' },
{ TH_PUSH,'P' },
{ TH_ECN, 'E' },
{ TH_CWR, 'C' },
{ TH_CWR, 'W' },
{ TH_AE, 'e' },
{ 0, '\0' }
};
@ -1196,7 +1197,7 @@ print_ipflog(config_t *conf, char *buf, int blen)
*t++ = ' ';
*t++ = '-';
for (i = 0; tcpfl[i].value; i++)
if (tp->th_flags & tcpfl[i].value)
if (__tcp_get_flags(tp) & tcpfl[i].value)
*t++ = tcpfl[i].flag;
if (ipmonopts & IPMON_VERBOSE) {
sprintf(t, " %lu %lu %hu",

View File

@ -261,7 +261,7 @@ send_tcp(int nfd, int mtu, ip_t *ip, struct in_addr gwip)
i = sizeof(struct tcpiphdr) / sizeof(long);
if ((t2->th_flags == TH_SYN) && !ntohs(ip->ip_off) &&
if ((__tcp_get_flags(t2) == TH_SYN) && !ntohs(ip->ip_off) &&
(lbuf[i] != htonl(0x020405b4))) {
lbuf[i] = htonl(0x020405b4);
bcopy((char *)ip + hlen + thlen, (char *)ip + hlen + thlen + 4,

View File

@ -250,7 +250,8 @@ unset, it defaults to 0 and is automatically calculated.
.TP
.B flags <tcp-flags>
sets the TCP flags field to match the flags specified. Valid flags are
"S" (SYN), "A" (ACK), "R" (RST), "F" (FIN), "U" (URG), "P" (PUSH).
"S" (SYN), "A" (ACK), "R" (RST), "F" (FIN), "U" (URG), "P" (PUSH),
"E" (ECE), "W" (CWR), "e" (AE).
.TP
.B opt
indicates that TCP header options follow. As TCP options are added to the

View File

@ -365,22 +365,31 @@ main(int argc, char **argv)
switch(c)
{
case 'S' : case 's' :
tcp->th_flags |= TH_SYN;
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_SYN);
break;
case 'A' : case 'a' :
tcp->th_flags |= TH_ACK;
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_ACK);
break;
case 'F' : case 'f' :
tcp->th_flags |= TH_FIN;
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_FIN);
break;
case 'R' : case 'r' :
tcp->th_flags |= TH_RST;
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_RST);
break;
case 'P' : case 'p' :
tcp->th_flags |= TH_PUSH;
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_PUSH);
break;
case 'U' : case 'u' :
tcp->th_flags |= TH_URG;
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_URG);
break;
case 'E' :
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_ECE);
break;
case 'W' :
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_CWR);
break;
case 'e' :
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | TH_AE);
break;
}
@ -390,8 +399,8 @@ main(int argc, char **argv)
printf("Source: %s\n", inet_ntoa(ip->ip_src));
printf("Dest: %s\n", inet_ntoa(ip->ip_dst));
printf("Gateway: %s\n", inet_ntoa(gwip));
if (ip->ip_p == IPPROTO_TCP && tcp->th_flags)
printf("Flags: %#x\n", tcp->th_flags);
if (ip->ip_p == IPPROTO_TCP && __tcp_get_flags(tcp))
printf("Flags: %#x\n", __tcp_get_flags(tcp));
printf("mtu: %d\n", mtu);
if (ip->ip_p == IPPROTO_UDP) {

View File

@ -924,9 +924,8 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
*/
TCP_OFF_A(t, sizeof(*t) >> 2);
printf("5.1 Test TCP flag combinations\n");
for (i = 0; i <= (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN);
i++) {
t->th_flags = i;
for (i = 0; i <= TH_FLAGS; i++) {
__tcp_set_flags(t, i);
(void) send_tcp(nfd, mtu, ip, gwip);
printf("%d\r", i);
fflush(stdout);
@ -936,7 +935,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
}
if (!ptest || (ptest == 2)) {
t->th_flags = TH_SYN;
__tcp_set_flags(t, TH_SYN);
/*
* Test 2: seq = 0, seq = 1, seq = 0x7fffffff, seq=0x80000000,
* seq = 0xa000000, seq = 0xffffffff
@ -979,7 +978,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
}
if (!ptest || (ptest == 3)) {
t->th_flags = TH_ACK;
__tcp_set_flags(t, TH_ACK);
/*
* Test 3: ack = 0, ack = 1, ack = 0x7fffffff, ack = 0x8000000
* ack = 0xa000000, ack = 0xffffffff
@ -1022,7 +1021,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
}
if (!ptest || (ptest == 4)) {
t->th_flags = TH_SYN;
__tcp_set_flags(t, TH_SYN);
/*
* Test 4: win = 0, win = 32768, win = 65535
*/
@ -1092,7 +1091,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
/*
* Test 5: urp
*/
t->th_flags = TH_ACK|TH_URG;
__tcp_set_flags(t, TH_ACK|TH_URG);
printf("5.5.1 TCP Urgent pointer, sport %hu dport %hu\n",
ntohs(t->th_sport), ntohs(t->th_dport));
t->th_urp = htons(1);
@ -1111,7 +1110,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
(void) send_tcp(nfd, mtu, ip, gwip);
PAUSE();
t->th_urp = 0;
t->th_flags &= ~TH_URG;
__tcp_set_flags(t, __tcp_get_flags(t) & ~TH_URG);
ip->ip_len = sizeof(ip_t) + sizeof(tcphdr_t);
}
@ -1119,7 +1118,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
/*
* Test 6: data offset, off = 0, off is inside, off is outside
*/
t->th_flags = TH_ACK;
__tcp_set_flags(t, TH_ACK);
printf("5.6.1 TCP off = 1-15, len = 40\n");
for (i = 1; i < 16; i++) {
TCP_OFF_A(t, ntohs(i));
@ -1141,7 +1140,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
TCP_OFF_A(t, 0);
if (!ptest || (ptest == 7)) {
t->th_flags = TH_SYN;
__tcp_set_flags(t, TH_SYN);
/*
* Test 7: sport = 0, sport = 1, sport = 32767
* sport = 32768, sport = 65535
@ -1179,7 +1178,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
if (!ptest || (ptest == 8)) {
t->th_sport = htons(1);
t->th_flags = TH_SYN;
__tcp_set_flags(t, TH_SYN);
/*
* Test 8: dport = 0, dport = 1, dport = 32767
* dport = 32768, dport = 65535
@ -1221,7 +1220,7 @@ ip_test5(char *dev, int mtu, ip_t *ip, struct in_addr gwip, int ptest)
/* chose SMTP port 25 */
t->th_sport = htons(25);
t->th_dport = htons(25);
t->th_flags = TH_SYN;
__tcp_set_flags(t, TH_SYN);
ip->ip_src = ip->ip_dst;
(void) send_tcp(nfd, mtu, ip, gwip);
fflush(stdout);

View File

@ -51,8 +51,8 @@ dumppacket(ip_t *ip)
printf(" seq %lu:%lu flags ",
(u_long)t->th_seq, (u_long)t->th_ack);
for (j = 0, i = 1; i < 256; i *= 2, j++)
if (t->th_flags & i)
printf("%c", "FSRPAU--"[j]);
if (__tcp_get_flags(t) & i)
printf("%c", "FSRPAUEWe"[j]);
}
putchar('\n');
}

View File

@ -18,7 +18,10 @@
#ifndef TH_CWR
# define TH_CWR 0x80
#endif
#ifndef TH_AE
# define TH_AE 0x100
#endif
char flagset[] = "FSRPAUEC";
u_char flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG,
TH_ECN, TH_CWR };
char flagset[] = "FSRPAUEWe";
uint16_t flags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH, TH_ACK, TH_URG,
TH_ECN, TH_CWR, TH_AE };

View File

@ -20,9 +20,9 @@ static int text_open(char *), text_close(void);
static int text_readip(mb_t *, char **, int *);
static int parseline(char *, ip_t *, char **, int *);
static char myflagset[] = "FSRPAUEC";
static u_char myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
TH_ACK, TH_URG, TH_ECN, TH_CWR };
static char myflagset[] = "FSRPAUEWe";
static uint16_t myflags[] = { TH_FIN, TH_SYN, TH_RST, TH_PUSH,
TH_ACK, TH_URG, TH_ECN, TH_CWR, TH_AE };
struct ipread iptext = { text_open, text_close, text_readip, R_DO_CKSUM };
static FILE *tfp = NULL;
@ -265,15 +265,15 @@ parseline(char *line, ip_t *ip, char **ifn, int *out)
if (*cpp != NULL) {
char *s, *t;
tcp->th_flags = 0;
__tcp_set_flags(tcp, 0);
for (s = *cpp; *s; s++)
if ((t = strchr(myflagset, *s)))
tcp->th_flags |= myflags[t-myflagset];
if (tcp->th_flags)
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | myflags[t-myflagset]);
if (__tcp_get_flags(tcp))
cpp++;
}
if (tcp->th_flags & TH_URG)
if (__tcp_get_flags(tcp) & TH_URG)
tcp->th_urp = htons(1);
if (*cpp && !strncasecmp(*cpp, "seq=", 4)) {
@ -436,15 +436,15 @@ parseipv6(char **cpp, ip6_t *ip6, char **ifn, int *out)
if (*cpp != NULL) {
char *s, *t;
tcp->th_flags = 0;
__tcp_set_flags(tcp, 0);
for (s = *cpp; *s; s++)
if ((t = strchr(myflagset, *s)))
tcp->th_flags |= myflags[t-myflagset];
if (tcp->th_flags)
__tcp_set_flags(tcp, __tcp_get_flags(tcp) | myflags[t-myflagset]);
if (__tcp_get_flags(tcp))
cpp++;
}
if (tcp->th_flags & TH_URG)
if (__tcp_get_flags(tcp) & TH_URG)
tcp->th_urp = htons(1);
if (*cpp && !strncasecmp(*cpp, "seq=", 4)) {

View File

@ -19,6 +19,7 @@ printpacket(int dir, mb_t *m)
{
u_short len, off;
tcphdr_t *tcp;
uint16_t tcpflags;
ip_t *ip;
ip = MTOD(m, ip_t *);
@ -82,24 +83,26 @@ printpacket(int dir, mb_t *m)
if (!(off & IP_OFFMASK)) {
if (ip->ip_p == IPPROTO_TCP || ip->ip_p == IPPROTO_UDP)
PRINTF(",%d", ntohs(tcp->th_dport));
if ((ip->ip_p == IPPROTO_TCP) && (tcp->th_flags != 0)) {
if ((ip->ip_p == IPPROTO_TCP) && ((tcpflags = __tcp_get_flags(tcp)) != 0)) {
putchar(' ');
if (tcp->th_flags & TH_FIN)
if (tcpflags & TH_FIN)
putchar('F');
if (tcp->th_flags & TH_SYN)
if (tcpflags & TH_SYN)
putchar('S');
if (tcp->th_flags & TH_RST)
if (tcpflags & TH_RST)
putchar('R');
if (tcp->th_flags & TH_PUSH)
if (tcpflags & TH_PUSH)
putchar('P');
if (tcp->th_flags & TH_ACK)
if (tcpflags & TH_ACK)
putchar('A');
if (tcp->th_flags & TH_URG)
if (tcpflags & TH_URG)
putchar('U');
if (tcp->th_flags & TH_ECN)
if (tcpflags & TH_ECN)
putchar('E');
if (tcp->th_flags & TH_CWR)
putchar('C');
if (tcpflags & TH_CWR)
putchar('W');
if (tcpflags & TH_AE)
putchar('e');
}
}

View File

@ -4,10 +4,10 @@
void
printtcpflags(u_32_t tcpf, u_32_t tcpfm)
{
u_char *t;
uint16_t *t;
char *s;
if (tcpf & ~TCPF_ALL) {
if (tcpf & ~TH_FLAGS) {
PRINTF("0x%x", tcpf);
} else {
for (s = flagset, t = flags; *s; s++, t++) {
@ -18,7 +18,7 @@ printtcpflags(u_32_t tcpf, u_32_t tcpfm)
if (tcpfm) {
(void)putchar('/');
if (tcpfm & ~TCPF_ALL) {
if (tcpfm & ~TH_FLAGS) {
PRINTF("0x%x", tcpfm);
} else {
for (s = flagset, t = flags; *s; s++, t++)

View File

@ -9,13 +9,13 @@
#include "ipf.h"
extern char flagset[];
extern u_char flags[];
extern char flagset[];
extern uint16_t flags[];
u_char tcp_flags(char *flgs, u_char *mask, int linenum)
uint16_t tcp_flags(char *flgs, uint16_t *mask, int linenum)
{
u_char tcpf = 0, tcpfm = 0;
uint16_t tcpf = 0, tcpfm = 0;
char *s;
s = strchr(flgs, '/');
@ -37,9 +37,9 @@ u_char tcp_flags(char *flgs, u_char *mask, int linenum)
if (!tcpfm) {
if (tcpf == TH_SYN)
tcpfm = 0xff & ~(TH_ECN|TH_CWR);
tcpfm = TH_FLAGS & ~(TH_ECN|TH_CWR);
else
tcpfm = 0xff & ~(TH_ECN);
tcpfm = TH_FLAGS & ~(TH_ECN);
}
*mask = tcpfm;
return (tcpf);

View File

@ -19,14 +19,17 @@
#ifndef TH_CWR
# define TH_CWR 0x80
#endif
#ifndef TH_AE
# define TH_AE 0x100
#endif
extern char flagset[];
extern u_char flags[];
extern char flagset[];
extern uint16_t flags[];
u_char tcpflags(char *flgs)
uint16_t tcpflags(char *flgs)
{
u_char tcpf = 0;
uint16_t tcpf = 0;
char *s, *t;
for (s = flgs; *s; s++) {

View File

@ -44,6 +44,7 @@
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <netinet/tcp.h>
#include <net/pfvar.h>
#include <arpa/inet.h>
@ -67,7 +68,7 @@
void print_op (u_int8_t, const char *, const char *);
void print_port (u_int8_t, u_int16_t, u_int16_t, const char *, int);
void print_ugid (u_int8_t, unsigned, unsigned, const char *, unsigned);
void print_flags (u_int8_t);
void print_flags (uint16_t);
void print_fromto(struct pf_rule_addr *, pf_osfp_t,
struct pf_rule_addr *, sa_family_t, u_int8_t, int, int);
int ifa_skip_if(const char *filter, struct node_host *p);
@ -77,7 +78,7 @@ struct node_host *host_v4(const char *, int);
struct node_host *host_v6(const char *, int);
struct node_host *host_dns(const char *, int, int);
const char * const tcpflags = "FSRPAUEW";
const char * const tcpflags = "FSRPAUEWe";
static const struct icmptypeent icmp_type[] = {
{ "echoreq", ICMP_ECHO },
@ -365,7 +366,7 @@ print_ugid(u_int8_t op, unsigned u1, unsigned u2, const char *t, unsigned umax)
}
void
print_flags(u_int8_t f)
print_flags(uint16_t f)
{
int i;
@ -1286,7 +1287,7 @@ int
parse_flags(char *s)
{
char *p, *q;
u_int8_t f = 0;
uint16_t f = 0;
for (p = s; *p; p++) {
if ((q = strchr(tcpflags, *p)) == NULL)
@ -1294,7 +1295,7 @@ parse_flags(char *s)
else
f |= 1 << (q - tcpflags);
}
return (f ? f : PF_TH_ALL);
return (f ? f : TH_FLAGS);
}
void

View File

@ -55,8 +55,6 @@
#define PF_OPT_RECURSE 0x4000
#define PF_OPT_KILLMATCH 0x8000
#define PF_TH_ALL 0xFF
#define PF_NAT_PROXY_PORT_LOW 50001
#define PF_NAT_PROXY_PORT_HIGH 65535

View File

@ -2343,7 +2343,7 @@ extern struct pf_ksrc_node *pf_find_src_node(struct pf_addr *,
extern void pf_unlink_src_node(struct pf_ksrc_node *);
extern u_int pf_free_src_nodes(struct pf_ksrc_node_list *);
extern void pf_print_state(struct pf_kstate *);
extern void pf_print_flags(u_int8_t);
extern void pf_print_flags(uint16_t);
extern int pf_addr_wrap_neq(struct pf_addr_wrap *,
struct pf_addr_wrap *);
extern u_int16_t pf_cksum_fixup(u_int16_t, u_int16_t, u_int16_t,

View File

@ -71,7 +71,7 @@ struct tcphdr {
#define TH_RES3 0x200
#define TH_RES2 0x400
#define TH_RES1 0x800
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECE|TH_CWR)
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|TH_ECE|TH_CWR|TH_AE)
#define PRINT_TH_FLAGS "\20\1FIN\2SYN\3RST\4PUSH\5ACK\6URG\7ECE\10CWR\11AE"
u_short th_win; /* window */

View File

@ -695,9 +695,6 @@ typedef struct tcpiphdr tcpiphdr_t;
#endif
#define IPMINLEN(i, h) ((i)->ip_len >= (IP_HL(i) * 4 + sizeof(struct h)))
#define TCPF_ALL (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG|\
TH_ECN|TH_CWR)
#if !SOLARIS && !defined(m_act)
# define m_act m_nextpkt
#endif
@ -1128,7 +1125,10 @@ typedef struct tcpiphdr tcpiphdr_t;
#ifndef TH_CWR
# define TH_CWR 0x80
#endif
#define TH_ECNALL (TH_ECN|TH_CWR)
#ifndef TH_AE
# define TH_AE 0x100
#endif
#define TH_ECNALL (TH_ECN|TH_CWR|TH_AE)
/*
* TCP States

View File

@ -2934,7 +2934,7 @@ pf_print_state_parts(struct pf_kstate *s,
}
void
pf_print_flags(u_int8_t f)
pf_print_flags(uint16_t f)
{
if (f)
printf(" ");
@ -2954,6 +2954,8 @@ pf_print_flags(u_int8_t f)
printf("E");
if (f & TH_CWR)
printf("W");
if (f & TH_AE)
printf("e");
}
#define PF_SET_SKIP_STEPS(i) \

View File

@ -561,7 +561,7 @@ PacketCheck(struct bundle *bundle, u_int32_t family,
{
char logbuf[200];
static const char *const TcpFlags[] = {
"FIN", "SYN", "RST", "PSH", "ACK", "URG"
"FIN", "SYN", "RST", "PSH", "ACK", "URG", "ECE", "CWR", "AE"
};
const struct tcphdr *th;
const struct udphdr *uh;
@ -830,7 +830,7 @@ PacketCheck(struct bundle *bundle, u_int32_t family,
"%s:%d", ncpaddr_ntoa(&dstaddr), ntohs(th->th_dport));
loglen += strlen(logbuf + loglen);
n = 0;
for (mask = TH_FIN; mask != 0x40; mask <<= 1) {
for (mask = TH_FIN; mask <= TH_FLAGS; mask <<= 1) {
if (__tcp_get_flags(th) & mask) {
snprintf(logbuf + loglen, sizeof logbuf - loglen, " %s", TcpFlags[n]);
loglen += strlen(logbuf + loglen);