OSDN Git Service

Fix no pic
[uclinux-h8/uClinux-dist.git] / user / ferret / igmp.c
1 /* Copyright (c) 2007 by Errata Security */\r
2 #include "protos.h"\r
3 #include "ferret.h"\r
4 #include "netframe.h"\r
5 #include "formats.h"\r
6 \r
7 \r
8 static const char *group_name(struct NetFrame *frame, unsigned group_address)\r
9 {\r
10         switch (group_address) {\r
11         case 0xeffffffa: return "SSDP"; break;\r
12         case 0xe00000fb: return "mDNS"; break;\r
13         case 0xe0000116: return "SLP (General)"; break;\r
14         case 0xe0000123: return "SLP (Discovery)"; break;\r
15         case 0xe4c8c8c9: return "(unknown)"; break;\r
16         case 0xeffffffd: return "SLP (Admin Scoped)"; break;\r
17         default: \r
18                 FRAMERR(frame, "igmp: unknown group: %d.%d.%d.%d\n", \r
19                         (group_address>>24)&0xFF,\r
20                         (group_address>>16)&0xFF,\r
21                         (group_address>> 8)&0xFF,\r
22                         (group_address>> 0)&0xFF\r
23                         );\r
24                 return "(unknown)";\r
25         }\r
26 }\r
27 void process_igmp(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)\r
28 {\r
29         struct {\r
30                 unsigned version;\r
31                 unsigned type;\r
32                 unsigned max_resp_time;\r
33                 unsigned checksum;\r
34                 unsigned group_address;\r
35         } igmp;\r
36 \r
37         if (length == 0) {\r
38                 FRAMERR(frame, "igmp: frame empty\n");\r
39                 return;\r
40         }\r
41         if (length < 8) {\r
42                 FRAMERR(frame, "igmp: frame too short\n");\r
43                 return;\r
44         }\r
45 \r
46         igmp.type = px[0];\r
47         igmp.max_resp_time = px[1];\r
48         igmp.checksum = ex16be(px+2);\r
49         igmp.group_address = ex32be(px+4);\r
50 \r
51         switch (igmp.type) {\r
52         case 0x11: /* membership query */\r
53                 break;\r
54         case 0x16: /* membership report */\r
55                 process_record(seap,\r
56                         "proto",        REC_SZ,                 "IGMP",                         -1,\r
57                         "op",           REC_SZ,                 "Membership",           -1,\r
58                         "group",        REC_IPv4,               &igmp.group_address,    sizeof(igmp.group_address),\r
59                         "groupname",REC_SZ,                     group_name(frame, igmp.group_address),  -1,\r
60                         0);\r
61                 break;\r
62         case 0x17:\r
63                 process_record(seap,\r
64                         "proto",        REC_SZ,                 "IGMP",                         -1,\r
65                         "op",           REC_SZ,                 "Membership",           -1,\r
66                         "group",        REC_IPv4,               &igmp.group_address,    sizeof(igmp.group_address),\r
67                         "groupname",REC_SZ,                     group_name(frame, igmp.group_address),  -1,\r
68                         0);\r
69                 break;\r
70         case 0x22: /*v3 membersip report */\r
71                 {\r
72                         unsigned num_records = ex16be(px+6);\r
73                         unsigned i;\r
74                         unsigned offset=8;\r
75 \r
76                         if (num_records != 1) \r
77                                 SAMPLE("igmp", "igmpv3.numrecs",        REC_UNSIGNED, &num_records,     sizeof(num_records));\r
78 \r
79                         for (i=0; i<num_records && offset+8 <= length; i++) {\r
80                                 unsigned ip = ex32be(px+offset+4);\r
81                                 unsigned sources = ex16be(px+offset+2);\r
82                                 unsigned aux_data_len = px[offset+1]*4;\r
83                                 process_record(seap,\r
84                                         "proto",        REC_SZ,                 "IGMP",                         -1,\r
85                                         "op",           REC_SZ,                 "Membership",           -1,\r
86                                         "group",        REC_IPv4,               &ip,    sizeof(ip),\r
87                                         "groupname",REC_SZ,                     group_name(frame, ip),  -1,\r
88                                         0);\r
89                                 offset += sources*4+aux_data_len+8;\r
90                         }\r
91                 }\r
92                 break;\r
93         default:\r
94                 FRAMERR(frame, "igmp: unknown type=%d\n", igmp.type);\r
95                 break;\r
96         }\r
97 }\r
98 \r