Skip to content

Commit

Permalink
tcp: add TH_AE capabilities to ppp and pf
Browse files Browse the repository at this point in the history
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
  • Loading branch information
rscheff committed Nov 29, 2024
1 parent 0fc7bdc commit 347dd05
Show file tree
Hide file tree
Showing 23 changed files with 108 additions and 88 deletions.
4 changes: 2 additions & 2 deletions sbin/ipf/common/ipf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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 *);
Expand Down
4 changes: 2 additions & 2 deletions sbin/ipf/ipf/ipf.5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion sbin/ipf/ipftest/ipftest.1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions sbin/ipf/iplang/iplang_y.y
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
Expand All @@ -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;
}
Expand Down
5 changes: 3 additions & 2 deletions sbin/ipf/ipmon/ipmon.c
Original file line number Diff line number Diff line change
Expand Up @@ -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' }
};

Expand Down Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion sbin/ipf/ipsend/ip.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion sbin/ipf/ipsend/ipsend.5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 17 additions & 8 deletions sbin/ipf/ipsend/ipsend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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) {
Expand Down
23 changes: 11 additions & 12 deletions sbin/ipf/ipsend/iptests.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand All @@ -1111,15 +1110,15 @@ 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);
}

if (!ptest || (ptest == 6)) {
/*
* 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));
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions sbin/ipf/ipsend/resend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
Expand Down
9 changes: 6 additions & 3 deletions sbin/ipf/libipf/flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
22 changes: 11 additions & 11 deletions sbin/ipf/libipf/ipft_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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)) {
Expand Down
23 changes: 13 additions & 10 deletions sbin/ipf/libipf/printpacket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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');
}
}

Expand Down
6 changes: 3 additions & 3 deletions sbin/ipf/libipf/printtcpflags.c
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand All @@ -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++)
Expand Down
Loading

0 comments on commit 347dd05

Please sign in to comment.