Ejemplo n.º 1
0
    def test_igmpv3_encode_kv(self):
        # Create reports using the new syntax.
        #c = igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) /                    \
        c = igmp() / \
            igmpv3.report(records=[GroupRecordField("",                    \
                                    group=inet_atol("239.0.1.2"),          \
                                    type=IGMP_CHANGE_TO_INCLUDE),
                                   GroupRecordField("",                    \
                                    group=inet_atol("239.3.2.1"),          \
                                    type=IGMP_CHANGE_TO_INCLUDE,           \
                                    sources=[inet_atol("192.0.2.1")]),     \
                                   GroupRecordField("",                    \
                                    group=inet_atol("224.111.222.111"),    \
                                    type=IGMP_CHANGE_TO_EXCLUDE),          \
                                   GroupRecordField("",                    \
                                    group=inet_atol("225.4.3.2"),          \
                                    type=IGMP_BLOCK_OLD_SOURCES,           \
                                    sources=[inet_atol("192.0.2.99")])])

        c.calc_lengths()
        c.calc_checksums()
        c.encode()

	#hd = hexdumper()
	#print hd.dump2(c.bytes)
	expected = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \
		   "\x03\x00\x00\x00\xEF\x00\x01\x02" \
		   "\x03\x00\x00\x01\xEF\x03\x02\x01" \
		   "\xC0\x00\x02\x01\x04\x00\x00\x00" \
		   "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \
		   "\xE1\x04\x03\x02\xC0\x00\x02\x63"
 
	#print hd.dump2(expected)
	gotttted = c.bytes
	self.assertEqual(expected, gotttted, "test encoding")
Ejemplo n.º 2
0
    def test_igmpv3_encode_kv(self):
        # Create reports using the new syntax.
        #c = igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) /                    \
        c = igmp() / \
            igmpv3.report(records=[GroupRecordField("",                    \
                                    group=inet_atol("239.0.1.2"),          \
                                    type=IGMP_CHANGE_TO_INCLUDE),
                                   GroupRecordField("",                    \
                                    group=inet_atol("239.3.2.1"),          \
                                    type=IGMP_CHANGE_TO_INCLUDE,           \
                                    sources=[inet_atol("192.0.2.1")]),     \
                                   GroupRecordField("",                    \
                                    group=inet_atol("224.111.222.111"),    \
                                    type=IGMP_CHANGE_TO_EXCLUDE),          \
                                   GroupRecordField("",                    \
                                    group=inet_atol("225.4.3.2"),          \
                                    type=IGMP_BLOCK_OLD_SOURCES,           \
                                    sources=[inet_atol("192.0.2.99")])])

        c.calc_lengths()
        c.calc_checksums()
        c.encode()

        #hd = hexdumper()
        #print hd.dump2(c.bytes)
        expected = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \
            "\x03\x00\x00\x00\xEF\x00\x01\x02" \
            "\x03\x00\x00\x01\xEF\x03\x02\x01" \
            "\xC0\x00\x02\x01\x04\x00\x00\x00" \
            "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \
            "\xE1\x04\x03\x02\xC0\x00\x02\x63"

        #print hd.dump2(expected)
        gotttted = c.bytes
        self.assertEqual(expected, gotttted, "test encoding")
Ejemplo n.º 3
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I",
                      "--ether_iface",
                      dest="ether_iface",
                      default=None,
                      help="The name of the source interface.")

    parser.add_option("-e",
                      "--ether_source",
                      dest="ether_source",
                      default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s",
                      "--ip_source",
                      dest="ip_source",
                      default=None,
                      help="The IP source address.")

    parser.add_option("-G",
                      "--igmp_group",
                      dest="igmp_group",
                      default=None,
                      help="The IPv4 group to spoof an IGMPv3 leave for.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.igmp_group is None:
        print "Non-optional argument missing."
        return

    # Create an IGMPv3 change-to-include report for the given group
    # with no sources, which means we're leaving the group.
    # IGMPv3 Host Reports are always sent to IGMP.MCAST.NET (224.0.0.22),
    # and must always contain the Router Alert option.

    c = ethernet(src=ether_atob(options.ether_source),                    \
                 dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRPTS_GROUP)) /      \
        ipv4(src=inet_atol(options.ip_source), dst=INADDR_ALLRPTS_GROUP,  \
             ttl=1, flags=IP_DF, options=[ipvt4opt(IPOPT_RA)]) /          \
        igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) /                       \
        igmpv3.report(records=[GroupRecordField("",                       \
                                group=inet_atol(options.igmp_group),      \
                                type=IGMP_CHANGE_TO_INCLUDE)])
    c.fixup()

    # Send it.
    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))
