Example #1
0
 def get_rddata(self, l, type, dlen, beg_index):
     if beg_index + dlen > len(l):
         raise Trunc('(dns) truncated rdata')
     # A
     if type == 1:
         if dlen != 4:
             raise Exception('(dns) invalid a data size',system='packet')
         return IPAddr(l[beg_index : beg_index + 4])
     # AAAA
     elif type == 28:
         if dlen != 16:
             raise Exception('(dns) invalid a data size',system='packet')
         return IPAddr6.from_raw(l[beg_index : beg_index + dlen])
     # NS
     elif type == 2:
         return self.read_dns_name_from_index(l, beg_index)[1]
     # PTR
     elif type == 12:
         return  self.read_dns_name_from_index(l, beg_index)[1]
     # CNAME
     elif type == 5:
         return self.read_dns_name_from_index(l, beg_index)[1]
     # MX
     elif type == 15:
         #TODO: Save priority (don't just jump past it)
         return self.read_dns_name_from_index(l, beg_index + 2)[1]
     else:
         return l[beg_index : beg_index + dlen]
Example #2
0
    def _unpack_new(cls, raw, offset, t, length, prev):
        o = cls()
        o.prefix_length,flags,o.valid_lifetime,o.preferred_lifetime = \
            struct.unpack_from('!BBII', raw, offset)
        offset += 1 + 1 + 4 + 4
        offset += 4  # Reserved
        o.prefix = IPAddr6(raw=raw[offset:offset + 16])
        offset += 16
        o.on_link = (flags & cls.ON_LINK_FLAG) != 0
        o.is_autonomous = (flags & cls.AUTONOMOUS_FLAG) != 0
        o.prev = prev

        return offset, o
Example #3
0
    def unpack_new(cls, raw, offset=0, buf_len=None, prev=None):
        o = cls()

        _offset = offset
        if buf_len is None: buf_len = len(raw)

        try:
            offset += 4  # Skip reserved
            o.target = IPAddr6(raw=raw[offset:offset + 16])
            offset += 16
            offset, o.options = _parse_ndp_options(raw, prev, offset, buf_len)

            o.parsed = True
        except TruncatedException:
            pass

        o.raw = raw[_offset:offset]
        o.prev = prev
        return offset, o
Example #4
0
    def unpack_new(cls, raw, offset=0, buf_len=None, prev=None):
        o = cls()

        _offset = offset
        if buf_len is None: buf_len = len(raw)

        try:
            flags = raw[offset]
            o.is_router = (flags & cls.ROUTER_FLAG) != 0
            o.is_solicited = (flags & cls.SOLICITED_FLAG) != 0
            o.is_override = (flags & cls.OVERRIDE_FLAG) != 0

            offset += 4  # Skip reserved
            o.target = IPAddr6(raw=raw[offset:offset + 16])
            offset += 16
            offset, o.options = _parse_ndp_options(raw, prev, offset, buf_len)

            o.parsed = True
        except TruncatedException:
            pass

        o.raw = raw[_offset:offset]
        o.prev = prev
        return offset, o
