예제 #1
0
파일: hello.py 프로젝트: changhe188/pyospf
    def check_active_router(self, pkt):
        active_nrid = pkt['V']['V']['NBORS']
        nrid = pkt['V']['RID']

        if self.rid in active_nrid:
            LOG.debug('[NSM] %s Event: NSM_TwoWayReceived.' % util.int2ip(nrid))
            self.nsm_list[nrid].fire('NSM_TwoWayReceived')
            return True
        else:
            LOG.debug('[NSM] %s Event: NSM_OneWayReceived' % util.int2ip(nrid))
            LOG.debug('[NSM] %s state is %s.' % (util.int2ip(nrid), self.nsm_list[nrid].state))
            if self.nsm_list[nrid].state >= NSM_STATE['NSM_TwoWay']:
                #This is not in RFC. When probe received hello without itself, make adj down.
                LOG.info('[NSM] One way state. Reset adjacency with router %s.' % util.int2ip(nrid))
                self.nsm_list[nrid].reset()
            self.nsm_list[nrid].fire('NSM_OneWayReceived')
            return False
예제 #2
0
파일: hello.py 프로젝트: changhe188/pyospf
    def get_dr_bdr(self, pkt):
        nrid = pkt['V']['RID']
        LOG.debug('[NSM] %s state is %s.' % (util.int2ip(nrid), self.nsm_list[nrid].state))
        if self.nsm_list[nrid].state < NSM_STATE['NSM_TwoWay']:
            return
        else:
            srcip = pkt['H']['SRC']
            dr = pkt['V']['V']['DESIG']
            bdr = pkt['V']['V']['BDESIG']
            prio = pkt['V']['V']['PRIO']

            if self.drip != dr:
                if dr == srcip or bdr == srcip:
                    self.drip, self.bdrip = dr, bdr
                    self.ism.drip, self.ism.bdrip = dr, bdr
                    LOG.debug('[ISM] DR/BDR found: %s, %s.'
                                   % (util.int2ip(self.ism.drip), util.int2ip(self.ism.bdrip)))

                    LOG.info('[ISM] Event: ISM_BackupSeen.')
                    self.ism.fire('ISM_BackupSeen')
예제 #3
0
 def _hello_received(self):
     if self.state == NSM_STATE["NSM_Down"]:
         self.change_nsm_state("NSM_Init")
         # start inactive timer
         if self._inactive_timer is None or self._inactive_timer.is_stop():
             self._inactive_timer = Timer(self.inactive_timer_interval, self.dead)
             self._inactive_timer.start()
             LOG.debug("[NSM] %s starts inactive timer." % util.int2ip(self.rtid))
         else:
             self._inactive_timer.reset()
     else:
         self._inactive_timer.reset()
예제 #4
0
    def get_dr_bdr(self, pkt):
        nrid = pkt['V']['RID']
        LOG.debug('[NSM] %s state is %s.' %
                  (util.int2ip(nrid), self.nsm_list[nrid].state))
        if self.nsm_list[nrid].state < NSM_STATE['NSM_TwoWay']:
            return
        else:
            srcip = pkt['H']['SRC']
            dr = pkt['V']['V']['DESIG']
            bdr = pkt['V']['V']['BDESIG']
            prio = pkt['V']['V']['PRIO']

            if self.drip != dr:
                if dr == srcip or bdr == srcip:
                    self.drip, self.bdrip = dr, bdr
                    self.ism.drip, self.ism.bdrip = dr, bdr
                    LOG.debug('[ISM] DR/BDR found: %s, %s.' % (util.int2ip(
                        self.ism.drip), util.int2ip(self.ism.bdrip)))

                    LOG.info('[ISM] Event: ISM_BackupSeen.')
                    self.ism.fire('ISM_BackupSeen')
