Changeset 929:9c5b5fd96213

Show
Ignore:
Timestamp:
09/17/08 20:44:49 (2 months ago)
Author:
Phil <phil@secdev.org>
Message:

Added RandRegExp?()

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • scapy/volatile.py

    r895 r929  
    6565    pass 
    6666 
    67  
    6867class RandNum(RandField): 
    6968    min = 0 
    7069    max = 0 
    7170    def __init__(self, min, max): 
    72         self.seq = randseq(min,max) 
    73     def _fix(self): 
    74         return self.seq.next() 
     71        self.min = min 
     72        self.max = max 
     73    def _fix(self): 
     74        # XXX: replace with sth that guarantee unicity 
     75        return random.randrange(self.min, self.max+1) 
    7576 
    7677class RandNumGamma(RandField): 
     
    8990 
    9091class RandNumExpo(RandField): 
    91     def __init__(self, lambd): 
     92    def __init__(self, lambd, base=0): 
    9293        self.lambd = lambd 
    93     def _fix(self): 
    94         return int(round(random.expovariate(self.lambd))) 
    95  
    96 class RandByte(RandNum): 
    97     def __init__(self): 
    98         RandNum.__init__(self, 0, 2L**8-1) 
    99  
    100 class RandShort(RandNum): 
    101     def __init__(self): 
    102         RandNum.__init__(self, 0, 2L**16-1) 
    103  
    104 class RandInt(RandNum): 
    105     def __init__(self): 
    106         RandNum.__init__(self, 0, 2L**32-1) 
    107  
    108 class RandSInt(RandNum): 
    109     def __init__(self): 
    110         RandNum.__init__(self, -2L**31, 2L**31-1) 
    111  
    112 class RandLong(RandNum): 
    113     def __init__(self): 
    114         RandNum.__init__(self, 0, 2L**64-1) 
    115  
    116 class RandSLong(RandNum): 
    117     def __init__(self): 
    118         RandNum.__init__(self, -2L**63, 2L**63-1) 
     94        self.base = base 
     95    def _fix(self): 
     96        return self.base+int(round(random.expovariate(self.lambd))) 
     97 
     98class RandSeq(RandNum): 
     99    def __init__(self, min, max): 
     100        self.seq = randseq(min,max) 
     101    def _fix(self): 
     102        return self.seq.next() 
     103 
     104class RandByte(RandSeq): 
     105    def __init__(self): 
     106        RandSeq.__init__(self, 0, 2L**8-1) 
     107 
     108class RandShort(RandSeq): 
     109    def __init__(self): 
     110        RandSeq.__init__(self, 0, 2L**16-1) 
     111 
     112class RandInt(RandSeq): 
     113    def __init__(self): 
     114        RandSeq.__init__(self, 0, 2L**32-1) 
     115 
     116class RandSInt(RandSeq): 
     117    def __init__(self): 
     118        RandSeq.__init__(self, -2L**31, 2L**31-1) 
     119 
     120class RandLong(RandSeq): 
     121    def __init__(self): 
     122        RandSeq.__init__(self, 0, 2L**64-1) 
     123 
     124class RandSLong(RandSeq): 
     125    def __init__(self): 
     126        RandSeq.__init__(self, -2L**63, 2L**63-1) 
    119127 
    120128class RandChoice(RandField): 
     
    166174            elif "-" in template[i]: 
    167175                x,y = template[i].split("-") 
    168                 v = RandNum(int(x,16), int(y,16)) 
     176                v = RandSeq(int(x,16), int(y,16)) 
    169177            else: 
    170178                v = int(template[i],16) 
     
    206214            return ".".join(oid) 
    207215             
     216 
     217from pprint import pprint 
     218         
     219class RandRegExp(RandField): 
     220    def __init__(self, regexp, lambda_=0.3,): 
     221        self._regexp = regexp 
     222        self._lambda = lambda_ 
     223 
     224    @staticmethod 
     225    def choice_expand(s): #XXX does not support special sets like (ex ':alnum:') 
     226        m = "" 
     227        invert = s and s[0] == "^" 
     228        while True: 
     229            p = s.find("-") 
     230            if p < 0: 
     231                break 
     232            if p == 0 or p == len(s)-1: 
     233                m = "-" 
     234                if p: 
     235                    s = s[:-1] 
     236                else: 
     237                    s = s[1:] 
     238            else: 
     239                c1 = s[p-1] 
     240                c2 = s[p+1] 
     241                rng = "".join(map(chr, range(ord(c1),ord(c2)+1))) 
     242                s = s[:p-1]+rng+s[p+1:] 
     243        res = m+s 
     244        if invert: 
     245            res = "".join([chr(x) for x in xrange(256) if chr(x) not in res]) 
     246        return res 
     247 
     248    @staticmethod 
     249    def stack_fix(lst, index): 
     250        r = "" 
     251        mul = 1 
     252        for e in lst: 
     253            if type(e) is list: 
     254                if mul != 1: 
     255                    mul = mul-1 
     256                    r += RandRegExp.stack_fix(e[1:]*mul, index) 
     257                # only the last iteration should be kept for back reference 
     258                f = RandRegExp.stack_fix(e[1:], index) 
     259                for i,idx in enumerate(index): 
     260                    if e is idx: 
     261                        index[i] = f 
     262                r += f 
     263                mul = 1 
     264            elif type(e) is tuple: 
     265                kind,val = e 
     266                if kind == "cite": 
     267                    r += index[val-1] 
     268                elif kind == "repeat": 
     269                    mul = val 
     270 
     271                elif kind == "choice": 
     272                    if mul == 1: 
     273                        c = random.choice(val) 
     274                        r += RandRegExp.stack_fix(c[1:], index) 
     275                    else: 
     276                        r += RandRegExp.stack_fix([e]*mul, index) 
     277                        mul = 1 
     278            else: 
     279                if mul != 1: 
     280                    r += RandRegExp.stack_fix([e]*mul, index) 
     281                    mul = 1 
     282                else: 
     283                    r += str(e) 
     284        return r 
     285 
     286    def _fix(self): 
     287        stack = [None] 
     288        index = [] 
     289        current = stack 
     290        i = 0 
     291        ln = len(self._regexp) 
     292        interp = True 
     293        while i < ln: 
     294            c = self._regexp[i] 
     295            i+=1 
    208296             
     297            if c == '(': 
     298                current = [current] 
     299                current[0].append(current) 
     300            elif c == '|': 
     301                p = current[0] 
     302                ch = p[-1] 
     303                if type(ch) is not tuple: 
     304                    ch = ("choice",[current]) 
     305                    p[-1] = ch 
     306                else: 
     307                    ch[1].append(current) 
     308                current = [p] 
     309            elif c == ')': 
     310                ch = current[0][-1] 
     311                if type(ch) is tuple: 
     312                    ch[1].append(current) 
     313                index.append(current) 
     314                current = current[0] 
     315            elif c == '[' or c == '{': 
     316                current = [current] 
     317                current[0].append(current) 
     318                interp = False 
     319            elif c == ']': 
     320                current = current[0] 
     321                choice = RandRegExp.choice_expand("".join(current.pop()[1:])) 
     322                current.append(RandChoice(*list(choice))) 
     323                interp = True 
     324            elif c == '}': 
     325                current = current[0] 
     326                num = "".join(current.pop()[1:]) 
     327                e = current.pop() 
     328                if "," not in num: 
     329                    n = int(num) 
     330                    current.append([current]+[e]*n) 
     331                else: 
     332                    num_min,num_max = num.split(",") 
     333                    if not num_min: 
     334                        num_min = "0" 
     335                    if num_max: 
     336                        n = RandNum(int(num_min),int(num_max)) 
     337                    else: 
     338                        n = RandNumExpo(self._lambda,base=int(num_min)) 
     339                    current.append(("repeat",n)) 
     340                    current.append(e) 
     341                interp = True 
     342            elif c == '\\': 
     343                c = self._regexp[i] 
     344                if c == "s": 
     345                    c = RandChoice(" ","\t") 
     346                elif c in "0123456789": 
     347                    c = ("cite",ord(c)-0x30) 
     348                current.append(c) 
     349                i += 1 
     350            elif not interp: 
     351                current.append(c) 
     352            elif c == '+': 
     353                e = current.pop() 
     354                current.append([current]+[e]*(int(random.expovariate(self._lambda))+1)) 
     355            elif c == '*': 
     356                e = current.pop() 
     357                current.append([current]+[e]*int(random.expovariate(self._lambda))) 
     358            elif c == '?': 
     359                if random.randint(0,1): 
     360                    current.pop() 
     361            elif c == '.': 
     362                current.append(RandChoice(*[chr(x) for x in xrange(256)])) 
     363            elif c == '$' or c == '^': 
     364                pass 
     365            else: 
     366                current.append(c) 
     367 
     368        return RandRegExp.stack_fix(stack[1:], index) 
     369    def __repr__(self): 
     370        return "<%s [%r]>" % (self.__class__.__name__, self._regexp) 
     371                 
     372                 
     373         
     374         
    209375 
    210376# Automatic timestamp