Example #5
0
File: dns.py Project: mattall/pox
class dns(packet_base):
    "DNS Packet struct"

    MDNS_ADDRESS = IPAddr('224.0.0.251')
    MDNS6_ADDRESS = IPAddr6('ff02::fb')
    MDNS_ETH = EthAddr('01:00:5E:00:00:fb')
    MDNS6_ETH = EthAddr('33:33:00:00:00:fb')

    SERVER_PORT = 53
    MDNS_PORT = 5353
    MIN_LEN = 12

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.questions = []
        self.answers = []
        self.authorities = []
        self.additional = []

        self.id = 0
        self.qr = False  # Is Query
        self.opcode = 0
        self.aa = False  # Authoritative Answer
        self.tc = False  # Truncated
        self.rd = False  # Recursion Desired
        self.ra = False  # Recursion Available
        self.z = False
        self.ad = False
        self.cd = False
        self.rcode = 0
        # TODO: everything else here

        if raw is not None:
            self.parse(raw)

        self._init(kw)

    def _exc(self, e, part=None):
        """
      Turn exception into log message
      """
        msg = "(dns)"
        if part is not None:
            msg += " " + part
        msg += ": "
        msg += str(e)
        if isinstance(e, Trunc):
            self.msg(msg)
        else:
            self.err(msg)

    def hdr(self, payload):
        bits0 = 0
        if self.qr: bits0 |= 0x80
        bits0 |= (self.opcode & 0x7) << 4
        if self.rd: bits0 |= 1
        if self.tc: bits0 |= 2
        if self.aa: bits0 |= 4
        bits1 = 0
        if self.ra: bits1 |= 0x80
        if self.z: bits1 |= 0x40
        if self.ad: bits1 |= 0x20
        if self.cd: bits1 |= 0x10
        bits1 |= (self.rcode & 0xf)

        s = struct.pack("!HBBHHHH", self.id, bits0, bits1, len(self.questions),
                        len(self.answers), len(self.authorities),
                        len(self.additional))

        def makeName(labels, term):
            o = ''  #TODO: unicode
            for l in labels.split('.'):
                o += chr(len(l))
                o += l
            if term: o += '\x00'
            return o

        name_map = {}

        def putName(s, name):
            pre = ''
            post = name
            while True:
                at = s.find(makeName(post, True))
                if at == -1:
                    if post in name_map:
                        at = name_map[post]
                if at == -1:
                    post = post.split('.', 1)
                    if pre: pre += '.'
                    pre += post[0]
                    if len(post) == 1:
                        if len(pre) == 0:
                            s += '\x00'
                        else:
                            name_map[name] = len(s)
                            s += makeName(pre, True)
                        break
                    post = post[1]
                else:
                    if len(pre) > 0:
                        name_map[name] = len(s)
                        s += makeName(pre, False)
                    s += struct.pack("!H", at | 0xc000)
                    break
            return s

        def putData(s, r):
            if r.qtype in (2, 12, 5, 15):  # NS, PTR, CNAME, MX
                return putName(s, r.rddata)
            elif r.qtype == 1:  # A
                assert isinstance(r.rddata, IPAddr)
                return s + r.rddata.raw
            elif r.qtype == 28:  # AAAA
                assert isinstance(r.rddata, IPAddr6)
                return s + r.rddata.raw
            else:
                return s + r.rddata

        for r in self.questions:
            s = putName(s, r.name)
            s += struct.pack("!HH", r.qtype, r.qclass)

        rest = self.answers + self.authorities + self.additional
        for r in rest:
            s = putName(s, r.name)
            s += struct.pack("!HHIH", r.qtype, r.qclass, r.ttl, 0)
            fixup = len(s) - 2
            s = putData(s, r)
            fixlen = len(s) - fixup - 2
            s = s[:fixup] + struct.pack('!H', fixlen) + s[fixup + 2:]

        return s

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < dns.MIN_LEN:
            self.msg('(dns) packet data too short to ' +
                     'parse header: data len %u' % (dlen, ))
            return None

        bits0 = 0
        bits1 = 0
        total_questions = 0
        total_answers = 0
        total_auth_rr = 0
        total_add_rr = 0
        (self.id, bits0,bits1, total_questions, total_answers,
         total_auth_rr, total_add_rr)\
             = struct.unpack('!HBBHHHH', raw[:12])

        self.qr = True if (bits0 & 0x80) else False
        self.opcode = (bits0 >> 4) & (0x07)
        self.aa = True if (bits0 & (0x04)) else False
        self.tc = True if (bits0 & (0x02)) else False
        self.rd = True if (bits0 & (0x01)) else False
        self.ra = True if (bits1 & 0x80) else False
        self.z = True if (bits1 & 0x40) else False
        self.ad = True if (bits1 & 0x20) else False
        self.cd = True if (bits1 & 0x10) else False
        self.rcode = bits1 & 0x0f

        query_head = 12

        # questions
        for i in range(0, total_questions):
            try:
                query_head = self.next_question(raw, query_head)
            except Exception as e:
                self._exc(e, 'parsing questions')
                return None

        # answers
        for i in range(0, total_answers):
            try:
                query_head = self.next_rr(raw, query_head, self.answers)
            except Exception as e:
                self._exc(e, 'parsing answers')
                return None

        # authoritative name servers
        for i in range(0, total_auth_rr):
            try:
                query_head = self.next_rr(raw, query_head, self.authorities)
            except Exception as e:
                self._exc(e, 'parsing authoritative name servers')
                return None

        # additional resource records
        for i in range(0, total_add_rr):
            try:
                query_head = self.next_rr(raw, query_head, self.additional)
            except Exception as e:
                self._exc(e, 'parsing additional resource records')
                return None

        self.parsed = True

    def _to_str(self):
        flags = "|"

        if self.qr != 0:
            flags += "QR "
        if self.tc != 0:
            flags += "TR "
        if self.rd != 0:
            flags += "RD "
        if self.ra != 0:
            flags += "RA "
        if self.z != 0:
            flags += "Z "

        flags += "|"

        s = "(id:%x fl:%s op:%d nq:%d na:%d nath:%d nadd:%d)" % (
            self.id, flags, self.opcode, len(self.questions), len(
                self.answers), len(self.authorities), len(self.additional))

        if len(self.questions) > 0:
            for q in self.questions:
                s += "(q? " + str(q) + ")"

        if len(self.answers) > 0:
            for a in self.answers:
                s += "(answ: " + str(a) + ")"

        if len(self.authorities) > 0:
            for a in self.authorities:
                s += "(auth: " + str(a) + ")"

        if len(self.additional) > 0:
            for a in self.additional:
                s += "(add: " + str(a) + ")"

        return s

    # Utility methods for parsing.  Generally these would be pulled out
    # into a separate class. However, because the lengths are not known
    # until the fields have been parsed, it is more convenient to keep
    # them in the DNS class

    @classmethod
    def _read_dns_name_from_index(cls, l, index, retlist):
        try:
            while True:
                chunk_size = ord(l[index])

                # check whether we have an internal pointer
                if (chunk_size & 0xc0) == 0xc0:
                    # pull out offset from last 14 bits
                    offset = ((ord(l[index]) & 0x3) << 8) | ord(l[index + 1])
                    cls._read_dns_name_from_index(l, offset, retlist)
                    index += 1
                    break
                if chunk_size == 0:
                    break
                index += 1
                retlist.append(l[index:index + chunk_size])
                index += chunk_size
            return index
        except IndexError:
            raise Trunc("incomplete name")

    @classmethod
    def read_dns_name_from_index(cls, l, index):
        retlist = []
        next = cls._read_dns_name_from_index(l, index, retlist)
        return (next + 1, b".".join(retlist))

    def next_rr(self, l, index, rr_list):
        array_len = len(l)

        # verify whether name is offset within packet
        if index > array_len:
            raise Trunc("next_rr: name truncated")

        index, name = self.read_dns_name_from_index(l, index)

        if index + 10 > array_len:
            raise Trunc("next_rr: truncated")

        (qtype, qclass, ttl, rdlen) = struct.unpack('!HHIH',
                                                    l[index:index + 10])
        if index + 10 + rdlen > array_len:
            raise Trunc("next_rr: data truncated")

        rddata = self.get_rddata(l, qtype, rdlen, index + 10)
        rr_list.append(dns.rr(name, qtype, qclass, ttl, rdlen, rddata))

        return index + 10 + rdlen

    def get_rddata(self, l, type, dlen, beg_index):
        if beg_index + dlen > len(l):
            raise Trunc('(dns) truncated rdata')
        # A
        if type == 1:
            if dlen != 4:
                raise Exception('(dns) invalid a data size', system='packet')
            return IPAddr(l[beg_index:beg_index + 4])
        # AAAA
        elif type == 28:
            if dlen != 16:
                raise Exception('(dns) invalid a data size', system='packet')
            return IPAddr6.from_raw(l[beg_index:beg_index + dlen])
        # NS
        elif type == 2:
            return self.read_dns_name_from_index(l, beg_index)[1]
        # PTR
        elif type == 12:
            return self.read_dns_name_from_index(l, beg_index)[1]
        # CNAME
        elif type == 5:
            return self.read_dns_name_from_index(l, beg_index)[1]
        # MX
        elif type == 15:
            #TODO: Save priority (don't just jump past it)
            return self.read_dns_name_from_index(l, beg_index + 2)[1]
        else:
            return l[beg_index:beg_index + dlen]

    def next_question(self, l, index):
        array_len = len(l)

        index, name = self.read_dns_name_from_index(l, index)

        if index + 4 > array_len:
            raise Trunc("next_question: truncated")

        (qtype, qclass) = struct.unpack('!HH', l[index:index + 4])
        self.questions.append(dns.question(name, qtype, qclass))
        return index + 4

    # Utility classes for questions and RRs

    class question(object):
        def __init__(self, name, qtype, qclass):
            self.name = name
            self.qtype = qtype
            self.qclass = qclass

        def __str__(self):
            s = self.name
            if self.qtype in rrtype_to_str:
                s += " " + rrtype_to_str[self.qtype]
            else:
                s += " #" + str(self.qtype)
            if self.qclass in rrclass_to_str:
                s += " " + rrclass_to_str[self.qclass]
            else:
                s += " #" + str(self.qclass)

            return s

    class rr(object):
        A_TYPE = 1
        NS_TYPE = 2
        MD_TYPE = 3
        MF_TYPE = 4
        CNAME_TYPE = 5
        SOA_TYPE = 6
        MB_TYPE = 7
        MG_TYPE = 8
        MR_TYPE = 9
        NULL_TYPE = 10
        WKS_TYPE = 11
        PTR_TYPE = 12
        HINFO_TYPE = 13
        MINFO_TYPE = 14
        MX_TYPE = 15
        TXT_TYPE = 16
        AAAA_TYPE = 28

        def __init__(self, _name, _qtype, _qclass, _ttl, _rdlen, _rddata):
            self.name = _name
            self.qtype = _qtype
            self.qclass = _qclass
            self.ttl = _ttl
            self.rdlen = _rdlen
            self.rddata = _rddata

        def __str__(self):
            s = self.name
            if self.qtype in rrtype_to_str:
                s += " " + rrtype_to_str[self.qtype]
            else:
                s += " #" + str(self.qtype)
            if self.qclass in rrclass_to_str:
                s += " " + rrclass_to_str[self.qclass]
            else:
                s += " #" + str(self.qclass)
            s += " ttl:" + str(self.ttl)
            s += " rdlen:" + str(self.rdlen)
            s += " datalen:" + str(len(self.rddata))
            if len(self.rddata) == 4:
                #FIXME: can be smarter about whether this is an IP
                s += " data:" + str(IPAddr(self.rddata))

            return s
