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 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')
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()
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')
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()
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()
def change_nsm_state(self, newstate): LOG.info("[NSM] %s change state to %s." % (util.int2ip(self.rtid), newstate)) self.state = NSM_STATE[newstate]
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
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
def change_nsm_state(self, newstate): LOG.info('[NSM] %s change state to %s.' % (util.int2ip(self.rtid), newstate)) self.state = NSM_STATE[newstate]
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