Retrieving MAC Address in Solaris using C as a non-root user
by paulie
I needed to find a way to get the physical (MAC) address using C. From what I could gather from searching opensolaris.org, there are two methods for retrieving it: libdlpi and arp. libdlpi is the more elegant solution as it requires a simple call to dlpi_get_physaddr(). This is how ifconfig prints your network interface's MAC address. Unfortunately, libdlpi calls are only permitted as root.

As explained by James Carlson:

The reason it was like this was historical: getting the 
MAC address in ifconfig meant opening up the DLPI node
and talking to the driver. As the drivers didn't have
discrete privileges for each operation, and you had to be
almighty root to touch them, 'ifconfig' didn't show the
MAC address when not privileged.
*whatever*

The second solution is to use arp. In Solaris you can determine the physical address by looking at the arp tables directly (`arp -a | grep <INTERFACE>` or `netstat -p | grep <INTERFACE>`). With C, this can be done by using the if sockets and arp libraries.

I wrote up a solution called "getmac" using both methods. You can gather it here.

  • Directions
    $ wget http://www.pauliesworld.org/project/getmac.c
    $ gcc getmac.c -o getmac -lsocket -ldlpi
    $ ./getmac <interface_name>
    arp:	ffffffffffff
    dlpi:	dlpi failure, are you root?
    $ pfexec ./getmac <interface_name>
    arp:	ffffffffffff
    dlpi:	ffffffffffff
    
Remember to use pfexec for the libdlpi method.

8:3 — February 9, 2010


Compiling libupnp on Solaris
by paulie
libupnp 1.6.6 is a little tricky to compile on Solaris. After downloading the source from Source Forge, you will want to extract the bzip2 and cd to the libupnp-1.6.6 directory, then do the following.
vi upnp/src/api/upnpapi.c
On line 59, there is a bug. Change
#if defined(_sun)
to
#if defined(__sun)
The change is adding an extra underscore. Otherwise sockio.h will not be recognized properly and you will get some missing networking variables when you try to build. After that is taken care of...
$ ./configure CFLAGS="-DSPARC_SOLARIS" --disable-samples
$ gmake
# gmake install


8:58 — February 3, 2010


OpenSolaris + Fit-PC2 + Mediasonic Pro Box 4 Bay Enclosure
by paulie
After the failure of the SATA and USB ports on my Intel D945GCL Atom board, I decided to build out a new file server. Sticking to the Atom theme, I decided to go small and get the CompuLab FIT-PC2. This little toy uses the Z530 1.6Ghz CPU that apparently uses only 6 watts of power. I'm assuming that means *without* a hard drive installed.



