tag:blogger.com,1999:blog-18914451283046776922024-03-13T14:16:23.723-07:0015 minutes of python a day!This is my drop back to the open source comunity. It is devoted to Python, the language I find myself using quite often to just-do-the-job. My small trips and tricks while i'm using it, how i use it and what for. And things like that.Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-1891445128304677692.post-15613368331406992912015-09-22T13:41:00.000-07:002015-09-22T13:41:25.836-07:00This is an example how to use <a href="https://github.com/vivisect/vivisect">Vivisect</a>.<br />
<br />
Vivisect is a cool collection of tools for both static and dynamic analysis of binaries.<br />
It supports x86, x86_64, and ARM binaries. Also runs on multiple platforms Linux, Win and osX<br />
You are probably wondering what is the link with this blog.<br />
It is all written in Python. Yes all of it. From the multi platform debugger through the disassembly<br />
engine up to the emulator and GUI. It's a piece of beauty.<br />
<br />
The code base is very nice. It uses introspection beautifiers etc. It's modular and well structured.<br />
That actually proves the people behind it are highly skilled with the language and enjoy it.<br />
<br />
For this presentation we will crack a middle difficulty crackme from <a href="http://crackmes.de/">http://crackmes.de/</a><br />
<br />
The binary used for the case is <a href="http://crackmes.de/users/tryger/keygen_rivendel/">Tryger's keygen_rivendel</a><br />
<br />
You can also download the whole solution from <a href="http://crackmes.de/users/tryger/keygen_rivendel/solutions/bat.serjo">http://crackmes.de/users/tryger/keygen_rivendel/solutions/bat.serjo</a><br />
<br />
SPOILER :)<br />
DEFAULT USER: \n<br />
DEFAULT PASS: \n<br />
<br />
But that's not interesting :) There is no goal in this other than fun :D<br />
<br />
This crackme is one small time, dirty, wanna be gangsta.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>$ gdb -q ./breakme<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Reading symbols from ./breakme...Segmentation fault<br />
<br />
Ayee gangsta?<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>$ nm ./breakme<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>08049e8c d (null)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>080484b0 t (null)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>080484e0 t (null)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>....<br />
<br />
Alright then let see how you do against Vivisect (https://github.com/vivisect)<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>$ ./vivbin -B ./breakme<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Failed to find file for 0x08049fb8 (_edata) (and filelocal == True!)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Failed to find file for 0x08049fb8 (__bss_start) (and filelocal == True!)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Failed to find file for 0x08049fb8 (__TMC_END__) (and filelocal == True!)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Loaded (0.0513 sec) ./breakme<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>ANALYSIS TIME: 0.267040967941<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>stats: {'functions': 24, 'relocations': 0}<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Saving workspace: ./breakme.viv<br />
<br />
Hmm ain't that tough after all :)<br />
<br />
<br />
First of all I would like to say that this crack me is a perfect example<br />
for security through obscurity. Anti debug protections combined with<br />
decoys and recursion for the check algorithm. It's so ahead in the game<br />
obscurity that even a successful check of the key sounds dubious :)<br />
You got it? or not! I don't really know.<br />
<br />
Anti debug protection number one. Obviously something is wrong with the ELF header.<br />
Wrong enough to crash gdb. I didn't spent much time figuring out what. Since the<br />
kernel is able to load it and execute it. Also vivisect coped well with it.<br />
<br />
Using vivisect analyze the __entry point of the program.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487b6 55 push ebp<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487b7 89e5 mov ebp,esp<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487b9 81ecb8000000 sub esp,184<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487bf 6a00 push 0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487c1 6a01 push 1<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487c3 6a00 push 0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487c5 6a00 push 0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487c7 e894fcffff call ptrace_08048460 ;<-- antidebug protection number two :)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487cc 83c410 add esp,16<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487cf 85c0 test eax,eax<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080487d1 791a jns loc_080487ed<br />
<br />
Hehe old school unix anti debug tricks. Ptrace your self so that nobody else can ptrace you :D<br />
Then there's a check for the result. So what happens if you try to debug it with something else than gdb :)<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>python ./crack.py ~/examples/CRACKME/rivendel/breakme<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>You are debugging me, I don't like it :(<br />
<br />
Hehe really bro? We'll see about that later.<br />
Now lets continue with analyzing the flow of the program using the FuncGraph.<br />
We notice that if ptrace succeeds we continue with some welcoming messages etc.<br />
Then we read the user input. With fgets.<br />
<br />
Spoiler. If fgets fails we end up jumping to 0x08048918.THIS IS A DECOY! everything after this is a decoy!<br />
Yes the binary is 90% bullshit :) But I'm not sure I get the reset 10% either.<br />
If getting the password fails it will also jump there!<br />
<br />
The password is read using getc from the function @ 0x0804877b.<br />
It must read 3 times more data from the input than the username length!<br />
<br />
Then the (username, password, counter, tmpVar, userLen) are fed to the function @ 0x0804856b<br />
This is where the magic happens 0x0804856b.<br />
<br />
Give the function a glance at the FuncGraph.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- It's recursive<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- It has multiple check points<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- It has multiple direct exit(-1) points<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- If you survive this function you pretty much 'own' the binary :)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- It takes multiple arguments<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- On every cycle it makes a check of the currently calculated theoretical hash<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- If the check fails you end up in the exit(-1) case.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- Otherwise continue recursion.<br />
<br />
Check out the function in the Viv window<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b <br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b FUNC: int cdecl breakme.magic( int arg0, int arg1, int arg2, int arg3, int arg4, ) [4 XREFS]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b <br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b Stack Variables:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b 20: int arg4<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b 16: int arg3<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b 12: int arg2<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b 8: int arg1<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b 4: int arg0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804856b -16: int local16<br />
<br />
<br />
Here's what the arguments are - as seen @<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488dc 83c410 add esp,16<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488df 83ec0c sub esp,12<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488e2 50 push eax <span class="Apple-tab-span" style="white-space: pre;"> </span>;ARG strlen_hashed_user<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488e3 6a00 push 0 <span class="Apple-tab-span" style="white-space: pre;"> </span>;ARG 0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488e5 6a00 push 0 <span class="Apple-tab-span" style="white-space: pre;"> </span>;ARG 0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488e7 8d8557ffffff lea eax,dword [ebp - 169]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488ed 50 push eax <span class="Apple-tab-span" style="white-space: pre;"> </span>;ARG Password<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488ee 8d45cf lea eax,dword [ebp - 49]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488f1 50 push eax <span class="Apple-tab-span" style="white-space: pre;"> </span>;ARG Hashed user<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488f2 e874fcffff call breakme.magic <span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488f7 83c420 add esp,32<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488fa 85c0 test eax,eax<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488fc 7510 jnz loc_0804890e<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x080488fe 83ec0c sub esp,12<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x08048901 688e8c0408 push str_Yout got it, or _08048c8e ;bingo<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x08048906 e8f5faffff call puts_08048400 ;puts_08048400()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804890b 83c410 add esp,16<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804890e loc_0804890e: [1 XREFS]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x0804890e 83ec0c sub esp,12<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x08048911 6a01 push 1 ;SUCCESS !!!<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>.text:0x08048913 e808fbffff call exit_08048420 <br />
<br />
In short breakme.magic(user, pwd, cnt, unk, userLen)<br />
Also here you can see that if you survive the magic you are done.<br />
<br />
Using the Symbolics window in Vivisect extract the results<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- Using the simplified view extract all possible paths<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- Sort them in a file.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- Try to figure out what all this means.<br />
<br />
It sounds hard but is actually not.<br />
In the Symbolics.txt you can find a log of my struggles.<br />
Actually I didn't expect to get anything useful out of this.<br />
But also didn't want to start debugging yet.<br />
The results were actually pretty good.<br />
In short I was able to make a skeleton of the algorithm<br />
in a pseudo language quite fast.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>def reverse(user, pwd, cnt, unk=0, userLen = len(user)):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if cnt == userLen*3:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>return 0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if cnt < userLen * 2:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if cnt < userLen:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if pwd[cnt] == (unk+15) ^ user[cnt]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>lvar = cnt+1<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if cnt + 1 == userLen:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>arg3 = ((unk + 15) ^ user[cnt]) - 10<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>reverse(user, pwd, cnt+1, arg3, userLen)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>arg3 = ((unk + 15) ^ user[cnt])<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>reverse(user, pwd, cnt+1, arg3, userLen)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>raise Exception("missed at %s %d %s" % (user, cnt, pwd))<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if pwd[cnt] != (18 - unk) ^ user[ (cnt/userLen) % userLen ]:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>raise Exception("missed at %s %d %s" % (user, cnt, pwd))<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>lvar = cnt + 1<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if cnt + 1 == userLen*2:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>arg3 = (18 - unk) ^ user[ (cnt/userLen) % userLen ] + 113<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>reverse(user, pwd, cnt+1, arg3, userLen)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>arg3 = (18 - unk) ^ user[ (cnt/userLen) % userLen ]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>reverse(user, pwd, cnt+1, arg3, userLen)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if pwd[cnt] == ((unk - 76) * 2) ^ user[ (cnt / userLen) % userLen ]:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>lvar = cnt + 1<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>arg3 = ((unk - 76) * 2) ^ user[ (cnt / userLen) % userLen ]<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>reverse(user, pwd, cnt+1, arg3, userLen)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>else<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>raise Exception("missed at %s %d %s" % (user, cnt, pwd))<br />
<br />
<br />
From this I made a "generator" (still not 100% working :).<br />
<br />
Problem. As it turns out you must enter non printable characters for the password.<br />
What the hell. Redirecting input from file or if you're a shell ninja get it done somehow.<br />
Guess the binary is supposed to be used as a part from a bigger system and called externaly<br />
then the exit status is used to make the judgment.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/examples/CRACKME/rivendel$ python keygen.py a<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>6ecf89<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/examples/CRACKME/rivendel$ ./breakme < input.raw<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Keygen me... if you can ;-)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Have fun & Good luck!<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>User (1 - 40 chars): Password for the user a (3 bytes):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Yout got it, or not... ;)<br />
<br />
Problem:<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/examples/CRACKME/rivendel$ python keygen.py plp<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>7fe281f777f7488808<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/examples/CRACKME/rivendel$ ./breakme < input.raw<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Keygen me... if you can ;-)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Have fun & Good luck!<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>User (1 - 40 chars): Password for the user plp (9 bytes): WRONG SERIAL :-(<br />
<br />
As mentioned before not 100% accurate.<br />
<br />
Lets debug this little fucker. vtrace is powerful tool. Maybe a tid bit slow.<br />
But powerful. Lets write a script that will runtime patch the binary to spit out the password.<br />
<br />
Using vtrace:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- Patch the ptrace call so that execution proceeds as normal.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- Add instrumentation to print the calculated value for the password<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>- Hook the unwanted branch of every check manipulate it and jump to the wanted branch as if nothing happened.<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<br />
I'm usint breakpoints for all this.<br />
For example a breakpoint on the ptrace call instruction can manipulate the eip register and simply continue.<br />
This effectively bypasses the ptrace protection.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class PtracePatch ( Breakpoint ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>def notify( self, event, trace ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>rctx = trace.getRegisterContext()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>curaddr = rctx.getProgramCounter()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>jumpaddr = curaddr + 5 #bytes: e894fcffff<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>rctx.setProgramCounter(jumpaddr)<br />
<br />
<br />
Get it right :) Something similar for the branch and printing and the crack.py was ready.<br />
<br />
Put the crack.py inside the vivisect folder in order to be able to resolve needed modules etc.<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/netstock/vivisect$ cp ~/examples/CRACKME/rivendel/crack.py ./<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/netstock/vivisect$ python ./crack.py ~/examples/CRACKME/rivendel/breakme<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Keygen me... if you can ;-)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Have fun & Good luck!<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>User (1 - 40 chars): plp<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Password for the user plp (9 bytes): aaaaaaaaa<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Yout got it, or not... ;)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>7f e2 81 eb 4b b7 c8 94 e0<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/examples/CRACKME/rivendel$ python ./keygen.py -use plp 7f e2 81 eb 4b b7 c8 94 e0<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>serj@debian:~/examples/CRACKME/rivendel$ ./breakme < input.raw<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Keygen me... if you can ;-)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Have fun & Good luck!<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>User (1 - 40 chars): Password for the user plp (9 bytes):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Yout got it, or not... ;)<br />
<br />
Problem solved :)<br />
So you got it? or not. I still have no idea. But at least I have a keygen :D<br />
<br />
And here is the script that does the job<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>'''<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Created on Apr 24, 2015<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>@author: serj<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>'''<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import sys<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import errno<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import struct<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import envi<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import envi.archs.i386 as e_i386<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>import vtrace<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>from vtrace.breakpoints import Breakpoint<br />
<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class PtracePatch ( Breakpoint ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>def notify( self, event, trace ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>rctx = trace.getRegisterContext()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#self.resolveAddress( trace )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>curaddr = rctx.getProgramCounter()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>jumpaddr = curaddr + 5 #bytes: e894fcffff<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#trace.setRegister( e_i386.REG_EIP, jumpaddr )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>rctx.setProgramCounter(jumpaddr)<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class BranchPatch ( Breakpoint ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>def setRedirectAddr(self, desiredAddr):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>self.desiredAddr = desiredAddr<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>def notify( self, event, trace ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>rctx = trace.getRegisterContext()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>rctx.setProgramCounter( self.desiredAddr )<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#1 part<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#0x080485b7<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#2 part<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#0x080485ec<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#3 part<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#0x08048622<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>class PrintAL ( Breakpoint ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>def notify( self, event, trace ):<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>rctx = trace.getRegisterContext()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>al = rctx.getRegister(e_i386.REG_AL)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>print '%.2x ' % al,<br />
<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>if __name__ == '__main__':<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace = vtrace.getTrace()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.execute('%s' % sys.argv[1])<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.requireAttached()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#maps = trace.getMemoryMaps()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>#for m in maps:<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span># print m<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_ppach1 = PtracePatch(0x80487c7)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.addBreakpoint( _ppach1 )<br />
<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_bb1 = BranchPatch(0x080485ca)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_bb1.setRedirectAddr(0x0804863c)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.addBreakpoint( _bb1 )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_bb2 = BranchPatch(0x080485ff)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_bb2.setRedirectAddr(0x0804866c)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.addBreakpoint( _bb2 )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_bb3 = BranchPatch(0x08048635)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_bb3.setRedirectAddr(0x080486a0)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.addBreakpoint( _bb3 )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_pal1 = PrintAL(0x080485b7)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.addBreakpoint( _pal1 )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_pal2 = PrintAL(0x080485ec)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.addBreakpoint( _pal2 )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>_pal3 = PrintAL(0x08048622)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.addBreakpoint( _pal3 )<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.setMode("RunForever", True)<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>trace.run()<br />
<span class="Apple-tab-span" style="white-space: pre;"> </span>Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0tag:blogger.com,1999:blog-1891445128304677692.post-54920928314942630092013-02-10T10:32:00.001-08:002013-02-10T10:32:22.954-08:00Controlling the network interfaces through Python, like a sir!<div style="text-align: justify;">
Ever wanted to be able to get all available network interfaces and control them through Python? Well so did I, thus I went on the web and started searching for such modules/packages that can do that. And I found. I found <a href="http://fedorapeople.org/cgit/dsommers/public_git/python-ethtool.git/">ethtool</a> I also found <a href="http://pypi.python.org/pypi/netifaces/">netifaces</a> and also this <a href="http://carnivore.it/2010/07/22/python_-_getifaddrs">dionaea's getifaddrs</a> and of course tons of questions about it on <a href="http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib">stackoverflow</a> but they all seem to lack one important feature. Controlling the interface, meaning bringing it up, changing it's IP address etc. Correct me if I'm wrong. Thus I decided to create one that can. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
In order to control a network interface in most Unix derivatives you need to deal with IOCTL - a obscure & useful system call used for everything you can imagine. For the purpose of manipulating a network interface we have to deal with one more hairy member of the Unix world. </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Meet "struct ifreq": </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
struct ifreq</div>
<div style="text-align: justify;">
{</div>
<div style="text-align: justify;">
# define IFHWADDRLEN 6</div>
<div style="text-align: justify;">
# define IFNAMSIZ IF_NAMESIZE</div>
<div style="text-align: justify;">
union</div>
<div style="text-align: justify;">
{</div>
<div style="text-align: justify;">
char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0". */</div>
<div style="text-align: justify;">
} ifr_ifrn;</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
union</div>
<div style="text-align: justify;">
{</div>
<div style="text-align: justify;">
struct sockaddr ifru_addr;</div>
<div style="text-align: justify;">
struct sockaddr ifru_dstaddr;</div>
<div style="text-align: justify;">
struct sockaddr ifru_broadaddr;</div>
<div style="text-align: justify;">
struct sockaddr ifru_netmask;</div>
<div style="text-align: justify;">
struct sockaddr ifru_hwaddr;</div>
<div style="text-align: justify;">
short int ifru_flags;</div>
<div style="text-align: justify;">
int ifru_ivalue;</div>
<div style="text-align: justify;">
int ifru_mtu;</div>
<div style="text-align: justify;">
struct ifmap ifru_map;</div>
<div style="text-align: justify;">
char ifru_slave[IFNAMSIZ]; /* Just fits the size */</div>
<div style="text-align: justify;">
char ifru_newname[IFNAMSIZ];</div>
<div style="text-align: justify;">
__caddr_t ifru_data;</div>
<div style="text-align: justify;">
} ifr_ifru;</div>
<div style="text-align: justify;">
};</div>
<div>
<br /></div>
<div>
Hairy stuff, really hairy. Just tell me what sockaddr really is? Yeah right it's another union. What about ifmap? Just how many structures do you have to know to be able to work with this one. Well can you really blame the people who did this structure? It's not their fault, after it is used for a lot of things. I mean almost every action connected with a network interface is stuffed through ioctl using this structure. So instead of bragging about it's hair style lets consider the techniques we have in the Python world to deal with such structure. </div>
<div>
<ul>
<li>For one we can always make a C/C++ extension and hide the complexity there. This approach was taken by ethtool and netifaces. I don't like this approach much. First you can't benefit from Pythons features. Second the code base becomes quite bloated with very similar patterns like 'set ifreq struct value, call ioctl, handle return code' and I don't like it.</li>
<li>A lot of answers on stackoverflow show how you can get or set a particular option of a network interface in pure python using the struct module. But can you imagine writing a function for every element of that ifreq structure like this:</li>
</ul>
<div>
def get_ip(iface = 'eth0'):</div>
<div>
... ifreq = struct.pack('16sH14s', iface, socket.AF_INET, '\x00'*14)</div>
<div>
... try:</div>
<div>
... res = fcntl.ioctl(sockfd, SIOCGIFADDR, ifreq)</div>
<div>
... except:</div>
<div>
... return None</div>
<div>
... ip = struct.unpack('16sH2x4s8x', res)[2]</div>
<div>
... return socket.inet_ntoa(ip)</div>
</div>
<div>
<br /></div>
<div>
Code taken from <a href="http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib">http://stackoverflow.com/questions/166506/finding-local-ip-addresses-using-pythons-stdlib</a></div>
<div>
<br /></div>
<div>
<ul>
<li>Then there's <a href="http://docs.python.org/2/library/ctypes.html">ctypes</a>. The module that helps you exploit those C libraries without having to deal with C. Inspired by the dionaeas approach I decided that this is the one and only path I will take.</li>
</ul>
</div>
<div>
I want easy and intuitive access to the network interfaces. I wan't a class representing a interface. I wan't to be able to get and set values of this interface by simply accessing them like variables. I wan't pretty printing. I wan't short but working code with as little replication as possible. I wan't something like this:</div>
<div>
<br /></div>
<div>
<span class="Apple-style-span" style="border-collapse: collapse; color: #333333; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 9.72222px; line-height: 16px;"><pre style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-family: Consolas, 'Liberation Mono', Courier, monospace; font-size: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"><div class="line" id="LC9" style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 10px; padding-right: 0px; padding-top: 0px;">
#!/usr/bin/env python
import pyiface
#Get all available network interfaces
allIfaces = PyIface.getIfaces()
for iface in allIfaces:
print iface
#Get a specific interface by name
eth0 = PyIface.Interface('eth0')
#view eth0 info
print eth0
#bring eth0 up
eth0.flags = eth0.flags | IFF_UP
#set ipv4 address of the interface
eth0.addr = (socket.AF_INET, '1.2.3.4')
#set ipv6 address of the interface
eth0.addr = (socket.AF_INET6, '2001:0db8:85a3:0000:0000:8a2e:0370:7334')</div>
<div class="line" id="LC9" style="border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 10px; padding-right: 0px; padding-top: 0px;">
</div>
</pre>
</span></div>
<div>
Beautiful isn't it? How hard can it be? Wee not much indeed. Using Pythons property attributes it becomes a piece of cake like this :)</div>
<div>
<br /></div>
<div>
<span class="Apple-style-span" style="font-family: Verdana, Helvetica, Arial, sans-serif;"><pre style="line-height: 16px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span style="color: green; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">sys</span>
<span style="color: green; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">fcntl</span>
<span style="color: green; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">struct</span>
<span style="color: green; font-weight: bold;">import</span> <span style="color: #0e84b5; font-weight: bold;">socket</span>
<span style="color: green; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">ctypes</span> <span style="color: green; font-weight: bold;">import</span> <span style="color: #303030;">*</span>
<span style="color: green; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">.ifreqioctls</span> <span style="color: green; font-weight: bold;">import</span> <span style="color: #303030;">*</span>
<span style="color: green; font-weight: bold;">from</span> <span style="color: #0e84b5; font-weight: bold;">binascii</span> <span style="color: green; font-weight: bold;">import</span> hexlify
flags2str <span style="color: #303030;">=</span> {
IFF_UP: <span style="background-color: #fff0f0;">'Interface is up.'</span>,
IFF_BROADCAST: <span style="background-color: #fff0f0;">'Broadcast address valid.'</span>,
IFF_DEBUG: <span style="background-color: #fff0f0;">'Turn on debugging.'</span>,
IFF_LOOPBACK: <span style="background-color: #fff0f0;">'Is a loopback net.'</span>,
IFF_POINTOPOINT: <span style="background-color: #fff0f0;">'Interface is point-to-point link.'</span>,
IFF_NOTRAILERS: <span style="background-color: #fff0f0;">'Avoid use of trailers.'</span>,
IFF_RUNNING: <span style="background-color: #fff0f0;">'Resources allocated.'</span>,
IFF_NOARP: <span style="background-color: #fff0f0;">'No address resolution protocol.'</span>,
IFF_PROMISC: <span style="background-color: #fff0f0;">'Receive all packets.'</span>,
IFF_ALLMULTI: <span style="background-color: #fff0f0;">'Receive all multicast packets.'</span>,
IFF_MASTER: <span style="background-color: #fff0f0;">'Master of a load balancer.'</span>,
IFF_SLAVE: <span style="background-color: #fff0f0;">'Slave of a load balancer.'</span>,
IFF_MULTICAST: <span style="background-color: #fff0f0;">'Supports multicast.'</span>,
IFF_PORTSEL: <span style="background-color: #fff0f0;">'Can set media type.'</span>,
IFF_AUTOMEDIA: <span style="background-color: #fff0f0;">'Auto media select active.'</span>,
IFF_DYNAMIC: <span style="background-color: #fff0f0;">'Dialup device with changing addresses.'</span>
}
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">flagsToStr</span>(fin):
ret <span style="color: #303030;">=</span> <span style="background-color: #fff0f0;">''</span>
<span style="color: green; font-weight: bold;">for</span> k <span style="color: black; font-weight: bold;">in</span> flags2str<span style="color: #303030;">.</span>keys():
<span style="color: green; font-weight: bold;">if</span> fin <span style="color: #303030;">&</span> k:
ret <span style="color: #303030;">=</span> ret <span style="color: #303030;">+</span><span style="background-color: #fff0f0;">'</span><span style="background-color: #fff0f0; color: #606060; font-weight: bold;">\t</span><span style="background-color: #fff0f0;">'</span><span style="color: #303030;">+</span> flags2str[k] <span style="color: #303030;">+</span> <span style="background-color: #fff0f0;">'</span><span style="background-color: #fff0f0; color: #606060; font-weight: bold;">\n</span><span style="background-color: #fff0f0;">'</span>
<span style="color: green; font-weight: bold;">return</span> ret
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">sockaddr_gen</span>(Structure):
_fields_ <span style="color: #303030;">=</span> [
( <span style="background-color: #fff0f0;">"sa_family"</span>, c_uint16 ),
( <span style="background-color: #fff0f0;">"sa_data"</span>, (c_uint8 <span style="color: #303030;">*</span> <span style="color: #0000d0; font-weight: bold;">22</span>) )
]
<span style="color: grey;"># AF_INET / IPv4</span>
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">in_addr</span>(Structure):
_pack_<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">"s_addr"</span>, c_uint32),
]
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">sockaddr_in</span>(Structure):
_pack_<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">"sin_family"</span>, c_ushort),
(<span style="background-color: #fff0f0;">"sin_port"</span>, c_ushort),
(<span style="background-color: #fff0f0;">"sin_addr"</span>, in_addr),
(<span style="background-color: #fff0f0;">"sin_zero"</span>, (c_uint8 <span style="color: #303030;">*</span> <span style="color: #0000d0; font-weight: bold;">16</span>) ), <span style="color: grey;"># padding</span>
]
<span style="color: grey;"># AF_INET6 / IPv6</span>
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">in6_u</span>(Union):
_pack_<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">"u6_addr8"</span>, (c_uint8 <span style="color: #303030;">*</span> <span style="color: #0000d0; font-weight: bold;">16</span>) ),
(<span style="background-color: #fff0f0;">"u6_addr16"</span>, (c_uint16 <span style="color: #303030;">*</span> <span style="color: #0000d0; font-weight: bold;">8</span>) ),
(<span style="background-color: #fff0f0;">"u6_addr32"</span>, (c_uint32 <span style="color: #303030;">*</span> <span style="color: #0000d0; font-weight: bold;">4</span>) )
]
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">in6_addr</span>(Structure):
_pack_ <span style="color: #303030;">=</span> <span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">"in6_u"</span>, in6_u),
]
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">sockaddr_in6</span>(Structure):
_pack_<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">"sin6_family"</span>, c_short),
(<span style="background-color: #fff0f0;">"sin6_port"</span>, c_ushort),
(<span style="background-color: #fff0f0;">"sin6_flowinfo"</span>, c_uint32),
(<span style="background-color: #fff0f0;">"sin6_addr"</span>, in6_addr),
(<span style="background-color: #fff0f0;">"sin6_scope_id"</span>, c_uint32),
]
<span style="color: grey;"># AF_LINK / BSD|OSX</span>
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">sockaddr_dl</span>( Structure ):
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">"sdl_len"</span>, c_uint8 ),
(<span style="background-color: #fff0f0;">"sdl_family"</span>, c_uint8 ),
(<span style="background-color: #fff0f0;">"sdl_index"</span>, c_uint16 ),
(<span style="background-color: #fff0f0;">"sdl_type"</span>, c_uint8 ),
(<span style="background-color: #fff0f0;">"sdl_nlen"</span>, c_uint8 ),
(<span style="background-color: #fff0f0;">"sdl_alen"</span>, c_uint8 ),
(<span style="background-color: #fff0f0;">"sdl_slen"</span>, c_uint8 )
<span style="color: grey;"># ("sdl_data", (c_uint8 * 46) ) </span>
]
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">sockaddr</span> ( Union ):
_pack_<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">'gen'</span>, sockaddr_gen),
(<span style="background-color: #fff0f0;">'in4'</span>, sockaddr_in ),
(<span style="background-color: #fff0f0;">'in6'</span>, sockaddr_in6 )
]
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">ifmap</span>( Structure ):
_pack_<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">'mem_start'</span>, c_ulong),
(<span style="background-color: #fff0f0;">'mem_end'</span>, c_ulong),
(<span style="background-color: #fff0f0;">'base_addr'</span>, c_ushort),
(<span style="background-color: #fff0f0;">'irq'</span>, c_ubyte ),
(<span style="background-color: #fff0f0;">'dma'</span>, c_ubyte ),
(<span style="background-color: #fff0f0;">'port'</span>, c_ubyte )
]
IFNAMSIZ <span style="color: #303030;">=</span> <span style="color: #0000d0; font-weight: bold;">16</span>
IFHWADDRLEN <span style="color: #303030;">=</span> <span style="color: #0000d0; font-weight: bold;">6</span>
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">ifr_data</span>( Union ):
_pack_ <span style="color: #303030;">=</span> <span style="color: #0000d0; font-weight: bold;">1</span>
_fields_ <span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">'ifr_addr'</span>, sockaddr),
(<span style="background-color: #fff0f0;">'ifr_dstaddr'</span>, sockaddr),
(<span style="background-color: #fff0f0;">'ifr_broadaddr'</span>,sockaddr),
(<span style="background-color: #fff0f0;">'ifr_netmask'</span>, sockaddr),
(<span style="background-color: #fff0f0;">'ifr_hwaddr'</span>, sockaddr),
(<span style="background-color: #fff0f0;">'ifr_flags'</span>, c_short),
(<span style="background-color: #fff0f0;">'ifr_ifindex'</span>, c_int),
(<span style="background-color: #fff0f0;">'ifr_ifqlen'</span>, c_int),
(<span style="background-color: #fff0f0;">'ifr_metric'</span>, c_int),
(<span style="background-color: #fff0f0;">'ifr_mtu'</span>, c_int),
(<span style="background-color: #fff0f0;">'ifr_map'</span>, ifmap),
(<span style="background-color: #fff0f0;">'ifr_slave'</span>, (c_ubyte<span style="color: #303030;">*</span>IFNAMSIZ)),
(<span style="background-color: #fff0f0;">'ifr_newname'</span>, (c_ubyte<span style="color: #303030;">*</span>IFNAMSIZ)),
(<span style="background-color: #fff0f0;">'ifr_data'</span>, c_void_p)
]
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">ifreq</span>( Structure ):
_pack_<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>
_fields_<span style="color: #303030;">=</span> [
(<span style="background-color: #fff0f0;">'ifr_name'</span>, (c_ubyte<span style="color: #303030;">*</span>IFNAMSIZ)),
(<span style="background-color: #fff0f0;">'data'</span>, ifr_data)
]
<span style="color: green; font-weight: bold;">class</span> <span style="color: #b00060; font-weight: bold;">Interface</span>(<span style="color: #007020;">object</span>):
<span style="color: #d04020;">"""</span>
<span style="color: #d04020;"> Represents a network interface.</span>
<span style="color: #d04020;"> </span>
<span style="color: #d04020;"> Almost all interesting attributes are exported in the form</span>
<span style="color: #d04020;"> of a variable. You can get or set this variable. For example:</span>
<span style="color: #d04020;"> </span>
<span style="color: #d04020;"> ifeth0 = Interface("eth0")</span>
<span style="color: #d04020;"> print ifeth0.addr # will print the current address</span>
<span style="color: #d04020;"> ...</span>
<span style="color: #d04020;"> or</span>
<span style="color: #d04020;"> ...</span>
<span style="color: #d04020;"> ifeth0.addr = (AF_INET, '1.2.3.4') # will set a new address</span>
<span style="color: #d04020;"> </span>
<span style="color: #d04020;"> """</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__init__</span>(<span style="color: #007020;">self</span>, idx<span style="color: #303030;">=</span><span style="color: #0000d0; font-weight: bold;">1</span>, name<span style="color: #303030;">=</span><span style="color: #007020;">None</span>):
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>skt <span style="color: #303030;">=</span> socket<span style="color: #303030;">.</span>socket(socket<span style="color: #303030;">.</span>AF_INET, socket<span style="color: #303030;">.</span>SOCK_DGRAM, <span style="color: #0000d0; font-weight: bold;">0</span>)
fcntl<span style="color: #303030;">.</span>fcntl(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>skt,
fcntl<span style="color: #303030;">.</span>F_SETFD,
fcntl<span style="color: #303030;">.</span>fcntl(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>skt, fcntl<span style="color: #303030;">.</span>F_GETFD) <span style="color: #303030;">|</span> fcntl<span style="color: #303030;">.</span>FD_CLOEXEC)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_index <span style="color: #303030;">=</span> idx
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name <span style="color: #303030;">=</span> name
<span style="color: grey;"># Get the name of the interface</span>
<span style="color: green; font-weight: bold;">if</span> (<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name <span style="color: #303030;">==</span> <span style="color: #007020;">None</span>):
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>name
<span style="color: green; font-weight: bold;">else</span>:
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name <span style="color: #303030;">=</span> (c_ubyte<span style="color: #303030;">*</span>IFNAMSIZ) (<span style="color: #303030;">*</span><span style="color: #007020;">bytearray</span>(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name))
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_index <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>index
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__newIfreqWithName</span>(<span style="color: #007020;">self</span>):
ifr <span style="color: #303030;">=</span> ifreq()
ifr<span style="color: #303030;">.</span>ifr_name <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name
<span style="color: green; font-weight: bold;">return</span> ifr
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__doIoctl</span>(<span style="color: #007020;">self</span>, ifr, SIOC, mutate <span style="color: #303030;">=</span> <span style="color: #007020;">True</span>):
<span style="color: green; font-weight: bold;">try</span>:
fcntl<span style="color: #303030;">.</span>ioctl(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>skt, SIOC, ifr, mutate)
<span style="color: green; font-weight: bold;">except</span> <span style="color: #f00000; font-weight: bold;">IOError</span> <span style="color: green; font-weight: bold;">as</span> ioException:
<span style="color: green; font-weight: bold;">if</span> ioException<span style="color: #303030;">.</span>errno <span style="color: #303030;">==</span> <span style="color: #0000d0; font-weight: bold;">99</span>:
<span style="color: green; font-weight: bold;">pass</span>
<span style="color: green; font-weight: bold;">else</span>:
<span style="color: green; font-weight: bold;">raise</span> ioException
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__getSimple</span>(<span style="color: #007020;">self</span>, ioctl, elem):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, ioctl)
elem <span style="color: #303030;">=</span> elem<span style="color: #303030;">.</span>split(<span style="background-color: #fff0f0;">'.'</span>)
tmpVal <span style="color: #303030;">=</span> ifr
<span style="color: green; font-weight: bold;">for</span> curElem <span style="color: black; font-weight: bold;">in</span> elem:
tmpVal <span style="color: #303030;">=</span> <span style="color: #007020;">getattr</span>(tmpVal, curElem)
<span style="color: green; font-weight: bold;">return</span> tmpVal
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__setSimple</span>(<span style="color: #007020;">self</span>,ioctl, elem, val):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
elem <span style="color: #303030;">=</span> elem<span style="color: #303030;">.</span>split(<span style="background-color: #fff0f0;">'.'</span>)
tmpVal <span style="color: #303030;">=</span> ifr
<span style="color: green; font-weight: bold;">for</span> curElem <span style="color: black; font-weight: bold;">in</span> elem[:<span style="color: #303030;">-</span><span style="color: #0000d0; font-weight: bold;">1</span>]:
tmpVal <span style="color: #303030;">=</span> <span style="color: #007020;">getattr</span>(tmpVal, curElem)
<span style="color: #007020;">setattr</span>(tmpVal, elem[<span style="color: #303030;">-</span><span style="color: #0000d0; font-weight: bold;">1</span>], val)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, ioctl)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">index</span>(<span style="color: #007020;">self</span>):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCGIFINDEX)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_index <span style="color: #303030;">=</span> ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_ifindex
<span style="color: green; font-weight: bold;">return</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>_index
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">name</span>(<span style="color: #007020;">self</span>):
ifr <span style="color: #303030;">=</span> ifreq()
ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_ifindex <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>_index
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCGIFNAME)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name <span style="color: #303030;">=</span> ifr<span style="color: #303030;">.</span>ifr_name
<span style="color: green; font-weight: bold;">return</span> string_at(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name)
<span style="color: #505050; font-weight: bold;">@name.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">name</span>(<span style="color: #007020;">self</span>, val):
ifr <span style="color: #303030;">=</span> ifreq()
ifr<span style="color: #303030;">.</span>ifr_name <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name
ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_newname <span style="color: #303030;">=</span> val
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCGIFNAME)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_name <span style="color: #303030;">=</span> val
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">flags</span>(<span style="color: #007020;">self</span>):
<span style="color: green; font-weight: bold;">return</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__getSimple(SIOCGIFFLAGS, <span style="background-color: #fff0f0;">'data.ifr_flags'</span>)
<span style="color: #505050; font-weight: bold;">@flags.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">flags</span>(<span style="color: #007020;">self</span>, val):
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__setSimple(SIOCSIFFLAGS, <span style="background-color: #fff0f0;">'data.ifr_flags'</span>, val)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">ifqlen</span>(<span style="color: #007020;">self</span>):
<span style="color: green; font-weight: bold;">return</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__getSimple(SIOCGIFTXQLEN, <span style="background-color: #fff0f0;">'data.ifr_ifqlen'</span>)
<span style="color: #505050; font-weight: bold;">@ifqlen.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">ifqlen</span>(<span style="color: #007020;">self</span>, val):
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__setSimple(SIOCSIFTXQLEN, <span style="background-color: #fff0f0;">'data.ifr_ifqlen'</span>, val)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">metric</span>(<span style="color: #007020;">self</span>):
<span style="color: green; font-weight: bold;">return</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__getSimple(SIOCGIFMETRIC, <span style="background-color: #fff0f0;">'data.ifr_metric'</span>)
<span style="color: #505050; font-weight: bold;">@metric.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">metric</span>(<span style="color: #007020;">self</span>, val):
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__getSimple(SIOCSIFMETRIC, <span style="background-color: #fff0f0;">'data.ifr_metric'</span>, val)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">mtu</span>(<span style="color: #007020;">self</span>):
<span style="color: green; font-weight: bold;">return</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__getSimple(SIOCGIFMTU, <span style="background-color: #fff0f0;">'data.ifr_mtu'</span>)
<span style="color: #505050; font-weight: bold;">@mtu.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">mtu</span>(<span style="color: #007020;">self</span>, val):
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__getSimple(SIOCSIFMTU, <span style="background-color: #fff0f0;">'data.ifr_mtu'</span>, val)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">hwaddr</span>(<span style="color: #007020;">self</span>):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCGIFHWADDR)
hw <span style="color: #303030;">=</span> ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_hwaddr<span style="color: #303030;">.</span>gen<span style="color: #303030;">.</span>sa_data
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_hwaddr <span style="color: #303030;">=</span> <span style="background-color: #fff0f0;">''</span>
<span style="color: green; font-weight: bold;">for</span> i <span style="color: black; font-weight: bold;">in</span> hw[:IFHWADDRLEN] :
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_hwaddr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>_hwaddr <span style="color: #303030;">+</span> <span style="background-color: #fff0f0;">'</span><span style="background-color: #e0e0e0;">%.2X</span><span style="background-color: #fff0f0;">:'</span> <span style="color: #303030;">%</span> i
<span style="color: green; font-weight: bold;">return</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>_hwaddr
<span style="color: #505050; font-weight: bold;">@hwaddr.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">hwaddr</span>(<span style="color: #007020;">self</span>, val):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_hwaddr<span style="color: #303030;">.</span>sin_addr<span style="color: #303030;">.</span>s_addr <span style="color: #303030;">=</span> val
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCSIFHWADDR)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">addr</span>(<span style="color: #007020;">self</span>):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCGIFADDR)
<span style="color: green; font-weight: bold;">return</span> ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_addr
<span style="color: #505050; font-weight: bold;">@addr.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">addr</span>(<span style="color: #007020;">self</span>, val):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_addr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__sockaddrFromTuple(val)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCSIFADDR, <span style="color: #007020;">False</span>)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">broadaddr</span>(<span style="color: #007020;">self</span>):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCGIFBRDADDR)
<span style="color: green; font-weight: bold;">return</span> ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_broadaddr
<span style="color: #505050; font-weight: bold;">@broadaddr.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">broadaddr</span>(<span style="color: #007020;">self</span>, val):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_broadaddr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__sockaddrFromTuple(val)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCSIFBRDADDR)
<span style="color: #505050; font-weight: bold;">@property</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">netmask</span>(<span style="color: #007020;">self</span>):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCGIFNETMASK)
<span style="color: green; font-weight: bold;">return</span> ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_netmask
<span style="color: #505050; font-weight: bold;">@netmask.setter</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">netmask</span>(<span style="color: #007020;">self</span>, val):
ifr <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__newIfreqWithName()
ifr<span style="color: #303030;">.</span>data<span style="color: #303030;">.</span>ifr_netmask <span style="color: #303030;">=</span> <span style="color: #007020;">self</span><span style="color: #303030;">.</span>__sockaddrFromTuple(val)
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__doIoctl(ifr, SIOCSIFNETMASK, <span style="color: #007020;">False</span>)
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__getSinAddr</span>(<span style="color: #007020;">self</span>, sockaddr):
<span style="color: green; font-weight: bold;">if</span> sockaddr<span style="color: #303030;">.</span>gen<span style="color: #303030;">.</span>sa_family <span style="color: #303030;">==</span> socket<span style="color: #303030;">.</span>AF_INET:
<span style="color: green; font-weight: bold;">return</span> sockaddr<span style="color: #303030;">.</span>in4<span style="color: #303030;">.</span>sin_addr<span style="color: #303030;">.</span>s_addr
<span style="color: green; font-weight: bold;">if</span> sockaddr<span style="color: #303030;">.</span>gen<span style="color: #303030;">.</span>sa_family <span style="color: #303030;">==</span> socket<span style="color: #303030;">.</span>AF_INET6:
<span style="color: green; font-weight: bold;">return</span> sockaddr<span style="color: #303030;">.</span>in6<span style="color: #303030;">.</span>sin6_addr<span style="color: #303030;">.</span>in6_u
<span style="color: green; font-weight: bold;">return</span> <span style="color: #0000d0; font-weight: bold;">0</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__sockaddrFromTuple</span>(<span style="color: #007020;">self</span>, inVal):
<span style="color: green; font-weight: bold;">if</span> inVal[<span style="color: #0000d0; font-weight: bold;">0</span>] <span style="color: #303030;">==</span> socket<span style="color: #303030;">.</span>AF_INET:
sin4 <span style="color: #303030;">=</span> sockaddr()
sin4<span style="color: #303030;">.</span>in4<span style="color: #303030;">.</span>sin_family <span style="color: #303030;">=</span> inVal[<span style="color: #0000d0; font-weight: bold;">0</span>]
sin4<span style="color: #303030;">.</span>in4<span style="color: #303030;">.</span>sin_addr<span style="color: #303030;">.</span>s_addr <span style="color: #303030;">=</span> struct<span style="color: #303030;">.</span>unpack(<span style="background-color: #fff0f0;">'<L'</span>, socket<span style="color: #303030;">.</span>inet_pton(
inVal[<span style="color: #0000d0; font-weight: bold;">0</span>],
inVal[<span style="color: #0000d0; font-weight: bold;">1</span>]))[<span style="color: #0000d0; font-weight: bold;">0</span>]
<span style="color: green; font-weight: bold;">return</span> sin4
<span style="color: green; font-weight: bold;">elif</span> inVal[<span style="color: #0000d0; font-weight: bold;">0</span>] <span style="color: #303030;">==</span> socket<span style="color: #303030;">.</span>AF_INET6:
sin6 <span style="color: #303030;">=</span> sockaddr()
sin6<span style="color: #303030;">.</span>in6<span style="color: #303030;">.</span>sin6_family <span style="color: #303030;">=</span> inVal[<span style="color: #0000d0; font-weight: bold;">0</span>]
sin6<span style="color: #303030;">.</span>in6<span style="color: #303030;">.</span>sin6_addr<span style="color: #303030;">.</span>in6_u <span style="color: #303030;">=</span> hexlify(socket<span style="color: #303030;">.</span>inet_pton(
inVal[<span style="color: #0000d0; font-weight: bold;">0</span>],
inVal[<span style="color: #0000d0; font-weight: bold;">1</span>]))
<span style="color: green; font-weight: bold;">return</span> sin6
<span style="color: green; font-weight: bold;">raise</span> <span style="background-color: #fff0f0;">"Input must be tuple like (AF_INET, '127.0.0.1')"</span>
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__sockaddrToStr</span>(<span style="color: #007020;">self</span>, sockaddr):
<span style="color: green; font-weight: bold;">if</span> sockaddr<span style="color: #303030;">.</span>gen<span style="color: #303030;">.</span>sa_family <span style="color: #303030;">==</span> <span style="color: #0000d0; font-weight: bold;">0</span>:
<span style="color: green; font-weight: bold;">return</span> <span style="background-color: #fff0f0;">'None'</span>
p <span style="color: #303030;">=</span> struct<span style="color: #303030;">.</span>pack(<span style="background-color: #fff0f0;">'<L'</span>,<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__getSinAddr(sockaddr))
<span style="color: green; font-weight: bold;">return</span> socket<span style="color: #303030;">.</span>inet_ntop(sockaddr<span style="color: #303030;">.</span>gen<span style="color: #303030;">.</span>sa_family, p)
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">__str__</span>(<span style="color: #007020;">self</span>):
x <span style="color: #303030;">=</span> <span style="background-color: #fff0f0;">''</span>
x <span style="color: #303030;">=</span> x <span style="color: #303030;">+</span> <span style="background-color: #fff0f0;">'Iface: </span><span style="background-color: #e0e0e0;">%s</span><span style="background-color: #fff0f0;"> Index: </span><span style="background-color: #e0e0e0;">%d</span><span style="background-color: #fff0f0;"> HWAddr: </span><span style="background-color: #e0e0e0;">%s</span><span style="background-color: #fff0f0; color: #606060; font-weight: bold;">\n</span><span style="background-color: #fff0f0;">'</span> <span style="color: #303030;">%</span> (
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>name,
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>_index,
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>hwaddr )
x <span style="color: #303030;">=</span> x <span style="color: #303030;">+</span> <span style="background-color: #fff0f0;">'Addr:</span><span style="background-color: #e0e0e0;">%s</span><span style="background-color: #fff0f0;"> Bcast:</span><span style="background-color: #e0e0e0;">%s</span><span style="background-color: #fff0f0;"> Mask:</span><span style="background-color: #e0e0e0;">%s</span><span style="background-color: #fff0f0; color: #606060; font-weight: bold;">\n</span><span style="background-color: #fff0f0;">'</span> <span style="color: #303030;">%</span> (
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__sockaddrToStr(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>addr),
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__sockaddrToStr(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>broadaddr),
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>__sockaddrToStr(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>netmask) )
x <span style="color: #303030;">=</span> x <span style="color: #303030;">+</span> <span style="background-color: #fff0f0;">'MTU: </span><span style="background-color: #e0e0e0;">%d</span><span style="background-color: #fff0f0;"> Metric: </span><span style="background-color: #e0e0e0;">%d</span><span style="background-color: #fff0f0;"> Txqueuelen: </span><span style="background-color: #e0e0e0;">%d</span><span style="background-color: #fff0f0; color: #606060; font-weight: bold;">\n</span><span style="background-color: #fff0f0;">'</span> <span style="color: #303030;">%</span> (
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>mtu,
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>metric <span style="color: #303030;">+</span> <span style="color: #0000d0; font-weight: bold;">1</span>,
<span style="color: #007020;">self</span><span style="color: #303030;">.</span>ifqlen)
x <span style="color: #303030;">=</span> x <span style="color: #303030;">+</span> <span style="background-color: #fff0f0;">'Flags:</span><span style="background-color: #fff0f0; color: #606060; font-weight: bold;">\n</span><span style="background-color: #e0e0e0;">%s</span><span style="background-color: #fff0f0;">'</span> <span style="color: #303030;">%</span> flagsToStr(<span style="color: #007020;">self</span><span style="color: #303030;">.</span>flags)
<span style="color: green; font-weight: bold;">return</span> x
<span style="color: green; font-weight: bold;">def</span> <span style="color: #0060b0; font-weight: bold;">getIfaces</span>():
<span style="color: #d04020;">"""</span>
<span style="color: #d04020;"> Returns a list of all available interfaces.</span>
<span style="color: #d04020;"> """</span>
ret <span style="color: #303030;">=</span> []
i <span style="color: #303030;">=</span> <span style="color: #0000d0; font-weight: bold;">1</span>
<span style="color: green; font-weight: bold;">while</span> <span style="color: #007020;">True</span>:
<span style="color: green; font-weight: bold;">try</span>:
ifa <span style="color: #303030;">=</span> Interface(idx<span style="color: #303030;">=</span>i)
ret<span style="color: #303030;">.</span>append(ifa)
i <span style="color: #303030;">=</span> i<span style="color: #303030;">+</span><span style="color: #0000d0; font-weight: bold;">1</span>
<span style="color: green; font-weight: bold;">except</span>:
<span style="color: green; font-weight: bold;">return</span> ret
<span style="color: green; font-weight: bold;">if</span> __name__ <span style="color: #303030;">==</span> <span style="background-color: #fff0f0;">'__main__'</span>:
<span style="color: green; font-weight: bold;">print</span> <span style="background-color: #fff0f0;">'All your interfaces'</span>
allIfaces <span style="color: #303030;">=</span> getIfaces()
<span style="color: green; font-weight: bold;">for</span> iface <span style="color: black; font-weight: bold;">in</span> allIfaces:
<span style="color: green; font-weight: bold;">print</span> iface
iff <span style="color: #303030;">=</span> Interface(name<span style="color: #303030;">=</span><span style="background-color: #fff0f0;">'eth0'</span>)
iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">=</span> iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">&</span> <span style="color: #303030;">~</span>IFF_UP
<span style="color: green; font-weight: bold;">print</span> iff
iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">=</span> iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">|</span> IFF_UP <span style="color: #303030;">|</span> IFF_RUNNING
iff<span style="color: #303030;">.</span>addr <span style="color: #303030;">=</span> (socket<span style="color: #303030;">.</span>AF_INET, sys<span style="color: #303030;">.</span>argv[<span style="color: #0000d0; font-weight: bold;">1</span>])
<span style="color: green; font-weight: bold;">print</span> iff
iff<span style="color: #303030;">.</span>netmask <span style="color: #303030;">=</span> (socket<span style="color: #303030;">.</span>AF_INET, sys<span style="color: #303030;">.</span>argv[<span style="color: #0000d0; font-weight: bold;">2</span>])
iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">=</span> iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">|</span> IFF_UP
<span style="color: green; font-weight: bold;">print</span> iff
iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">=</span> iff<span style="color: #303030;">.</span>flags <span style="color: #303030;">&</span> <span style="color: #303030;">~</span>IFF_UP
<span style="color: green; font-weight: bold;">print</span> iff</pre>
</span></div>
<div>
<br /></div>
<div>
I wrapped this code in a package and named it pyiface. Available to you now here: <a href="https://github.com/bat-serjo/PyIface">https://github.com/bat-serjo/PyIface</a></div>
<div>
<br /></div>
<div>
Soon I will make this package available as PyPI.</div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0tag:blogger.com,1999:blog-1891445128304677692.post-31071007338147082412007-06-22T11:54:00.000-07:002007-06-22T12:31:45.731-07:00Burglars cops treasures and python, this time we got it all.So we got these burglars who have this map that shows where the treasures are. Hmmm right, this is clear. Then we got these cops that want to stop the burglars. Now the map looks something like this.<br /><br />4 3 3 3<br />3 -1 2<br />-1 -1 -1<br />3 12 7<br /><br />The first row contains some stupid numbers showing different things, because the solution of this problem is supposed to be written in C, but hey fuck C and it's stupid libraries ( this from a guy who makes a living like a professional C programmer - me ) The most important number from the first row is the second one which shows the time ticks the burglars have before the cops show up. The rest of the numbers say what's the array height and width (useless in python and in fact in C if you take the time to code is right).<br /><br />Now the rules are simple. The burglars have the map so they know where the treasures are. Each treasure is represented by a positive number showing the amount of money the gain when they reach it. The cells with negative numbers does not contain treasures and they cost money to be dug. Each cell is dug for one tick time. The cops will come in K ticks of time where K is the second number in the first row. In order to get to a cell the burglars must dug out all the cell in it's column prior to it. The burglars may start from any column and stop digging within the column whenever they want.<br /><br /> Make a program that finds the maximum amount of money the burglars can gain without being caught from the cops.<br /><br /> He he, me lazy so code in python.<br /><br /><pre class="hl"><span class="slc">#!/usr/bin/env python</span><br /><span class="kwa">import</span> os<span class="sym">,</span> sys<br />K <span class="sym">=</span> <span class="num">0</span> <span class="slc"># edinici vreme, broi kletki koito mogat da izkopaqt</span><br /><br /><span class="kwa">def</span> <span class="kwd">GetData</span><span class="sym">(</span><span class="kwb">file</span><span class="sym">=</span><span class="str">''</span><span class="sym">):</span><br /> f <span class="sym">=</span> <span class="kwb">open</span><span class="sym">(</span><span class="kwb">file</span><span class="sym">,</span> <span class="str">'r'</span><span class="sym">)</span><br /> data <span class="sym">=</span> f<span class="sym">.</span><span class="kwd">readlines</span><span class="sym">()</span><br /> f<span class="sym">.</span><span class="kwd">close</span><span class="sym">()</span><br /> params <span class="sym">= []</span><br /><br /> <span class="kwa">for</span> i <span class="kwa">in</span> data<span class="sym">[</span><span class="num">0</span><span class="sym">].</span><span class="kwd">split</span><span class="sym">():</span><br /> params<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span><span class="kwb">int</span><span class="sym">(</span>i<span class="sym">))</span><br /><br /> data <span class="sym">=</span> data<span class="sym">[</span><span class="num">1</span><span class="sym">:</span>data<span class="sym">.</span><span class="kwd">__len__</span><span class="sym">()]</span><br /> array <span class="sym">= []</span><br /> <span class="kwa">for</span> d <span class="kwa">in</span> data<span class="sym">:</span><br /> array<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span>d<span class="sym">.</span><span class="kwd">split</span><span class="sym">())</span><br /><br /> <span class="kwa">return</span> <span class="sym">(</span>params<span class="sym">,</span> array<span class="sym">)</span><br /><br /><span class="kwa">class</span> PreData<span class="sym">:</span><br /> <span class="kwa">def</span> <span class="kwd">__init__</span><span class="sym">(</span>self<span class="sym">,</span> t<span class="sym">=</span><span class="num">0</span><span class="sym">,</span> m<span class="sym">=</span><span class="num">0</span><span class="sym">):</span><br /> self<span class="sym">.</span>time <span class="sym">=</span> t<br /> self<span class="sym">.</span>money <span class="sym">=</span> m<br /> <span class="kwa">def</span> <span class="kwd">__repr__</span><span class="sym">(</span>self<span class="sym">):</span><br /> <span class="kwa">return</span> <span class="str">'Time: '</span><span class="sym">+</span><span class="kwb">str</span><span class="sym">(</span>self<span class="sym">.</span>time<span class="sym">)+</span><span class="str">' Money: '</span><span class="sym">+</span><span class="kwb">str</span><span class="sym">(</span>self<span class="sym">.</span>money<span class="sym">)</span><br /> <span class="kwa">def</span> <span class="kwd">__str__</span><span class="sym">(</span>self<span class="sym">):</span><br /> <span class="kwa">return</span> <span class="str">'Time: '</span><span class="sym">+</span><span class="kwb">str</span><span class="sym">(</span>self<span class="sym">.</span>time<span class="sym">)+</span><span class="str">' Money: '</span><span class="sym">+</span><span class="kwb">str</span><span class="sym">(</span>self<span class="sym">.</span>money<span class="sym">)</span><br /><br /><span class="kwa">def</span> <span class="kwd">GetPreData</span><span class="sym">():</span><br /> columns <span class="sym">= []</span><br /> tmpK <span class="sym">=</span> <span class="num">0</span><br /> tmpAward <span class="sym">=</span> <span class="num">0</span><br /> r <span class="sym">=</span> <span class="num">0</span><br /> c <span class="sym">=</span> <span class="num">0</span><br /> <span class="kwa">global</span> K<br /><br /><br /> <span class="sym">((</span>N<span class="sym">,</span>K<span class="sym">,</span>L<span class="sym">,</span>D<span class="sym">),</span> data<span class="sym">) =</span> <span class="kwd">GetData</span><span class="sym">(</span><span class="str">'input'</span><span class="sym">)</span><br /> <span class="kwa">for</span> c <span class="kwa">in</span> <span class="kwb">xrange</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> L<span class="sym">):</span><br /> treasures <span class="sym">= []</span><br /> tmpC <span class="sym">=</span> <span class="kwd">PreData</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">)</span><br /><br /> <span class="kwa">for</span> r <span class="kwa">in</span> <span class="kwb">xrange</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> D<span class="sym">):</span><br /> tmpC<span class="sym">.</span>time <span class="sym">=</span> tmpC<span class="sym">.</span>time <span class="sym">+</span> <span class="num">1</span><br /> tmpC<span class="sym">.</span>money <span class="sym">=</span> tmpC<span class="sym">.</span>money <span class="sym">+</span> <span class="kwb">int</span><span class="sym">(</span>data<span class="sym">[</span>r<span class="sym">][</span>c<span class="sym">])</span><br /><br /> <span class="kwa">if</span> <span class="kwb">int</span><span class="sym">(</span>data<span class="sym">[</span>r<span class="sym">][</span>c<span class="sym">]) ></span> <span class="num">0</span><span class="sym">:</span><br /> <span class="kwa">if</span> tmpC<span class="sym">.</span>time <span class="sym">></span> <span class="kwb">int</span><span class="sym">(</span>K<span class="sym">):</span><br /> <span class="kwa">break</span><br /> <span class="kwa">if</span> tmpC<span class="sym">.</span>money <span class="sym">></span> <span class="num">0</span><span class="sym">:</span><br /> treasures<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span><span class="kwd">PreData</span><span class="sym">(</span>tmpC<span class="sym">.</span>time<span class="sym">,</span> tmpC<span class="sym">.</span>money<span class="sym">))</span><br /> tmpC<span class="sym">.</span>time <span class="sym">=</span> <span class="num">0</span><br /> tmpC<span class="sym">.</span>money <span class="sym">=</span> <span class="num">0</span><br /><br /> columns<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span>treasures<span class="sym">)</span><br /> <span class="kwa">return</span> columns<br /><br />maxMoney<span class="sym">=</span><span class="num">0</span><br /><span class="kwa">def</span> <span class="kwd">Recursion</span><span class="sym">(</span>cols<span class="sym">=[],</span> c<span class="sym">=</span><span class="num">0</span><span class="sym">,</span> r<span class="sym">=</span><span class="num">0</span><span class="sym">,</span> money<span class="sym">=</span><span class="num">0</span><span class="sym">,</span> time<span class="sym">=</span><span class="num">0</span><span class="sym">):</span><br /> <span class="kwa">global</span> maxMoney<br /><br /> <span class="kwa">if</span> c <span class="sym">>=</span> cols<span class="sym">.</span><span class="kwd">__len__</span><span class="sym">():</span><br /> <span class="kwa">return</span><br /> <span class="kwa">if</span> r <span class="sym">>=</span> cols<span class="sym">[</span>c<span class="sym">].</span><span class="kwd">__len__</span><span class="sym">():</span><br /> <span class="kwa">return</span><br /> <span class="kwa">if</span> <span class="sym">(</span>cols<span class="sym">[</span>c<span class="sym">][</span>r<span class="sym">].</span>time<span class="sym">+</span>time<span class="sym">) ></span> K<span class="sym">:</span><br /> <span class="kwa">return</span><br /><br /> cmoney <span class="sym">=</span> money <span class="sym">+</span> cols<span class="sym">[</span>c<span class="sym">][</span>r<span class="sym">].</span>money<br /> ctime <span class="sym">=</span> time <span class="sym">+</span> cols<span class="sym">[</span>c<span class="sym">][</span>r<span class="sym">].</span>time<br /> <span class="kwa">if</span> maxMoney <span class="sym"><</span> cmoney<span class="sym">:</span><br /> maxMoney <span class="sym">=</span> cmoney<br /><br /> <span class="kwd">Recursion</span><span class="sym">(</span>cols<span class="sym">,</span> c <span class="sym">+</span> <span class="num">1</span><span class="sym">,</span> r<span class="sym">,</span> cmoney <span class="sym">,</span> ctime <span class="sym">)</span><br /> <span class="kwd">Recursion</span><span class="sym">(</span>cols<span class="sym">,</span> c<span class="sym">,</span> r <span class="sym">+</span> <span class="num">1</span><span class="sym">,</span> cmoney <span class="sym">,</span> ctime <span class="sym">)</span><br /><br />cols <span class="sym">=</span> <span class="kwd">GetPreData</span><span class="sym">()</span><br /><span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> cols<span class="sym">.</span><span class="kwd">__len__</span><span class="sym">()):</span><br /> <span class="kwd">Recursion</span><span class="sym">(</span>cols<span class="sym">,</span> i<span class="sym">,</span> <span class="num">0</span><span class="sym">,</span> <span class="num">0</span><span class="sym">,</span> <span class="num">0</span><span class="sym">)</span><br /><span class="kwa">print</span> maxMoney<br /></pre><br /><br /><br />Now test it!<br />serj@tokamak ~> cat input<br />4 3 3 3<br />3 -1 2<br />-1 -1 -1<br />3 12 7<br />serj@tokamak ~> ./stamen.py<br />10<br /><br />Now test it again.<br />serj@tokamak ~> cat input; ./stamen.py<br />4 3 3 3<br />3 -1 24<br />-1 -1 -1<br />3 12 7<br />30<br /><br />Yes it wErks! :-DAnonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0tag:blogger.com,1999:blog-1891445128304677692.post-26437088329640003392007-05-14T12:14:00.000-07:002007-05-14T12:39:59.845-07:00Ok i confess i'm lazy and i like python so what good might come out of this. Yeess, oh yes an automated sudoku-python-solver. The ultimate lame implementation of a sudoku solving algorithm in python, done in an hour or two it's not capable YET of solving sudokus with more than one solution but it'll do the job for that thick whole-year-list-a-day-sudoku-calendar. So here it goes, like this:<br /><br /><pre class="hl"><span class="line"> 1 </span><span class="slc">#!/usr/bin/env python</span><br /><span class="line"> 2 </span><br /><span class="line"> 3 </span><span class="kwa">class</span> box<span class="sym">:</span><br /><span class="line"> 4 </span> <span class="slc">#value 0 means empty</span><br /><span class="line"> 5 </span> <span class="slc">#numP</span><br /><span class="line"> 6 </span> <span class="kwa">pass</span><br /><span class="line"> 7 </span><br /><span class="line"> 8 </span><br /><span class="line"> 9 </span><span class="kwa">class</span> Board<span class="sym">:</span><br /><span class="line"> 10 </span> <span class="kwa">def</span> <span class="kwd">__init__</span><span class="sym">(</span>self<span class="sym">,</span> rows<span class="sym">=</span><span class="num">9</span><span class="sym">,</span> cols<span class="sym">=</span><span class="num">9</span><span class="sym">):</span><br /><span class="line"> 11 </span> self<span class="sym">.</span>rows <span class="sym">=</span> rows<br /><span class="line"> 12 </span> self<span class="sym">.</span>cols <span class="sym">=</span> cols<br /><span class="line"> 13 </span> <span class="kwa">print</span> av<br /><span class="line"> 14 </span> self<span class="sym">.</span>board <span class="sym">= []</span><br /><span class="line"> 15 </span> <span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> rows<span class="sym">):</span><br /><span class="line"> 16 </span> self<span class="sym">.</span>board<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span> self<span class="sym">.</span><span class="kwd">MakeRow</span><span class="sym">(</span>size<span class="sym">=</span>cols<span class="sym">) )</span><br /><span class="line"> 17 </span><br /><span class="line"> 18 </span> <span class="kwa">def</span> <span class="kwd">MakeRow</span><span class="sym">(</span>self<span class="sym">,</span> size<span class="sym">=</span><span class="num">9</span><span class="sym">):</span><br /><span class="line"> 19 </span> r <span class="sym">= []</span><br /><span class="line"> 20 </span> <span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> size<span class="sym">):</span><br /><span class="line"> 21 </span> r<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span> <span class="kwd">box</span><span class="sym">() )</span><br /><span class="line"> 22 </span><br /><span class="line"> 23 </span> <span class="kwa">return</span> r<br /><span class="line"> 24 </span><br /><span class="line"> 25 </span> <span class="kwa">def</span> <span class="kwd">InitBoard</span><span class="sym">(</span>self<span class="sym">,</span> data<span class="sym">=[]):</span><br /><span class="line"> 26 </span> rw <span class="sym">=</span> <span class="num">0</span><br /><span class="line"> 27 </span> cl <span class="sym">=</span> <span class="num">0</span><br /><span class="line"> 28 </span><br /><span class="line"> 29 </span> <span class="kwa">for</span> e <span class="kwa">in</span> data<span class="sym">:</span><br /><span class="line"> 30 </span> self<span class="sym">.</span>board<span class="sym">[</span>rw<span class="sym">][</span>cl<span class="sym">].</span>value <span class="sym">=</span> e<br /><span class="line"> 31 </span> cl <span class="sym">=</span> cl <span class="sym">+</span> <span class="num">1</span><br /><span class="line"> 32 </span><br /><span class="line"> 33 </span> <span class="kwa">if</span> cl <span class="sym">==</span> self<span class="sym">.</span>cols<span class="sym">:</span><br /><span class="line"> 34 </span> cl <span class="sym">=</span> <span class="num">0</span><span class="sym">;</span><br /><span class="line"> 35 </span> rw <span class="sym">=</span> rw <span class="sym">+</span> <span class="num">1</span><br /><span class="line"> 36 </span><br /><span class="line"> 37 </span> <span class="kwa">def</span> <span class="kwd">GetRCInfo</span><span class="sym">(</span>self<span class="sym">,</span> row<span class="sym">,</span> col<span class="sym">):</span><br /><span class="line"> 38 </span> r <span class="sym">= []</span><br /><span class="line"> 39 </span> c <span class="sym">= []</span><br /><span class="line"> 40 </span> sq <span class="sym">= []</span><br /><span class="line"> 41 </span><br /><span class="line"> 42 </span> <span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> self<span class="sym">.</span>cols<span class="sym">):</span><br /><span class="line"> 43 </span> r<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span> self<span class="sym">.</span>board<span class="sym">[</span>row<span class="sym">][</span>i<span class="sym">].</span>value <span class="sym">)</span><br /><span class="line"> 44 </span><br /><span class="line"> 45 </span> <span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> self<span class="sym">.</span>rows<span class="sym">):</span><br /><span class="line"> 46 </span> c<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span> self<span class="sym">.</span>board<span class="sym">[</span>i<span class="sym">][</span>col<span class="sym">].</span>value <span class="sym">)</span><br /><span class="line"> 47 </span><br /><span class="line"> 48 </span> br <span class="sym">= (</span>row<span class="sym">/</span><span class="num">3</span><span class="sym">)*</span><span class="num">3</span><br /><span class="line"> 49 </span> bc <span class="sym">= (</span>col<span class="sym">/</span><span class="num">3</span><span class="sym">)*</span><span class="num">3</span><br /><span class="line"> 50 </span><br /><span class="line"> 51 </span> <span class="kwa">for</span> sqR <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span>br<span class="sym">,</span> br<span class="sym">+</span><span class="num">3</span><span class="sym">):</span><br /><span class="line"> 52 </span> <span class="kwa">for</span> sqC <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span>bc<span class="sym">,</span> bc<span class="sym">+</span><span class="num">3</span><span class="sym">):</span><br /><span class="line"> 53 </span> sq<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span> self<span class="sym">.</span>board<span class="sym">[</span>sqR<span class="sym">][</span>sqC<span class="sym">].</span>value <span class="sym">)</span><br /><span class="line"> 54 </span><br /><span class="line"> 55 </span> all <span class="sym">= []</span><br /><span class="line"> 56 </span><br /><span class="line"> 57 </span> <span class="kwa">for</span> i <span class="kwa">in</span> r<span class="sym">:</span><br /><span class="line"> 58 </span> <span class="kwa">if</span> all<span class="sym">.</span><span class="kwd">__contains__</span><span class="sym">(</span>i<span class="sym">):</span><br /><span class="line"> 59 </span> <span class="kwa">continue</span><br /><span class="line"> 60 </span> all<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span>i<span class="sym">)</span><br /><span class="line"> 61 </span><br /><span class="line"> 62 </span> <span class="kwa">for</span> i <span class="kwa">in</span> c<span class="sym">:</span><br /><span class="line"> 63 </span> <span class="kwa">if</span> all<span class="sym">.</span><span class="kwd">__contains__</span><span class="sym">(</span>i<span class="sym">):</span><br /><span class="line"> 64 </span> <span class="kwa">continue</span><br /><span class="line"> 65 </span> all<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span>i<span class="sym">)</span><br /><span class="line"> 66 </span><br /><span class="line"> 67 </span> <span class="kwa">for</span> i <span class="kwa">in</span> sq<span class="sym">:</span><br /><span class="line"> 68 </span> <span class="kwa">if</span> all<span class="sym">.</span><span class="kwd">__contains__</span><span class="sym">(</span>i<span class="sym">):</span><br /><span class="line"> 69 </span> <span class="kwa">continue</span><br /><span class="line"> 70 </span> all<span class="sym">.</span><span class="kwd">append</span><span class="sym">(</span>i<span class="sym">)</span><br /><span class="line"> 71 </span><br /><span class="line"> 72 </span> all<span class="sym">.</span><span class="kwd">sort</span><span class="sym">()</span><br /><span class="line"> 73 </span> all<span class="sym">.</span><span class="kwd">remove</span><span class="sym">(</span><span class="num">0</span><span class="sym">)</span><br /><span class="line"> 74 </span><br /><span class="line"> 75 </span> left <span class="sym">= [</span><span class="num">1</span><span class="sym">,</span><span class="num">2</span><span class="sym">,</span><span class="num">3</span><span class="sym">,</span><span class="num">4</span><span class="sym">,</span><span class="num">5</span><span class="sym">,</span><span class="num">6</span><span class="sym">,</span><span class="num">7</span><span class="sym">,</span><span class="num">8</span><span class="sym">,</span><span class="num">9</span><span class="sym">]</span><br /><span class="line"> 76 </span> <span class="kwa">for</span> i <span class="kwa">in</span> all<span class="sym">:</span><br /><span class="line"> 77 </span> left<span class="sym">.</span><span class="kwd">remove</span><span class="sym">(</span>i<span class="sym">)</span><br /><span class="line"> 78 </span><br /><span class="line"> 79 </span> <span class="kwa">return</span> left<br /><span class="line"> 80 </span><br /><span class="line"> 81 </span> <span class="kwa">def</span> <span class="kwd">PrintBoard</span><span class="sym">(</span>self<span class="sym">):</span><br /><span class="line"> 82 </span> <span class="kwa">for</span> rw <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span>self<span class="sym">.</span>rows<span class="sym">):</span><br /><span class="line"> 83 </span> <span class="kwa">for</span> cl <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> self<span class="sym">.</span>cols<span class="sym">):</span><br /><span class="line"> 84 </span> <span class="kwa">print</span> self<span class="sym">.</span>board<span class="sym">[</span>rw<span class="sym">][</span>cl<span class="sym">].</span>value<span class="sym">,</span> <span class="str">" "</span><span class="sym">,</span><br /><span class="line"> 85 </span> <span class="kwa">print</span><br /><span class="line"> 86 </span> <span class="kwa">print</span><br /><span class="line"> 87 </span><br /><span class="line"> 88 </span><br /><span class="line"> 89 </span> <span class="kwa">def</span> <span class="kwd">Solve</span><span class="sym">(</span>self<span class="sym">):</span><br /><span class="line"> 90 </span> done <span class="sym">=</span> <span class="kwa">False</span><br /><span class="line"> 91 </span> <span class="kwa">while</span> done <span class="sym">!=</span> <span class="kwa">True</span><span class="sym">:</span><br /><span class="line"> 92 </span><br /><span class="line"> 93 </span> <span class="kwa">for</span> r <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> self<span class="sym">.</span>rows<span class="sym">):</span><br /><span class="line"> 94 </span> <span class="kwa">for</span> c <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> self<span class="sym">.</span>cols<span class="sym">):</span><br /><span class="line"> 95 </span> <span class="kwa">if</span> self<span class="sym">.</span>board<span class="sym">[</span>r<span class="sym">][</span>c<span class="sym">].</span>value <span class="sym">==</span> <span class="num">0</span><span class="sym">:</span><br /><span class="line"> 96 </span> av <span class="sym">=</span> self<span class="sym">.</span><span class="kwd">GetRCInfo</span><span class="sym">(</span>r<span class="sym">,</span>c<span class="sym">)</span><br /><span class="line"> 97 </span> <span class="kwa">if</span> av<span class="sym">.</span><span class="kwd">__len__</span><span class="sym">() ==</span> <span class="num">1</span><span class="sym">:</span><br /><span class="line"> 98 </span> self<span class="sym">.</span>board<span class="sym">[</span>r<span class="sym">][</span>c<span class="sym">].</span>value <span class="sym">=</span> av<span class="sym">[</span><span class="num">0</span><span class="sym">]</span><br /><span class="line"> 99 </span> <span class="kwa">print</span> <span class="str">"Adding "</span><span class="sym">,</span> av<span class="sym">,</span> <span class="str">" coords row:"</span><span class="sym">,</span> r<span class="sym">,</span> <span class="str">" col:"</span><span class="sym">,</span> c<br /><span class="line"> 100 </span> self<span class="sym">.</span><span class="kwd">PrintBoard</span><span class="sym">()</span><br /><span class="line"> 101 </span><br /><span class="line"> 102 </span><br /><span class="line"> 103 </span> done <span class="sym">=</span> <span class="kwa">True</span><br /><span class="line"> 104 </span> <span class="kwa">for</span> r <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span>self<span class="sym">.</span>rows<span class="sym">):</span><br /><span class="line"> 105 </span> <span class="kwa">for</span> c <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> self<span class="sym">.</span>cols<span class="sym">):</span><br /><span class="line"> 106 </span> <span class="kwa">if</span> self<span class="sym">.</span>board<span class="sym">[</span>r<span class="sym">][</span>c<span class="sym">].</span>value <span class="sym">==</span> <span class="num">0</span><span class="sym">:</span><br /><span class="line"> 107 </span> done <span class="sym">=</span> <span class="kwa">False</span><br /><span class="line"> 108 </span> <span class="kwa">break</span><br /><span class="line"> 109 </span><br /><span class="line"> 110 </span>b <span class="sym">=</span> <span class="kwd">Board</span><span class="sym">(</span><span class="num">9</span><span class="sym">,</span><span class="num">9</span><span class="sym">)</span><br /><span class="line"> 111 </span>b<span class="sym">.</span><span class="kwd">InitBoard</span><span class="sym">([</span> <span class="num">0</span><span class="sym">,</span><span class="num">6</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">1</span><span class="sym">,</span><span class="num">3</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><br /><span class="line"> 112 </span> <span class="num">0</span><span class="sym">,</span><span class="num">5</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">6</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">9</span><span class="sym">,</span><span class="num">1</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><br /><span class="line"> 113 </span> <span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">5</span><span class="sym">,</span><span class="num">2</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">7</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><br /><span class="line"> 114 </span> <span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">2</span><span class="sym">,</span><span class="num">6</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">7</span><span class="sym">,</span><br /><span class="line"> 115 </span> <span class="num">5</span><span class="sym">,</span><span class="num">4</span><span class="sym">,</span><span class="num">8</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">7</span><span class="sym">,</span><span class="num">2</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><br /><span class="line"> 116 </span> <span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">9</span><span class="sym">,</span><span class="num">1</span><span class="sym">,</span><span class="num">8</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">5</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><br /><span class="line"> 117 </span> <span class="num">6</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">2</span><span class="sym">,</span><br /><span class="line"> 118 </span> <span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">5</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">7</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><br /><span class="line"> 119 </span> <span class="num">9</span><span class="sym">,</span><span class="num">1</span><span class="sym">,</span><span class="num">7</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">0</span><span class="sym">,</span><span class="num">6</span><span class="sym">,</span><span class="num">8</span><br /><span class="line"> 120 </span> <span class="sym">])</span><br /><span class="line"> 121 </span><br /><span class="line"> 122 </span>b<span class="sym">.</span><span class="kwd">PrintBoard</span><span class="sym">()</span><br /><span class="line"> 123 </span><span class="kwa">print</span> b<span class="sym">.</span><span class="kwd">Solve</span><span class="sym">()</span><br /><span class="line"> 124 </span><br /><span class="line"> 125 </span><br /></pre>Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0tag:blogger.com,1999:blog-1891445128304677692.post-42525328220498485972007-04-27T00:43:00.000-07:002007-04-27T00:52:54.660-07:00More on reg exps. Parsing a C or C++ file with regexps in PythonOk, so while i'm on the regexp wave. It's plain dumb but works fine. I know i could have used ctags or smth else, but for the sake of it. Also I googled for an example like this one but found nothing. It's always a good idea to have smth like this i case you need to generate prototypes for a long C file or nomatter what.<br /><br /><pre><br /><a name="line1"> 1</a> <font color="#444444">#!/usr/bin/env python<br /><a name="line2"> 2</a> <br /><a name="line3"> 3</a> </font><font color="a52a2a"><strong>import</strong></font> os, re, sys<br /><a name="line4"> 4</a> <br /><a name="line5"> 5</a> class Cexploder<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font>:<br /><a name="line6"> 6</a> Body = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"{[^{}]*}"</font>, re.DOTALL|re.MULTILINE<font color="4444FF"><strong>)</strong></font><br /><a name="line7"> 7</a> Func = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"(<font color="#77dd77">\w</font>+<font color="#77dd77">\s</font>+)*<font color="#77dd77">\w</font>+<font color="#77dd77">\s</font>*<font color="#77dd77">\(</font>.*?<font color="#77dd77">\)</font>"</font>, re.DOTALL| re.MULTILINE<font color="4444FF"><strong>)</strong></font><br /><a name="line8"> 8</a> MultiLineComment = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"/<font color="#77dd77">\*</font>.*?<font color="#77dd77">\*</font>/"</font>, re.DOTALL|re.MULTILINE<font color="4444FF"><strong>)</strong></font><br /><a name="line9"> 9</a> OneLineComment = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"//.*?<font color="#2040a0">$"</font></font>, re.DOTALL|re.MULTILINE<font color="4444FF"><strong>)</strong></font><br /><a name="line10">10</a> CppDirectives = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"^<font color="#77dd77">\s</font>*#.*?<font color="#2040a0">$"</font></font>, re.DOTALL|re.MULTILINE<font color="4444FF"><strong>)</strong></font><br /><a name="line11">11</a> <font color="#444444">#^\s*#(.*?(\\\n)*)+\n<br /><a name="line12">12</a> <br /><a name="line13">13</a> </font>def __init__<font color="4444FF"><strong>(</strong></font>self, File=<font color="#008000">''</font><font color="4444FF"><strong>)</strong></font>:<br /><a name="line14">14</a> f = <font color="a52a2a"><strong>open</strong></font><font color="4444FF"><strong>(</strong></font>File, <font color="#008000">'r'</font><font color="4444FF"><strong>)</strong></font><br /><a name="line15">15</a> self.data = f.<font color="a52a2a"><strong>read</strong></font><font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line16">16</a> f.<font color="a52a2a"><strong>close</strong></font><font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line17">17</a> <br /><a name="line18">18</a> def GetPrototypes<font color="4444FF"><strong>(</strong></font>self<font color="4444FF"><strong>)</strong></font>:<br /><a name="line19">19</a> FuncList = <font color="4444FF"><strong>[</strong></font><font color="4444FF"><strong>]</strong></font><br /><a name="line20">20</a> pdata = self.data<br /><a name="line21">21</a> pdata = self.OneLineComment.sub<font color="4444FF"><strong>(</strong></font><font color="#008000">''</font>, pdata<font color="4444FF"><strong>)</strong></font><br /><a name="line22">22</a> pdata = self.MultiLineComment.sub<font color="4444FF"><strong>(</strong></font><font color="#008000">''</font>, pdata<font color="4444FF"><strong>)</strong></font><br /><a name="line23">23</a> pdata = self.CppDirectives.sub<font color="4444FF"><strong>(</strong></font><font color="#008000">''</font>, pdata<font color="4444FF"><strong>)</strong></font><br /><a name="line24">24</a> <br /><a name="line25">25</a> <strong>while</strong> self.Body.search<font color="4444FF"><strong>(</strong></font>pdata<font color="4444FF"><strong>)</strong></font> != None:<br /><a name="line26">26</a> pdata = self.Body.sub<font color="4444FF"><strong>(</strong></font><font color="#008000">''</font>, pdata<font color="4444FF"><strong>)</strong></font><br /><a name="line27">27</a> <br /><a name="line28">28</a> fiter = self.Func.finditer<font color="4444FF"><strong>(</strong></font>pdata<font color="4444FF"><strong>)</strong></font><br /><a name="line29">29</a> <strong>for</strong> i in fiter:<br /><a name="line30">30</a> FuncList.append<font color="4444FF"><strong>(</strong></font> pdata<font color="4444FF"><strong>[</strong></font>i.start<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font> : i.end<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><font color="4444FF"><strong>]</strong></font> <font color="4444FF"><strong>)</strong></font><br /><a name="line31">31</a> <br /><a name="line32">32</a> <strong>return</strong> FuncList<br /><a name="line33">33</a> <br /><a name="line34">34</a> c = Cexploder<font color="4444FF"><strong>(</strong></font>sys.argv<font color="4444FF"><strong>[</strong></font>1<font color="4444FF"><strong>]</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line35">35</a> f = c.GetPrototypes<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line36">36</a> <strong>for</strong> i in f:<br /><a name="line37">37</a> <font color="a52a2a"><strong>print</strong></font> i<br /><br /></pre>Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0tag:blogger.com,1999:blog-1891445128304677692.post-89780691349899105092007-04-26T23:47:00.000-07:002007-04-27T00:25:40.402-07:00Regular expressions for fun and profit!So the year is 2007 the century 21-th, but still there are ppl who deny using regular expressions to do the job. Why? I don't know. May be they just don't know how to do it, may be they think it's slow, or they just never heard of it. But it makes me sick looking at lame pseudo parsers their awkward logic and tons of stupid useless code around for something as simple as digging a file for a pattern. I've seen guys spending a day writing code that can be replaced with just one line using a regular expression, and why? Do they gain something out of this? Performance? Speed? No, they usualy do this for a lame script to automate something and they don't care much if it's gonna take 10mS ot a second. The truth is they realy don't know how much easier it just because they have never done it before. <br /><br />So for all of them here's a example of a quick and dirty script I used to generate a report. It simply goes through every file in a directory and looks for the following pattern "/*#.*?#*/". It's a bracket structure taken as a comment within C files. It's simple and i use it to write stuff about something that later might end up in a report. Sometimes i write in there something like "See line 1923" or "Line 192" wich ofcourse means a reference to that line, that's why i made my script look for such patterns and if one exists it'll dump it. <br /><br />So enough goofing around this is the script:<br /><pre><br /><a name="line1"> 1</a> <font color="#444444">#!/usr/bin/env python<br /><a name="line2"> 2</a> <br /><a name="line3"> 3</a> </font><font color="a52a2a"><strong>import</strong></font> os, re, sys<br /><a name="line4"> 4</a> <br /><a name="line5"> 5</a> Cover = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"/<font color="#77dd77">\*</font><font color="#77dd77">\#</font>.*?<font color="#77dd77">\#</font><font color="#77dd77">\*</font>/"</font>, re.DOTALL|re.MULTILINE<font color="4444FF"><strong>)</strong></font><br /><a name="line6"> 6</a> SeeAlso = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"(see|line)+.*?<font color="#77dd77">\d</font>+"</font>, re.DOTALL|re.MULTILINE|re.IGNORECASE<font color="4444FF"><strong>)</strong></font><br /><a name="line7"> 7</a> Number = re.compile<font color="4444FF"><strong>(</strong></font><font color="#008000">"<font color="#77dd77">\d</font>+"</font><font color="4444FF"><strong>)</strong></font><br /><a name="line8"> 8</a> <br /><a name="line9"> 9</a> class Result:<br /><a name="line10">10</a> pass<br /><a name="line11">11</a> <br /><a name="line12">12</a> def GetLinesAround<font color="4444FF"><strong>(</strong></font>Data = <font color="#008000">''</font>, Line = 0, LinesAround = 5<font color="4444FF"><strong>)</strong></font>:<br /><a name="line13">13</a> ret = <font color="#008000">''</font><br /><a name="line14">14</a> d = Data.<font color="a52a2a"><strong>split</strong></font><font color="4444FF"><strong>(</strong></font><font color="#008000">'<font color="#77dd77">\n</font>'</font><font color="4444FF"><strong>)</strong></font><br /><a name="line15">15</a> <br /><a name="line16">16</a> <strong>if</strong> Line >= LinesAround/2:<br /><a name="line17">17</a> upper = Line - LinesAround/2<br /><a name="line18">18</a> <strong>else</strong>:<br /><a name="line19">19</a> upper = 0;<br /><a name="line20">20</a> <br /><a name="line21">21</a> lower = Line + LinesAround/2 + 1<br /><a name="line22">22</a> <strong>if</strong> lower > d.__len__<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font>:<br /><a name="line23">23</a> lower = d.__len__<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line24">24</a> <br /><a name="line25">25</a> try:<br /><a name="line26">26</a> d = d<font color="4444FF"><strong>[</strong></font>upper : lower<font color="4444FF"><strong>]</strong></font><br /><a name="line27">27</a> except Exception: <br /><a name="line28">28</a> <strong>return</strong> ret<br /><a name="line29">29</a> <br /><a name="line30">30</a> <strong>for</strong> s in d:<br /><a name="line31">31</a> ret = ret + str<font color="4444FF"><strong>(</strong></font>s<font color="4444FF"><strong>)</strong></font> + <font color="#008000">'<font color="#77dd77">\n</font>'</font><br /><a name="line32">32</a> <br /><a name="line33">33</a> <strong>return</strong> ret<br /><a name="line34">34</a> <br /><a name="line35">35</a> def GenUtReport<font color="4444FF"><strong>(</strong></font>File = <font color="#008000">''</font>, RelativePath=<font color="#008000">''</font><font color="4444FF"><strong>)</strong></font>:<br /><a name="line36">36</a> f = <font color="a52a2a"><strong>open</strong></font><font color="4444FF"><strong>(</strong></font>File, <font color="#008000">'r'</font><font color="4444FF"><strong>)</strong></font><br /><a name="line37">37</a> data = f.<font color="a52a2a"><strong>read</strong></font><font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line38">38</a> f.<font color="a52a2a"><strong>close</strong></font><font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line39">39</a> <br /><a name="line40">40</a> ret = <font color="4444FF"><strong>[</strong></font><font color="4444FF"><strong>]</strong></font><br /><a name="line41">41</a> <br /><a name="line42">42</a> utIter = Cover.finditer<font color="4444FF"><strong>(</strong></font>data<font color="4444FF"><strong>)</strong></font><br /><a name="line43">43</a> <strong>for</strong> i in utIter:<br /><a name="line44">44</a> res = Result<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line45">45</a> <br /><a name="line46">46</a> avLine = data<font color="4444FF"><strong>[</strong></font>0:i.start<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><font color="4444FF"><strong>]</strong></font>.count<font color="4444FF"><strong>(</strong></font><font color="#008000">'<font color="#77dd77">\n</font>'</font><font color="4444FF"><strong>)</strong></font> + <font color="4444FF"><strong>(</strong></font>data<font color="4444FF"><strong>[</strong></font>i.start<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font>:i.end<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><font color="4444FF"><strong>]</strong></font>.count<font color="4444FF"><strong>(</strong></font><font color="#008000">'<font color="#77dd77">\n</font>'</font><font color="4444FF"><strong>)</strong></font>/2<font color="4444FF"><strong>)</strong></font><br /><a name="line47">47</a> <br /><a name="line48">48</a> res.fInfo = <font color="#008000">"File: "</font> + str<font color="4444FF"><strong>(</strong></font>RelativePath<font color="4444FF"><strong>)</strong></font> + <font color="#008000">" Line: "</font> + str<font color="4444FF"><strong>(</strong></font>avLine<font color="4444FF"><strong>)</strong></font><br /><a name="line49">49</a> res.utInfo = data<font color="4444FF"><strong>[</strong></font>i.start<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font>:i.end<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><font color="4444FF"><strong>]</strong></font>.<font color="a52a2a"><strong>split</strong></font><font color="4444FF"><strong>(</strong></font><font color="#008000">':'</font><font color="4444FF"><strong>)</strong></font><font color="4444FF"><strong>[</strong></font>1<font color="4444FF"><strong>]</strong></font>.replace<font color="4444FF"><strong>(</strong></font><font color="#008000">'#*/'</font>, <font color="#008000">''</font><font color="4444FF"><strong>)</strong></font><br /><a name="line50">50</a> res.codeAroundUt = GetLinesAround<font color="4444FF"><strong>(</strong></font>data, avLine<font color="4444FF"><strong>)</strong></font><br /><a name="line51">51</a> <br /><a name="line52">52</a> res.seeAlsoInfo = <font color="4444FF"><strong>[</strong></font><font color="4444FF"><strong>]</strong></font><br /><a name="line53">53</a> seeIter = SeeAlso.finditer<font color="4444FF"><strong>(</strong></font>res.utInfo<font color="4444FF"><strong>)</strong></font><br /><a name="line54">54</a> <strong>for</strong> si in seeIter:<br /><a name="line55">55</a> seeLine = Number.findall<font color="4444FF"><strong>(</strong></font>res.utInfo<font color="4444FF"><strong>[</strong></font>si.start<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font>:si.end<font color="4444FF"><strong>(</strong></font><font color="4444FF"><strong>)</strong></font><font color="4444FF"><strong>]</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line56">56</a> <strong>if</strong> seeLine != None:<br /><a name="line57">57</a> seeLine = seeLine<font color="4444FF"><strong>[</strong></font>0<font color="4444FF"><strong>]</strong></font><br /><a name="line58">58</a> res.seeAlsoInfo.append<font color="4444FF"><strong>(</strong></font> <font color="4444FF"><strong>(</strong></font> seeLine, 10, GetLinesAround<font color="4444FF"><strong>(</strong></font>data, <font color="a52a2a"><strong>int</strong></font><font color="4444FF"><strong>(</strong></font>seeLine<font color="4444FF"><strong>)</strong></font>, 10<font color="4444FF"><strong>)</strong></font> <font color="4444FF"><strong>)</strong></font> <font color="4444FF"><strong>)</strong></font><br /><a name="line59">59</a> <br /><a name="line60">60</a> ret.append<font color="4444FF"><strong>(</strong></font>res<font color="4444FF"><strong>)</strong></font><br /><a name="line61">61</a> <br /><a name="line62">62</a> <strong>return</strong> ret<br /><a name="line63">63</a> <br /><a name="line64">64</a> def PrityPrint<font color="4444FF"><strong>(</strong></font>ret = <font color="4444FF"><strong>[</strong></font><font color="4444FF"><strong>]</strong></font><font color="4444FF"><strong>)</strong></font>:<br /><a name="line65">65</a> tmpStr = <font color="#008000">''</font><br /><a name="line66">66</a> <br /><a name="line67">67</a> <strong>for</strong> res in ret:<br /><a name="line68">68</a> tmpStr = tmpStr + <font color="#008000">"<tr>"</font><br /><a name="line69">69</a> tmpStr = tmpStr + <font color="#008000">"<td>"</font> + res.fInfo + <font color="#008000">"</td>"</font><br /><a name="line70">70</a> tmpStr = tmpStr + <font color="#008000">"<td>"</font> + res.utInfo + <font color="#008000">"</td>"</font><br /><a name="line71">71</a> tmpStr = tmpStr + <font color="#008000">"<td>"</font> + res.codeAroundUt + <font color="#008000">"</td>"</font><br /><a name="line72">72</a> tmpStr = tmpStr + <font color="#008000">"<td>"</font> <br /><a name="line73">73</a> <strong>for</strong> i in res.seeAlsoInfo:<br /><a name="line74">74</a> tmpStr = tmpStr + <font color="#008000">"See Also. Code around LINE: "</font> + i<font color="4444FF"><strong>[</strong></font>0<font color="4444FF"><strong>]</strong></font> + <font color="#008000">" (+/-)"</font>+ str<font color="4444FF"><strong>(</strong></font>i<font color="4444FF"><strong>[</strong></font>1<font color="4444FF"><strong>]</strong></font>/2<font color="4444FF"><strong>)</strong></font> +<font color="#008000">"<font color="#77dd77">\n</font><font color="#77dd77">\n</font>"</font>+ str<font color="4444FF"><strong>(</strong></font>i<font color="4444FF"><strong>[</strong></font>2<font color="4444FF"><strong>]</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line75">75</a> tmpStr = tmpStr + <font color="#008000">"</td>"</font><br /><a name="line76">76</a> tmpStr = tmpStr + <font color="#008000">"</tr>"</font><br /><a name="line77">77</a> <br /><a name="line78">78</a> <strong>return</strong> tmpStr.replace<font color="4444FF"><strong>(</strong></font><font color="#008000">'<font color="#77dd77">\n</font>'</font>, <font color="#008000">'<br>'</font><font color="4444FF"><strong>)</strong></font><br /><a name="line79">79</a> <br /><a name="line80">80</a> tmpStr = <font color="#008000">""</font><font color="#008000">"<html><head></head><body><table border="</font>1<font color="#008000">"><br /><a name="line81">81</a> <tr><br /><a name="line82">82</a> <td><b>Filename, Line number</b></td><br /><a name="line83">83</a> <td><b>UT not covered reason</b></td><br /><a name="line84">84</a> <td><b>Related code</b></td><br /><a name="line85">85</a> <td><b>See also</b></td><br /><a name="line86">86</a> </tr>"</font><font color="#008000">""</font><br /><a name="line87">87</a> <br /><a name="line88">88</a> <strong>for</strong> r, d, f in os.walk<font color="4444FF"><strong>(</strong></font>sys.argv<font color="4444FF"><strong>[</strong></font>1<font color="4444FF"><strong>]</strong></font><font color="4444FF"><strong>)</strong></font>:<br /><a name="line89">89</a> <strong>for</strong> file in f:<br /><a name="line90">90</a> tmpStr = tmpStr + PrityPrint<font color="4444FF"><strong>(</strong></font>GenUtReport<font color="4444FF"><strong>(</strong></font> os.path.<font color="a52a2a"><strong>join</strong></font><font color="4444FF"><strong>(</strong></font>r, file<font color="4444FF"><strong>)</strong></font> , file<font color="4444FF"><strong>)</strong></font><font color="4444FF"><strong>)</strong></font><br /><a name="line91">91</a> <br /><a name="line92">92</a> tmpStr = tmpStr + <font color="#008000">"</table></body></html>"</font><br /><a name="line93">93</a> <font color="a52a2a"><strong>print</strong></font> tmpStr<br /><br /></pre><br /><br />So you see in less than 100 lines I did it all. Parsing, referencing, generating a report in html. It took me less than 2 hours to finish this.Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0tag:blogger.com,1999:blog-1891445128304677692.post-45276877008944994922007-03-06T02:34:00.000-08:002007-04-26T10:09:44.185-07:00FuzzXmlOk si i was playing around the other day with a Jabber server written in java. I don't quite remember the name but it had a nice web configuration interface. I remember thinking "why not just throw some garbage at this little server of ours?" Yeah sounds like a nice idea! Lets proceede in python of course. First we know jabber is based on XML, second we know it can work without encryption. How much easier could it be? I made a list of all the xml files i could find in my home dir. From all the browsing on the net for this year and a half since i got this laptop i had a hell of alot of them. I did "cat" them all into one big.blob, then refined it with "strings" and the resulting pile of XML stored as good.blob.<br /><br />serj@tokamak:~$ du -h good.blob<br />2.4M good.blob<br /><br />Now all i need is a bit of python to make this work.<br /><span><span><br /><pre class="hl"><span class="slc">#!/usr/bin/env python</span><br /><br /><span class="kwa">import</span> sys<br /><span class="kwa">import</span> time<br /><span class="kwa">import</span> random<br /><span class="kwa">import</span> socket<br /><span class="kwa">import</span> string<br /><span class="kwa">import</span> threading<br /><br /><span class="kwa">def</span> <span class="kwd">fuzzFile</span><span class="sym">(</span><span class="kwb">file</span><span class="sym">,</span> <span class="kwb">iter</span><span class="sym">,</span> chunkLen<span class="sym">):</span><br /> f <span class="sym">=</span> <span class="kwb">open</span><span class="sym">(</span><span class="kwb">file</span><span class="sym">,</span> <span class="str">'r'</span><span class="sym">)</span><br /> data <span class="sym">=</span> f<span class="sym">.</span><span class="kwd">read</span><span class="sym">()</span><br /> f<span class="sym">.</span><span class="kwd">close</span><span class="sym">()</span><br /><br /> retStr <span class="sym">=</span> <span class="str">""</span><br /> <span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> <span class="kwb">int</span><span class="sym">(</span><span class="kwb">iter</span><span class="sym">)):</span><br /> x <span class="sym">=</span> random<span class="sym">.</span><span class="kwd">randint</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span>data<span class="sym">.</span><span class="kwd">__len__</span><span class="sym">());</span><br /> retStr <span class="sym">=</span> retStr <span class="sym">+</span> <span class="kwb">str</span><span class="sym">(</span> data<span class="sym">[</span> x <span class="sym">:</span> x<span class="sym">+</span>random<span class="sym">.</span><span class="kwd">randint</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> <span class="kwb">int</span><span class="sym">(</span>chunkLen<span class="sym">)) ] ) +</span> <span class="str">"</span><span class="esc">\n\n</span><span class="str">"</span><br /> <span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span> <span class="num">0</span><span class="sym">,</span> <span class="kwb">int</span><span class="sym">(</span>random<span class="sym">.</span><span class="kwd">randint</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> <span class="num">3</span><span class="sym">)) ):</span><br /> retStr <span class="sym">=</span> retStr <span class="sym">+</span> <span class="str">"</span><span class="esc">\n</span><span class="str">"</span><br /><br /> <span class="kwa">return</span> retStr<br /><br /><br /><span class="kwa">class</span> <span class="kwd">FuzzAServer</span><span class="sym">(</span>threading<span class="sym">.</span>Thread<span class="sym">):</span><br /> <span class="kwa">def</span> <span class="kwd">__init__</span><span class="sym">(</span>self<span class="sym">,</span> addr<span class="sym">,</span> port<span class="sym">,</span> <span class="kwb">file</span><span class="sym">,</span> <span class="kwb">iter</span><span class="sym">,</span> chunkLen<span class="sym">):</span><br /> threading<span class="sym">.</span>Thread<span class="sym">.</span><span class="kwd">__init__</span><span class="sym">(</span>self<span class="sym">,</span> name<span class="sym">=</span><span class="str">"Producer"</span><span class="sym">)</span><br /> self<span class="sym">.</span>addr <span class="sym">=</span> addr<span class="sym">;</span><br /> self<span class="sym">.</span>port <span class="sym">=</span> port<span class="sym">;</span><br /> self<span class="sym">.</span><span class="kwb">file</span> <span class="sym">=</span> <span class="kwb">file</span><span class="sym">;</span><br /> self<span class="sym">.</span><span class="kwb">iter</span> <span class="sym">=</span> <span class="kwb">iter</span><span class="sym">;</span><br /> self<span class="sym">.</span>chunkLen <span class="sym">=</span> chunkLen<span class="sym">;</span><br /><br /> <span class="kwa">def</span> <span class="kwd">run</span><span class="sym">(</span>self<span class="sym">):</span><br /> <span class="kwa">while</span> <span class="num">1</span><span class="sym">:</span><br /><br /> <span class="kwa">try</span><span class="sym">:</span><br /> sox <span class="sym">=</span> socket<span class="sym">.</span><span class="kwd">socket</span> <span class="sym">(</span> socket<span class="sym">.</span>AF_INET<span class="sym">,</span> socket<span class="sym">.</span>SOCK_STREAM <span class="sym">)</span><br /> sox<span class="sym">.</span><span class="kwd">connect</span><span class="sym">((</span>self<span class="sym">.</span>addr<span class="sym">,</span><span class="kwb">int</span><span class="sym">(</span>self<span class="sym">.</span>port<span class="sym">)))</span><br /><br /> <span class="kwa">while</span> sox<span class="sym">.</span><span class="kwd">send</span><span class="sym">(</span><span class="kwd">fuzzFile</span><span class="sym">(</span>self<span class="sym">.</span><span class="kwb">file</span><span class="sym">,</span> self<span class="sym">.</span><span class="kwb">iter</span><span class="sym">,</span> self<span class="sym">.</span>chunkLen<span class="sym">)):</span><br /> <span class="kwa">pass</span><br /><br /> sox<span class="sym">.</span><span class="kwd">close</span><span class="sym">()</span><br /> <span class="kwa">except</span> <span class="kwc">Exception</span><span class="sym">,</span> err<span class="sym">:</span><br /> <span class="kwa">print</span> err<br /><br /> time<span class="sym">.</span><span class="kwd">sleep</span><span class="sym">(</span><span class="num">10</span><span class="sym">)</span><br /><br /><br /><span class="kwa">class</span> <span class="kwd">FuzzAClient</span><span class="sym">(</span>threading<span class="sym">.</span>Thread<span class="sym">):</span><br /> <span class="kwa">def</span> <span class="kwd">__init__</span><span class="sym">(</span>self<span class="sym">,</span> addr<span class="sym">,</span> port<span class="sym">,</span> <span class="kwb">file</span><span class="sym">,</span> <span class="kwb">iter</span><span class="sym">,</span> chunkLen<span class="sym">):</span><br /> threading<span class="sym">.</span>Thread<span class="sym">.</span><span class="kwd">__init__</span><span class="sym">(</span>self<span class="sym">,</span> name<span class="sym">=</span><span class="str">"Producer"</span><span class="sym">)</span><br /> self<span class="sym">.</span>addr <span class="sym">=</span> addr<span class="sym">;</span><br /> self<span class="sym">.</span>port <span class="sym">=</span> <span class="kwb">int</span><span class="sym">(</span>port<span class="sym">);</span><br /> self<span class="sym">.</span><span class="kwb">file</span> <span class="sym">=</span> <span class="kwb">file</span><span class="sym">;</span><br /> self<span class="sym">.</span><span class="kwb">iter</span> <span class="sym">=</span> <span class="kwb">iter</span><span class="sym">;</span><br /> self<span class="sym">.</span>chunkLen <span class="sym">=</span> chunkLen<span class="sym">;</span><br /><br /> <span class="kwa">def</span> <span class="kwd">run</span><span class="sym">(</span>self<span class="sym">):</span><br /> <span class="kwa">while</span> <span class="num">1</span><span class="sym">:</span><br /><br /> <span class="kwa">try</span><span class="sym">:</span><br /> s <span class="sym">=</span> socket<span class="sym">.</span><span class="kwd">socket</span><span class="sym">(</span>socket<span class="sym">.</span>AF_INET<span class="sym">,</span> socket<span class="sym">.</span>SOCK_STREAM<span class="sym">)</span><br /> s<span class="sym">.</span><span class="kwd">bind</span><span class="sym">((</span>self<span class="sym">.</span>addr<span class="sym">,</span> self<span class="sym">.</span>port<span class="sym">))</span><br /> s<span class="sym">.</span><span class="kwd">listen</span><span class="sym">(</span><span class="num">1</span><span class="sym">)</span><br /> conn<span class="sym">,</span> addr <span class="sym">=</span> s<span class="sym">.</span><span class="kwd">accept</span><span class="sym">()</span><br /> <span class="kwa">print</span> <span class="str">'Connected by'</span><span class="sym">,</span> addr<br /> <span class="kwa">while</span> <span class="num">1</span><span class="sym">:</span><br /> data <span class="sym">=</span> conn<span class="sym">.</span><span class="kwd">recv</span><span class="sym">(</span><span class="num">1024</span><span class="sym">)</span><br /> <span class="kwa">print</span> data<span class="sym">,</span><br /><br /> <span class="kwa">if not</span> data<span class="sym">:</span><br /> <span class="kwa">break</span><br /><br /><br /> data <span class="sym">=</span> <span class="kwd">fuzzFile</span><span class="sym">(</span>self<span class="sym">.</span><span class="kwb">file</span><span class="sym">,</span> self<span class="sym">.</span><span class="kwb">iter</span><span class="sym">,</span> self<span class="sym">.</span>chunkLen<span class="sym">)</span><br /> <span class="kwa">print</span> data<br /><br /> conn<span class="sym">.</span><span class="kwd">send</span><span class="sym">(</span>data<span class="sym">)</span><br /><br /> conn<span class="sym">.</span><span class="kwd">close</span><span class="sym">()</span><br /> <span class="kwa">except</span> <span class="kwc">Exception</span><span class="sym">,</span> err<span class="sym">:</span><br /> <span class="kwa">print</span> err<br /><br /> s<span class="sym">.</span><span class="kwd">shutdown</span><span class="sym">(</span><span class="num">2</span><span class="sym">)</span><br /> s<span class="sym">.</span><span class="kwd">close</span><span class="sym">()</span><br /><br /><span class="kwa">for</span> i <span class="kwa">in</span> <span class="kwb">range</span><span class="sym">(</span><span class="num">0</span><span class="sym">,</span> <span class="num">1000</span><span class="sym">):</span><br /> t <span class="sym">=</span> <span class="kwd">FuzzAServer</span><span class="sym">(</span>sys<span class="sym">.</span>argv<span class="sym">[</span><span class="num">1</span><span class="sym">],</span> sys<span class="sym">.</span>argv<span class="sym">[</span><span class="num">2</span><span class="sym">],</span> sys<span class="sym">.</span>argv<span class="sym">[</span><span class="num">3</span><span class="sym">],</span> sys<span class="sym">.</span>argv<span class="sym">[</span><span class="num">4</span><span class="sym">],</span> sys<span class="sym">.</span>argv<span class="sym">[</span><span class="num">5</span><span class="sym">])</span><br /> t<span class="sym">.</span><span class="kwd">start</span><span class="sym">()</span><br /><span class="slc"># print "thread ", i</span><br /></pre><br /><br /></span></span><br /><br />The idea is simple. Connect to the server build some random string of XML-ish garbage and send it back. And like this as fast as you can. And yeah lets spawn a couple of more in parallel.<br /><br />As you can see i also included a server who can handle a client a time and send bad XML. I decided to test not just the server but the clients also.<br /><br />The results? Well after about 10-30 seconds the java Jabber server eat about 1.2G ram and 98%cpu for more than 20 minutes (at least i killed it after 20 mins). The clients that i tested were examples from the XmlRpc++ library. The did handle the server without problems.Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0tag:blogger.com,1999:blog-1891445128304677692.post-85597171595281714852007-03-01T11:37:00.000-08:002007-04-27T00:42:34.071-07:00Ok so i've played some more with the idea.<br />In this release of the previous client-server thing up there.<br />- Turbo charged Function for getting the queue length. ( based on my 67 seconds research with strace over exim )<br />- Server Implementation in C++ WooooW.<br />- Client Implementation in C++ even more WOOOOWWW!<br /><br />now this is what my screen looks like. The lines with one more blank unerneath are C++ Servers<br />the others Python servers ;)<br /><br />Thu Mar 1 21:34:29 2007<br />XXX 1 : Mail Queue: 2545<br />XXX 3 : Mail Queue: 4030<br />XXX 7 : Mail Queue: 89653<br />XXX 8 : Mail Queue: 238<br /><br />XXX 9 : Mail Queue: 123<br /><br />XXX12 : Mail Queue: 1767<br /><br />XXX14 : Mail Queue: 567<br /><br />XXX15 : Mail Queue: 567<br /><br />XXX16 : Mail Queue: 717<br /><br />XXX20 : Mail Queue: 477<br />XXX21 : Mail Queue: 477Anonymoushttp://www.blogger.com/profile/06445290557764783547noreply@blogger.com0