tech-net archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: NPF: TCP options

Le 13/03/2018 à 21:44, Maxime Villard a écrit :
Le 13/03/2018 à 21:22, Mindaugas Rasiukevicius a écrit :
Maxime Villard <> wrote:
Answering in this thread now, to prevent further confusions.

Le 13/03/2018 à 00:23, Mindaugas Rasiukevicius a écrit :
So NPF's behavior should be aligned to that of the kernel; that is to
say, NPF should ignore TCP options with uncommon lengths - which does
not mean dropping the packet. (We can discuss about changing the
kernel's behavior to be that of NPF, but as I said in my answer to
Joerg, the kernel's behavior is the one that is the most "common".)

Not exactly, no.  NPF is not a host/kernel.  It is a man in the middle,
concerning packets sent by different hosts (which might have different
TCP/IP implementations and applications).  It operates based on its own
set of rules.

It sounds like you didn't understand my point.

I'm saying that the TCP-options behavior in the NetBSD kernel and NPF is
not the same. There is a divergence. Since there is a divergence, it is
possible to bypass the normalization procedures on TCP options (and along
with that, to lead to possibly unexpected behavior).

So what?  You talk about differences in behaviour, but you fail to explain
the reasons why any of this matters.

Read the very first email of this thread, I said what was wrong about not
looking at the length of the TCP options.

It matters because of bypasses, as I said only an hour ago in the mail you
just quoted.

Back on this; so I tested, and it works, the scenario I described in my first
email does bypass max-mss clamping.

That is to say, when you have a configuration of the kind:

	procedure "norm" {
		normalize: "max-mss" 25000
	group default {
		pass in all apply "norm"

sending a packet crafted as:

	uint8_t *nptr = (uint8_t *)(tcphdr + 1);
	uint16_t *mss;

	nptr[0] = TCPOPT_MAXSEG;
	nptr[1] = TCPOLEN_MAXSEG + 1;
	mss = (uint16_t *)&nptr[2];
	*mss = htons(20000); /* NPF reads this */
	nptr[4] = TCPOPT_EOL;
	nptr[5] = TCPOPT_MAXSEG;
	nptr[6] = TCPOLEN_MAXSEG;
	mss = (uint16_t *)&nptr[7];
	*mss = htons(30000); /* the kernel reads this */

allows you to bypass the rule. NPF reads mss=20000, but the kernel reads
mss=30000 and registers the segment size as 30000.

You can easily see that by adding two printfs, one in npf_normalize and one
in tcp_dooptions.

I will commit my patch, unless there is a valid technical reason for not
doing so.


Home | Main Index | Thread Index | Old Index