1 /* Copyright (c) 2007 by Errata Security */
\r
4 #include "netframe.h"
\r
8 static const char *group_name(struct NetFrame *frame, unsigned group_address)
\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
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
27 void process_igmp(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
\r
32 unsigned max_resp_time;
\r
34 unsigned group_address;
\r
38 FRAMERR(frame, "igmp: frame empty\n");
\r
42 FRAMERR(frame, "igmp: frame too short\n");
\r
47 igmp.max_resp_time = px[1];
\r
48 igmp.checksum = ex16be(px+2);
\r
49 igmp.group_address = ex32be(px+4);
\r
51 switch (igmp.type) {
\r
52 case 0x11: /* membership query */
\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
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
70 case 0x22: /*v3 membersip report */
\r
72 unsigned num_records = ex16be(px+6);
\r
76 if (num_records != 1)
\r
77 SAMPLE("igmp", "igmpv3.numrecs", REC_UNSIGNED, &num_records, sizeof(num_records));
\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
89 offset += sources*4+aux_data_len+8;
\r
94 FRAMERR(frame, "igmp: unknown type=%d\n", igmp.type);
\r