For any web page visibility on search engines is a vital.

So how does my blog is doing?

search phrase: yazzgoth
place: 3
(when I’ve chosen this nickname I didn’t know that “yazzgoth” is a name of heavy metal band - polish band btw :) )

search phrase: bartosz ptaszynski
place: 5
(small note here: the 1st place takes my LinkedIn profile :D)

search phrase: coder’s life
place: unknown (I didn’t find it on the first 10pages)
So I guess there’s a reason to change the blog’s name to something more informative… hmm but what?

So this is like the world looks like at 4am :)

After reading ZenHabits I’ve decided to convert myself from being a Night Owl into an Early Bird.
I’m rather extremist when it comes to changing something. I usually do things on one go when it comes to changes in my life, so instead of waking up every day 10 minutes earlier until I would reach the 4am target - I have set up my alarm to 4am :)

To be honest this is not my first attempt :)

Yesterday I’ve tried, but made a critical error of reasoning with myself to go to bed for just a bit more… and I’ve stayed in until 8am :P Well they have warned me not to reason with myself in the morning…

And again, Fridays are not the best time to change something in your life… but hey, had to start someday.

This little program is what I’ve mentioned earlier on my blog. It connects to all devices it can find in specified IP ranges via SMTP and gathers their MAC tables.
The plan is to keep this data in a DB and update it once in a while (20min would seem appropriate ). Then you can easily pin point what route do packets take on the L2 of the network and what Subscriber Module (SM) has a client using specific IP address/MAC.
This can be very useful in Motorola Canopy based networks with open architecture.

Package still under development.

Currently to make it work you need:

* Motorola Canopy based network
* Net-SNMP binaries (snmpwalk)
* Python 2.5
* SQLObject
* IPy
* SQLite

1) Download and install Net-SNMP binaries (or compile it if you wish) and make sure the executables are within PATH.

2) Install Python 2.5

3) To make your life easier download and run ez_setup.py to install latest distutils.

4) From the command line type: easy_install SQLObject
which should download and install SQLObject (and most likely SQLite as well - if not download SQLite and install it)

5) From the command line type: easy_install IPy

6) Now you can use following script

macsearch.py