Example #6
0
class dns(packet_base):
    "DNS Packet struct"

    MDNS_ADDRESS = IPAddr('224.0.0.251')
    MDNS6_ADDRESS = IPAddr6('ff02::fb')
    MDNS_ETH = EthAddr('01:00:5E:00:00:fb')
    MDNS6_ETH = EthAddr('33:33:00:00:00:fb')

    SERVER_PORT = 53
    MDNS_PORT = 5353
    MIN_LEN = 12

    def __init__(self, raw=None, prev=None, **kw):
        packet_base.__init__(self)

        self.prev = prev

        self.questions = []
        self.answers = []
        self.authorities = []
        self.additional = []

        self.id = 0
        self.qr = False  # Is Query
        self.opcode = 0
        self.aa = False  # Authoritative Answer
        self.tc = False  # Truncated
        self.rd = False  # Recursion Desired
        self.ra = False  # Recursion Available
        self.z = False
        self.ad = False
        self.cd = False
        self.rcode = 0
        # TODO: everything else here

        if raw is not None:
            self.parse(raw)

        self._init(kw)

    def _exc(self, e, part=None):
        """
      Turn exception into log message
      """
        msg = "(dns)"
        if part is not None:
            msg += " " + part
        msg += ": "
        msg += str(e)
        if isinstance(e, Trunc):
            self.msg(msg)
        else:
            self.err(msg)

    def hdr(self, payload):
        bits0 = 0
        if self.qr: bits0 |= 0x80
        bits0 |= (self.opcode & 0x7) << 4
        if self.rd: bits0 |= 1
        if self.tc: bits0 |= 2
        if self.aa: bits0 |= 4
        bits1 = 0
        if self.ra: bits1 |= 0x80
        if self.z: bits1 |= 0x40
        if self.ad: bits1 |= 0x20
        if self.cd: bits1 |= 0x10
        bits1 |= (self.rcode & 0xf)

        s = struct.pack("!HBBHHHH", self.id, bits0, bits1, len(self.questions),
                        len(self.answers), len(self.authorities),
                        len(self.additional))

        def makeName(labels, term):
            o = ''  #TODO: unicode
            for l in labels.split('.'):
                o += chr(len(l))
                o += l
            if term: o += '\x00'
            return o

        name_map = {}

        def putName(s, name):
            pre = ''
            post = name
            while True:
                at = s.find(makeName(post, True))
                if at == -1:
                    if post in name_map:
                        at = name_map[post]
                if at == -1:
                    post = post.split('.', 1)
                    if pre: pre += '.'
                    pre += post[0]
                    if len(post) == 1:
                        if len(pre) == 0:
                            s += '\x00'
                        else:
                            name_map[name] = len(s)
                            s += makeName(pre, True)
                        break
                    post = post[1]
                else:
                    if len(pre) > 0:
                        name_map[name] = len(s)
                        s += makeName(pre, False)
                    s += struct.pack("!H", at | 0xc000)
                    break
            return s

        def putData(s, r):
            if r.qtype in (2, 12, 5, 15):
                return putName(s, r.rddata)
            elif r.qtype == 1:
                assert isinstance(r.rddata, IPAddr)
                return s + r.rddata.toRaw()
            else:
                return s + r.rddata

        for r in self.questions:
            s = putName(s, r.name)
            s += struct.pack("!HH", r.qtype, r.qclass)

        rest = self.answers + self.authorities + self.additional
        for r in rest:
            s = putName(s, r.name)
            s += struct.pack("!HHIH", r.qtype, r.qclass, r.ttl, 0)
            fixup = len(s) - 2
            s = putData(s, r)
            fixlen = len(s) - fixup - 2
            s = s[:fixup] + struct.pack('!H', fixlen) + s[fixup + 2:]

        return s

    def parse(self, raw):
        assert isinstance(raw, bytes)
        self.raw = raw
        dlen = len(raw)
        if dlen < dns.MIN_LEN:
            self.msg('(dns) packet data too short to ' +
                     'parse header: data len %u' % (dlen, ))
            return None

        bits0 = 0
        bits1 = 0
        total_questions = 0
        total_answers = 0
        total_auth_rr = 0
        total_add_rr = 0
        (self.id, bits0,bits1, total_questions, total_answers,
         total_auth_rr, total_add_rr)\
             = struct.unpack('!HBBHHHH', raw[:12])

        self.qr = True if (bits0 & 0x80) else False
        self.opcode = (bits0 >> 4) & (0x07)
        self.aa = True if (bits0 & (0x04)) else False
        self.tc = True if (bits0 & (0x02)) else False
        self.rd = True if (bits0 & (0x01)) else False
        self.ra = True if (bits1 & 0x80) else False
        self.z = True if (bits1 & 0x40) else False
        self.ad = True if (bits1 & 0x20) else False
        self.cd = True if (bits1 & 0x10) else False
        self.rcode = bits1 & 0x0f

        query_head = 12

        # questions
        for i in range(0, total_questions):
            try:
                query_head = self.next_question(raw, query_head)
            except Exception, e:
                self._exc(e, 'parsing questions')
                return None

        # answers
        for i in range(0, total_answers):
            try:
                query_head = self.next_rr(raw, query_head, self.answers)
            except Exception, e:
                self._exc(e, 'parsing answers')
                return None