Ejemplo n.º 4
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I",
                      "--ether_iface",
                      dest="ether_iface",
                      default=None,
                      help="The name of the source interface.")

    parser.add_option("-e",
                      "--ether_source",
                      dest="ether_source",
                      default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s",
                      "--ip_source",
                      dest="ip_source",
                      default=None,
                      help="The IP source address.")

    parser.add_option("-G",
                      "--igmp_group",
                      dest="igmp_group",
                      default=None,
                      help="The IPv4 group to spoof a leave message for.")

    parser.add_option("-A",
                      "--no-router-alert",
                      action="store_true",
                      dest="no_ra",
                      help="Disable the use of the IP Router Alert option.")

    (options, args) = parser.parse_args()

    if options.igmp_group is None or \
       options.ether_source is None or \
       options.ether_iface is None or \
       options.ip_source is None:
        print "A required argument is missing."
        return

    output = PcapConnector(options.ether_iface)

    c = ethernet(src=ether_atob(options.ether_source),	\
                 dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRTRS_GROUP)) / \
        ipv4(flags=IP_DF, id=123, ttl=1, 		\
             src=inet_atol(options.ip_source),		\
             dst=INADDR_ALLRTRS_GROUP) /		\
        igmp(type=IGMP_HOST_LEAVE_MESSAGE) /		\
        igmpv2(group=inet_atol(options.igmp_group))
    c.fixup()

    out = output.write(c.bytes, len(c.bytes))
Ejemplo n.º 5
0
    def test_igmpv3_encode(self):
        # create one packet, copy its bytes, then compare their fields.
        c = igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) / igmpv3.report()
        rep = c.packets[1]

        # An ASM/SSM leave.
        rec0 = GroupRecordField("rec0")
        rec0.type.value = IGMP_CHANGE_TO_INCLUDE
        rec0.group.value = inet_atol("239.0.1.2")
        rep.records.append(rec0)

        # An SSM join.
        rec1 = GroupRecordField("rec1")
        rec1.type.value = IGMP_CHANGE_TO_INCLUDE
        rec1.group.value = inet_atol("239.3.2.1")
        rec1.sources.append(pcs.Field("", 32,
                                      default = inet_atol("192.0.2.1")))
        rec1.nsources.value = len(rec1.sources)
        rep.records.append(rec1)

        # An ASM join.
        rec2 = GroupRecordField("rec2")
        rec2.type.value = IGMP_CHANGE_TO_EXCLUDE
        rec2.group.value = inet_atol("224.111.222.111")
        rep.records.append(rec2)

        # An ASM filter change.
        # XXX I can't get auxiliary data embedding to work reliably,
        # this seems to be because the syntactic sugar for OptionListField
        # makes it difficult to retrieve the size of the embedded fields.
        rec3 = GroupRecordField("rec3")
        rec3.type.value = IGMP_BLOCK_OLD_SOURCES
        rec3.group.value = inet_atol("225.4.3.2")
        rec3.sources.append(pcs.Field("", 32,
                                      default = inet_atol("192.0.2.99")))
        rec3.nsources.value = len(rec3.sources)
        rep.records.append(rec3)

        rep.nrecords = len(rep.records)

        c.calc_checksums()
        c.encode()

	#hd = hexdumper()
	#print hd.dump2(c.bytes)
	expected = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \
		   "\x03\x00\x00\x00\xEF\x00\x01\x02" \
		   "\x03\x00\x00\x01\xEF\x03\x02\x01" \
		   "\xC0\x00\x02\x01\x04\x00\x00\x00" \
		   "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \
		   "\xE1\x04\x03\x02\xC0\x00\x02\x63"
 
	#print hd.dump2(expected)
	gotttted = c.bytes
	self.assertEqual(expected, gotttted, "test encoding")
Ejemplo n.º 6
0
    def test_igmpv3_decode(self):
        # Try decoding the same packet as above, see what we get.
        input    = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \
            "\x03\x00\x00\x00\xEF\x00\x01\x02" \
            "\x03\x00\x00\x01\xEF\x03\x02\x01" \
            "\xC0\x00\x02\x01\x04\x00\x00\x00" \
            "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \
            "\xE1\x04\x03\x02\xC0\x00\x02\x63"

        igh = igmp(input)
        self.assertEqual(input, igh.chain().bytes, "test decoding")
Ejemplo n.º 7
0
    def test_igmpv3_decode(self):
	# Try decoding the same packet as above, see what we get.
	input    = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \
		   "\x03\x00\x00\x00\xEF\x00\x01\x02" \
		   "\x03\x00\x00\x01\xEF\x03\x02\x01" \
		   "\xC0\x00\x02\x01\x04\x00\x00\x00" \
		   "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \
		   "\xE1\x04\x03\x02\xC0\x00\x02\x63"

	igh = igmp(input)
	self.assertEqual(input, igh.chain().bytes, "test decoding")
