(self, fmt, relax=1)
return s
sprintf(format, [relax=1]) -> str
where format is a string that can include directives. A directive begins and
ends by % and has the following format %[fmt[r],][cls[:nb].]field%.

fmt is a classic printf directive, "r" can be appended for raw substitution
(ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
(ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
Special case : "%.time%" is the creation time.
Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
               "%03xr,IP.proto% %r,TCP.flags%")

Moreover, the format string can include conditionnal statements. A conditionnal
statement looks like : {layer:string} where layer is a layer name, and string
is the string to insert in place of the condition if it is true, i.e. if layer
is present. If layer is preceded by a "!", the result si inverted. Conditions
can be imbricated. A valid statement can be :
  p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
  p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")

A side effect is that, to obtain "{" and "}" characters, you must use
"%(" and "%)".
sprintf(format, [relax=1]) -> str
where format is a string that can include directives. A directive begins and
ends by % and has the following format %[fmt[r],][cls[:nb].]field%.
sprintf ( format [ relax = 1 ] ) - > str where format is a string that can include directives . A directive begins and ends by % and has the following format % [ fmt [ r ] ] [ cls [ : nb ] . ] field% .
def sprintf(self, fmt, relax=1):
        """sprintf(format, [relax=1]) -> str
where format is a string that can include directives. A directive begins and
ends by % and has the following format %[fmt[r],][cls[:nb].]field%.

fmt is a classic printf directive, "r" can be appended for raw substitution
(ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
(ex: for IP/IP packets, IP:2.src is the src of the upper IP layer).
Special case : "%.time%" is the creation time.
Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% "
               "%03xr,IP.proto% %r,TCP.flags%")

Moreover, the format string can include conditionnal statements. A conditionnal
statement looks like : {layer:string} where layer is a layer name, and string
is the string to insert in place of the condition if it is true, i.e. if layer
is present. If layer is preceded by a "!", the result si inverted. Conditions
can be imbricated. A valid statement can be :
  p.sprintf("This is a{TCP: TCP}{UDP: UDP}{ICMP:n ICMP} packet")
  p.sprintf("{IP:%IP.dst% {ICMP:%ICMP.type%}{TCP:%TCP.dport%}}")

A side effect is that, to obtain "{" and "}" characters, you must use
"%(" and "%)".
"""

        escape = { "%": "%",
                   "(": "{",
                   ")": "}" }


        # Evaluate conditions 
        while "{" in fmt:
            i = fmt.rindex("{")
            j = fmt[i+1:].index("}")
            cond = fmt[i+1:i+j+1]
            k = cond.find(":")
            if k < 0:
                raise Scapy_Exception("Bad condition in format string: [%s] (read sprintf doc!)"%cond)
            cond,format = cond[:k],cond[k+1:]
            res = False
            if cond[0] == "!":
                res = True
                cond = cond[1:]
            if self.haslayer(cond):
                res = not res
            if not res:
                format = ""
            fmt = fmt[:i]+format+fmt[i+j+2:]

        # Evaluate directives
        s = ""
        while "%" in fmt:
            i = fmt.index("%")
            s += fmt[:i]
            fmt = fmt[i+1:]
            if fmt and fmt[0] in escape:
                s += escape[fmt[0]]
                fmt = fmt[1:]
                continue
            try:
                i = fmt.index("%")
                sfclsfld = fmt[:i]
                fclsfld = sfclsfld.split(",")
                if len(fclsfld) == 1:
                    f = "s"
                    clsfld = fclsfld[0]
                elif len(fclsfld) == 2:
                    f,clsfld = fclsfld
                else:
                    raise Scapy_Exception
                if "." in clsfld:
                    cls,fld = clsfld.split(".")
                else:
                    cls = self.__class__.__name__
                    fld = clsfld
                num = 1
                if ":" in cls:
                    cls,num = cls.split(":")
                    num = int(num)
                fmt = fmt[i+1:]
            except:
                raise Scapy_Exception("Bad format string [%%%s%s]" % (fmt[:25], fmt[25:] and "..."))
            else:
                if fld == "time":
                    val = time.strftime("%H:%M:%S.%%06i", time.localtime(self.time)) % int((self.time-int(self.time))*1000000)
                elif cls == self.__class__.__name__ and hasattr(self, fld):
                    if num > 1:
                        val = self.payload.sprintf("%%%s,%s:%s.%s%%" % (f,cls,num-1,fld), relax)
                        f = "s"
                    elif f[-1] == "r":  # Raw field value
                        val = getattr(self,fld)
                        f = f[:-1]
                        if not f:
                            f = "s"
                    else:
                        val = getattr(self,fld)
                        if fld in self.fieldtype:
                            val = self.fieldtype[fld].i2repr(self,val)
                else:
                    val = self.payload.sprintf("%%%s%%" % sfclsfld, relax)
                    f = "s"
                s += ("%"+f) % val
            
        s += fmt
        return s
def sprintf ( self , fmt , relax = 1 ) : escape = { "%" : "%" , "(" : "{" , ")" : "}" } # Evaluate conditions  while "{" in fmt : i = fmt . rindex ( "{" ) j = fmt [ i + 1 : ] . index ( "}" ) cond = fmt [ i + 1 : i + j + 1 ] k = cond . find ( ":" ) if k < 0 : raise Scapy_Exception ( "Bad condition in format string: [%s] (read sprintf doc!)" % cond ) cond , format = cond [ : k ] , cond [ k + 1 : ] res = False if cond [ 0 ] == "!" : res = True cond = cond [ 1 : ] if self . haslayer ( cond ) : res = not res if not res : format = "" fmt = fmt [ : i ] + format + fmt [ i + j + 2 : ] # Evaluate directives s = "" while "%" in fmt : i = fmt . index ( "%" ) s += fmt [ : i ] fmt = fmt [ i + 1 : ] if fmt and fmt [ 0 ] in escape : s += escape [ fmt [ 0 ] ] fmt = fmt [ 1 : ] continue try : i = fmt . index ( "%" ) sfclsfld = fmt [ : i ] fclsfld = sfclsfld . split ( "," ) if len ( fclsfld ) == 1 : f = "s" clsfld = fclsfld [ 0 ] elif len ( fclsfld ) == 2 : f , clsfld = fclsfld else : raise Scapy_Exception if "." in clsfld : cls , fld = clsfld . split ( "." ) else : cls = self . __class__ . __name__ fld = clsfld num = 1 if ":" in cls : cls , num = cls . split ( ":" ) num = int ( num ) fmt = fmt [ i + 1 : ] except : raise Scapy_Exception ( "Bad format string [%%%s%s]" % ( fmt [ : 25 ] , fmt [ 25 : ] and "..." ) ) else : if fld == "time" : val = time . strftime ( "%H:%M:%S.%%06i" , time . localtime ( self . time ) ) % int ( ( self . time - int ( self . time ) ) * 1000000 ) elif cls == self . __class__ . __name__ and hasattr ( self , fld ) : if num > 1 : val = self . payload . sprintf ( "%%%s,%s:%s.%s%%" % ( f , cls , num - 1 , fld ) , relax ) f = "s" elif f [ - 1 ] == "r" : # Raw field value val = getattr ( self , fld ) f = f [ : - 1 ] if not f : f = "s" else : val = getattr ( self , fld ) if fld in self . fieldtype : val = self . fieldtype [ fld ] . i2repr ( self , val ) else : val = self . payload . sprintf ( "%%%s%%" % sfclsfld , relax ) f = "s" s += ( "%" + f ) % val s += fmt return s