예제 #5
0
    def check_active_router(self, pkt):
        active_nrid = pkt['V']['V']['NBORS']
        nrid = pkt['V']['RID']

        if self.rid in active_nrid:
            LOG.debug('[NSM] %s Event: NSM_TwoWayReceived.' %
                      util.int2ip(nrid))
            self.nsm_list[nrid].fire('NSM_TwoWayReceived')
            return True
        else:
            LOG.debug('[NSM] %s Event: NSM_OneWayReceived' % util.int2ip(nrid))
            LOG.debug('[NSM] %s state is %s.' %
                      (util.int2ip(nrid), self.nsm_list[nrid].state))
            if self.nsm_list[nrid].state >= NSM_STATE['NSM_TwoWay']:
                #This is not in RFC. When probe received hello without itself, make adj down.
                LOG.info(
                    '[NSM] One way state. Reset adjacency with router %s.' %
                    util.int2ip(nrid))
                self.nsm_list[nrid].reset()
            self.nsm_list[nrid].fire('NSM_OneWayReceived')
            return False
 def _hello_received(self):
     if self.state == NSM_STATE['NSM_Down']:
         self.change_nsm_state('NSM_Init')
         #start inactive timer
         if self._inactive_timer is None or self._inactive_timer.is_stop():
             self._inactive_timer = Timer(self.inactive_timer_interval, self.dead)
             self._inactive_timer.start()
             LOG.debug('[NSM] %s starts inactive timer.' % util.int2ip(self.rtid))
         else:
             self._inactive_timer.reset()
     else:
         self._inactive_timer.reset()
예제 #7
0
    def _seq_mismatch_or_bad_lsr(self):
        LOG.warn("[NSM] %s sequence mismatch or bad LSR." % util.int2ip(self.rtid))
        # make sure that all these are clear
        self.ls_req = list()
        self.ls_rxmt = list()
        self.db_sum = list()
        self.last_recv = tuple()
        self.last_send = None
        self.last_send_ts = 0

        self.change_nsm_state("NSM_ExStart")
        self.dd_flags = 7  # set init bit, more bit, master bit
        self.dd_seqnum = int(time.time())
        self._send_dd()
        if self._dd_exstart_timer is None:
            self._dd_exstart_timer = Timer(self.ism.rxmt_interval, self._send_dd)
            self._dd_exstart_timer.start()
        elif self._dd_exstart_timer.is_stop():
            del self._dd_exstart_timer
            self._dd_exstart_timer = Timer(self.ism.rxmt_interval, self._send_dd)
            self._dd_exstart_timer.start()
        else:
            self._dd_exstart_timer.reset()
    def _seq_mismatch_or_bad_lsr(self):
        LOG.warn('[NSM] %s sequence mismatch or bad LSR.' % util.int2ip(self.rtid))
        #make sure that all these are clear
        self.ls_req = list()
        self.ls_rxmt = list()
        self.db_sum = list()
        self.last_recv = tuple()
        self.last_send = None
        self.last_send_ts = 0

        self.change_nsm_state('NSM_ExStart')
        self.dd_flags = 7    # set init bit, more bit, master bit
        self.dd_seqnum = int(time.time())
        self._send_dd()
        if self._dd_exstart_timer is None:
            self._dd_exstart_timer = Timer(self.ism.rxmt_interval, self._send_dd)
            self._dd_exstart_timer.start()
        elif self._dd_exstart_timer.is_stop():
            del self._dd_exstart_timer
            self._dd_exstart_timer = Timer(self.ism.rxmt_interval, self._send_dd)
            self._dd_exstart_timer.start()
        else:
            self._dd_exstart_timer.reset()
예제 #9
0
 def change_nsm_state(self, newstate):
     LOG.info("[NSM] %s change state to %s." % (util.int2ip(self.rtid), newstate))
     self.state = NSM_STATE[newstate]
