Linux /proc/net/route addresses unreadable

So you may have looked at /proc/net/route before and thought how the heck am I suppose to read this. Well here is the low down.

This file uses endianness to store the addresses as hexadecimal,
in reverse; for example 192 as hex is C0:

In []: hex(192)
Out[]: '0xc0'

So lets take a look at our route file:

Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT
eth0    00087F0A        00000000        0001    0       0       0       00FFFFFF        0       0       0
eth0    0000FEA9        00000000        0001    0       0       1002    0000FFFF        0       0       0
eth0    00000000        01087F0A        0003    0       0       0       00000000        0       0       0

Now the first entry has a destination of 00087F0A, lets go ahead and chunk these in to hex
characters:

In []: x = iter('00087F0A')

In []: res = [ ''.join(i) for i in zip(x, x) ]

In []: res
Out[]: ['00', '08', '7F', '0A']

Now if we wanted we could convert these hex codes manually:

In []: int('0A', 16)
Out[]: 10

But we want to do this in one big swoop:

In []: d = [ str(int(i, 16)) for i in res ]

In []: d
Out[]: ['0', '8', '127', '10']

And there we go, our IP address; however, it appears to be backwards. Lets go ahead and fix that, and return as a string:

In []: '.'.join(d[::-1])
Out[]: '10.127.8.0'

And there we have it! Your function may look something like this when all said and done:

In []: def hex_to_ip(hexaddr):
   ....:     x = iter(hexaddr)
   ....:     res = [str(int(''.join(i), 16)) for i in zip(x, x)]
   ....:     return '.'.join(res[::-1])
   ....:

And with output like so:

In []: hex_to_ip('00087F0A')
Out[]: '10.127.8.0'

In []: hex_to_ip('0000FEA9')
Out[]: '169.254.0.0'

Bitcoin Mining for Fun results

So yesterday my ASICMiner Block Erupter USB 330MH/s Sapphire Miner arrived in the mail, much earlier than I planned I may add.

I went ahead and plugged it in to my Arch Linux tower, and fired up cgminer.

IMG_20131110_100913

With no further hacking cgminer noticed the card and began mining with it.

--------------------------------------------------------------------------------
 [P]ool management [S]ettings [D]isplay options [Q]uit
 AMU 0:                | 335.4M/335.7Mh/s | A:5760 R:12 HW:74 WU: 4.6/m
--------------------------------------------------------------------------------

I went ahead and left the mining over night (roughly about 24 hours) connected to the BTC Guild mining pool.

With my 330Mh/s card, and roughly 24 hours, I was able to mass 0.00027419 BTC. In US currency, with the current rate of bitcoin ($318 per coin) this is $0.09.

Using this math that would be about $32.85 a year ($0.09 x 365).

So in about 6 months I will of paid off my ASICMiner Block Erupter USB 330MH/s Sapphire Miner, please note this does not include electricity to run my PC.

 

Python Running System Command

So there are a few ways to run system command using python, but I tend to find the below approach the easiest to use and has error handling.

First off I would create a function rather than running the commands over and over:

import subprocess

def run(command):
    '''takes a string command and hands back a subprocess object'''
    process = subprocess.Popen(command.split(), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    process.wait()
    return process

The function itself is pretty small and makes use of the subprocess library.

Popen takes a list which is each part of your command, for example the command ls -lt file would be written as:

['ls', '-lt', 'file']

This however is avoided by using the split method on our function input.

Once we have our function loaded the usage is pretty easy:

>>> c = run('pwd')
>>> c
< subprocess.Popen object at 0x1004a3c50>

Like mentioned above Popen returns a subprocess object, not the result of your command. To access the results and other useful information we are just a method away:

>>> c.communicate()
('/Users/jeffreyness\n', '')

The real beauty I find in using this approach is error handling, something os.system doesn’t provide. Using our object we can check the returncode and validate everything ran cleanly:

>>> c.returncode
0

A return code of 0 is telling us an error was not returned, but what would happen if something did happen:

>>> c = run('ls -ld not_a_file_here.txt')
>>>
>>> c.communicate()
('', 'ls: not_a_file_here.txt: No such file or directory\n')
>>>
>>> c.returncode
1

A return code greater than 0 tells us something went wrong.

Lets see that same command work properly:

>>> c = run('ls -ld Desktop')
>>>
>>> c.communicate()
('drwx------+ 42 jeffreyness  staff  1428 Nov  9 10:35 Desktop\n', '')
>>>
>>> c.returncode
0

Now isn’t that slick!

Using this approach you may want to write blocks of commands something like this:

command = 'ls -ld not_a_file_here.txt'
try:
    c = run(command)
except OSError as e:
    raise(e)

if c.returncode > 0:
    print 'Error: we received a return code of %s' % c.returncode
else:
    print c.communicate()