1 /* David Leonard, 2004. Public domain. */
2 /* $Id$ */
3 
4 #if HAVE_CONFIG_H
5 # include "config.h"
6 #endif
7 
8 #if STDC_HEADERS
9 # include <stdio.h>
10 # include <string.h>
11 #endif
12 
13 #include "type.h"
14 #include "tag.h"
15 #include "flow.h"
16 
17 #define MINLEN (6 + 6 * 16)
18 #define MACFMT "%02x:%02x:%02x:%02x:%02x:%02x"
19 #define MACVAL(p) \
20 		(unsigned char)((p)[0]), \
21 		(unsigned char)((p)[1]), \
22 		(unsigned char)((p)[2]), \
23 		(unsigned char)((p)[3]), \
24 		(unsigned char)((p)[4]), \
25 		(unsigned char)((p)[5])
26 
27 
28 /*
29  * Wake-on-LAN (aka AMD Magic Packet) is an unusual packet pattern
30  * that we detect early, before higher protocols. They can be broadcast
31  * raw, or even routed, but for ethernet we assume the sender's MAC
32  * is at the beginning.
33  */
34 const char *
ether_wol(p,end,src)35 ether_wol(p, end, src)
36 	const char *p;
37 	const char *end;
38 	const char *src;
39 {
40 	static const unsigned char
41             magic[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
42 	    bad1[6] =  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
43 	    bad2[6] =  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
44         static char tag[TAGLEN];
45 	const char *q;
46 
47 	for (q = p; q + MINLEN <= end; q++)  {
48 	    const char *b = q + 6;
49 	    if (memcmp(q, magic, 6) == 0 &&
50 		memcmp(b, b+(6*1), 6*1) == 0 &&
51 		memcmp(b, b+(6*2), 6*2) == 0 &&
52 		memcmp(b, b+(6*4), 6*4) == 0 &&
53 		memcmp(b, b+(6*8), 6*8) == 0 &&
54 		memcmp(b, bad1, 6) != 0 &&
55 		memcmp(b, bad2, 6) != 0)
56 	    {
57 		snprintf(tag, sizeof tag,
58 		    "wol " MACFMT " -> " MACFMT,
59 		    MACVAL(src), MACVAL(b));
60 		return tag;
61 	    }
62 	}
63 	return NULL;
64 }
65