예제 #10
0
    def ospf_handler(self, data, timestamp):
        """
        Distinguish different kind OSPF packet, and call according functions
        """
        if not data:
            return
        LOG.debug('[Receiver] Received packet: %s:%f' % (time.strftime(
            '%H:%M', time.localtime(timestamp)), timestamp % 60))

        pkt = OspfParser.parse(data, verbose=self.pkt_dis)
        if pkt is None:
            LOG.error('[Receiver] Wrong Packet.')
            return False

        self.ism.ai.oi.stat.total_received_packet_count += 1

        hdr = pkt['V']

        ospf_type = hdr['TYPE']
        dst = pkt['H']['DST']
        nrid = hdr['RID']
        aid = hdr['AID']

        LOG.debug('[Receiver] Type: %s, Dst: %s, NRID: %s, Area: %s' %
                  (ospf_type, int2ip(dst), int2ip(nrid), int2ip(aid)))

        if ospf_type == 1:
            LOG.debug('[Receiver] Received a Hello.')
            self.ism.ai.oi.stat.recv_hello_count += 1
            neighborLock.acquire()
            if self.ism.hp.check_hello(pkt):
                self.ism.ai.oi.stat.total_handled_packet_count += 1
                if self.ism.hp.check_active_router(pkt):
                    if self.ism.link_type != 'Point-to-Point':
                        self.ism.hp.get_dr_bdr(pkt)
            neighborLock.release()

        elif ospf_type == 2:
            self.ism.ai.oi.stat.recv_dd_count += 1
            LOG.debug(
                '[Receiver] Received a Database Description from %s to %s.' %
                (util.int2ip(nrid), util.int2ip(dst)))
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.nsm_list[nrid].ep.check_dd(pkt)
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.debug('[Receiver] DD from %s not handled.' %
                              util.int2ip(nrid))

        elif ospf_type == 3:
            LOG.debug('[Receiver] Received a LSR from %s to %s.' %
                      (util.int2ip(nrid), util.int2ip(dst)))
            self.ism.ai.oi.stat.recv_lsr_count += 1
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.nsm_list[nrid].ep.check_lsr(pkt)
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.debug('[Receiver] LSR from %s not handled.' %
                              util.int2ip(nrid))

        elif ospf_type == 4:
            LOG.debug('[Receiver] Received a LSU from %s to %s.' %
                      (util.int2ip(nrid), util.int2ip(dst)))
            self.ism.ai.oi.stat.recv_lsu_count += 1
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.lsu_handler.addTask(self._handle_lsu, (nrid, pkt))
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.warn('[Receiver] LSU from %s not handled.' %
                             util.int2ip(nrid))

        elif ospf_type == 5:
            LOG.debug('[Receiver] Received a LSAck from %s.' %
                      util.int2ip(nrid))
            self.ism.ai.oi.stat.recv_lsack_count += 1
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.nsm_list[nrid].fp.check_lsack(pkt)
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.warn('[Receiver] LSAck from %s not handled.' %
                             util.int2ip(nrid))

        else:
            LOG.error('[Error] Wrong OSPF packet type.')
            pass
예제 #11
0
파일: hello.py 프로젝트: changhe188/pyospf
    def check_hello(self, pkt):
        """
        check neighbor hello contents match or not
        """
        ver = pkt['V']['VER']
        nrid = pkt['V']['RID']
        aid = pkt['V']['AID']
        net = pkt['V']['V']['NETMASK']
        hi = pkt['V']['V']['HELLO']
        di = pkt['V']['V']['DEAD']
        opt = pkt['V']['V']['OPTS']

        if ver != self.version:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'VERSION_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.version, ver]
            # ))
            LOG.warn('[Hello] Router %s version %d mismatch.' % (util.int2ip(nrid), ver))
            return False

        #area check has be handled in ospf receiver
        # if aid != self.area:
        #     self.ism.ai.oi.msgHandler.record_event(Event.str_event(
        #         'AREA_MISMATCH',
        #         self.ism.ai.oi.processId,
        #         [util.int2ip(nrid), util.int2ip(self.area), util.int2ip(aid)]
        #     ))
        #     LOG.warn('[Hello] Router %s area ID %s mismatch.' % (util.int2ip(nrid), util.int2ip(aid)))
        #     return False

        if hi != self.hello_interval:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'HELLO_TIMER_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.helloInterval, hi]
            # ))
            LOG.warn('[Hello] Router %s hello interval %d mismatch.' % (util.int2ip(nrid), hi))
            return False
        if di != self.dead_interval:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'DEAD_TIMER_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.deadInterval, di]
            # ))
            LOG.warn('[Hello] Router %s dead interval %d mismatch.' % (util.int2ip(nrid), di))
            return False
        if self.link_type != 'Point-to-Point' and self.link_type != 'Virtual':
        #If linkType is p2p or virtual link, ignore this check
            if net != self.netmask:
                # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
                #     'NETMASK_MISMATCH',
                #     self.ism.ai.oi.processId,
                #     [util.int2ip(nrid), util.int2ip(self.netmask), util.int2ip(net)]
                # ))
                LOG.warn('[Hello] Router %s netmask %s mismatch.' % (util.int2ip(nrid), util.int2ip(net)))
                return False

        if self.options >> 1 & 0x1 != opt['E']:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'OPT_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.options, opt]
            # ))
            LOG.warn('[Hello] Router %s E-bit option %s mismatch.' % (util.int2ip(nrid), opt['E']))
            return False
        if self.options >> 3 & 0x1 != opt['NP']:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'OPT_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.options, opt]
            # ))
            LOG.warn('[Hello] Router %s NP-bit option %s mismatch.' % (util.int2ip(nrid), opt['NP']))
            return False
        #TODO: check other options

        #Pass check, add to active neighbor
        if not nrid in self.ism.neighbor:
            LOG.info('[Hello] Add new active neighbor %s.' % util.int2ip(nrid))
            self.ism.neighbor.append(nrid)

            #Meanwhile, create an NSM for this router.
            if not nrid in self.nsm_list:
                self.nsm_list[nrid] = NSM(self.ism, nrid, pkt)

        LOG.debug('[NSM] %s Event: NSM_PacketReceived.' % util.int2ip(nrid))
        self.nsm_list[nrid].fire('NSM_PacketReceived')
        return True