Ejemplo n.º 8
0
    def test_igmpv3_encode(self):
        # create one packet, copy its bytes, then compare their fields.
        c = igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) / igmpv3.report()
        rep = c.packets[1]

        # An ASM/SSM leave.
        rec0 = GroupRecordField("rec0")
        rec0.type.value = IGMP_CHANGE_TO_INCLUDE
        rec0.group.value = inet_atol("239.0.1.2")
        rep.records.append(rec0)

        # An SSM join.
        rec1 = GroupRecordField("rec1")
        rec1.type.value = IGMP_CHANGE_TO_INCLUDE
        rec1.group.value = inet_atol("239.3.2.1")
        rec1.sources.append(pcs.Field("", 32, default=inet_atol("192.0.2.1")))
        rec1.nsources.value = len(rec1.sources)
        rep.records.append(rec1)

        # An ASM join.
        rec2 = GroupRecordField("rec2")
        rec2.type.value = IGMP_CHANGE_TO_EXCLUDE
        rec2.group.value = inet_atol("224.111.222.111")
        rep.records.append(rec2)

        # An ASM filter change.
        # XXX I can't get auxiliary data embedding to work reliably,
        # this seems to be because the syntactic sugar for OptionListField
        # makes it difficult to retrieve the size of the embedded fields.
        rec3 = GroupRecordField("rec3")
        rec3.type.value = IGMP_BLOCK_OLD_SOURCES
        rec3.group.value = inet_atol("225.4.3.2")
        rec3.sources.append(pcs.Field("", 32, default=inet_atol("192.0.2.99")))
        rec3.nsources.value = len(rec3.sources)
        rep.records.append(rec3)

        rep.nrecords = len(rep.records)

        c.calc_checksums()
        c.encode()

        #hd = hexdumper()
        #print hd.dump2(c.bytes)
        expected = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \
            "\x03\x00\x00\x00\xEF\x00\x01\x02" \
            "\x03\x00\x00\x01\xEF\x03\x02\x01" \
            "\xC0\x00\x02\x01\x04\x00\x00\x00" \
            "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \
            "\xE1\x04\x03\x02\xC0\x00\x02\x63"

        #print hd.dump2(expected)
        gotttted = c.bytes
        self.assertEqual(expected, gotttted, "test encoding")
Ejemplo n.º 9
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I", "--ether_iface",
                      dest="ether_iface", default=None,
                      help="The name of the source interface.")

    parser.add_option("-e", "--ether_source",
                      dest="ether_source", default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s", "--ip_source",
                      dest="ip_source", default=None,
                      help="The IP source address.")

    parser.add_option("-G", "--igmp_group",
                      dest="igmp_group", default=None,
                      help="The IPv4 group to spoof an IGMPv3 leave for.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.igmp_group is None:
	print "Non-optional argument missing."
	return

    # Create an IGMPv3 change-to-include report for the given group
    # with no sources, which means we're leaving the group.
    # IGMPv3 Host Reports are always sent to IGMP.MCAST.NET (224.0.0.22),
    # and must always contain the Router Alert option.

    c = ethernet(src=ether_atob(options.ether_source),                    \
                 dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRPTS_GROUP)) /      \
        ipv4(src=inet_atol(options.ip_source), dst=INADDR_ALLRPTS_GROUP,  \
             ttl=1, flags=IP_DF, options=[ipvt4opt(IPOPT_RA)]) /          \
        igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) /                       \
        igmpv3.report(records=[GroupRecordField("",                       \
                                group=inet_atol(options.igmp_group),      \
                                type=IGMP_CHANGE_TO_INCLUDE)])
    c.fixup()

    # Send it.
    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))
Ejemplo n.º 10
0
def main():

    from optparse import OptionParser
    
    parser = OptionParser()

    parser.add_option("-I", "--ether_iface",
                      dest="ether_iface", default=None,
                      help="The name of the source interface.")

    parser.add_option("-e", "--ether_source",
                      dest="ether_source", default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s", "--ip_source",
                      dest="ip_source", default=None,
                      help="The IP source address.")

    parser.add_option("-G", "--igmp_group",
                      dest="igmp_group", default=None,
                      help="The IPv4 group to spoof a leave message for.")

    parser.add_option("-A", "--no-router-alert",
                      action="store_true", dest="no_ra",
                      help="Disable the use of the IP Router Alert option.")

    (options, args) = parser.parse_args()

    if options.igmp_group is None or \
       options.ether_source is None or \
       options.ether_iface is None or \
       options.ip_source is None:
           print "A required argument is missing."
           return

    output = PcapConnector(options.ether_iface)

    c = ethernet(src=ether_atob(options.ether_source),	\
                 dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRTRS_GROUP)) / \
        ipv4(flags=IP_DF, id=123, ttl=1, 		\
             src=inet_atol(options.ip_source),		\
             dst=INADDR_ALLRTRS_GROUP) /		\
        igmp(type=IGMP_HOST_LEAVE_MESSAGE) /		\
        igmpv2(group=inet_atol(options.igmp_group))
    c.fixup()

    out = output.write(c.bytes, len(c.bytes))
