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