예제 #12
0
    def check_hello(self, pkt):
        """
        check neighbor hello contents match or not
        """
        ver = pkt['V']['VER']
        nrid = pkt['V']['RID']
        aid = pkt['V']['AID']
        net = pkt['V']['V']['NETMASK']
        hi = pkt['V']['V']['HELLO']
        di = pkt['V']['V']['DEAD']
        opt = pkt['V']['V']['OPTS']

        if ver != self.version:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'VERSION_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.version, ver]
            # ))
            LOG.warn('[Hello] Router %s version %d mismatch.' %
                     (util.int2ip(nrid), ver))
            return False

        #area check has be handled in ospf receiver
        # if aid != self.area:
        #     self.ism.ai.oi.msgHandler.record_event(Event.str_event(
        #         'AREA_MISMATCH',
        #         self.ism.ai.oi.processId,
        #         [util.int2ip(nrid), util.int2ip(self.area), util.int2ip(aid)]
        #     ))
        #     LOG.warn('[Hello] Router %s area ID %s mismatch.' % (util.int2ip(nrid), util.int2ip(aid)))
        #     return False

        if hi != self.hello_interval:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'HELLO_TIMER_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.helloInterval, hi]
            # ))
            LOG.warn('[Hello] Router %s hello interval %d mismatch.' %
                     (util.int2ip(nrid), hi))
            return False
        if di != self.dead_interval:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'DEAD_TIMER_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.deadInterval, di]
            # ))
            LOG.warn('[Hello] Router %s dead interval %d mismatch.' %
                     (util.int2ip(nrid), di))
            return False
        if self.link_type != 'Point-to-Point' and self.link_type != 'Virtual':
            #If linkType is p2p or virtual link, ignore this check
            if net != self.netmask:
                # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
                #     'NETMASK_MISMATCH',
                #     self.ism.ai.oi.processId,
                #     [util.int2ip(nrid), util.int2ip(self.netmask), util.int2ip(net)]
                # ))
                LOG.warn('[Hello] Router %s netmask %s mismatch.' %
                         (util.int2ip(nrid), util.int2ip(net)))
                return False

        if self.options >> 1 & 0x1 != opt['E']:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'OPT_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.options, opt]
            # ))
            LOG.warn('[Hello] Router %s E-bit option %s mismatch.' %
                     (util.int2ip(nrid), opt['E']))
            return False
        if self.options >> 3 & 0x1 != opt['NP']:
            # self.ism.ai.oi.msgHandler.record_event(Event.str_event(
            #     'OPT_MISMATCH',
            #     self.ism.ai.oi.processId,
            #     [util.int2ip(nrid), self.options, opt]
            # ))
            LOG.warn('[Hello] Router %s NP-bit option %s mismatch.' %
                     (util.int2ip(nrid), opt['NP']))
            return False
        #TODO: check other options

        #Pass check, add to active neighbor
        if not nrid in self.ism.neighbor:
            LOG.info('[Hello] Add new active neighbor %s.' % util.int2ip(nrid))
            self.ism.neighbor.append(nrid)

            #Meanwhile, create an NSM for this router.
            if not nrid in self.nsm_list:
                self.nsm_list[nrid] = NSM(self.ism, nrid, pkt)

        LOG.debug('[NSM] %s Event: NSM_PacketReceived.' % util.int2ip(nrid))
        self.nsm_list[nrid].fire('NSM_PacketReceived')
        return True