Ejemplo n.º 11
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I",
                      "--ether_iface",
                      dest="ether_iface",
                      default=None,
                      help="The name of the source interface.")

    parser.add_option("-e",
                      "--ether_source",
                      dest="ether_source",
                      default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s",
                      "--ip_source",
                      dest="ip_source",
                      default=None,
                      help="The IP source address.")

    parser.add_option("-G",
                      "--igmp_group",
                      dest="igmp_group",
                      default=None,
                      help="The IPv4 group for a group-specific query. "
                      "If omitted, send a general query.")

    parser.add_option("-S",
                      "--seconds",
                      dest="seconds",
                      default=1.0,
                      help="Number of seconds between packets.")

    parser.add_option("-c",
                      "--count",
                      dest="count",
                      default=None,
                      help="Stop after sending count packets.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    maxresp = 3 * 10

    if options.igmp_group is None:
        # General query.
        dst = INADDR_ALLHOSTS_GROUP
        group = INADDR_ANY
    else:
        # Group-specific query.
        dst = inet_atol(options.igmp_group)
        group = dst

    # Queries don't contain the Router Alert option as they are
    # destined for end stations, not routers.

    c = ethernet(src=ether_atob(options.ether_source),		\
                 dst=ETHER_MAP_IP_MULTICAST(dst)) /		\
        ipv4(flags=IP_DF, ttl=1,				\
             src=inet_atol(options.ip_source),			\
             dst=dst) /						\
        igmp(type=IGMP_v2_HOST_MEMBERSHIP_REPORT, code=maxresp) /	\
        igmpv2(group=group)
    c.fixup()

    output = PcapConnector(options.ether_iface)
    #
    # Send count packets, delayed by seconds
    #
    count = int(options.count)
    if count < 0:
        count = sys.maxint
    while count > 0:
        out = output.write(c.bytes, len(c.bytes))
        count -= 1
        sleep(float(options.seconds))
Ejemplo n.º 12
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I", "--ether_iface",
                      dest="ether_iface", default=None,
                      help="The name of the source interface.")

    parser.add_option("-e", "--ether_source",
                      dest="ether_source", default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-g", "--ether_dest",
                      dest="ether_dest", default=None,
                      help="The host Ethernet destination address.")

    parser.add_option("-s", "--ip_source",
                      dest="ip_source", default=None,
                      help="The IP source address.")

    parser.add_option("-D", "--ip_dest",
                      dest="ip_dest", default=None,
                      help="The IP destination address.")

    parser.add_option("-G", "--igmp_group",
                      dest="igmp_group", default=None,
                      help="The IPv4 group to query.")

    parser.add_option("-S", "--igmp_sources",
                      dest="igmp_sources", default=None,
                      help="Comma-delimited list of IPv4 sources for "
			   "a group-and-source specific query.")

    parser.add_option("-M", "--igmp_maxresp",
                      dest="igmp_maxresp", default=None,
                      help="The maximum time for end-stations to "
		           "respond (in seconds).")

    parser.add_option("-c", "--count",
                      dest="count", default=None,
                      help="Stop after receiving at least count responses.")

    parser.add_option("-2", "--igmp_v2_listen",
                      action="store_true", dest="igmp_v2_listen",
                      help="Listen for responses from IGMPv2 end-stations.")

    parser.add_option("-R", "--igmp_robustness",
                      dest="igmp_robustness", default=None,
                      help="Querier Robustness (default 2)")

    parser.add_option("-Q", "--igmp_qqic",
                      dest="igmp_qqic", default=None,
                      help="Querier's Query Interval (default 10s)")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.count is None:
	print "Non-optional argument missing."
	return

    #if options.ip_dest is not None and options.ether_dest is None:
    #	print "Non-optional argument missing."
    #	return

    maxresp = 10 * 10
    if options.igmp_maxresp is not None:
        maxresp = int(options.igmp_maxresp) * 10    # in units of deciseconds

    #
    # Parse source list for a GSR query.
    #
    sources = []
    if options.igmp_sources is not None:
	if options.igmp_group is None:
	    raise "A group must be specified for a GSR query."
	else:
	    for source in options.igmp_sources.split(','):
		sources.append(inet_atol(source))
	    if len(sources) == 0:
	 	raise "Error parsing source list."

    # Set up the vanilla packet

    if options.ether_dest is not None:
        edst = ether_atob(options.ether_dest)
    else:
        edst = ETHER_MAP_IP_MULTICAST(INADDR_ALLHOSTS_GROUP)

    c = ethernet(src=ether_atob(options.ether_source), dst=edst) / \
        ipv4(flags=IP_DF, ttl=1, src=inet_atol(options.ip_source)) / \
        igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \
        igmpv3.query()
    ip = c.packets[1]
    q = c.packets[3]

    # IGMPv3 General Queries are always sent to ALL-SYSTEMS.MCAST.NET.
    # However we allow this to be overidden for protocol testing -- Windows,
    # in particular, doesn't seem to respond.
    #
    # We expect reports on 224.0.0.22.
    # Queries don't contain the Router Alert option as they are
    # destined for end stations, not routers.

    if options.igmp_robustness is not None:
        q.qrv = int(options.igmp_robustness)
    else:
        q.qrv = 2		    # SHOULD NOT be 1, MUST NOT be 0

    if options.igmp_qqic is not None:
        q.qqic = int(options.igmp_qqic)
    else:
        q.qqic = 10		    # I query every 10 seconds

    if options.igmp_group is None:
        # General query.
        if options.ip_dest is not None:
            ip.dst = inet_atol(options.ip_dest)
        else:
            ip.dst = INADDR_ALLHOSTS_GROUP
        q.group = INADDR_ANY
    else:
        # Group-specific query, possibly with sources.
        if options.ip_dest is not None:
            ip.dst = inet_atol(options.ip_dest)
        else:
            ip.dst = inet_atol(options.igmp_group)
        q.group = ip.dst

    if IN_MULTICAST(ip.dst) is True and \
       options.ether_dest is None:
        c.packets[0].dst = ETHER_MAP_IP_MULTICAST(ip.dst)

    for src in sources:
        q.sources.append(pcs.Field("", 32, default = src))

    c.fixup()

    input = PcapConnector(options.ether_iface)
    input.setfilter("igmp")

    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))

    #
    # Wait for up to 'count' responses to the query to arrive and print them.
    # If options.igmp_v2_listen is True, also count responses from
    # end-stations which respond with IGMPv2.
    #
    # TODO: Pretty-print IGMPv3 reports.
    #
    count = int(options.count)
    while count > 0:
        packet = input.readpkt()
	chain = packet.chain()
	if ((chain.packets[2].type == IGMP_v3_HOST_MEMBERSHIP_REPORT) or
            ((chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT) and \
             (options.igmp_v2_listen is True))):
            version = 3
            if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT:
                version = 2
	    #print chain.packets[2].println()
	    print "%s responded to query with IGMPv%d." % \
	        ((inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src))),
                 version)
	    count -= 1