Python [Show Plain Code]:
  1. #!/usr/bin/env python
  2.  
  3. #  Copyright (c) 2007, Bartosz Ptaszynski
  4. #
  5. #  macsearch.py is free software; you can redistribute it and/or modify
  6. #  it under the terms of the GNU General Public License as published by
  7. #  the Free Software Foundation; either version 2 of the License, or
  8. #  (at your option) any later version.
  9.  
  10. """
  11.  
  12. @author: Bartosz Ptaszynski
  13. @copyright: (C) 2007 Bartosz Ptaszynski
  14. @license: GNU General Public License (GPL)
  15. """
  16.  
  17. # Standard Library imports
  18. from os import popen
  19. from sys import argv
  20. from optparse import OptionParser
  21. from datetime import datetime
  22.  
  23. # 3rd Party Library imports
  24. from sqlobject import *
  25. from IPy import IP
  26.  
  27.  
  28. class MAC(SQLObject):
  29.     ip = StringCol(length=16)
  30.     mac = StringCol(length=18)
  31.     device_type = StringCol(length=6)
  32.     last_seen = DateTimeCol(default=datetime.now())
  33.     site_name = StringCol(default="")
  34.  
  35. class Subnet(SQLObject):
  36.     subnet = StringCol(length=20, alternateID=True)
  37.  
  38. class MACDiscoveryAgent(object):   
  39.     snmp_site_name = " SNMPv2-MIB::sysName.0"
  40.     snmp_macs = " enterprises.161.19.3.3.4.1.1"
  41.     snmp_device_type = " enterprises.161.19.3.3.1.7.0"
  42.    
  43.     def __init__(self, community="Canopy", snmp_version="2c", db_uri="sqlite:/:memory:"):
  44.         self.community = community
  45.         self.snmp_version = snmp_version
  46.         self.snmpwalk = str("snmpwalk -c "+community+" -v "+snmp_version+" ")
  47.         self.db_uri = db_uri
  48.         self._db_connect()
  49.  
  50.     def _init_db(self):
  51.         try:
  52.             MAC.createTable()
  53.             Subnet.createTable()           
  54.             return True
  55.         except:
  56.             return False
  57.        
  58.     def _db_connect(self):
  59.         """ Connect to the Database
  60.         """
  61.         sqlhub.processConnection = connectionForURI(self.db_uri)
  62.         self._init_db()
  63.  
  64.     def _db_addMAC(self, ip, mac, device_type, site_name):
  65.         """ Add a MAC to the Database, refresh the last_seen if it already exists
  66.         """
  67.         oldmac = MAC.selectBy(mac=mac, ip=ip, device_type=device_type)
  68.  
  69.         try:
  70.             if oldmac.last_seen:
  71.                 oldmac.last_seen = datetime.now()
  72.         except AttributeError:       
  73.             m = MAC(ip=ip, mac=mac, device_type=device_type, site_name=site_name)
  74.             #print m
  75.    
  76.     def _db_removeSubnet(self, subnet):
  77.         """ Removes a subnet that the MAC lookup should sweep from the Database
  78.         """
  79.         pass
  80.  
  81.     def _db_removeMAC(self, mac):
  82.         """ Completely removes a MAC address from the database
  83.         """
  84.         pass
  85.    
  86.     def _db_lookupMAC(self, mac):
  87.         """ Looks up a MAC address in the Database
  88.         """
  89.         results = MAC.selectBy(mac=mac)
  90.         return results
  91.    
  92.     def _normalizeMAC(self, mac):
  93.         # TODO: use regexp here
  94.         if "-" in mac:
  95.             mac = mac.split("-")
  96.         elif ":" in mac:
  97.             mac = mac.split(":")
  98.         elif " " in mac:
  99.             mac = mac.split(" ")
  100.         mac = .join(mac)           
  101.         mac = mac.upper()
  102.         return mac
  103.  
  104.     def _getMACs(self, ip):
  105.         """ Get all MAC addresses from the device
  106.         """
  107.         print ip
  108.         device_type = popen( str(self.snmpwalk + ip + self.snmp_device_type) )
  109.         device_type = device_type.read()
  110.         device_type = device_type[52:-2] # TODO: I should use regexp here!
  111.         macs = popen( str(self.snmpwalk + ip + self.snmp_macs) )
  112.         macs = macs.readlines()
  113.         site_name = popen( str(self.snmpwalk + ip + self.snmp_site_name) )
  114.         site_name = site_name.read()
  115.         for mac in macs:
  116.             self._db_addMAC(ip=ip, mac=self._normalizeMAC(mac[-19:-2]), device_type=device_type, site_name=site_name[32:]) # TODO: use regexp!
  117.  
  118.     def addSubnet(self, subnet):
  119.         """ Add a subnet that the MAC lookup should sweep to the Database
  120.         """
  121.         try:
  122.             Subnet(subnet=subnet)
  123.             return True
  124.         except:
  125.             return False
  126.  
  127.     def sweep(self):
  128.         for subnet in Subnet.select():
  129.             for ip in IP(subnet.subnet):
  130.                 self._getMACs(str(ip))
  131.        
  132.     def lookupMAC(self, mac):
  133.         """ Lookup a MAC address in the Database
  134.  
  135.             If successful it returns IP address of the SM with provided MAC address.
  136.             If not successful it returns a list with all APs and BHs that have provided MAC address.
  137.             It’s a list of dictionaries. This list has a format [ {’device_type’: string, ‘ip’, string}, … ]
  138.            
  139.         """
  140.         mac = self._normalizeMAC(mac)
  141.         results = self._db_lookupMAC(mac)
  142.         for result in results:
  143.             if "SM" in str(result.device_type):
  144.                 return result
  145.         return results
  146.        
  147. # Example usage below…
  148.  
  149. m = MACDiscoveryAgent()
  150. m.addSubnet("192.168.105.44/30")
  151. print "Sweeping the network…"
  152. m.sweep()
  153. print "Sweeping completed."
  154. print "Looking up the MAC address…"
  155. res = m.lookupMAC(‘00 E0 4C A0 28 CC’)
  156. if type(res) is MAC:
  157.     print "Found it:", res.device_type,":", res.ip, ":",res.site_name,": last seen:", res.last_seen
  158. else:
  159.     print "Couldn’t find the SM, But found following items with this MAC in their MAC table"
  160.     for i in res:
  161.         print i.device_type, ":", i.ip, ":", i.site_name, ": last seen ", i.last_seen