Example #7
0
    def parse(self, raw, offset=0):
        assert isinstance(raw, bytes)
        self.next = None  # In case of unfinished parsing
        self.raw = raw
        if len(raw) < self.MIN_LEN:
            self.msg('warning IP packet data too short to parse header:'
                     ' data len %u' % (len(raw), ))
            return

        (vtcfl, self.payload_length, nht, self.hop_limit) \
            = struct.unpack('!IHBB', raw[offset:offset+8])
        self.srcip = IPAddr6(raw[offset + 8:offset + 24], raw=True)
        self.dstip = IPAddr6(raw[offset + 24:offset + 40], raw=True)
        self.next_header_type = nht
        offset += 40

        self.v = vtcfl >> 28
        self.tc = (vtcfl >> 20) & 0xff
        self.flow = vtcfl & 0xfffff

        if self.v != 6:
            self.msg('ip parse) warning IP version %u not IPv6' % self.v)
            return

        length = self.payload_length
        if length > len(raw):
            length = len(raw)  # Clamp to what we've got
            self.msg('(ipv6) warning IP packet data incomplete (%s of %s)' %
                     (len(raw), self.payload_length))

        while nht != ipv6.NO_NEXT_HEADER:
            c = _extension_headers.get(nht)
            if c:
                if length < 8:
                    self.msg('(ipv6) warning, packet data incomplete')
                    return
                try:
                    offset, o = c.unpack_new(raw, offset, max_length=length)
                    length -= len(o)
                except TruncatedException:
                    self.msg('(ipv6) warning, packet data truncated')
                    return
                self.extension_headers.append(o)
                nht = o.next_header_type
            else:
                break

        self.parsed = True

        #TODO: This should be done a better way (and shared with IPv4?).
        if nht == self.UDP_PROTOCOL:
            self.next = udp(raw=raw[offset:offset + length], prev=self)
        elif nht == self.TCP_PROTOCOL:
            self.next = tcp(raw=raw[offset:offset + length], prev=self)
        elif nht == self.ICMP6_PROTOCOL:
            self.next = icmpv6(raw=raw[offset:offset + length], prev=self)


