1 /*
2
3 Construct a TCP packet based upon a template.
4
5 The (eventual) idea of this module is to make this scanner extensible
6 by providing an arbitrary packet template. Thus, the of this module
7 is to take an existing packet template, parse it, then make
8 appropriate changes.
9 */
10 #include "templ-pkt.h"
11 #include "massip-port.h"
12 #include "proto-preprocess.h"
13 #include "proto-sctp.h"
14 #include "string_s.h"
15 #include "pixie-timer.h"
16 #include "logger.h"
17 #include "templ-payloads.h"
18 #include "syn-cookie.h"
19 #include "unusedparm.h"
20 #include "vulncheck.h"
21 #include "util-checksum.h"
22 #include "util-malloc.h"
23 #include "stub-pcap-dlt.h" /* data link types, like NULL, RAW, or ETHERNET */
24 #include <assert.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 static unsigned char default_tcp_template[] =
29 "\0\1\2\3\4\5" /* Ethernet: destination */
30 "\6\7\x8\x9\xa\xb" /* Ethernet: source */
31 "\x08\x00" /* Ethernet type: IPv4 */
32 "\x45" /* IP type */
33 "\x00"
34 "\x00\x28" /* total length = 40 bytes */
35 "\x00\x00" /* identification */
36 "\x00\x00" /* fragmentation flags */
37 "\xFF\x06" /* TTL=255, proto=TCP */
38 "\xFF\xFF" /* checksum */
39 "\0\0\0\0" /* source address */
40 "\0\0\0\0" /* destination address */
41
42 "\0\0" /* source port */
43 "\0\0" /* destination port */
44 "\0\0\0\0" /* sequence number */
45 "\0\0\0\0" /* ack number */
46 "\x50" /* header length */
47 "\x02" /* SYN */
48 "\x04\x0" /* window fixed to 1024 */
49 "\xFF\xFF" /* checksum */
50 "\x00\x00" /* urgent pointer */
51 "\x02\x04\x05\xb4" /* added options [mss 1460] */
52 ;
53
54 static unsigned char default_udp_template[] =
55 "\0\1\2\3\4\5" /* Ethernet: destination */
56 "\6\7\x8\x9\xa\xb" /* Ethernet: source */
57 "\x08\x00" /* Ethernet type: IPv4 */
58 "\x45" /* IP type */
59 "\x00"
60 "\x00\x1c" /* total length = 28 bytes */
61 "\x00\x00" /* identification */
62 "\x00\x00" /* fragmentation flags */
63 "\xFF\x11" /* TTL=255, proto=UDP */
64 "\xFF\xFF" /* checksum */
65 "\0\0\0\0" /* source address */
66 "\0\0\0\0" /* destination address */
67
68 "\xfe\xdc" /* source port */
69 "\x00\x00" /* destination port */
70 "\x00\x08" /* length */
71 "\x00\x00" /* checksum */
72 ;
73
74 static unsigned char default_sctp_template[] =
75 "\0\1\2\3\4\5" /* Ethernet: destination */
76 "\6\7\x8\x9\xa\xb" /* Ethernet: source */
77 "\x08\x00" /* Ethernet type: IPv4 */
78 "\x45" /* IP type */
79 "\x00"
80 "\x00\x34" /* total length = 52 bytes */
81 "\x00\x00" /* identification */
82 "\x00\x00" /* fragmentation flags */
83 "\xFF\x84" /* TTL=255, proto = SCTP */
84 "\x00\x00" /* checksum */
85 "\0\0\0\0" /* source address */
86 "\0\0\0\0" /* destination address */
87
88 "\x00\x00" /* source port */
89 "\x00\x00" /* destination port */
90 "\x00\x00\x00\x00" /* verification tag */
91 "\x58\xe4\x5d\x36" /* checksum */
92 "\x01" /* type = init */
93 "\x00" /* flags = none */
94 "\x00\x14" /* length = 20 */
95 "\x9e\x8d\x52\x25" /* initiate tag */
96 "\x00\x00\x80\x00" /* receiver window credit */
97 "\x00\x0a" /* outbound streams = 10 */
98 "\x08\x00" /* inbound streams = 2048 */
99 "\x46\x1a\xdf\x3d" /* initial TSN */
100 ;
101
102
103 static unsigned char default_icmp_ping_template[] =
104 "\0\1\2\3\4\5" /* Ethernet: destination */
105 "\6\7\x8\x9\xa\xb" /* Ethernet: source */
106 "\x08\x00" /* Ethernet type: IPv4 */
107 "\x45" /* IP type */
108 "\x00"
109 "\x00\x4c" /* total length = 76 bytes */
110 "\x00\x00" /* identification */
111 "\x00\x00" /* fragmentation flags */
112 "\xFF\x01" /* TTL=255, proto=ICMP */
113 "\xFF\xFF" /* checksum */
114 "\0\0\0\0" /* source address */
115 "\0\0\0\0" /* destination address */
116
117 "\x08\x00" /* Ping Request */
118 "\x00\x00" /* checksum */
119
120 "\x00\x00\x00\x00" /* ID, seqno */
121
122 "\x08\x09\x0a\x0b" /* payload */
123 "\x0c\x0d\x0e\x0f"
124 "\x10\x11\x12\x13"
125 "\x14\x15\x16\x17"
126 "\x18\x19\x1a\x1b"
127 "\x1c\x1d\x1e\x1f"
128 "\x20\x21\x22\x23"
129 "\x24\x25\x26\x27"
130 "\x28\x29\x2a\x2b"
131 "\x2c\x2d\x2e\x2f"
132 "\x30\x31\x32\x33"
133 "\x34\x35\x36\x37"
134 ;
135
136 static unsigned char default_icmp_timestamp_template[] =
137 "\0\1\2\3\4\5" /* Ethernet: destination */
138 "\6\7\x8\x9\xa\xb" /* Ethernet: source */
139 "\x08\x00" /* Ethernet type: IPv4 */
140 "\x45" /* IP type */
141 "\x00"
142 "\x00\x28" /* total length = 84 bytes */
143 "\x00\x00" /* identification */
144 "\x00\x00" /* fragmentation flags */
145 "\xFF\x01" /* TTL=255, proto=UDP */
146 "\xFF\xFF" /* checksum */
147 "\0\0\0\0" /* source address */
148 "\0\0\0\0" /* destination address */
149
150 "\x0d\x00" /* timestamp request */
151 "\x00\x00" /* checksum */
152 "\x00\x00" /* identifier */
153 "\x00\x00" /* sequence number */
154 "\x00\x00\x00\x00"
155 "\x00\x00\x00\x00"
156 "\x00\x00\x00\x00"
157 ;
158
159
160 static unsigned char default_arp_template[] =
161 "\xff\xff\xff\xff\xff\xff" /* Ethernet: destination */
162 "\x00\x00\x00\x00\x00\x00" /* Ethernet: source */
163 "\x08\x06" /* Ethernet type: ARP */
164 "\x00\x01" /* hardware = Ethernet */
165 "\x08\x00" /* protocol = IPv4 */
166 "\x06\x04" /* MAC length = 6, IPv4 length = 4 */
167 "\x00\x01" /* opcode = request */
168
169 "\x00\x00\x00\x00\x00\x00"
170 "\x00\x00\x00\x00"
171
172 "\x00\x00\x00\x00\x00\x00"
173 "\x00\x00\x00\x00"
174 ;
175
176
177 /***************************************************************************
178 * Checksum the IP header. This is a "partial" checksum, so we
179 * don't reverse the bits ~.
180 ***************************************************************************/
181 static unsigned
ip_header_checksum(const unsigned char * px,unsigned offset,unsigned max_offset)182 ip_header_checksum(const unsigned char *px, unsigned offset, unsigned max_offset)
183 {
184 unsigned header_length = (px[offset]&0xF) * 4;
185 unsigned xsum = 0;
186 unsigned i;
187
188 /* restrict check only over packet */
189 if (max_offset > offset + header_length)
190 max_offset = offset + header_length;
191
192 /* add all the two-byte words together */
193 xsum = 0;
194 for (i = offset; i < max_offset; i += 2) {
195 xsum += px[i]<<8 | px[i+1];
196 }
197
198 /* if more than 16 bits in result, reduce to 16 bits */
199 xsum = (xsum & 0xFFFF) + (xsum >> 16);
200 xsum = (xsum & 0xFFFF) + (xsum >> 16);
201 xsum = (xsum & 0xFFFF) + (xsum >> 16);
202
203 return xsum;
204 }
205
206 /***************************************************************************
207 ***************************************************************************/
208 static unsigned
tcp_checksum2(const unsigned char * px,unsigned offset_ip,unsigned offset_tcp,size_t tcp_length)209 tcp_checksum2(const unsigned char *px, unsigned offset_ip,
210 unsigned offset_tcp, size_t tcp_length)
211 {
212 uint64_t xsum = 0;
213 unsigned i;
214
215 /* pseudo checksum */
216 xsum = 6;
217 xsum += tcp_length;
218 xsum += px[offset_ip + 12] << 8 | px[offset_ip + 13];
219 xsum += px[offset_ip + 14] << 8 | px[offset_ip + 15];
220 xsum += px[offset_ip + 16] << 8 | px[offset_ip + 17];
221 xsum += px[offset_ip + 18] << 8 | px[offset_ip + 19];
222
223 /* tcp checksum */
224 for (i=0; i<tcp_length; i += 2) {
225 xsum += px[offset_tcp + i]<<8 | px[offset_tcp + i + 1];
226 }
227
228 xsum -= (tcp_length & 1) * px[offset_tcp + i - 1]; /* yea I know going off end of packet is bad so sue me */
229 xsum = (xsum & 0xFFFF) + (xsum >> 16);
230 xsum = (xsum & 0xFFFF) + (xsum >> 16);
231 xsum = (xsum & 0xFFFF) + (xsum >> 16);
232
233 return (unsigned)xsum;
234 }
235
236 /***************************************************************************
237 ***************************************************************************/
238 /***************************************************************************
239 ***************************************************************************/
240 static unsigned
tcp_ipv4_checksum(struct TemplatePacket * tmpl)241 tcp_ipv4_checksum(struct TemplatePacket *tmpl)
242 {
243 const unsigned char *px = tmpl->ipv4.packet;
244 unsigned offset_ip = tmpl->ipv4.offset_ip;
245 unsigned offset_app = tmpl->ipv4.offset_app;
246 unsigned offset_tcp = tmpl->ipv4.offset_tcp;
247 unsigned xsum = 0;
248 unsigned i;
249
250
251
252 /* pseudo checksum */
253 xsum = 6;
254 xsum += offset_app - offset_tcp;
255 xsum += px[offset_ip + 12] << 8 | px[offset_ip + 13];
256 xsum += px[offset_ip + 14] << 8 | px[offset_ip + 15];
257 xsum += px[offset_ip + 16] << 8 | px[offset_ip + 17];
258 xsum += px[offset_ip + 18] << 8 | px[offset_ip + 19];
259
260 /* tcp checksum */
261 for (i=offset_tcp; i<offset_app; i += 2) {
262 xsum += px[i]<<8 | px[i+1];
263 }
264 xsum = (xsum & 0xFFFF) + (xsum >> 16);
265 xsum = (xsum & 0xFFFF) + (xsum >> 16);
266 xsum = (xsum & 0xFFFF) + (xsum >> 16);
267
268 return xsum;
269 }
270
271
272
273 /***************************************************************************
274 ***************************************************************************/
275 unsigned
udp_checksum2(const unsigned char * px,unsigned offset_ip,unsigned offset_tcp,size_t tcp_length)276 udp_checksum2(const unsigned char *px, unsigned offset_ip,
277 unsigned offset_tcp, size_t tcp_length)
278 {
279 uint64_t xsum = 0;
280 unsigned i;
281
282 /* pseudo checksum */
283 xsum = 17;
284 xsum += tcp_length;
285 xsum += px[offset_ip + 12] << 8 | px[offset_ip + 13];
286 xsum += px[offset_ip + 14] << 8 | px[offset_ip + 15];
287 xsum += px[offset_ip + 16] << 8 | px[offset_ip + 17];
288 xsum += px[offset_ip + 18] << 8 | px[offset_ip + 19];
289
290 /* tcp checksum */
291 for (i=0; i<tcp_length; i += 2) {
292 xsum += px[offset_tcp + i]<<8 | px[offset_tcp + i + 1];
293 }
294
295 xsum -= (tcp_length & 1) * px[offset_tcp + i - 1]; /* yea I know going off end of packet is bad so sue me */
296 xsum = (xsum & 0xFFFF) + (xsum >> 16);
297 xsum = (xsum & 0xFFFF) + (xsum >> 16);
298 xsum = (xsum & 0xFFFF) + (xsum >> 16);
299
300 return (unsigned)xsum;
301 }
302
303 /***************************************************************************
304 ***************************************************************************/
305 static unsigned
udp_ipv4_checksum(struct TemplatePacket * tmpl)306 udp_ipv4_checksum(struct TemplatePacket *tmpl)
307 {
308 return udp_checksum2(
309 tmpl->ipv4.packet,
310 tmpl->ipv4.offset_ip,
311 tmpl->ipv4.offset_tcp,
312 tmpl->ipv4.length - tmpl->ipv4.offset_tcp);
313 }
314
315 /***************************************************************************
316 ***************************************************************************/
317 static unsigned
icmp_checksum2(const unsigned char * px,unsigned offset_icmp,size_t icmp_length)318 icmp_checksum2(const unsigned char *px,
319 unsigned offset_icmp, size_t icmp_length)
320 {
321 uint64_t xsum = 0;
322 unsigned i;
323
324 for (i=0; i<icmp_length; i += 2) {
325 xsum += px[offset_icmp + i]<<8 | px[offset_icmp + i + 1];
326 }
327
328 xsum -= (icmp_length & 1) * px[offset_icmp + i - 1]; /* yea I know going off end of packet is bad so sue me */
329 xsum = (xsum & 0xFFFF) + (xsum >> 16);
330 xsum = (xsum & 0xFFFF) + (xsum >> 16);
331 xsum = (xsum & 0xFFFF) + (xsum >> 16);
332
333 return (unsigned)xsum;
334 }
335
336 /***************************************************************************
337 ***************************************************************************/
338 static unsigned
icmp_ipv4_checksum(struct TemplatePacket * tmpl)339 icmp_ipv4_checksum(struct TemplatePacket *tmpl)
340 {
341 return icmp_checksum2(
342 tmpl->ipv4.packet,
343 tmpl->ipv4.offset_tcp,
344 tmpl->ipv4.length - tmpl->ipv4.offset_tcp);
345 }
346
347
348 /***************************************************************************
349 ***************************************************************************/
templ_copy(const struct TemplateSet * templset)350 struct TemplateSet templ_copy(const struct TemplateSet *templset)
351 {
352 struct TemplateSet result;
353 unsigned i;
354
355 memcpy(&result, templset, sizeof(result));
356
357 for (i=0; i<templset->count; i++) {
358 const struct TemplatePacket *p1 = &templset->pkts[i];
359 struct TemplatePacket *p2 = &result.pkts[i];
360 p2->ipv4.packet = MALLOC(p2->ipv4.length);
361 memcpy(p2->ipv4.packet, p1->ipv4.packet, p2->ipv4.length);
362 p2->ipv6.packet = MALLOC(p2->ipv6.length);
363 memcpy(p2->ipv6.packet, p1->ipv6.packet, p2->ipv6.length);
364 }
365
366 return result;
367 }
368
369 /***************************************************************************
370 ***************************************************************************/
371 void
tcp_set_window(unsigned char * px,size_t px_length,unsigned window)372 tcp_set_window(unsigned char *px, size_t px_length, unsigned window)
373 {
374 struct PreprocessedInfo parsed;
375 unsigned x;
376 size_t offset;
377 unsigned xsum;
378
379 /* Parse the frame looking for hte TCP header */
380 x = preprocess_frame(px, (unsigned)px_length, 1 /*enet*/, &parsed);
381 if (!x || parsed.found == FOUND_NOTHING)
382 return;
383 if (parsed.ip_protocol != 6)
384 return;
385 offset = parsed.transport_offset;
386 if (offset + 20 > px_length)
387 return;
388
389
390 /* set the new window */
391 #if 0
392 xsum = px[offset + 16] << 8 | px[offset + 17];
393 xsum = (~xsum)&0xFFFF;
394 xsum += window & 0xFFFF;
395 xsum -= px[offset + 14] << 8 | px[offset + 15];
396 xsum = ((xsum)&0xFFFF) + (xsum >> 16);
397 xsum = ((xsum)&0xFFFF) + (xsum >> 16);
398 xsum = ((xsum)&0xFFFF) + (xsum >> 16);
399 xsum = (~xsum)&0xFFFF;
400 #endif
401
402 px[offset + 14] = (unsigned char)(window>>8);
403 px[offset + 15] = (unsigned char)(window>>0);
404 px[offset + 16] = (unsigned char)(0);
405 px[offset + 17] = (unsigned char)(0);
406
407
408 xsum = ~tcp_checksum2(px, parsed.ip_offset, parsed.transport_offset,
409 parsed.transport_length);
410
411 px[offset + 16] = (unsigned char)(xsum>>8);
412 px[offset + 17] = (unsigned char)(xsum>>0);
413 }
414
415 /***************************************************************************
416 ***************************************************************************/
417 size_t
tcp_create_packet(struct TemplatePacket * tmpl,ipaddress ip_them,unsigned port_them,ipaddress ip_me,unsigned port_me,unsigned seqno,unsigned ackno,unsigned flags,const unsigned char * payload,size_t payload_length,unsigned char * px,size_t px_length)418 tcp_create_packet(
419 struct TemplatePacket *tmpl,
420 ipaddress ip_them, unsigned port_them,
421 ipaddress ip_me, unsigned port_me,
422 unsigned seqno, unsigned ackno,
423 unsigned flags,
424 const unsigned char *payload, size_t payload_length,
425 unsigned char *px, size_t px_length)
426 {
427 uint64_t xsum;
428
429 if (ip_them.version == 4) {
430 unsigned ip_id = ip_them.ipv4 ^ port_them ^ seqno;
431 unsigned offset_ip = tmpl->ipv4.offset_ip;
432 unsigned offset_tcp = tmpl->ipv4. offset_tcp;
433 unsigned offset_payload = offset_tcp + ((tmpl->ipv4.packet[offset_tcp+12]&0xF0)>>2);
434 size_t new_length = offset_payload + payload_length;
435 size_t ip_len = (offset_payload - offset_ip) + payload_length;
436 unsigned old_len;
437
438 if (new_length > px_length) {
439 fprintf(stderr, "tcp: err generating packet: too much payload\n");
440 return 0;
441 }
442
443 memcpy(px + 0, tmpl->ipv4.packet, tmpl->ipv4.length);
444 memcpy(px + offset_payload, payload, payload_length);
445 old_len = px[offset_ip+2]<<8 | px[offset_ip+3];
446
447 /*
448 * Fill in the empty fields in the IP header and then re-calculate
449 * the checksum.
450 */
451 px[offset_ip+2] = (unsigned char)(ip_len>> 8);
452 px[offset_ip+3] = (unsigned char)(ip_len & 0xFF);
453 px[offset_ip+4] = (unsigned char)(ip_id >> 8);
454 px[offset_ip+5] = (unsigned char)(ip_id & 0xFF);
455 px[offset_ip+12] = (unsigned char)((ip_me.ipv4 >> 24) & 0xFF);
456 px[offset_ip+13] = (unsigned char)((ip_me.ipv4 >> 16) & 0xFF);
457 px[offset_ip+14] = (unsigned char)((ip_me.ipv4 >> 8) & 0xFF);
458 px[offset_ip+15] = (unsigned char)((ip_me.ipv4 >> 0) & 0xFF);
459 px[offset_ip+16] = (unsigned char)((ip_them.ipv4 >> 24) & 0xFF);
460 px[offset_ip+17] = (unsigned char)((ip_them.ipv4 >> 16) & 0xFF);
461 px[offset_ip+18] = (unsigned char)((ip_them.ipv4 >> 8) & 0xFF);
462 px[offset_ip+19] = (unsigned char)((ip_them.ipv4 >> 0) & 0xFF);
463
464 xsum = tmpl->ipv4.checksum_ip;
465 xsum += (ip_id&0xFFFF);
466 xsum += ip_me.ipv4;
467 xsum += ip_them.ipv4;
468 xsum += ip_len - old_len;
469 xsum = (xsum >> 16) + (xsum & 0xFFFF);
470 xsum = (xsum >> 16) + (xsum & 0xFFFF);
471 xsum = ~xsum;
472
473 px[offset_ip+10] = (unsigned char)(xsum >> 8);
474 px[offset_ip+11] = (unsigned char)(xsum & 0xFF);
475
476 /*
477 * now do the same for TCP
478 */
479 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
480 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
481 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
482 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
483 px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);
484 px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);
485 px[offset_tcp+ 6] = (unsigned char)(seqno >> 8);
486 px[offset_tcp+ 7] = (unsigned char)(seqno >> 0);
487
488 px[offset_tcp+ 8] = (unsigned char)(ackno >> 24);
489 px[offset_tcp+ 9] = (unsigned char)(ackno >> 16);
490 px[offset_tcp+10] = (unsigned char)(ackno >> 8);
491 px[offset_tcp+11] = (unsigned char)(ackno >> 0);
492
493 px[offset_tcp+13] = (unsigned char)flags;
494
495 px[offset_tcp+14] = (unsigned char)(1200>>8);
496 px[offset_tcp+15] = (unsigned char)(1200 & 0xFF);
497
498 px[offset_tcp+16] = (unsigned char)(0 >> 8);
499 px[offset_tcp+17] = (unsigned char)(0 >> 0);
500
501 xsum = tcp_checksum2(px, tmpl->ipv4.offset_ip, tmpl->ipv4.offset_tcp,
502 new_length - tmpl->ipv4.offset_tcp);
503 xsum = ~xsum;
504
505 px[offset_tcp+16] = (unsigned char)(xsum >> 8);
506 px[offset_tcp+17] = (unsigned char)(xsum >> 0);
507
508 if (new_length < 60) {
509 memset(px+new_length, 0, 60-new_length);
510 new_length = 60;
511 }
512 return new_length;
513 } else {
514 unsigned offset_ip = tmpl->ipv6.offset_ip;
515 unsigned offset_tcp = tmpl->ipv6.offset_tcp;
516 unsigned offset_app = tmpl->ipv6.offset_app;
517
518 /* Make sure the new packet won't exceed buffer size */
519 if (offset_app + payload_length > px_length) {
520 fprintf(stderr, "tcp: err generating packet: too much payload\n");
521 return 0;
522 }
523
524 /* Copy over everything up to the new application-layer-payload */
525 memcpy(px, tmpl->ipv6.packet, tmpl->ipv6.offset_app);
526
527 /* Replace the template's application-layer-payload with the new app-payload */
528 memcpy(px + tmpl->ipv6.offset_app, payload, payload_length);
529
530 /* Fixup the "payload length" field in the IPv6 header. This is everything
531 * after the IPv6 header. There may be additional headers between the IPv6
532 * and TCP headers, so the calculation isn't simply the length of the TCP portion */
533 {
534 size_t len = tmpl->ipv6.offset_app + payload_length - tmpl->ipv6.offset_ip - 40;
535 px[offset_ip + 4] = (unsigned char)(len>>8) & 0xFF;
536 px[offset_ip + 5] = (unsigned char)(len>>0) & 0xFF;
537 }
538
539 /* Copy over the IP addresses */
540 px[offset_ip+ 8] = (unsigned char)((ip_me.ipv6.hi >> 56ULL) & 0xFF);
541 px[offset_ip+ 9] = (unsigned char)((ip_me.ipv6.hi >> 48ULL) & 0xFF);
542 px[offset_ip+10] = (unsigned char)((ip_me.ipv6.hi >> 40ULL) & 0xFF);
543 px[offset_ip+11] = (unsigned char)((ip_me.ipv6.hi >> 32ULL) & 0xFF);
544 px[offset_ip+12] = (unsigned char)((ip_me.ipv6.hi >> 24ULL) & 0xFF);
545 px[offset_ip+13] = (unsigned char)((ip_me.ipv6.hi >> 16ULL) & 0xFF);
546 px[offset_ip+14] = (unsigned char)((ip_me.ipv6.hi >> 8ULL) & 0xFF);
547 px[offset_ip+15] = (unsigned char)((ip_me.ipv6.hi >> 0ULL) & 0xFF);
548
549 px[offset_ip+16] = (unsigned char)((ip_me.ipv6.lo >> 56ULL) & 0xFF);
550 px[offset_ip+17] = (unsigned char)((ip_me.ipv6.lo >> 48ULL) & 0xFF);
551 px[offset_ip+18] = (unsigned char)((ip_me.ipv6.lo >> 40ULL) & 0xFF);
552 px[offset_ip+19] = (unsigned char)((ip_me.ipv6.lo >> 32ULL) & 0xFF);
553 px[offset_ip+20] = (unsigned char)((ip_me.ipv6.lo >> 24ULL) & 0xFF);
554 px[offset_ip+21] = (unsigned char)((ip_me.ipv6.lo >> 16ULL) & 0xFF);
555 px[offset_ip+22] = (unsigned char)((ip_me.ipv6.lo >> 8ULL) & 0xFF);
556 px[offset_ip+23] = (unsigned char)((ip_me.ipv6.lo >> 0ULL) & 0xFF);
557
558 px[offset_ip+24] = (unsigned char)((ip_them.ipv6.hi >> 56ULL) & 0xFF);
559 px[offset_ip+25] = (unsigned char)((ip_them.ipv6.hi >> 48ULL) & 0xFF);
560 px[offset_ip+26] = (unsigned char)((ip_them.ipv6.hi >> 40ULL) & 0xFF);
561 px[offset_ip+27] = (unsigned char)((ip_them.ipv6.hi >> 32ULL) & 0xFF);
562 px[offset_ip+28] = (unsigned char)((ip_them.ipv6.hi >> 24ULL) & 0xFF);
563 px[offset_ip+29] = (unsigned char)((ip_them.ipv6.hi >> 16ULL) & 0xFF);
564 px[offset_ip+30] = (unsigned char)((ip_them.ipv6.hi >> 8ULL) & 0xFF);
565 px[offset_ip+31] = (unsigned char)((ip_them.ipv6.hi >> 0ULL) & 0xFF);
566
567 px[offset_ip+32] = (unsigned char)((ip_them.ipv6.lo >> 56ULL) & 0xFF);
568 px[offset_ip+33] = (unsigned char)((ip_them.ipv6.lo >> 48ULL) & 0xFF);
569 px[offset_ip+34] = (unsigned char)((ip_them.ipv6.lo >> 40ULL) & 0xFF);
570 px[offset_ip+35] = (unsigned char)((ip_them.ipv6.lo >> 32ULL) & 0xFF);
571 px[offset_ip+36] = (unsigned char)((ip_them.ipv6.lo >> 24ULL) & 0xFF);
572 px[offset_ip+37] = (unsigned char)((ip_them.ipv6.lo >> 16ULL) & 0xFF);
573 px[offset_ip+38] = (unsigned char)((ip_them.ipv6.lo >> 8ULL) & 0xFF);
574 px[offset_ip+39] = (unsigned char)((ip_them.ipv6.lo >> 0ULL) & 0xFF);
575
576
577 /*
578 * now do the same for TCP
579 */
580 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
581 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
582 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
583 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
584 px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);
585 px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);
586 px[offset_tcp+ 6] = (unsigned char)(seqno >> 8);
587 px[offset_tcp+ 7] = (unsigned char)(seqno >> 0);
588
589 px[offset_tcp+ 8] = (unsigned char)(ackno >> 24);
590 px[offset_tcp+ 9] = (unsigned char)(ackno >> 16);
591 px[offset_tcp+10] = (unsigned char)(ackno >> 8);
592 px[offset_tcp+11] = (unsigned char)(ackno >> 0);
593
594 px[offset_tcp+13] = (unsigned char)flags;
595
596 px[offset_tcp+14] = (unsigned char)(1200>>8);
597 px[offset_tcp+15] = (unsigned char)(1200 & 0xFF);
598
599 px[offset_tcp+16] = (unsigned char)(0 >> 8);
600 px[offset_tcp+17] = (unsigned char)(0 >> 0);
601
602 xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 6, (offset_app - offset_tcp) + payload_length, px + offset_tcp);
603 px[offset_tcp+16] = (unsigned char)(xsum >> 8);
604 px[offset_tcp+17] = (unsigned char)(xsum >> 0);
605
606 px[offset_tcp+16] = (unsigned char)(xsum >> 8);
607 px[offset_tcp+17] = (unsigned char)(xsum >> 0);
608
609 return offset_app + payload_length;
610 }
611 }
612
613 /***************************************************************************
614 ***************************************************************************/
615 static void
udp_payload_fixup(struct TemplatePacket * tmpl,unsigned port,unsigned seqno)616 udp_payload_fixup(struct TemplatePacket *tmpl, unsigned port, unsigned seqno)
617 {
618 const unsigned char *px2 = 0;
619 unsigned length2 = 0;
620 unsigned source_port2 = 0x1000;
621 uint64_t xsum2 = 0;
622 //unsigned char *px = tmpl->packet;
623 SET_COOKIE set_cookie = 0;
624
625 UNUSEDPARM(seqno);
626
627 payloads_udp_lookup(tmpl->payloads,
628 port,
629 &px2,
630 &length2,
631 &source_port2,
632 &xsum2,
633 &set_cookie);
634
635 /* Copy over the payloads */
636 memcpy( tmpl->ipv4.packet + tmpl->ipv4.offset_app,
637 px2,
638 length2);
639 memcpy( tmpl->ipv6.packet + tmpl->ipv6.offset_app,
640 px2,
641 length2);
642
643 /* Change the cookie values */
644 if (set_cookie) {
645 set_cookie(
646 tmpl->ipv4.packet + tmpl->ipv4.offset_app,
647 length2,
648 seqno);
649 set_cookie(
650 tmpl->ipv6.packet + tmpl->ipv6.offset_app,
651 length2,
652 seqno);
653 }
654
655 tmpl->ipv4.length = tmpl->ipv4.offset_app + length2;
656 tmpl->ipv6.length = tmpl->ipv6.offset_app + length2;
657 }
658
659 void
template_set_target_ipv6(struct TemplateSet * tmplset,ipv6address ip_them,unsigned port_them,ipv6address ip_me,unsigned port_me,unsigned seqno,unsigned char * px,size_t sizeof_px,size_t * r_length)660 template_set_target_ipv6(
661 struct TemplateSet *tmplset,
662 ipv6address ip_them, unsigned port_them,
663 ipv6address ip_me, unsigned port_me,
664 unsigned seqno,
665 unsigned char *px, size_t sizeof_px, size_t *r_length
666 )
667 {
668 unsigned offset_ip;
669 unsigned offset_tcp;
670 uint64_t xsum;
671 struct TemplatePacket *tmpl = NULL;
672 uint64_t entropy = tmplset->entropy;
673 unsigned payload_length;
674
675 *r_length = sizeof_px;
676
677 /*
678 * Find out which packet template to use. This is because we can
679 * simultaneously scan for both TCP and UDP (and others). We've
680 * just overloaded the "port" field to signal which protocol we
681 * are using
682 */
683 if (port_them < Templ_TCP + 65536)
684 tmpl = &tmplset->pkts[Proto_TCP];
685 else if (port_them < Templ_UDP + 65536) {
686 tmpl = &tmplset->pkts[Proto_UDP];
687 port_them &= 0xFFFF;
688 udp_payload_fixup(tmpl, port_them, seqno);
689 } else if (port_them < Templ_SCTP + 65536) {
690 tmpl = &tmplset->pkts[Proto_SCTP];
691 port_them &= 0xFFFF;
692 } else if (port_them == Templ_ICMP_echo) {
693 tmpl = &tmplset->pkts[Proto_ICMP_ping];
694 } else if (port_them == Templ_ICMP_timestamp) {
695 tmpl = &tmplset->pkts[Proto_ICMP_timestamp];
696 } else if (port_them == Templ_ARP) {
697 tmpl = &tmplset->pkts[Proto_ARP];
698 if (*r_length > tmpl->ipv6.length)
699 *r_length = tmpl->ipv6.length;
700 memcpy(px, tmpl->ipv6.packet, *r_length);
701 return;
702 } else if (port_them == Templ_VulnCheck) {
703 tmpl = &tmplset->pkts[Proto_VulnCheck];
704 port_them &= 0xFFFF;
705 } else {
706 return;
707 }
708
709 /* Create some shorter local variables to work with */
710 if (*r_length > tmpl->ipv6.length)
711 *r_length = tmpl->ipv6.length;
712 memcpy(px, tmpl->ipv6.packet, *r_length);
713 offset_ip = tmpl->ipv6.offset_ip;
714 offset_tcp = tmpl->ipv6.offset_tcp;
715 //ip_id = ip_them ^ port_them ^ seqno;
716
717 /*
718
719 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
720 |Version| Traffic Class | Flow Label |
721 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
722 | Payload Length | Next Header | Hop Limit |
723 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
724 | |
725 + +
726 | |
727 + Source Address +
728 | |
729 + +
730 | |
731 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
732 | |
733 + +
734 | |
735 + Destination Address +
736 | |
737 + +
738 | |
739 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
740 */
741 /*
742 * Fill in the empty fields in the IP header and then re-calculate
743 * the checksum.
744 */
745 payload_length = tmpl->ipv6.length - tmpl->ipv6.offset_ip - 40;
746 px[offset_ip+4] = (unsigned char)(payload_length>>8);
747 px[offset_ip+5] = (unsigned char)(payload_length>>0);
748 px[offset_ip+ 8] = (unsigned char)((ip_me.hi >> 56ULL) & 0xFF);
749 px[offset_ip+ 9] = (unsigned char)((ip_me.hi >> 48ULL) & 0xFF);
750 px[offset_ip+10] = (unsigned char)((ip_me.hi >> 40ULL) & 0xFF);
751 px[offset_ip+11] = (unsigned char)((ip_me.hi >> 32ULL) & 0xFF);
752 px[offset_ip+12] = (unsigned char)((ip_me.hi >> 24ULL) & 0xFF);
753 px[offset_ip+13] = (unsigned char)((ip_me.hi >> 16ULL) & 0xFF);
754 px[offset_ip+14] = (unsigned char)((ip_me.hi >> 8ULL) & 0xFF);
755 px[offset_ip+15] = (unsigned char)((ip_me.hi >> 0ULL) & 0xFF);
756
757 px[offset_ip+16] = (unsigned char)((ip_me.lo >> 56ULL) & 0xFF);
758 px[offset_ip+17] = (unsigned char)((ip_me.lo >> 48ULL) & 0xFF);
759 px[offset_ip+18] = (unsigned char)((ip_me.lo >> 40ULL) & 0xFF);
760 px[offset_ip+19] = (unsigned char)((ip_me.lo >> 32ULL) & 0xFF);
761 px[offset_ip+20] = (unsigned char)((ip_me.lo >> 24ULL) & 0xFF);
762 px[offset_ip+21] = (unsigned char)((ip_me.lo >> 16ULL) & 0xFF);
763 px[offset_ip+22] = (unsigned char)((ip_me.lo >> 8ULL) & 0xFF);
764 px[offset_ip+23] = (unsigned char)((ip_me.lo >> 0ULL) & 0xFF);
765
766 px[offset_ip+24] = (unsigned char)((ip_them.hi >> 56ULL) & 0xFF);
767 px[offset_ip+25] = (unsigned char)((ip_them.hi >> 48ULL) & 0xFF);
768 px[offset_ip+26] = (unsigned char)((ip_them.hi >> 40ULL) & 0xFF);
769 px[offset_ip+27] = (unsigned char)((ip_them.hi >> 32ULL) & 0xFF);
770 px[offset_ip+28] = (unsigned char)((ip_them.hi >> 24ULL) & 0xFF);
771 px[offset_ip+29] = (unsigned char)((ip_them.hi >> 16ULL) & 0xFF);
772 px[offset_ip+30] = (unsigned char)((ip_them.hi >> 8ULL) & 0xFF);
773 px[offset_ip+31] = (unsigned char)((ip_them.hi >> 0ULL) & 0xFF);
774
775 px[offset_ip+32] = (unsigned char)((ip_them.lo >> 56ULL) & 0xFF);
776 px[offset_ip+33] = (unsigned char)((ip_them.lo >> 48ULL) & 0xFF);
777 px[offset_ip+34] = (unsigned char)((ip_them.lo >> 40ULL) & 0xFF);
778 px[offset_ip+35] = (unsigned char)((ip_them.lo >> 32ULL) & 0xFF);
779 px[offset_ip+36] = (unsigned char)((ip_them.lo >> 24ULL) & 0xFF);
780 px[offset_ip+37] = (unsigned char)((ip_them.lo >> 16ULL) & 0xFF);
781 px[offset_ip+38] = (unsigned char)((ip_them.lo >> 8ULL) & 0xFF);
782 px[offset_ip+39] = (unsigned char)((ip_them.lo >> 0ULL) & 0xFF);
783
784 /*
785 * Now do the checksum for the higher layer protocols
786 */
787 switch (tmpl->proto) {
788 case Proto_TCP:
789 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
790 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
791 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
792 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
793 px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);
794 px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);
795 px[offset_tcp+ 6] = (unsigned char)(seqno >> 8);
796 px[offset_tcp+ 7] = (unsigned char)(seqno >> 0);
797
798 xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 6, tmpl->ipv6.length - offset_tcp, px + offset_tcp);
799 px[offset_tcp+16] = (unsigned char)(xsum >> 8);
800 px[offset_tcp+17] = (unsigned char)(xsum >> 0);
801 break;
802 case Proto_UDP:
803 /* TODO: IPv6 */
804 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
805 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
806 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
807 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
808 px[offset_tcp+ 4] = (unsigned char)((tmpl->ipv6.length - tmpl->ipv6.offset_app + 8)>>8);
809 px[offset_tcp+ 5] = (unsigned char)((tmpl->ipv6.length - tmpl->ipv6.offset_app + 8)&0xFF);
810
811 px[offset_tcp+6] = (unsigned char)(0);
812 px[offset_tcp+7] = (unsigned char)(0);
813 xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 17, tmpl->ipv6.length - offset_tcp, px + offset_tcp);
814 px[offset_tcp+6] = (unsigned char)(xsum >> 8);
815 px[offset_tcp+7] = (unsigned char)(xsum >> 0);
816 break;
817 case Proto_SCTP:
818 /* TODO: IPv6 */
819 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
820 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
821 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
822 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
823
824 px[offset_tcp+16] = (unsigned char)(seqno >> 24);
825 px[offset_tcp+17] = (unsigned char)(seqno >> 16);
826 px[offset_tcp+18] = (unsigned char)(seqno >> 8);
827 px[offset_tcp+19] = (unsigned char)(seqno >> 0);
828
829 xsum = sctp_checksum(px + offset_tcp, tmpl->ipv6.length - offset_tcp);
830 px[offset_tcp+ 8] = (unsigned char)(xsum >> 24);
831 px[offset_tcp+ 9] = (unsigned char)(xsum >> 16);
832 px[offset_tcp+10] = (unsigned char)(xsum >> 8);
833 px[offset_tcp+11] = (unsigned char)(xsum >> 0);
834 break;
835 case Proto_ICMP_ping:
836 case Proto_ICMP_timestamp:
837 /* TODO: IPv6 */
838 seqno = (unsigned)syn_cookie_ipv6(ip_them, port_them, ip_me, 0, entropy);
839 px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);
840 px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);
841 px[offset_tcp+ 6] = (unsigned char)(seqno >> 8);
842 px[offset_tcp+ 7] = (unsigned char)(seqno >> 0);
843 xsum = checksum_ipv6(px + offset_ip + 8, px + offset_ip + 24, 58, tmpl->ipv6.length - offset_tcp, px + offset_tcp);
844 px[offset_tcp+2] = (unsigned char)(xsum >> 8);
845 px[offset_tcp+3] = (unsigned char)(xsum >> 0);
846 break;
847 case Proto_VulnCheck:
848 /* TODO: IPv6 */
849 /*tmplset->vulncheck->set_target(tmpl,
850 ip_them, port_them,
851 ip_me, port_me,
852 seqno,
853 px, sizeof_px, r_length);*/
854 break;
855 case Proto_ARP:
856 /* TODO: IPv6 */
857 /* don't do any checksumming */
858 break;
859 case Proto_Oproto:
860 /* TODO: IPv6 */
861 /* TODO: probably need to add checksums for certain protocols */
862 break;
863 case Proto_Count:
864 break;
865 }
866 }
867
868
869 /***************************************************************************
870 * This is the function that formats the transmitted packets for probing
871 * machines. It takes a template for the protocol (usually a TCP SYN
872 * packet), then sets the destination IP address and port numbers.
873 ***************************************************************************/
874 void
template_set_target_ipv4(struct TemplateSet * tmplset,ipv4address ip_them,unsigned port_them,ipv4address ip_me,unsigned port_me,unsigned seqno,unsigned char * px,size_t sizeof_px,size_t * r_length)875 template_set_target_ipv4(
876 struct TemplateSet *tmplset,
877 ipv4address ip_them, unsigned port_them,
878 ipv4address ip_me, unsigned port_me,
879 unsigned seqno,
880 unsigned char *px, size_t sizeof_px, size_t *r_length
881 )
882 {
883 unsigned offset_ip;
884 unsigned offset_tcp;
885 uint64_t xsum;
886 unsigned ip_id;
887 struct TemplatePacket *tmpl = NULL;
888 unsigned xsum2;
889 uint64_t entropy = tmplset->entropy;
890
891 *r_length = sizeof_px;
892
893 /*
894 * Find out which packet template to use. This is because we can
895 * simultaneously scan for both TCP and UDP (and others). We've
896 * just overloaded the "port" field to signal which protocol we
897 * are using
898 */
899 if (port_them < Templ_TCP + 65536)
900 tmpl = &tmplset->pkts[Proto_TCP];
901 else if (port_them < Templ_UDP + 65536) {
902 tmpl = &tmplset->pkts[Proto_UDP];
903 port_them &= 0xFFFF;
904 udp_payload_fixup(tmpl, port_them, seqno);
905 } else if (port_them < Templ_SCTP + 65536) {
906 tmpl = &tmplset->pkts[Proto_SCTP];
907 port_them &= 0xFFFF;
908 } else if (port_them == Templ_ICMP_echo) {
909 tmpl = &tmplset->pkts[Proto_ICMP_ping];
910 } else if (port_them == Templ_ICMP_timestamp) {
911 tmpl = &tmplset->pkts[Proto_ICMP_timestamp];
912 } else if (port_them == Templ_ARP) {
913 tmpl = &tmplset->pkts[Proto_ARP];
914 if (*r_length > tmpl->ipv4.length)
915 *r_length = tmpl->ipv4.length;
916 memcpy(px, tmpl->ipv4.packet, *r_length);
917 px = px + tmpl->ipv4.offset_ip;
918 px[14] = (unsigned char)((ip_me >> 24) & 0xFF);
919 px[15] = (unsigned char)((ip_me >> 16) & 0xFF);
920 px[16] = (unsigned char)((ip_me >> 8) & 0xFF);
921 px[17] = (unsigned char)((ip_me >> 0) & 0xFF);
922 px[24] = (unsigned char)((ip_them >> 24) & 0xFF);
923 px[25] = (unsigned char)((ip_them >> 16) & 0xFF);
924 px[26] = (unsigned char)((ip_them >> 8) & 0xFF);
925 px[27] = (unsigned char)((ip_them >> 0) & 0xFF);
926 return;
927 } else if (port_them == Templ_VulnCheck) {
928 tmpl = &tmplset->pkts[Proto_VulnCheck];
929 port_them &= 0xFFFF;
930 } else {
931 return;
932 }
933
934 /* Create some shorter local variables to work with */
935 if (*r_length > tmpl->ipv4.length)
936 *r_length = tmpl->ipv4.length;
937 memcpy(px, tmpl->ipv4.packet, *r_length);
938 offset_ip = tmpl->ipv4.offset_ip;
939 offset_tcp = tmpl->ipv4.offset_tcp;
940 ip_id = ip_them ^ port_them ^ seqno;
941
942 /*
943
944 0 1 2 3
945 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
946 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
947 |Version| IHL |Type of Service| Total Length |
948 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
949 | Identification |Flags| Fragment Offset |
950 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
951 | Time to Live | Protocol | Header Checksum |
952 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
953 | Source Address |
954 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
955 | Destination Address |
956 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
957 | Options | Padding |
958 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
959
960 */
961
962 /*
963 * Fill in the empty fields in the IP header and then re-calculate
964 * the checksum.
965 */
966 {
967 unsigned total_length = tmpl->ipv4.length - tmpl->ipv4.offset_ip;
968 px[offset_ip+2] = (unsigned char)(total_length>>8);
969 px[offset_ip+3] = (unsigned char)(total_length>>0);
970 }
971 px[offset_ip+4] = (unsigned char)(ip_id >> 8);
972 px[offset_ip+5] = (unsigned char)(ip_id & 0xFF);
973 px[offset_ip+12] = (unsigned char)((ip_me >> 24) & 0xFF);
974 px[offset_ip+13] = (unsigned char)((ip_me >> 16) & 0xFF);
975 px[offset_ip+14] = (unsigned char)((ip_me >> 8) & 0xFF);
976 px[offset_ip+15] = (unsigned char)((ip_me >> 0) & 0xFF);
977 px[offset_ip+16] = (unsigned char)((ip_them >> 24) & 0xFF);
978 px[offset_ip+17] = (unsigned char)((ip_them >> 16) & 0xFF);
979 px[offset_ip+18] = (unsigned char)((ip_them >> 8) & 0xFF);
980 px[offset_ip+19] = (unsigned char)((ip_them >> 0) & 0xFF);
981
982
983 px[offset_ip+10] = (unsigned char)(0);
984 px[offset_ip+11] = (unsigned char)(0);
985
986 xsum2 = (unsigned)~ip_header_checksum(px, offset_ip, tmpl->ipv4.length);
987
988 px[offset_ip+10] = (unsigned char)(xsum2 >> 8);
989 px[offset_ip+11] = (unsigned char)(xsum2 & 0xFF);
990
991
992 /*
993 * Now do the checksum for the higher layer protocols
994 */
995 xsum = 0;
996 switch (tmpl->proto) {
997 case Proto_TCP:
998 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
999 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
1000 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
1001 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
1002 px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);
1003 px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);
1004 px[offset_tcp+ 6] = (unsigned char)(seqno >> 8);
1005 px[offset_tcp+ 7] = (unsigned char)(seqno >> 0);
1006
1007 xsum += (uint64_t)tmpl->ipv4.checksum_tcp
1008 + (uint64_t)ip_me
1009 + (uint64_t)ip_them
1010 + (uint64_t)port_me
1011 + (uint64_t)port_them
1012 + (uint64_t)seqno;
1013 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1014 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1015 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1016 xsum = ~xsum;
1017
1018 px[offset_tcp+16] = (unsigned char)(xsum >> 8);
1019 px[offset_tcp+17] = (unsigned char)(xsum >> 0);
1020 break;
1021 case Proto_UDP:
1022 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
1023 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
1024 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
1025 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
1026 px[offset_tcp+ 4] = (unsigned char)((tmpl->ipv4.length - tmpl->ipv4.offset_app + 8)>>8);
1027 px[offset_tcp+ 5] = (unsigned char)((tmpl->ipv4.length - tmpl->ipv4.offset_app + 8)&0xFF);
1028
1029 px[offset_tcp+6] = (unsigned char)(0);
1030 px[offset_tcp+7] = (unsigned char)(0);
1031 xsum = udp_checksum2(px, offset_ip, offset_tcp, tmpl->ipv4.length - offset_tcp);
1032 /*xsum += (uint64_t)tmpl->checksum_tcp
1033 + (uint64_t)ip_me
1034 + (uint64_t)ip_them
1035 + (uint64_t)port_me
1036 + (uint64_t)port_them
1037 + (uint64_t)2*(tmpl->length - tmpl->offset_app);
1038 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1039 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1040 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1041 printf("%04x\n", xsum);*/
1042 xsum = ~xsum;
1043 px[offset_tcp+6] = (unsigned char)(xsum >> 8);
1044 px[offset_tcp+7] = (unsigned char)(xsum >> 0);
1045 break;
1046 case Proto_SCTP:
1047 px[offset_tcp+ 0] = (unsigned char)(port_me >> 8);
1048 px[offset_tcp+ 1] = (unsigned char)(port_me & 0xFF);
1049 px[offset_tcp+ 2] = (unsigned char)(port_them >> 8);
1050 px[offset_tcp+ 3] = (unsigned char)(port_them & 0xFF);
1051
1052 px[offset_tcp+16] = (unsigned char)(seqno >> 24);
1053 px[offset_tcp+17] = (unsigned char)(seqno >> 16);
1054 px[offset_tcp+18] = (unsigned char)(seqno >> 8);
1055 px[offset_tcp+19] = (unsigned char)(seqno >> 0);
1056
1057 xsum = sctp_checksum(px + offset_tcp, tmpl->ipv4.length - offset_tcp);
1058 px[offset_tcp+ 8] = (unsigned char)(xsum >> 24);
1059 px[offset_tcp+ 9] = (unsigned char)(xsum >> 16);
1060 px[offset_tcp+10] = (unsigned char)(xsum >> 8);
1061 px[offset_tcp+11] = (unsigned char)(xsum >> 0);
1062 break;
1063 case Proto_ICMP_ping:
1064 case Proto_ICMP_timestamp:
1065 seqno = (unsigned)syn_cookie_ipv4(ip_them, port_them, ip_me, 0, entropy);
1066 px[offset_tcp+ 4] = (unsigned char)(seqno >> 24);
1067 px[offset_tcp+ 5] = (unsigned char)(seqno >> 16);
1068 px[offset_tcp+ 6] = (unsigned char)(seqno >> 8);
1069 px[offset_tcp+ 7] = (unsigned char)(seqno >> 0);
1070 xsum = (uint64_t)tmpl->ipv4.checksum_tcp
1071 + (uint64_t)seqno;
1072 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1073 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1074 xsum = (xsum >> 16) + (xsum & 0xFFFF);
1075 xsum = ~xsum;
1076 px[offset_tcp+2] = (unsigned char)(xsum >> 8);
1077 px[offset_tcp+3] = (unsigned char)(xsum >> 0);
1078 break;
1079 case Proto_VulnCheck:
1080 tmplset->vulncheck->set_target(tmpl,
1081 ip_them, port_them,
1082 ip_me, port_me,
1083 seqno,
1084 px, sizeof_px, r_length);
1085 break;
1086 case Proto_ARP:
1087 /* don't do any checksumming */
1088 break;
1089 case Proto_Oproto:
1090 /* TODO: probably need to add checksums for certain protocols */
1091 break;
1092 case Proto_Count:
1093 break;
1094 }
1095 }
1096
1097 #if defined(WIN32) || defined(_WIN32)
1098 #define AF_INET6 23
1099 #else
1100 #include <sys/socket.h>
1101 #endif
1102
1103 /***************************************************************************
1104 * Creates an IPv6 packet from an IPv4 template, by simply replacing
1105 * the IPv4 header with the IPv6 header.
1106 ***************************************************************************/
1107 static void
_template_init_ipv6(struct TemplatePacket * tmpl,macaddress_t router_mac_ipv6,unsigned data_link_type)1108 _template_init_ipv6(struct TemplatePacket *tmpl, macaddress_t router_mac_ipv6, unsigned data_link_type)
1109 {
1110 struct PreprocessedInfo parsed;
1111 unsigned x;
1112 unsigned payload_length;
1113 unsigned offset_ip;
1114 unsigned offset_tcp;
1115 unsigned offset_tcp6;
1116 unsigned char *buf;
1117
1118 /* Zero out everything and start from scratch */
1119 if (tmpl->ipv6.packet) {
1120 free(tmpl->ipv6.packet);
1121 memset(&tmpl->ipv6, 0, sizeof(tmpl->ipv6));
1122 }
1123
1124 /* Parse the existing IPv4 packet */
1125 x = preprocess_frame(tmpl->ipv4.packet, tmpl->ipv4.length, data_link_type, &parsed);
1126 if (!x || parsed.found == FOUND_NOTHING) {
1127 LOG(0, "ERROR: bad packet template\n");
1128 exit(1);
1129 }
1130
1131 /* The "payload" in this case is everything past the IP header,
1132 * so TCP or UDP headers are inside the IP payload */
1133 payload_length = tmpl->ipv4.length - tmpl->ipv4.offset_tcp;
1134 offset_ip = tmpl->ipv4.offset_ip;
1135 offset_tcp = tmpl->ipv4.offset_tcp;
1136
1137 /* Create a copy of the IPv4 packet */
1138 buf = MALLOC(tmpl->ipv4.length + 40);
1139 memcpy(buf, tmpl->ipv4.packet, tmpl->ipv4.length);
1140 tmpl->ipv6.packet = buf;
1141
1142
1143 /* destination = end of IPv6 header
1144 * source = end of IPv4 header
1145 * contents = everything after IPv4/IPv6 header */
1146 offset_tcp6 = offset_ip + 40;
1147 memmove(buf + offset_tcp6,
1148 buf + offset_tcp,
1149 payload_length
1150 );
1151
1152 /* fill the IPv6 header with zeroes */
1153 memset(buf + offset_ip, 0, 40);
1154 tmpl->ipv6.length = offset_ip + 40 + payload_length;
1155
1156 switch (data_link_type) {
1157 case PCAP_DLT_NULL: /* Null VPN tunnel */
1158 /* FIXME: insert platform dependent value here */
1159 *(int*)buf = AF_INET6;
1160 break;
1161 case PCAP_DLT_RAW: /* Raw (nothing before IP header) */
1162 break;
1163 case PCAP_DLT_ETHERNET: /* Etherent */
1164 /* Reset the destination MAC address to be the IPv6 router
1165 * instead of the IPv4 router, which sometimes are different */
1166 memcpy(buf + 0, router_mac_ipv6.addr, 6);
1167
1168 /* Reset the Ethertype field to 0x86dd (meaning IPv6) */
1169 buf[12] = 0x86;
1170 buf[13] = 0xdd;
1171 break;
1172 }
1173
1174
1175 /* IP.version = 6 */
1176 buf[offset_ip + 0] = 0x60;
1177
1178 /* Set payload length field. In IPv4, this field included the header,
1179 * but in IPv6, it's everything after the header. In other words,
1180 * the size of an IPv6 packet is 40+payload_length, whereas in IPv4
1181 * it was total_length. */
1182 buf[offset_ip + 4] = (unsigned char)(payload_length >> 8);
1183 buf[offset_ip + 5] = (unsigned char)(payload_length >> 0);
1184
1185 /* Set the "next header" field.
1186 * TODO: need to fix ICMP */
1187 buf[offset_ip + 6] = (unsigned char)parsed.ip_protocol;
1188 if (parsed.ip_protocol == 1) {
1189 buf[offset_ip + 6] = 58; /* ICMPv6 */
1190 if (payload_length > 0 && buf[offset_tcp6 + 0] == 8) {
1191 /* PING -> PINGv6 */
1192 buf[offset_tcp6 + 0] = 128;
1193 }
1194 }
1195
1196 /* Hop limit starts out as 255 */
1197 buf[offset_ip + 7] = 0xFF;
1198
1199 /* Parse our newly construct IPv6 packet */
1200 x = preprocess_frame(buf, tmpl->ipv6.length, data_link_type, &parsed);
1201 if (!x || parsed.found == FOUND_NOTHING) {
1202 LOG(0, "[-] FAILED: bad packet template\n");
1203 exit(1);
1204 }
1205 tmpl->ipv6.offset_ip = parsed.ip_offset;
1206 tmpl->ipv6.offset_tcp = parsed.transport_offset;
1207 tmpl->ipv6.offset_app = parsed.app_offset;
1208
1209
1210 }
1211
1212 /***************************************************************************
1213 * Here we take a packet template, parse it, then make it easier to work
1214 * with.
1215 ***************************************************************************/
1216 static void
_template_init(struct TemplatePacket * tmpl,macaddress_t source_mac,macaddress_t router_mac_ipv4,macaddress_t router_mac_ipv6,const void * packet_bytes,size_t packet_size,unsigned data_link_type)1217 _template_init(
1218 struct TemplatePacket *tmpl,
1219 macaddress_t source_mac,
1220 macaddress_t router_mac_ipv4,
1221 macaddress_t router_mac_ipv6,
1222 const void *packet_bytes,
1223 size_t packet_size,
1224 unsigned data_link_type
1225 )
1226 {
1227 unsigned char *px;
1228 struct PreprocessedInfo parsed;
1229 unsigned x;
1230
1231 /*
1232 * Create the new template structure:
1233 * - zero it out
1234 * - make copy of the old packet to serve as new template
1235 */
1236 memset(tmpl, 0, sizeof(*tmpl));
1237 tmpl->ipv4.length = (unsigned)packet_size;
1238
1239 tmpl->ipv4.packet = MALLOC(2048 + packet_size);
1240 memcpy(tmpl->ipv4.packet, packet_bytes, tmpl->ipv4.length);
1241 px = tmpl->ipv4.packet;
1242
1243 /*
1244 * Parse the existing packet template. We support TCP, UDP, ICMP,
1245 * and ARP packets.
1246 */
1247 x = preprocess_frame(px, tmpl->ipv4.length, 1 /*enet*/, &parsed);
1248 if (!x || parsed.found == FOUND_NOTHING) {
1249 LOG(0, "ERROR: bad packet template\n");
1250 exit(1);
1251 }
1252 tmpl->ipv4.offset_ip = parsed.ip_offset;
1253 tmpl->ipv4.offset_tcp = parsed.transport_offset;
1254 tmpl->ipv4.offset_app = parsed.app_offset;
1255 if (parsed.found == FOUND_ARP) {
1256 tmpl->ipv4.length = parsed.ip_offset + 28;
1257 } else
1258 tmpl->ipv4.length = parsed.ip_offset + parsed.ip_length;
1259
1260 /*
1261 * Overwrite the MAC and IP addresses
1262 */
1263 memcpy(px+0, router_mac_ipv4.addr, 6);
1264 memcpy(px+6, source_mac.addr, 6);
1265 memset((void*)parsed._ip_src, 0, 4);
1266 memset((void*)parsed._ip_dst, 0, 4);
1267
1268
1269 /*
1270 * ARP
1271 *
1272 * If this is an ARP template (for doing arpscans), then just set our
1273 * configured source IP and MAC addresses.
1274 */
1275 if (parsed.found == FOUND_ARP) {
1276 memcpy((char*)parsed._ip_src - 6, source_mac.addr, 6);
1277 tmpl->proto = Proto_ARP;
1278 return;
1279 }
1280
1281 /*
1282 * IPv4
1283 *
1284 * Calculate the partial checksum. We zero out the fields that will be
1285 * added later the packet, then calculate the checksum as if they were
1286 * zero. This makes recalculation of the checksum easier when we transmit
1287 */
1288 memset(px + tmpl->ipv4.offset_ip + 4, 0, 2); /* IP ID field */
1289 memset(px + tmpl->ipv4.offset_ip + 10, 0, 2); /* checksum */
1290 memset(px + tmpl->ipv4.offset_ip + 12, 0, 8); /* addresses */
1291 tmpl->ipv4.checksum_ip = ip_header_checksum( tmpl->ipv4.packet,
1292 tmpl->ipv4.offset_ip,
1293 tmpl->ipv4.length);
1294
1295 /*
1296 * Higher layer protocols: zero out dest/checksum fields, then calculate
1297 * a partial checksum
1298 */
1299 switch (parsed.ip_protocol) {
1300 case 1: /* ICMP */
1301 tmpl->ipv4.offset_app = tmpl->ipv4.length;
1302 tmpl->ipv4.checksum_tcp = icmp_ipv4_checksum(tmpl);
1303 switch (px[tmpl->ipv4.offset_tcp]) {
1304 case 8:
1305 tmpl->proto = Proto_ICMP_ping;
1306 break;
1307 case 13:
1308 tmpl->proto = Proto_ICMP_timestamp;
1309 break;
1310 }
1311 break;
1312 break;
1313 case 6: /* TCP */
1314 /* zero out fields that'll be overwritten */
1315 memset(px + tmpl->ipv4.offset_tcp + 0, 0, 8); /* destination port and seqno */
1316 memset(px + tmpl->ipv4.offset_tcp + 16, 0, 2); /* checksum */
1317 tmpl->ipv4.checksum_tcp = tcp_ipv4_checksum(tmpl);
1318 tmpl->proto = Proto_TCP;
1319 break;
1320 case 17: /* UDP */
1321 memset(px + tmpl->ipv4.offset_tcp + 6, 0, 2); /* checksum */
1322 tmpl->ipv4.checksum_tcp = udp_ipv4_checksum(tmpl);
1323 tmpl->proto = Proto_UDP;
1324 break;
1325 case 132: /* SCTP */
1326 tmpl->ipv4.checksum_tcp = sctp_checksum(
1327 tmpl->ipv4.packet + tmpl->ipv4.offset_tcp,
1328 tmpl->ipv4.length - tmpl->ipv4.offset_tcp);
1329 tmpl->proto = Proto_SCTP;
1330 break;
1331 }
1332
1333 /*
1334 * DATALINK KLUDGE
1335 *
1336 * Adjust the data link header in case of Raw IP packets. This isn't
1337 * the correct way to do this, but I'm too lazy to refactor code
1338 * for the right way, so we'll do it this way now.
1339 */
1340 if (data_link_type == PCAP_DLT_NULL /* Null VPN tunnel */) {
1341 int linkproto = 2; /* AF_INET */
1342 tmpl->ipv4.length -= tmpl->ipv4.offset_ip - sizeof(int);
1343 tmpl->ipv4.offset_tcp -= tmpl->ipv4.offset_ip - sizeof(int);
1344 tmpl->ipv4.offset_app -= tmpl->ipv4.offset_ip - sizeof(int);
1345 memmove(tmpl->ipv4.packet + sizeof(int),
1346 tmpl->ipv4.packet + tmpl->ipv4.offset_ip,
1347 tmpl->ipv4.length);
1348 tmpl->ipv4.offset_ip = 4;
1349 memcpy(tmpl->ipv4.packet, &linkproto, sizeof(int));
1350 } else if (data_link_type == PCAP_DLT_RAW /* Raw IP */) {
1351 tmpl->ipv4.length -= tmpl->ipv4.offset_ip;
1352 tmpl->ipv4.offset_tcp -= tmpl->ipv4.offset_ip;
1353 tmpl->ipv4.offset_app -= tmpl->ipv4.offset_ip;
1354 memmove(tmpl->ipv4.packet,
1355 tmpl->ipv4.packet + tmpl->ipv4.offset_ip,
1356 tmpl->ipv4.length);
1357 tmpl->ipv4.offset_ip = 0;
1358 } else if (data_link_type == PCAP_DLT_ETHERNET) {
1359 /* the default, do nothing */
1360 } else {
1361 LOG(0, "[-] FAILED: bad packet template, unknown data link type\n");
1362 LOG(0, " [hint] masscan doesn't know how to format packets for this interface\n");
1363 exit(1);
1364 }
1365
1366 /* Now create an IPv6 template based upon the IPv4 template */
1367 _template_init_ipv6(tmpl, router_mac_ipv6, data_link_type);
1368 }
1369
1370 /***************************************************************************
1371 ***************************************************************************/
1372 void
template_packet_init(struct TemplateSet * templset,macaddress_t source_mac,macaddress_t router_mac_ipv4,macaddress_t router_mac_ipv6,struct PayloadsUDP * udp_payloads,struct PayloadsUDP * oproto_payloads,int data_link,uint64_t entropy)1373 template_packet_init(
1374 struct TemplateSet *templset,
1375 macaddress_t source_mac,
1376 macaddress_t router_mac_ipv4,
1377 macaddress_t router_mac_ipv6,
1378 struct PayloadsUDP *udp_payloads,
1379 struct PayloadsUDP *oproto_payloads,
1380 int data_link,
1381 uint64_t entropy)
1382 {
1383 templset->count = 0;
1384 templset->entropy = entropy;
1385
1386 /* [SCTP] */
1387 _template_init(&templset->pkts[Proto_SCTP],
1388 source_mac, router_mac_ipv4, router_mac_ipv6,
1389 default_sctp_template,
1390 sizeof(default_sctp_template)-1,
1391 data_link);
1392 templset->count++;
1393
1394 /* [TCP] */
1395 _template_init(&templset->pkts[Proto_TCP],
1396 source_mac, router_mac_ipv4, router_mac_ipv6,
1397 default_tcp_template,
1398 sizeof(default_tcp_template)-1,
1399 data_link);
1400 templset->count++;
1401
1402 /* [UDP] */
1403 _template_init(&templset->pkts[Proto_UDP],
1404 source_mac, router_mac_ipv4, router_mac_ipv6,
1405 default_udp_template,
1406 sizeof(default_udp_template)-1,
1407 data_link);
1408 templset->pkts[Proto_UDP].payloads = udp_payloads;
1409 templset->count++;
1410
1411 /* [UDP oproto] */
1412 _template_init(&templset->pkts[Proto_Oproto],
1413 source_mac, router_mac_ipv4, router_mac_ipv6,
1414 default_udp_template,
1415 sizeof(default_udp_template)-1,
1416 data_link);
1417 templset->pkts[Proto_Oproto].payloads = oproto_payloads;
1418 templset->count++;
1419
1420
1421 /* [ICMP ping] */
1422 _template_init(&templset->pkts[Proto_ICMP_ping],
1423 source_mac, router_mac_ipv4, router_mac_ipv6,
1424 default_icmp_ping_template,
1425 sizeof(default_icmp_ping_template)-1,
1426 data_link);
1427 templset->count++;
1428
1429 /* [ICMP timestamp] */
1430 _template_init(&templset->pkts[Proto_ICMP_timestamp],
1431 source_mac, router_mac_ipv4, router_mac_ipv6,
1432 default_icmp_timestamp_template,
1433 sizeof(default_icmp_timestamp_template)-1,
1434 data_link);
1435 templset->count++;
1436
1437 /* [ARP] */
1438 _template_init( &templset->pkts[Proto_ARP],
1439 source_mac, router_mac_ipv4, router_mac_ipv6,
1440 default_arp_template,
1441 sizeof(default_arp_template)-1,
1442 data_link);
1443 templset->count++;
1444
1445 /* [VulnCheck] */
1446 if (templset->vulncheck) {
1447 _template_init( &templset->pkts[Proto_VulnCheck],
1448 source_mac, router_mac_ipv4, router_mac_ipv6,
1449 templset->vulncheck->packet,
1450 templset->vulncheck->packet_length,
1451 data_link);
1452 templset->count++;
1453 }
1454 }
1455
1456
1457
1458
1459 /***************************************************************************
1460 * Overwrites the TTL of the packet
1461 ***************************************************************************/
1462 void
template_set_ttl(struct TemplateSet * tmplset,unsigned ttl)1463 template_set_ttl(struct TemplateSet *tmplset, unsigned ttl)
1464 {
1465 unsigned i;
1466
1467 for (i=0; i<tmplset->count; i++) {
1468 struct TemplatePacket *tmpl = &tmplset->pkts[i];
1469 unsigned char *px = tmpl->ipv4.packet;
1470 unsigned offset = tmpl->ipv4.offset_ip;
1471
1472 px[offset+8] = (unsigned char)(ttl);
1473 tmpl->ipv4.checksum_ip = ip_header_checksum( tmpl->ipv4.packet,
1474 tmpl->ipv4.offset_ip,
1475 tmpl->ipv4.length);
1476 }
1477 }
1478
1479 void
template_set_vlan(struct TemplateSet * tmplset,unsigned vlan)1480 template_set_vlan(struct TemplateSet *tmplset, unsigned vlan)
1481 {
1482 unsigned i;
1483
1484 for (i=0; i<tmplset->count; i++) {
1485 struct TemplatePacket *tmpl = &tmplset->pkts[i];
1486 unsigned char *px;
1487
1488 if (tmpl->ipv4.length < 14)
1489 continue;
1490
1491 px = MALLOC(tmpl->ipv4.length + 4);
1492 memcpy(px, tmpl->ipv4.packet, 12);
1493 memcpy(px+16, tmpl->ipv4.packet+12, tmpl->ipv4.length - 12);
1494
1495 px[12] = 0x81;
1496 px[13] = 0x00;
1497 px[14] = (unsigned char)(vlan>>8);
1498 px[15] = (unsigned char)(vlan>>0);
1499
1500 tmpl->ipv4.packet = px;
1501 tmpl->ipv4.length += 4;
1502
1503 tmpl->ipv4.offset_ip += 4;
1504 tmpl->ipv4.offset_tcp += 4;
1505 tmpl->ipv4.offset_app += 4;
1506 }
1507 }
1508
1509
1510
1511 /***************************************************************************
1512 ***************************************************************************/
1513 int
template_selftest(void)1514 template_selftest(void)
1515 {
1516 struct TemplateSet tmplset[1];
1517 int failures = 0;
1518
1519 memset(tmplset, 0, sizeof(tmplset[0]));
1520 template_packet_init(
1521 tmplset,
1522 macaddress_from_bytes("\x00\x11\x22\x33\x44\x55"),
1523 macaddress_from_bytes("\x66\x55\x44\x33\x22\x11"),
1524 macaddress_from_bytes("\x66\x55\x44\x33\x22\x11"),
1525 0, /* UDP payloads = empty */
1526 0, /* Oproto payloads = empty */
1527 1, /* Ethernet */
1528 0 /* no entropy */
1529 );
1530 failures += tmplset->pkts[Proto_TCP].proto != Proto_TCP;
1531 failures += tmplset->pkts[Proto_UDP].proto != Proto_UDP;
1532 //failures += tmplset->pkts[Proto_SCTP].proto != Proto_SCTP;
1533 failures += tmplset->pkts[Proto_ICMP_ping].proto != Proto_ICMP_ping;
1534 //failures += tmplset->pkts[Proto_ICMP_timestamp].proto != Proto_ICMP_timestamp;
1535 //failures += tmplset->pkts[Proto_ARP].proto != Proto_ARP;
1536
1537 if (failures)
1538 fprintf(stderr, "template: failed\n");
1539 return failures;
1540 }
1541
1542