Ejemplo n.º 13
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I", "--ether_iface",
                      dest="ether_iface", default=None,
                      help="The name of the source interface.")

    parser.add_option("-e", "--ether_source",
                      dest="ether_source", default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s", "--ip_source",
                      dest="ip_source", default=None,
                      help="The IP source address.")

    parser.add_option("-G", "--igmp_group",
                      dest="igmp_group", default=None,
                      help="The IPv4 group for a group-specific query. "
			   "If omitted, send a general query.")

    parser.add_option("-M", "--maxresp",
                      dest="igmp_maxresp", default=None,
                      help="The maximum time for end-stations to respond "
			   "(in seconds).")

    parser.add_option("-c", "--count",
                      dest="count", default=None,
                      help="Stop after receiving at least count responses.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    maxresp = 3 * 10
    if options.igmp_maxresp is not None:
        maxresp = int(options.igmp_maxresp) * 10    # in units of deciseconds

    if options.igmp_group is None:
	# General query.
    	dst = INADDR_ALLHOSTS_GROUP
        group = INADDR_ANY
    else:
	# Group-specific query.
    	dst = inet_atol(options.igmp_group)
        group = dst

    # Queries don't contain the Router Alert option as they are
    # destined for end stations, not routers.

    c = ethernet(src=ether_atob(options.ether_source),		\
                 dst=ETHER_MAP_IP_MULTICAST(dst)) /		\
        ipv4(flags=IP_DF, ttl=1,				\
             src=inet_atol(options.ip_source),			\
             dst=dst) /						\
        igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) /	\
        igmpv2(group=group)
    c.fixup()

    input = PcapConnector(options.ether_iface)
    input.setfilter("igmp")

    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))

    #
    # Wait for up to 'count' responses to the query to arrive and print them.
    #
    count = int(options.count)
    while count > 0:
        packet = input.readpkt()
        chain = packet.chain()
	if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT:
	    #print chain.packets[2].println()
	    print "%s is in %s" % \
	        (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \
	         inet_ntop(AF_INET, struct.pack('!L', chain.packets[3].group)))
	    count -= 1
Ejemplo n.º 14
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I",
                      "--ether_iface",
                      dest="ether_iface",
                      default=None,
                      help="The name of the source interface.")

    parser.add_option("-e",
                      "--ether_source",
                      dest="ether_source",
                      default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s",
                      "--ip_source",
                      dest="ip_source",
                      default=None,
                      help="The IP source address.")

    parser.add_option("-G",
                      "--igmp_group",
                      dest="igmp_group",
                      default=None,
                      help="The IPv4 group for a group-specific query. "
                      "If omitted, send a general query.")

    parser.add_option("-M",
                      "--maxresp",
                      dest="igmp_maxresp",
                      default=None,
                      help="The maximum time for end-stations to respond "
                      "(in seconds).")

    parser.add_option("-c",
                      "--count",
                      dest="count",
                      default=None,
                      help="Stop after receiving at least count responses.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    maxresp = 3 * 10
    if options.igmp_maxresp is not None:
        maxresp = int(options.igmp_maxresp) * 10  # in units of deciseconds

    if options.igmp_group is None:
        # General query.
        dst = INADDR_ALLHOSTS_GROUP
        group = INADDR_ANY
    else:
        # Group-specific query.
        dst = inet_atol(options.igmp_group)
        group = dst

    # Queries don't contain the Router Alert option as they are
    # destined for end stations, not routers.

    c = ethernet(src=ether_atob(options.ether_source),		\
                 dst=ETHER_MAP_IP_MULTICAST(dst)) /		\
        ipv4(flags=IP_DF, ttl=1,				\
             src=inet_atol(options.ip_source),			\
             dst=dst) /						\
        igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) /	\
        igmpv2(group=group)
    c.fixup()

    input = PcapConnector(options.ether_iface)
    input.setfilter("igmp")

    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))

    #
    # Wait for up to 'count' responses to the query to arrive and print them.
    #
    count = int(options.count)
    while count > 0:
        packet = input.readpkt()
        chain = packet.chain()
        if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT:
            #print chain.packets[2].println()
            print "%s is in %s" % \
                (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \
                 inet_ntop(AF_INET, struct.pack('!L', chain.packets[3].group)))
            count -= 1