예제 #13
0
 def change_nsm_state(self, newstate):
     LOG.info('[NSM] %s change state to %s.' % (util.int2ip(self.rtid), newstate))
     self.state = NSM_STATE[newstate]
예제 #14
0
    def ospf_handler(self, data, timestamp):
        """
        Distinguish different kind OSPF packet, and call according functions
        """
        if not data:
            return
        LOG.debug('[Receiver] Received packet: %s:%f'
                  % (time.strftime('%H:%M', time.localtime(timestamp)), timestamp % 60))

        pkt = OspfParser.parse(data, verbose=self.pkt_dis)
        if pkt is None:
            LOG.error('[Receiver] Wrong Packet.')
            return False

        self.ism.ai.oi.stat.total_received_packet_count += 1

        hdr = pkt['V']

        ospf_type = hdr['TYPE']
        dst = pkt['H']['DST']
        nrid = hdr['RID']
        aid = hdr['AID']

        LOG.debug('[Receiver] Type: %s, Dst: %s, NRID: %s, Area: %s' %
                  (ospf_type, int2ip(dst), int2ip(nrid), int2ip(aid)))

        if ospf_type == 1:
            LOG.debug('[Receiver] Received a Hello.')
            self.ism.ai.oi.stat.recv_hello_count += 1
            neighborLock.acquire()
            if self.ism.hp.check_hello(pkt):
                self.ism.ai.oi.stat.total_handled_packet_count += 1
                if self.ism.hp.check_active_router(pkt):
                    if self.ism.link_type != 'Point-to-Point':
                        self.ism.hp.get_dr_bdr(pkt)
            neighborLock.release()

        elif ospf_type == 2:
            self.ism.ai.oi.stat.recv_dd_count += 1
            LOG.debug('[Receiver] Received a Database Description from %s to %s.'
                           % (util.int2ip(nrid), util.int2ip(dst)))
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.nsm_list[nrid].ep.check_dd(pkt)
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.debug('[Receiver] DD from %s not handled.' % util.int2ip(nrid))

        elif ospf_type == 3:
            LOG.debug('[Receiver] Received a LSR from %s to %s.' % (util.int2ip(nrid), util.int2ip(dst)))
            self.ism.ai.oi.stat.recv_lsr_count += 1
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.nsm_list[nrid].ep.check_lsr(pkt)
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.debug('[Receiver] LSR from %s not handled.' % util.int2ip(nrid))

        elif ospf_type == 4:
            LOG.debug('[Receiver] Received a LSU from %s to %s.' % (util.int2ip(nrid), util.int2ip(dst)))
            self.ism.ai.oi.stat.recv_lsu_count += 1
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.lsu_handler.addTask(self._handle_lsu, (nrid, pkt))
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.warn('[Receiver] LSU from %s not handled.' % util.int2ip(nrid))

        elif ospf_type == 5:
            LOG.debug('[Receiver] Received a LSAck from %s.' % util.int2ip(nrid))
            self.ism.ai.oi.stat.recv_lsack_count += 1
            if util.int2ip(dst) == ALL_D_ROUTER:
                LOG.warn('[Receiver] Not DR/BDR, drop it.')
            else:
                if nrid in self.nsm_list:
                    self.nsm_list[nrid].fp.check_lsack(pkt)
                    self.ism.ai.oi.stat.total_handled_packet_count += 1
                else:
                    LOG.warn('[Receiver] LSAck from %s not handled.' % util.int2ip(nrid))

        else:
            LOG.error('[Error] Wrong OSPF packet type.')
            pass