npf_nbuf_test.c revision 1.3 1 /* $NetBSD: npf_nbuf_test.c,v 1.3 2012/12/24 19:05:48 rmind Exp $ */
2
3 /*
4 * NPF nbuf interface test.
5 *
6 * Public Domain.
7 */
8
9 #include <sys/types.h>
10 #include <sys/kmem.h>
11
12 #include "npf_impl.h"
13 #include "npf_test.h"
14
15 #define MBUF_CHAIN_LEN 128
16
17 CTASSERT((MBUF_CHAIN_LEN % sizeof(uint32_t)) == 0);
18
19 static char *
20 parse_nbuf_chain(struct mbuf *m)
21 {
22 const void *dummy_ifp = (void *)0xdeadbeef;
23 char *s = kmem_zalloc(MBUF_CHAIN_LEN + 1, KM_SLEEP);
24 nbuf_t nbuf;
25 int n;
26
27 nbuf_init(&nbuf, m, dummy_ifp);
28 for (n = 0; ; ) {
29 void *nptr;
30 char d[4 + 1];
31
32 nptr = nbuf_ensure_contig(&nbuf, sizeof(uint32_t));
33 if (nptr == NULL) {
34 break;
35 }
36 memcpy(&d, nptr, sizeof(uint32_t));
37
38 d[sizeof(d) - 1] = '\0';
39 strcat(s, d);
40
41 if (n + sizeof(uint32_t) == MBUF_CHAIN_LEN) {
42 assert(nbuf_advance(&nbuf, sizeof(uint32_t) - 1, 0));
43 assert(!nbuf_advance(&nbuf, 1, 0));
44 break;
45 }
46 if (!nbuf_advance(&nbuf, sizeof(uint32_t), 0)) {
47 break;
48 }
49 n += sizeof(uint32_t);
50 }
51 return s;
52 }
53
54 static char *
55 mbuf_getstring(struct mbuf *m)
56 {
57 char *s = kmem_zalloc(MBUF_CHAIN_LEN + 1, KM_SLEEP);
58 u_int tlen = 0;
59
60 while (m) {
61 int len = m->m_len;
62 char *d = m->m_data;
63 while (len--) {
64 s[tlen++] = *d++;
65 }
66 m = m->m_next;
67 }
68 return s;
69 }
70
71 static struct mbuf *
72 mbuf_alloc_with_off(size_t off, int len)
73 {
74 struct mbuf *m;
75
76 KASSERT(off + len < MLEN);
77 m = m_get(M_WAITOK, MT_DATA);
78 m->m_data = (char *)m->m_data + off;
79 m->m_len = len;
80 return m;
81 }
82
83 /*
84 * Create an mbuf chain, each of 1 byte size.
85 */
86 static struct mbuf *
87 mbuf_bytesize(size_t clen)
88 {
89 struct mbuf *m0 = NULL, *m = NULL;
90 u_int i, n;
91
92 /* Chain of clen (e.g. 128) mbufs, each storing 1 byte of data. */
93 for (i = 0, n = 0; i < clen; i++) {
94 /* Range of offset: 0 .. 15. */
95 m0 = mbuf_alloc_with_off(n & 0xf, 1);
96
97 /* Fill data with letters from 'a' to 'z'. */
98 memset(m0->m_data, 'a' + n, 1);
99 n = ('a' + n) < 'z' ? n + 1 : 0;
100
101 /* Next mbuf.. */
102 m0->m_next = m;
103 m = m0;
104 }
105
106 m0 = m_gethdr(M_WAITOK, MT_HEADER);
107 m0->m_pkthdr.len = clen;
108 m0->m_len = 0;
109 m0->m_next = m;
110 return m0;
111 }
112
113 /*
114 * Generate random amount of mbufs, with random offsets and lengths.
115 */
116 static struct mbuf *
117 mbuf_random_len(size_t chain_len)
118 {
119 struct mbuf *m0 = NULL, *m = NULL;
120 u_int tlen = 0, n = 0;
121
122 while (tlen < chain_len) {
123 u_int off, len;
124 char *d;
125
126 /* Random offset and length range: 1 .. 16. */
127 off = (random() % 16) + 1;
128 len = (random() % 16) + 1;
129
130 /* Do not exceed 128 bytes of total length. */
131 if (tlen + len > chain_len) {
132 len = chain_len - tlen;
133 }
134 tlen += len;
135
136 /* Consistently fill data with letters from 'a' to 'z'. */
137 m0 = mbuf_alloc_with_off(off, len);
138 d = m0->m_data;
139 while (len--) {
140 *d++ = ('a' + n);
141 n = ('a' + n) < 'z' ? n + 1 : 0;
142 }
143
144 /* Next mbuf.. */
145 m0->m_next = m;
146 m = m0;
147 }
148 KASSERT(tlen == chain_len);
149
150 m0 = m_gethdr(M_WAITOK, MT_HEADER);
151 m0->m_pkthdr.len = tlen;
152 m0->m_next = m;
153 m0->m_len = 0;
154 return m0;
155 }
156
157 static bool
158 validate_mbuf_data(bool verbose, char *bufa, char *bufb)
159 {
160 bool ret = (strcmp(bufa, bufb) == 0);
161
162 if (verbose) {
163 printf("Buffer A: %s\nBuffer B: %s\n", bufa, bufb);
164 }
165 kmem_free(bufa, MBUF_CHAIN_LEN + 1);
166 kmem_free(bufb, MBUF_CHAIN_LEN + 1);
167 return ret;
168 }
169
170 bool
171 npf_nbuf_test(bool verbose)
172 {
173 struct mbuf *m1, *m2;
174 char *bufa, *bufb;
175 bool fail = false;
176
177 m1 = mbuf_random_len(MBUF_CHAIN_LEN);
178 bufa = mbuf_getstring(m1);
179 bufb = parse_nbuf_chain(m1);
180 fail |= !validate_mbuf_data(verbose, bufa, bufb);
181
182 m2 = mbuf_bytesize(MBUF_CHAIN_LEN);
183 bufa = mbuf_getstring(m2);
184 bufb = parse_nbuf_chain(m2);
185 fail |= !validate_mbuf_data(verbose, bufa, bufb);
186
187 return !fail;
188 }
189