Ejemplo n.º 15
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I",
                      "--ether_iface",
                      dest="ether_iface",
                      default=None,
                      help="The name of the source interface.")

    parser.add_option("-e",
                      "--ether_source",
                      dest="ether_source",
                      default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-g",
                      "--ether_dest",
                      dest="ether_dest",
                      default=None,
                      help="The host Ethernet destination address.")

    parser.add_option("-s",
                      "--ip_source",
                      dest="ip_source",
                      default=None,
                      help="The IP source address.")

    parser.add_option("-D",
                      "--ip_dest",
                      dest="ip_dest",
                      default=None,
                      help="The IP destination address.")

    parser.add_option("-G",
                      "--igmp_group",
                      dest="igmp_group",
                      default=None,
                      help="The IPv4 group to query.")

    parser.add_option("-S",
                      "--igmp_sources",
                      dest="igmp_sources",
                      default=None,
                      help="Comma-delimited list of IPv4 sources for "
                      "a group-and-source specific query.")

    parser.add_option("-M",
                      "--igmp_maxresp",
                      dest="igmp_maxresp",
                      default=None,
                      help="The maximum time for end-stations to "
                      "respond (in seconds).")

    parser.add_option("-c",
                      "--count",
                      dest="count",
                      default=None,
                      help="Stop after receiving at least count responses.")

    parser.add_option("-2",
                      "--igmp_v2_listen",
                      action="store_true",
                      dest="igmp_v2_listen",
                      help="Listen for responses from IGMPv2 end-stations.")

    parser.add_option("-R",
                      "--igmp_robustness",
                      dest="igmp_robustness",
                      default=None,
                      help="Querier Robustness (default 2)")

    parser.add_option("-Q",
                      "--igmp_qqic",
                      dest="igmp_qqic",
                      default=None,
                      help="Querier's Query Interval (default 10s)")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    #if options.ip_dest is not None and options.ether_dest is None:
    #	print "Non-optional argument missing."
    #	return

    maxresp = 10 * 10
    if options.igmp_maxresp is not None:
        maxresp = int(options.igmp_maxresp) * 10  # in units of deciseconds

    #
    # Parse source list for a GSR query.
    #
    sources = []
    if options.igmp_sources is not None:
        if options.igmp_group is None:
            raise "A group must be specified for a GSR query."
        else:
            for source in options.igmp_sources.split(','):
                sources.append(inet_atol(source))
            if len(sources) == 0:
                raise "Error parsing source list."

    # Set up the vanilla packet

    if options.ether_dest is not None:
        edst = ether_atob(options.ether_dest)
    else:
        edst = ETHER_MAP_IP_MULTICAST(INADDR_ALLHOSTS_GROUP)

    c = ethernet(src=ether_atob(options.ether_source), dst=edst) / \
        ipv4(flags=IP_DF, ttl=1, src=inet_atol(options.ip_source)) / \
        igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \
        igmpv3.query()
    ip = c.packets[1]
    q = c.packets[3]

    # IGMPv3 General Queries are always sent to ALL-SYSTEMS.MCAST.NET.
    # However we allow this to be overidden for protocol testing -- Windows,
    # in particular, doesn't seem to respond.
    #
    # We expect reports on 224.0.0.22.
    # Queries don't contain the Router Alert option as they are
    # destined for end stations, not routers.

    if options.igmp_robustness is not None:
        q.qrv = int(options.igmp_robustness)
    else:
        q.qrv = 2  # SHOULD NOT be 1, MUST NOT be 0

    if options.igmp_qqic is not None:
        q.qqic = int(options.igmp_qqic)
    else:
        q.qqic = 10  # I query every 10 seconds

    if options.igmp_group is None:
        # General query.
        if options.ip_dest is not None:
            ip.dst = inet_atol(options.ip_dest)
        else:
            ip.dst = INADDR_ALLHOSTS_GROUP
        q.group = INADDR_ANY
    else:
        # Group-specific query, possibly with sources.
        if options.ip_dest is not None:
            ip.dst = inet_atol(options.ip_dest)
        else:
            ip.dst = inet_atol(options.igmp_group)
        q.group = ip.dst

    if IN_MULTICAST(ip.dst) is True and \
       options.ether_dest is None:
        c.packets[0].dst = ETHER_MAP_IP_MULTICAST(ip.dst)

    for src in sources:
        q.sources.append(pcs.Field("", 32, default=src))

    c.fixup()

    input = PcapConnector(options.ether_iface)
    input.setfilter("igmp")

    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))

    #
    # Wait for up to 'count' responses to the query to arrive and print them.
    # If options.igmp_v2_listen is True, also count responses from
    # end-stations which respond with IGMPv2.
    #
    # TODO: Pretty-print IGMPv3 reports.
    #
    count = int(options.count)
    while count > 0:
        packet = input.readpkt()
        chain = packet.chain()
        if ((chain.packets[2].type == IGMP_v3_HOST_MEMBERSHIP_REPORT) or
                   ((chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT) and \
                    (options.igmp_v2_listen is True))):
            version = 3
            if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT:
                version = 2

