npf_state_test.c revision 1.1.2.2 1 1.1.2.2 riz /* $NetBSD: npf_state_test.c,v 1.1.2.2 2012/06/26 00:07:18 riz Exp $ */
2 1.1.2.2 riz
3 1.1.2.2 riz /*
4 1.1.2.2 riz * NPF state tracking test.
5 1.1.2.2 riz *
6 1.1.2.2 riz * Public Domain.
7 1.1.2.2 riz */
8 1.1.2.2 riz
9 1.1.2.2 riz #include <sys/types.h>
10 1.1.2.2 riz #include <sys/kmem.h>
11 1.1.2.2 riz
12 1.1.2.2 riz #include "npf_impl.h"
13 1.1.2.2 riz #include "npf_test.h"
14 1.1.2.2 riz
15 1.1.2.2 riz typedef struct {
16 1.1.2.2 riz int tcpfl; /* TCP flags. */
17 1.1.2.2 riz int tlen; /* TCP data length. */
18 1.1.2.2 riz uint32_t seq; /* SEQ number. */
19 1.1.2.2 riz uint32_t ack; /* ACK number. */
20 1.1.2.2 riz uint32_t win; /* TCP Window. */
21 1.1.2.2 riz int flags; /* Direction et al. */
22 1.1.2.2 riz } tcp_meta_t;
23 1.1.2.2 riz
24 1.1.2.2 riz #define S TH_SYN
25 1.1.2.2 riz #define A TH_ACK
26 1.1.2.2 riz #define F TH_FIN
27 1.1.2.2 riz #define OUT 0x1
28 1.1.2.2 riz #define IN 0x2
29 1.1.2.2 riz #define ERR 0x4
30 1.1.2.2 riz #define CLEAR .flags = 0
31 1.1.2.2 riz
32 1.1.2.2 riz static const tcp_meta_t packet_sequence[] = {
33 1.1.2.2 riz /*
34 1.1.2.2 riz * TCP data SEQ ACK WIN
35 1.1.2.2 riz */
36 1.1.2.2 riz
37 1.1.2.2 riz /* Out of order ACK. */
38 1.1.2.2 riz { S, 0, 9999, 0, 4096, OUT },
39 1.1.2.2 riz { S|A, 0, 9, 10000, 2048, IN },
40 1.1.2.2 riz { A, 0, 10000, 10, 4096, OUT },
41 1.1.2.2 riz /* --- */
42 1.1.2.2 riz { A, 0, 10, 10000, 2048, IN },
43 1.1.2.2 riz { A, 1000, 10000, 10, 4096, OUT },
44 1.1.2.2 riz { A, 1000, 11000, 10, 4096, OUT },
45 1.1.2.2 riz { A, 0, 10, 12000, 2048, IN },
46 1.1.2.2 riz { A, 0, 10, 13000, 2048, IN },
47 1.1.2.2 riz { A, 1000, 12000, 10, 4096, OUT },
48 1.1.2.2 riz { A, 0, 10, 11000, 1048, IN },
49 1.1.2.2 riz /* --- */
50 1.1.2.2 riz { A, 1000, 14000, 10, 4096, OUT },
51 1.1.2.2 riz { A, 0, 10, 13000, 2048, IN },
52 1.1.2.2 riz { CLEAR },
53 1.1.2.2 riz
54 1.1.2.2 riz /* Retransmission after out of order ACK and missing ACK. */
55 1.1.2.2 riz { S, 0, 9999, 0, 1000, OUT },
56 1.1.2.2 riz { S|A, 0, 9, 10000, 4000, IN },
57 1.1.2.2 riz { A, 0, 10000, 10, 1000, OUT },
58 1.1.2.2 riz /* --- */
59 1.1.2.2 riz { A, 1000, 10000, 10, 1000, OUT },
60 1.1.2.2 riz { A, 0, 10, 11000, 4000, IN },
61 1.1.2.2 riz { A, 1000, 11000, 10, 1000, OUT },
62 1.1.2.2 riz { A, 1000, 12000, 10, 1000, OUT },
63 1.1.2.2 riz { A, 1000, 13000, 10, 1000, OUT },
64 1.1.2.2 riz { A, 1000, 14000, 10, 1000, OUT },
65 1.1.2.2 riz /* --- Assume the first was delayed; second was lost after us. */
66 1.1.2.2 riz { A, 0, 10, 15000, 4000, IN },
67 1.1.2.2 riz { A, 0, 10, 15000, 2000, IN },
68 1.1.2.2 riz /* --- */
69 1.1.2.2 riz { A, 1000, 12000, 10, 1000, OUT },
70 1.1.2.2 riz { CLEAR },
71 1.1.2.2 riz
72 1.1.2.2 riz /* Out of window. */
73 1.1.2.2 riz { S, 0, 9, 0, 8760, OUT },
74 1.1.2.2 riz { S|A, 0, 9999, 10, 1000, IN },
75 1.1.2.2 riz { A, 0, 10, 10000, 8760, OUT },
76 1.1.2.2 riz /* --- */
77 1.1.2.2 riz { A, 1460, 10000, 10, 1000, IN },
78 1.1.2.2 riz { A, 1460, 11460, 10, 1000, IN },
79 1.1.2.2 riz { A, 0, 10, 12920, 8760, OUT },
80 1.1.2.2 riz { A, 1460, 12920, 10, 1000, IN },
81 1.1.2.2 riz { A, 0, 10, 14380, 8760, OUT },
82 1.1.2.2 riz { A, 1460, 17300, 10, 1000, IN },
83 1.1.2.2 riz { A, 0, 10, 14380, 8760, OUT },
84 1.1.2.2 riz { A, 1460, 18760, 10, 1000, IN },
85 1.1.2.2 riz { A, 0, 10, 14380, 8760, OUT },
86 1.1.2.2 riz { A, 1460, 20220, 10, 1000, IN },
87 1.1.2.2 riz { A, 0, 10, 14380, 8760, OUT },
88 1.1.2.2 riz { A, 1460, 21680, 10, 1000, IN },
89 1.1.2.2 riz { A, 0, 10, 14380, 8760, OUT },
90 1.1.2.2 riz /* --- */
91 1.1.2.2 riz { A, 1460, 14380, 10, 1000, IN },
92 1.1.2.2 riz { A, 1460, 23140, 10, 1000, IN|ERR },
93 1.1.2.2 riz { CLEAR },
94 1.1.2.2 riz
95 1.1.2.2 riz };
96 1.1.2.2 riz
97 1.1.2.2 riz #undef S
98 1.1.2.2 riz #undef A
99 1.1.2.2 riz #undef F
100 1.1.2.2 riz
101 1.1.2.2 riz static struct mbuf *
102 1.1.2.2 riz construct_packet(const tcp_meta_t *p)
103 1.1.2.2 riz {
104 1.1.2.2 riz struct mbuf *m = mbuf_construct(IPPROTO_TCP);
105 1.1.2.2 riz struct ip *ip;
106 1.1.2.2 riz struct tcphdr *th;
107 1.1.2.2 riz
108 1.1.2.2 riz th = mbuf_return_hdrs(m, false, &ip);
109 1.1.2.2 riz
110 1.1.2.2 riz /* Imitate TCP payload, set TCP sequence numbers, flags and window. */
111 1.1.2.2 riz ip->ip_len = htons(sizeof(struct ip) + sizeof(struct tcphdr) + p->tlen);
112 1.1.2.2 riz th->th_seq = htonl(p->seq);
113 1.1.2.2 riz th->th_ack = htonl(p->ack);
114 1.1.2.2 riz th->th_flags = p->tcpfl;
115 1.1.2.2 riz th->th_win = htons(p->win);
116 1.1.2.2 riz return m;
117 1.1.2.2 riz }
118 1.1.2.2 riz
119 1.1.2.2 riz static bool
120 1.1.2.2 riz process_packet(const int i, npf_state_t *nst, bool *snew)
121 1.1.2.2 riz {
122 1.1.2.2 riz const tcp_meta_t *p = &packet_sequence[i];
123 1.1.2.2 riz npf_cache_t npc = { .npc_info = 0 };
124 1.1.2.2 riz nbuf_t *nbuf;
125 1.1.2.2 riz int ret;
126 1.1.2.2 riz
127 1.1.2.2 riz if (p->flags == 0) {
128 1.1.2.2 riz npf_state_destroy(nst);
129 1.1.2.2 riz *snew = true;
130 1.1.2.2 riz return true;
131 1.1.2.2 riz }
132 1.1.2.2 riz
133 1.1.2.2 riz nbuf = (nbuf_t *)construct_packet(p);
134 1.1.2.2 riz ret = npf_cache_all(&npc, nbuf);
135 1.1.2.2 riz KASSERT((ret & NPC_IPFRAG) == 0);
136 1.1.2.2 riz
137 1.1.2.2 riz if (*snew) {
138 1.1.2.2 riz ret = npf_state_init(&npc, nbuf, nst);
139 1.1.2.2 riz KASSERT(ret == true);
140 1.1.2.2 riz *snew = false;
141 1.1.2.2 riz }
142 1.1.2.2 riz ret = npf_state_inspect(&npc, nbuf, nst, p->flags == OUT);
143 1.1.2.2 riz m_freem(nbuf);
144 1.1.2.2 riz
145 1.1.2.2 riz return ret ? true : (p->flags & ERR) != 0;
146 1.1.2.2 riz }
147 1.1.2.2 riz
148 1.1.2.2 riz bool
149 1.1.2.2 riz npf_state_test(bool verbose)
150 1.1.2.2 riz {
151 1.1.2.2 riz npf_state_t nst;
152 1.1.2.2 riz bool snew = true;
153 1.1.2.2 riz
154 1.1.2.2 riz for (u_int i = 0; i < __arraycount(packet_sequence); i++) {
155 1.1.2.2 riz if (process_packet(i, &nst, &snew)) {
156 1.1.2.2 riz continue;
157 1.1.2.2 riz }
158 1.1.2.2 riz if (verbose) {
159 1.1.2.2 riz printf("Failed on packet %d, state dump:\n", i);
160 1.1.2.2 riz npf_state_dump(&nst);
161 1.1.2.2 riz }
162 1.1.2.2 riz return false;
163 1.1.2.2 riz }
164 1.1.2.2 riz return true;
165 1.1.2.2 riz }
166