#    elif nht == self.IGMP_PROTOCOL:
#      self.next = igmp(raw=raw[offset:offset+length], prev=self)
        elif nht == self.NO_NEXT_HEADER:
            self.next = None
        else:
            self.next = raw[offset:offset + length]

        if isinstance(self.next, packet_base) and not self.next.parsed:
            self.next = raw[offset:offset + length]
 def ip6(addr):
     if addr is None:
         return None
     return IPAddr6.from_raw(addr)
             0x2f, 0x93, 0x0a, 0x00, 0x02, 0x0f, 0xc3, 0x58, 0x36, 0x10]
             

payload_packet = b"".join(map(chr, ipv4_header))
ethernet_packet_b = b"".join(map(chr, ethernet_packet))
'''
'''
This is a Client. Can be an IoT Device and use CoAP communication. 
We just send an IP packet without actually knowing IPv6 with 
just a tag in the IP packet payload.

'''

#Create an IP packet
ipv6_packet = ipv6()
ipv6_packet.srcip = IPAddr6("::0")

#Random IP destination address
ipv6_packet.dstip = IPAddr6("::7")
ipv6_packet.next_header_type = 0xFD

# Set a tag in IP payload. e.g color = red. Tag-Based Forwarding
ipv6_packet.payload = "[color='red']"
ether = ethernet()
ether.type = 0x86DD

# Because we don't know the destination mac address we set :00 as mac
ether.dst = EthAddr(b"\x00\x00\x00\x00\x00\x00")
ether.src = EthAddr(b"\x08\x00\x27\xc8\x18\xa5")
ether.payload = ipv6_packet
    def __init__(self, connection):
        self.connection = connection
        connection.addListeners(self)
        if (connection.eth_addr.toStr() == "00:00:00:00:00:01"):
            print "Preparing of rules"
            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0
            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::1"), IPAddr6("::1"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            #table 1
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)

        if (connection.eth_addr.toStr() == "00:00:00:00:00:02"):
            print "Preparing of rules"
            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0
            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            #table 1
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::4"), IPAddr6("::4"))
            msg.actions.append(of.ofp_action_output(port=2))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)
Example #11
0
 def ip6(addr):
     if addr is None: return None
     return IPAddr6.from_raw(addr)
    def __init__(self, connection):
        self.connection = connection
        connection.addListeners(self)
        if (connection.eth_addr.toStr() == "00:00:00:00:00:01"):
            # Rules for switch s1 !
            '''
        Table id is a number for the the table of rules for each switch.
        Priority is for overlapping matches. Higher values are higher priority.
        in_port - If using a buffer_id, this is the associated input port.
        match - An ofp_match object. By default, this matches everything,
        so you should probably set some of its fields!
        
        '''

            print "Preparing of rules"

            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0 - Rules for IP :01
            '''
        
        Forward a packet to source if the port that is coming is the same as the input
        
        '''

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            '''
             When a message comes to the Switch if has a rule for this IPv6 
             forward it to next port 
        '''

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::1"), IPAddr6("::1"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            '''
        
        If you have no rule for this IP check 
        table 1 for IP :02
        
        '''

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            #table 1 - Rules for IP :02
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)

        if (connection.eth_addr.toStr() == "00:00:00:00:00:02"):
            # Rules for switch s2  !
            print "Preparing of rules"
            '''
        
        The same Rules also for Switch 2 check the above comments..
        
        '''

            msg = nx.nx_flow_mod_table_id()
            connection.send(msg)
            #table 0
            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 1
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::2"), IPAddr6("::2"))
            msg.actions.append(of.ofp_action_output(port=1))
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 0
            msg.priority = 500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.actions.append(nx.nx_action_resubmit.resubmit_table(table=1))
            self.connection.send(msg)
            #table 1
            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1000
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.nx_ipv6_dst = (IPAddr6("::4"), IPAddr6("::4"))
            msg.actions.append(of.ofp_action_output(port=2))
            self.connection.send(msg)

            msg = nx.nx_flow_mod()
            msg.table_id = 1
            msg.priority = 1500
            msg.match.of_eth_dst = "00:00:00:00:00:00"
            msg.match.of_eth_type = 0x86dd
            msg.match.of_in_port = 2
            self.connection.send(msg)