#print chain.packets[2].println()
            print "%s responded to query with IGMPv%d." % \
                ((inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src))),
                        version)
            count -= 1
Ejemplo n.º 16
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I", "--ether_iface",
                      dest="ether_iface", default=None,
                      help="The name of the source interface.")

    parser.add_option("-e", "--ether_source",
                      dest="ether_source", default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-G", "--ether_dest",
                      dest="ether_dest", default=None,
                      help="The gateway Ethernet destination address.")

    parser.add_option("-s", "--ip_source",
                      dest="ip_source", default=None,
                      help="The IP source address.")

    parser.add_option("-d", "--ip_dest",
                      dest="ip_dest", default=None,
                      help="The IP destination address.")

    parser.add_option("-c", "--count",
                      dest="count", default=None,
                      help="Stop after receiving at least count responses.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ether_dest is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    if options.ip_dest is None:
        idst = INADDR_DVMRP_GROUP
    else:
        idst = inet_atol(options.ip_dest)

    c = ethernet(src=ether_atob(options.ether_source), \
                 dst=ether_atob(options.ether_dest)) / \
        ipv4(ttl=1, src=inet_atol(options.ip_source), dst=idst) / \
        igmp(type=IGMP_DVMRP, code=DVMRP_ASK_NEIGHBORS2) / \
        dvmrp(capabilities=DVMRP_CAP_DEFAULT, minor=0xFF, major=3)

    #
    # DVMRP "ask neighbors" does not contain the Router Alert option,
    # because DVMRP traffic is usually tunneled, and we don't need to
    # wake up every router on the path.
    #
    # The Ask_neighbors2 payload is: reserved, caps, minor, major:
    # 0x00, 0E, 0xFF, 0x03 is how mrinfo fills this out (DVMRPv3 compliant).
    #
    # PIM itself knows nothing about these messages, however, a DVMRP router
    # which handles these messages MAY tell you if it's peering with other
    # PIM routers (I believe only Ciscos do this).
    #

    c.calc_lengths()
    c.calc_checksums()
    c.encode()

    input = PcapConnector(options.ether_iface)
    input.setfilter("igmp")

    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))

    #
    # Wait for up to 'count' responses to the query to arrive and print them.
    #
    count = int(options.count)
    while count > 0:
        packet = input.readpkt()
        chain = packet.chain()
	if chain.packets[2].type == IGMP_DVMRP:
	    print chain.packets[2].println()
	    #print "%s is in %s" % \
	    #    (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \
	    #     inet_ntop(AF_INET, struct.pack('!L', chain.packets[2].group)))
	    count -= 1