My blog has moved to this page.

Well I was tempted to give the WordPress a ride for some time now. The thing that pushed me over the edge was the code syntax highlighting that I had some problems with on blogger.

I’m using SyntHihol with geishi and it’s working perfectly.

I’ve just stumbled upon Microsoft’s Photosynth. This astonishing technology takes hundreds pictures of the same place taken from a different angles and creates a 3D image…
I can imagine that if someone would take this technology, used the images from Google Images or Flickr and assigned them to a location and plugged that into Google Earth … the result would be just jaw dropping.

I have a feeling that in some time that someone will be Google :)

I’ve stumbled upon a great website on Lifehacking while reading Torley’s blog

I find a lot of things mentioned there that I already do or figured out the hard way… but there’s so many things I can introduce to my life it makes me so excited that I think I’ll start straight away.

Having a good idea is easy. Executing the idea is where most people fail.

…as you can read here.
This is so true it just hurts… I have so many ideas, just making a decision on which to pursue first is the hard one, and often a fatal in this sense that it may lead to not doing anything at all!

Heh I still can’t get myself from the floor after reading this

It seems that Microsoft has some weird way of checking if the Windows is genuine or not… I wonder what this will lead to as it may open doors for quite some interesting possibilities.

I’ve joined Twitter, let’s see what all the hype is about :)
My twitter is available here

Well it’s time for Linden Scripting Language quirks today.

Heh the LSL is one big quirk but that’s a different story.

What I found today the empirical way is that when you send a request to the dataserver, ie when querying with llRequestAgentData the event if fired up after the current function finishes.
This is very annoying when you want to query the dataserver wait for it’s results and process the data.
I’ve tried to llSleep for some time and also llSleep in while loop waiting for the dataserver to trigger the event and return data… but the dataserver never did that before the current function finished.

Example:

  1. string born;
  2. someFunction()
  3. {
  4.        llSleep(10.0);
  5.        llOwnerSay("You were born "+born);
  6. }
  7.  
  8. default
  9. {
  10.        dataserver(key id, string data)
  11.        {
  12.           born = data;
  13.        }
  14. }

What will you get is:

Object: You were born

This example is easy to fix as there is only one query to the dataserver.
But in my case I’ve had a list of avatar keys which I wanted to query one by one and at the end send the results over the llHTTPRequest.
I couldn’t call llHTTPRequest every time I’ve did the query to the dataserver or I would trigger the throttling on the script…

The thing was that the dataserver event was designed to modify the original list with avatar keys and add the results just after corresponding key and I couldn’t proceed without having the events finished their job.

My solution to that was queuing up all the dataserver requests and using two global variables. First was holding the length of the list with avatar keys, the other was incremented from 0 every time the dataserver event fired up. At the end of each dataserver event I’ve called a function that compared the variable with length of the list with avatar keys with the counter on event calls.
When they’ve matched that indicated that the llRequestAgentData was executed on all avatars and I could proceed freely.

There’s something about Fridays that makes me feel great. I wonder if going on retirement feels like Friday multiplied by fifty.

Heh :)