def configure(self, mac=None, rreqrate=None, datarate=None, **kwargs): """Configure pointers and parameters. :param mac: `MAC` module corresponding to this network protocol. :param rreqrate: Rate index used for flooding RREQ messages. :param datarate: Rate index used for sending other DSR messages. :param kwargs: Additional keywords passed to `Routing.configure()`. If `mac` is not provided, this module will attempt to automatically determine the appropriate `MAC`. If `rreqrate` and/or `datarate` are not specified, `DSR` will not attempt to set the rate annotation of the outgoing packet. It is important that the `rreqrate` be higher than `datarate` to ensure stable links for DSR. """ Routing.configure(self, **kwargs) self.mac = mac self.rreqrate = rreqrate self.datarate = datarate self.maintbuffer = {} self.table = self.newchild('routingtable', RouteCache, \ name=self.name+".rcache", \ tracename=self.tracename+".RCACHE") rreqtable = self.newchild('rreqtable', RouteRequestTable, \ name=self.name+".rreqtable", \ tracename=self.tracename+".RREQTBL")
def __init__(self, *args, **kwargs): """Constructor.""" # set up parameters self.__mac = None self.rreqrate = None self.datarate = None self.maintbuffer = None # additional parameters for signalling self.sndrreq = SimEvent() self.drprreq = SimEvent() self.finrreq = SimEvent() self.sndfail = SimEvent() # call base constructor Routing.__init__(self, *args, **kwargs)
def getproto(self, p): """Overloaded to check for DSR packets.""" if isinstance(p, Reference): p = p._deref # determine protocol type of packet if isinstance(p, DSRPacket): proto = const.IP_PROTO_DSR else: proto = Routing.getproto(self, p) return proto
def checkiprecv(self, p, nextheader=True, **kwargs): """Overloaded to check for valid IP+DSR packet. :param p: Packet received in `IPRECV`. :param args: Additional arguments passed to base class method. :param kwargs: Additional keywords passed to base class method. :return: String containing any error condition, or nothing for no error. """ # error messages dropnondsr = "non-IP+DSR packet in IPRECV" dropheader = "invalid IP+DSR nextheader" dropdsropt = "invalid DSR options!" # call base method drop = Routing.checkiprecv(self, p, **kwargs) if drop: return drop # valid IP+DSR? isdsr = p.haslayer(IP) and p.haslayer(DSRPacket) if not isdsr: return dropnondsr dsr = p[DSRPacket] # check nextheader if nextheader: payproto = self.getproto(dsr.payload) if (payproto!=dsr.nextheader): return dropheader # check DSR options if not self.checkdsropt(p, exception=False): return dropdsropt return "" # no error
def set_sendanno(self, *args, **kwargs): """Overloaded to set rate annotations in outgoing packets.""" p = Routing.set_sendanno(self, *args, **kwargs) isip = isinstance(p, Packet) and p.haslayer(IP) isdsr = isip and p.haslayer(DSRPacket) if not isdsr: return p # remove stale annotations if p.hasanno('phy-fixed-rate'): p.delanno('phy-fixed-rate') # set rate annotation rreq = getdsr_rreq(p) rate = None if rreq: rate = self.rreqrate # assume RREQ rate is higher else: rate = self.datarate if (rate is not None): p.setanno('phy-rate', rate) # use fixed-rate anno for broadcast packets if rreq: p.setanno('phy-fixed-rate', rate) return p
def encap_data(self, p, src, dst, force=False, **kwargs): """Encapsulate data packet (if needed) for delivery to next hop. :param p: Packet to deliver. :param src: Source address. :param dst: Destination address. :param force: If true, force encapsulation into a new IP packet. :param kwargs: Additional keywords passed to IP constructor. :return: Encapsulated/modified packet for delivery. If `p` is already an IP packet and `force` is false, this method will update 'src', 'dst', and 'ttl' fields as needed. Otherwise, this method encapsulates `p` with an IP header. :note: By default this method assumes that `ptype` indicates IPv4. *Overload this method to handle other protocol types*. """ # if no encapsulation needed -> update parameters isip = isinstance(p, Packet) and p.haslayer(IP) isdsr = isip and p.haslayer(DSRPacket) if isdsr and (not force): ip, dsr = p[IP], p[DSRPacket] dsr.nextheader = self.getproto(dsr.payload) if self.hasroute(ip.dst): p = self.updateroute(ip) # update IP parameters return Routing.encap_data(self, p, src, dst, force=False, **kwargs) # create DSR nextheader = self.getproto(p) dsr = DSRPacket(nextheader=nextheader) dsr.add_payload(p) # create IP+DSR proto = self.getproto(dsr) ip = IP(src=src, dst=dst, proto=proto, **kwargs) ip.add_payload(dsr) # update and return return self.encap_data(ip, src, dst, force=False, **kwargs)
def get_ip_anno(self, p): """Internal method to get relevant annotations for an IP+DSR packet.""" kwargs = Routing.get_ip_anno(self, p) kwargs.update(self.get_dsr_anno(p) ) kwargs.update(self.get_agt_anno(p) ) return kwargs