Ejemplo n.º 17
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I", "--ether_iface",
                      dest="ether_iface", default=None,
                      help="The name of the source interface.")

    parser.add_option("-e", "--ether_source",
                      dest="ether_source", default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s", "--ip_source",
                      dest="ip_source", default=None,
                      help="The IP source address.")

    parser.add_option("-G", "--igmp_group",
                      dest="igmp_group", default=None,
                      help="The IPv4 group for a group-specific query. "
			   "If omitted, send a general query.")

    parser.add_option("-S", "--seconds",
                      dest="seconds", default=1.0,
                      help="Number of seconds between packets.")

    parser.add_option("-c", "--count",
                      dest="count", default=None,
                      help="Stop after sending count packets.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    maxresp = 3 * 10

    if options.igmp_group is None:
	# General query.
    	dst = INADDR_ALLHOSTS_GROUP
        group = INADDR_ANY
    else:
	# Group-specific query.
    	dst = inet_atol(options.igmp_group)
        group = dst

    # Queries don't contain the Router Alert option as they are
    # destined for end stations, not routers.

    c = ethernet(src=ether_atob(options.ether_source),		\
                 dst=ETHER_MAP_IP_MULTICAST(dst)) /		\
        ipv4(flags=IP_DF, ttl=1,				\
             src=inet_atol(options.ip_source),			\
             dst=dst) /						\
        igmp(type=IGMP_v2_HOST_MEMBERSHIP_REPORT, code=maxresp) /	\
        igmpv2(group=group)
    c.fixup()

    output = PcapConnector(options.ether_iface)
    #
    # Send count packets, delayed by seconds
    #
    count = int(options.count)
    if count < 0:
        count = sys.maxint
    while count > 0:
        out = output.write(c.bytes, len(c.bytes))
        count -= 1
        sleep(float(options.seconds))
Ejemplo n.º 18
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I",
                      "--ether_iface",
                      dest="ether_iface",
                      default=None,
                      help="The name of the source interface.")

    parser.add_option("-e",
                      "--ether_source",
                      dest="ether_source",
                      default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-G",
                      "--ether_dest",
                      dest="ether_dest",
                      default=None,
                      help="The gateway Ethernet destination address.")

    parser.add_option("-s",
                      "--ip_source",
                      dest="ip_source",
                      default=None,
                      help="The IP source address.")

    parser.add_option("-d",
                      "--ip_dest",
                      dest="ip_dest",
                      default=None,
                      help="The IP destination address.")

    parser.add_option("-c",
                      "--count",
                      dest="count",
                      default=None,
                      help="Stop after receiving at least count responses.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ether_dest is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    if options.ip_dest is None:
        idst = INADDR_DVMRP_GROUP
    else:
        idst = inet_atol(options.ip_dest)

    c = ethernet(src=ether_atob(options.ether_source), \
                 dst=ether_atob(options.ether_dest)) / \
        ipv4(ttl=1, src=inet_atol(options.ip_source), dst=idst) / \
        igmp(type=IGMP_DVMRP, code=DVMRP_ASK_NEIGHBORS2) / \
        dvmrp(capabilities=DVMRP_CAP_DEFAULT, minor=0xFF, major=3)

    #
    # DVMRP "ask neighbors" does not contain the Router Alert option,
    # because DVMRP traffic is usually tunneled, and we don't need to
    # wake up every router on the path.
    #
    # The Ask_neighbors2 payload is: reserved, caps, minor, major:
    # 0x00, 0E, 0xFF, 0x03 is how mrinfo fills this out (DVMRPv3 compliant).
    #
    # PIM itself knows nothing about these messages, however, a DVMRP router
    # which handles these messages MAY tell you if it's peering with other
    # PIM routers (I believe only Ciscos do this).
    #

    c.calc_lengths()
    c.calc_checksums()
    c.encode()

    input = PcapConnector(options.ether_iface)
    input.setfilter("igmp")

    output = PcapConnector(options.ether_iface)
    out = output.write(c.bytes, len(c.bytes))

    #
    # Wait for up to 'count' responses to the query to arrive and print them.
    #
    count = int(options.count)
    while count > 0:
        packet = input.readpkt()
        chain = packet.chain()
        if chain.packets[2].type == IGMP_DVMRP:
            print chain.packets[2].println()
            #print "%s is in %s" % \
            #    (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \
            #     inet_ntop(AF_INET, struct.pack('!L', chain.packets[2].group)))
            count -= 1
Ejemplo n.º 19
0
def main():

    from optparse import OptionParser

    parser = OptionParser()

    parser.add_option("-I", "--ether_iface",
                      dest="ether_iface", default=None,
                      help="The name of the source interface.")

    parser.add_option("-e", "--ether_source",
                      dest="ether_source", default=None,
                      help="The host Ethernet source address.")

    parser.add_option("-s", "--ip_source",
                      dest="ip_source", default=None,
                      help="The IP source address.")

    parser.add_option("-G", "--igmp_group",
                      dest="igmp_group", default=None,
                      help="The IPv4 group for a group-specific query. "
			   "If omitted, send a general query.")

    parser.add_option("-M", "--maxresp",
                      dest="igmp_maxresp", default=None,
                      help="The maximum time for end-stations to respond "
			   "(in seconds).")

    parser.add_option("-l", "--host_list",
                      dest="hostlist", action="append",
                      help="List of hosts we expect responses from.")

    parser.add_option("-n", "--number",
                      dest="number", default = 1, type=int,
                      help="Query a number of groups starting at "
                      "the one given by -G")

    parser.add_option("-c", "--count",
                      dest="count", default=None,
                      help="Stop after receiving at least count responses.")

    (options, args) = parser.parse_args()

    if options.ether_iface is None or \
       options.ether_source is None or \
       options.ip_source is None or \
       options.count is None:
        print "Non-optional argument missing."
        return

    maxresp = 3 * 10
    if options.igmp_maxresp is not None:
        maxresp = int(options.igmp_maxresp) * 10    # in units of deciseconds

    if options.igmp_group is None:
	# General query.
    	dst = INADDR_ALLHOSTS_GROUP
        group = INADDR_ANY
    else:
	# Group-specific query.
    	dst = inet_atol(options.igmp_group)
        group = dst

    # Set up our match table
    global match
    match = {}
    for host in options.hostlist:
        for addr in range(group, group + options.number):
            match[(inet_atol(host), (addr))] = False

    signal.signal(signal.SIGINFO, results)

    while (options.number >= 0):

        # Queries don't contain the Router Alert option as they are
        # destined for end stations, not routers.

        c = ethernet(src=ether_atob(options.ether_source),		\
                     dst=ETHER_MAP_IP_MULTICAST(dst)) /		\
            ipv4(flags=IP_DF, ttl=1,				\
                 src=inet_atol(options.ip_source),			\
                 dst=dst + options.number) /   \
            igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) /	\
            igmpv2(group=(group + options.number))
        c.fixup()

        input = PcapConnector(options.ether_iface)
        input.setfilter("igmp")

        output = PcapConnector(options.ether_iface)
        out = output.write(c.bytes, len(c.bytes))

        options.number -= 1
        
    #
    # Wait for up to 'count' responses to the query to arrive and print them.
    #
    count = int(options.count)
    while count > 0:
        packet = input.readpkt()
        chain = packet.chain()
	if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT:
	    #print chain.packets[2].println()
	    # print "%s is in %s" % \
	    #     (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \
	    #      inet_ntop(AF_INET, struct.pack('!L', chain.packets[3].group)))
            match[(chain.packets[1].src, chain.packets[3].group)] = True
	    count -= 1

    results(0, 0)