Measuring in at around 115 x 101 x 27mm (~ 4.5"x4.0"x1.0"), it is only big enough to hold one laptop sized 2.5" SATA drive.



The drive I installed only has 80GB of space. That would run out real quick with my needs, so I decided to get a MediaSonic USB disk enclosure to link up with my server. It can hold up to 4 SATA drives.



The PC sits on top of the enclosure on my bookshelf taking up 8.5" x 5.0" x 6.5" amount of space. This is not only power efficient, but space efficient since I am using 4 x 1TB drives. 4TB total (theoretical), ~2.6TB in a ZFS raidz. If I were to have purchased the 2TB drives, it would be even better.

Doug's blog on the FIT-PC2 gives a good overview on the features of the device and what works. There is no wifi driver and Xorg doesn't work, so you may want to install OpenSolaris on another machine before installing the internal HDD. My server is headless and uses the built-in gigabit ethernet, so I don't care about those issues.


Links and prices Total = $748

10:50 — January 21, 2010


E-mail private messages gathered in Irssi
by paulie
I usually have the IRC client irssi running in a screen session so I can stay connected to certain servers and channels all the time. Unfortunately, if I get a private message (PM), I tend to miss it if I neglect IRC for a few days at a time. To correct this, I looked around for an irssi script to send me an e-mail when I get these messages. The closest thing I could find was awayproxy.pl. It seemed to be overkill and relied on sendmail to relay e-mails.

So, I decided to write my own script that uses SendEmail. All you need to do is edit the $SENDEMAIL, $SRCEMAIL, $DESTEMAIL, and $SMTPSERVER variables. It's a VERY simple script, so don't expect a lot from it. You can always substitute sendEmail for sendmail, and you may want to add some extra options for username and password if your SMTP server requires it (mine doesn't).

use strict;
use vars qw($VERSION %IRSSI);

use Irssi;
$VERSION = '1.0.0';
%IRSSI = (
        author      => 'Paul Johnson',
        contact     => 'paulie@pauliesworld.org',
        name        => 'E-mail PM',
        description => 'E-mails a private message to you 
			from IRC.',
        url         => 'http://www.pauliesworld.org/emailpm/',
        changed     => '$Date: 2009-01-09 :00:00 +0100 
			(Sat, 9 Jan 2009) $'
);

my $SENDEMAIL   = "/location/of/sendEmail";
my $SRCEMAIL    = "source\@emailaddress.com";
my $DESTEMAIL   = "destination\@emailaddress.com;
my $SMTPSERVER  = "smtp.youremailserver.com";

sub parsePrivateMessage()
{
        my ($server,$message,$user,$address,$target) = @_;
        emailPrivateMessage($user,$message);
}

sub emailPrivateMessage()
{
        my ($user,$message)=@_;
        my $subject = "IRC message from $user";
        my $send=`${SENDEMAIL} -f ${SRCEMAIL} -t ${DESTEMAIL} 
		-u ${subject} -m ${message} -s ${SMTPSERVER}
}

Irssi::signal_add_last("message private", 
"parsePrivateMessage");
[ EmailPM.pl ]

11:54 — January 11, 2010


Capture Live Webcam Images and Create Time-Lapse Videos with Linksys WVC54GCA
by paulie
On occasion I get an e-mail asking me about my live webcam. What model is it? Does it support FTP/SSH? How does it automatically upload to your site? And so on...

Some answers:

Model: Linksys WVC54GCA Wireless G Home Monitoring Camera
FTP/SSH support: Nope

Capturing Live Images

So how do I automate taking pictures with the thing? Well, a hidden feature to the camera is to navigate to the static picture site of the webcam. For my example, I use DNS to map my camera hostname garfunkel to its IP address. You may want to enter whatever IP your camera uses instead of garfunkel.
http://garfunkel/img/snapshot.cgi?size=3&quality=1
To grab a picture at any given time, use wget.
wget http://garfunkel/img/snapshot.cgi?size=3\&quality=1
-O webcam.jpg
If you have a UNIX-based or UNIX-like OS, you can schedule a cron job to grab this image as often as you like. I prefer capturing once every half hour, so I use this template:
*/30 * * * * /path/to/wget/script
Now, if you have your own web page, you can use ftp/sftp/scp to upload the picture to your server using one script.

Creating Time-Lapse Videos

If you can capture a picture once every minute, you can create a pretty neat time-lapse video every day. This can be accomplished using wget and ffmpeg. For my camera, I point it outside, so it's only worth capturing between certain hours, say 6am to 6pm. After 6pm, I will have created over 700 pictures. I can then use ffmpeg to stitch them together to form a short video on the day's weather. It's a little complicated to discuss every detail behind this, so I'll just post the bourne script I use.
#!/bin/sh

hour=`date +%H`
captime=`date +%H%M`
dirpath="/location/of/your/timelapse/directory"
img=`ls ${dirpath}*jpg | wc -l`;
expr=`expr 1 + $img`

timelapse()
{
	# File format will be Month.Day.Year.flv (flv for 
	# flash)
	date=`date +%m.%d.%y.flv`

	# ffmpeg reads in each image and incrementally
	# makes a flash video at 16 fps
	cd ${dirpath}
	ffmpeg -i %04d.jpg -r 16 ${dirpath}${date}

        # Cleanup, upload time-lapse to server and remove 
	# all jpg files
	# scp user@host:location
	# rm ${dirpath}*jpg
}

capture()
{
        # ffmpeg expects pictures in the format 0001.jpg ... 
	# 0001.jpg so we need to add a fluff of zeros to
	# make each pic 4 digits long

	if [ $expr -lt 10 ]
	then
        	expr="000${expr}"

	elif [ $expr -lt 100 ]
	then
        	expr="00${expr}"

	elif [ $expr -lt 1000 ]
	then
        	expr="0${expr}"
	fi

        wget http://garfunkel/img/snapshot.cgi?size=3\&quality=1
--output-document=${dirpath}${expr}.jpg
} 

case "$hour" in
# Eliminate the hours of the day that are too dark to capture
00|01|02|03|04|05|19|20|21|22|23)
	;;
# If it is 6:00pm (18), time to make a video
18)
	if [ $captime -eq 1800 ]
	then
		timelapse
	fi
	;;
# Every other hour is assumed to have light, so take a pic
*)
	capture
	;;
esac
You might want to change the dirpath variable to wherever you want to store the pictures. Finally, add a cron entry to run every minute:
* * * * * /path/to/timelapse/script
After 6pm, you will have an flv file. This is a flash file that can be played by various flash players for viewing on the web. You can change the file format to avi or mpg instead of flv if you just want to view it on your computer.

Sample video from my camera



7:40 — December 14, 2009


Can't use NumPad in OpenSolaris?
by paulie
Today I thought I broke the numpad on my keyboard; none of then numbers were working. Switching on and off the Num Lock key didn't work. However, anytime I hit a number and held the key down, the mouse cursor would move across the screen. By some sort of black magic, I found a secret keyboard combo to turn on Mouse control via keypad.

Solution to turn it off
System -> Preferences -> Assistive Technologies -> 
Keyboard Accessibility -> Mouse Keys

Uncheck 'Pointer can be controlled using the keypad'
I must admit, however, this can be a handy feature when working with a mouse-less machine.

13:22 — December 9, 2009


Cannot remove directory: File exists
by paulie
If you try to delete a directory over NFS and get an error such as...
rm: cannot remove directory `asdf/': File exists
... you will notice that conventional methods won't be good enough to remove it.
$ chmod -R 777 asdf/
$ rm -rf asdf/
$ rm: cannot remove directory `asdf/': File exists
Usually there is a file like .nfs234B inside the directory than can be displayed with ls -la
$ ls -la
total 146
drwxr-xr-x 2 user group    512 2009-05-20 08:51 .
drwxr-xr-x 3 user group    512 2009-05-19 08:59 ..
-rwxr-xr-x 1 user group 134888 2009-05-18 12:45 .nfs234B
Removing this file only replaces it with another. There are two solutions: manually delete the file on the NFS server, or (if you don't have that type of access) kill its process.
$fuser -u asdf/.*
asdf/.:     9070c(user)
asdf/..:    28690c(user)   24845c(user)
asdf/.nfs934B:     9070tm(user)
9070 is the offending process. Kill it with fire.
$ kill -9 9070
Should be able to remove that directory now.

1:12 — May 20, 2009


Testing Network Performance in Solaris
by paulie
So you think your wireless link is slow, or your gigabit ethernet card is under performing. How can you tell? Here are two tools I use to test network throughput.

netio


Created by Kai Uwe Rommel, it tests by sending and receiving packets of varying sizes and reports throughput in kilobytes per second.

Installation
  • x86
  • # wget
    # ftp://ftp.sunfreeware.com/pub/freeware/intel/
    10/netio-1.26-sol10-x86-local.gz
    # gzip -d netio-1.26-sol10-x86-local.gz
    # pkgadd -d netio-1.26-sol10-x86-local
    
  • SPARC
  • # wget
    # ftp://ftp.sunfreeware.com/pub/freeware/sparc/
    10/netio-1.26-sol10-sparc-local.gz
    # gzip -d netio-1.26-sol10-sparc-local.gz
    # pkgadd -d netio-1.26-sol10-sparc-local
    
    Usage
  • Server-side
  • # netio -u -s
    
  • Client-side
  • # netio -u SERVER_IP_ADDRESS
    

    Here are results on a 100Mbps link:
    UDP connection established.
    Packet size  1k bytes:  11913 KB/s  Tx, 11468 KB/s Rx.
    Packet size  2k bytes:  11954 KB/s  Tx, 11509 KB/s Rx.
    Packet size  4k bytes:  12274 KB/s  Tx, 11687 KB/s Rx.
    Packet size  8k bytes:  12284 KB/s  Tx, 11697 KB/s Rx.
    Packet size 16k bytes:  12292 KB/s  Tx, 11702 KB/s Rx.
    Packet size 32k bytes:  12348 KB/s  Tx, 11714 KB/s Rx.
    Done.
    
    Sending and receiving hovered around 11-12MB/s which is on par with 100Mbps.

    netperf


    Created by Rick Jones and discovers the maximum throughput of a link, reporting in megabits per second.

    Installation
    # wget ftp://ftp.netperf.org/netperf/netperf-2.4.4.tar.gz
    # tar zxvf netperf-2.4.4.tar.gz
    # cd netperf-2.4.4
    # export CFLAGS="-lsocket -lnsl -lkstat"
    # ./configure
    # make
    # make install
    
    Usage
  • Server-side
  • # netserver
    
  • Client-side
  • # netperf -H SERVER_IP_ADDRESS
    

    Here are results on a 100Mbps link:
    Recv   Send    Send                          
    Socket Socket  Message  Elapsed              
    Size   Size    Size     Time     Throughput  
    bytes  bytes   bytes    secs.    10^6bits/sec  
    
     49152  49152  49152    10.00      94.88
    

    94.88 Mbps is the final result, not bad.

    5:35 — May 1, 2009



    Powered by Perl