Shallow Thoughts : : Mar

Akkana's Musings on Open Source Computing and Technology, Science, and Nature.

Sat, 24 Mar 2012

Find out what processes are making network connections

A thread on the Ubuntu-devel-discuss mailing list last month asked about how to find out what processes are making outgoing network connectsion on a Linux machine. It referenced Ubuntu bug 820895: Log File Viewer does not log "Process Name", which is specific to Ubuntu's iptables logging of apps that are already blocked in iptables ... but the question goes deeper.

Several years ago, my job required me to use a program -- never mind which one -- from a prominent closed-source company. This program was doing various annoying things in addition to its primary task -- operations that got around the window manager and left artifacts all over my screen, operations that potentially opened files other than the ones I asked it to open -- but in addition, I noticed that when I ran the program, the lights on the DSL modem started going crazy. It looked like the program was making network connections, when it had no reason to do that. Was it really doing that?

Unfortunately, at the time I couldn't find any Linux command that would tell me the answer. As mentioned in the above Ubuntu thread, there are programs for Mac and even Windows to tell you this sort of information, but there's no obvious way to find out on Linux.

The discussion ensuing in the ubuntu-devel-discuss thread tossed around suggestions like apparmor and selinux -- massive, complex ways of putting up fortifications your whole system. But nobody seemed to have a simple answer to how to find information about what apps are making network connections.

Well, it turns out there are a a couple ofsimple way to get that list. First, you can use ss:

$ ss -tp
State      Recv-Q Send-Q      Local Address:Port          Peer Address:Port   
ESTAB      0      0                     ::1:58466                  ::1:ircd     users:(("xchat",1063,43))
ESTAB      0      0             192.168.1.6:57526       140.211.166.64:ircd     users:(("xchat",1063,36))
ESTAB      0      0                     ::1:ircd                   ::1:58466    users:(("bitlbee",1076,10))
ESTAB      0      0             192.168.1.6:54253       94.125.182.252:ircd     users:(("xchat",1063,24))
ESTAB      0      0             192.168.1.6:52167       184.72.217.144:https
users:(("firefox-bin",1097,47))

Update: you might also want to add listening connections where programs are listening for incoming connections: ss -tpla
Though this may be less urgent if you have a firewall in place.

-t shows only TCP connections (so you won't see all the interprocess communication among programs running on your machine). -p prints the process associated with each connection.

ss can do some other useful things, too, like show all the programs connected to your X server right now, or show all your ssh connections. See man ss for examples.

Or you can use netstat:

$ netstat -A inet -p
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 imbrium.timochari:51800 linuxchix.osuosl.o:ircd ESTABLISHED 1063/xchat      
tcp        0      0 imbrium.timochari:59011 ec2-107-21-74-122.:ircd ESTABLISHED 1063/xchat      
tcp        0      0 imbrium.timochari:54253 adams.freenode.net:ircd ESTABLISHED 1063/xchat      
tcp        0      0 imbrium.timochari:58158 s3-1-w.amazonaws.:https ESTABLISHED
1097/firefox-bin

In both cases, the input is a bit crowded and hard to read. If all you want is a list of processes making connections, that's easy enough to do with the usual Unix utilities like grep and sed:

$ ss -tp | grep -v Recv-Q | sed -e 's/.*users:(("//' -e 's/".*$//' | sort | uniq
$ netstat -A inet -p | grep '^tcp' | grep '/' | sed 's_.*/__' | sort | uniq

Finally, you can keep an eye on what's going on by using watch to run one of these commands repeatedly:

watch ss -tp

Using watch with one of the pipelines to print only process names is possible, but harder since you have to escape a lot of quotation marks. If you want to do that, I recommend writing a script.

And back to the concerns expressed on the Ubuntu thread, you could also write a script to keep logs of which processes made connections over the course of a day. That's definitely a tool I'll keep in my arsenal.

Tags: , , ,
[ 12:28 Mar 24, 2012    More linux | permalink to this entry | ]

Fri, 16 Mar 2012

Image manipulation in Python

Someone asked me about determining whether an image was "portrait" or "landscape" mode from a script.

I've long had a script for automatically rescaling and rotating images, using ImageMagick under the hood and adjusting automatically for aspect ratio. But the scripts are kind of a mess -- I've been using them for over a decade, and they started life as a csh script back in the pnmscale days, gradually added ImageMagick and jpegtran support and eventually got translated to (not very good) Python.

I've had it in the back of my head that I should rewrite this stuff in cleaner Python using the ImageMagick bindings, rather than calling its commandline tools. So the question today spurred me to look into that. I found that ImageMagick isn't the way to go, but PIL would be a fine solution for most of what I need.

ImageMagick: undocumented and inconstant

Ubuntu has a python-pythonmagick package, which I installed. Unfortunately, it has no documentation, and there seems to be no web documentation either. If you search for it, you find a few other people asking where the documentation is.

Using things like help(PythonMagick) and help(PythonMagick.Image), you can ferret out a few details, like how to get an image's size:

import PythonMagick
filename = 'img001.jpg'
img = PythonMagick.Image(filename)
size = img.size()
print filename, "is", size.width(), "x", size.height()

Great. Now what if you want to rescale it to some other size? Web searching found examples of that, but it doesn't work, as illustrated here:

>>> img.scale('1024x768')
>>> img.size().height()
640

The built-in help was no help:

>>> help(img.scale)
Help on method scale:

scale(...) method of PythonMagick.Image instance
    scale( (Image)arg1, (Geometry)arg2) -> None :
    
        C++ signature :
            void scale(Magick::Image {lvalue},Magick::Geometry)

So what does it want for (Geometry)? Strings don't seem to work, 2-tuples don't work, and there's no Geometry object in PythonMagick. By this time I was tired of guesswork. Can the Python Imaging Library do better?

PIL -- the Python Imaging Library

PIL, happily, does have documentation. So it was easy to figure out how to get an image's size:

from PIL import Image
im = Image.open(filename)
w = im.size[0]
h = im.size[1]
print filename, "is", w, "x", h
It was equally easy to scale it to half its original size, then write it to a file:
newim = im.resize((w/2, h/2))
newim.save("small-" + filename)

Reading EXIF

Wow, that's great! How about EXIF -- can you read that? Yes, PIL has a module for that too:

import PIL.ExifTags

exif = im._getexif()
for tag, value in exif.items():
    decoded = PIL.ExifTags.TAGS.get(tag, tag)
    print decoded, '->', value

There are other ways to read exif -- pyexiv2 seems highly regarded. It has documentation, a tutorial, and apparently it can even write EXIF tags.

If neither PIL nor pyexiv2 meets your needs, here's a Stack Overflow thread on other Python EXIF solutions, and here's another discussion of Python EXIF. But since you probably already have PIL, it's certainly an easy way to get started.

What about the query that started all this: how to find out whether an image is portrait or landscape? Well, the most important thing is the image dimensions themselves -- whether img.size[0] > img.size[1]. But sometimes you want to know what the camera's orientation sensor thought. For that, you can use this code snippet:

for tag, value in exif.items():
    decoded = PIL.ExifTags.TAGS.get(tag, tag)
    if decoded == 'Orientation':
        print decoded, ":", value
Then compare the number you get to this Exif Orientation table. Normal landscape-mode photos will be 1.

Given all this, have I actually rewritten resizeall and rotateall using PIL? Why, no! I'll put it on my to-do list, honest. But since the scripts are actually working fine (just don't look at the code), I'll leave them be for now.

Tags: , , , ,
[ 15:33 Mar 16, 2012    More programming | permalink to this entry | ]

Tue, 13 Mar 2012

Numeric Integration tricks

The MITx 6.002 "Circuits and Electronics" class started a week ago Monday. Exciting -- I'm hoping I'll be able to learn all those electronics concepts that baffle me while I'm trying to design simple circuits. (Assuming I make it -- I'm struggling and it's only the first week.)

One of the early exercises required integrating a trig function. No problem -- I used Wikipedia's tables of integrals. But subsequent discussion of that problem in the forums reminded me that when you're after a numeric solution, we do have computers to do that sort of thing for us.

[Wolfram Alpha symbolic integration] In particular, someone linked to Wolfram Alpha: integral (120sqrt(2)cos(2pi60t))^2/110 from 0 to 1/60 A nifty tool that I should remember to use more often! Not only does it give you the numeric answer, but it also gives you a nice symbolic display (so you can make sure you typed in what you thought you were typing in), and a graph.

There was one hitch, though. In this particular problem, there was some debate over the integration limits -- should it be 0 to 1/60 or 0 to 1? If you try the same thing with 0 to 1, you still get the numeric answer, but you get "Computation timed out", with a link labeled "Try again with more time" that leads to an exhortation to subscribe to Wolfram Alpha Pro.

Of course, that made me antsy and made me wonder ... aren't there local solutions? What if I want to calculate an integral when I'm away from a fast network? Is there some way to do this using Python, Octave or R?

And of course there is. I haven't found an easy way to get the pretty graphics, but you can get the numerical results fairly easily.

In Octave, it's a bit roundabout: you have to define a function, then call quad. The easiest way is to use inline:

octave:2> f = inline("(120 * sqrt(2) * cos(120 * pi * x))^2 / 110");
octave:3> quad(f, 0, 1/60)
ans =  2.1818
though you can also define a function this way:
octave:4> function y = ff(t)
>   y = (120 * sqrt(2) * cos(120 * pi * tx))^2 / 110;
> endfunction
octave:5> quad(f, 0, 1/60)
ans =  2.1818

Here's how to do the same thing in Python using SciPy:

import scipy
import math

scipy.integrate.quad(lambda t: (120 * math.sqrt(2) * math.cos(120 * math.pi * t))**2 / 110., 0, 1./60)[0] * 60

Of course, you don't need to use lambda -- you can also define a function and pass it to scipy.integrate.quad.

None of this gets the nice graphics of Wolfram Alpha, though of course either Python or Octave can be programmed to generate them. I saw a presentation at PyCon about a package called Sage that can probably do nice graphics. But it's about a 350Mb download, so trying it wasn't an option during the conference, and now the site is down due to an electrical problem. So for now, Wolfram Alpha wins the graphics war.

Tags:
[ 20:44 Mar 13, 2012    More science | permalink to this entry | ]

Tue, 06 Mar 2012

Arduino Talk (with robotic shark) Wednesday night at SVLUG

[Linux controlled Air Swimmers flying robotic shark] I got a request from SVLUG to fill in at the last minute for a speaker with a health emergency. Fortunately, I'd been slated to give them my Arduino talk from SCALE in a few months, so I was happy to accept. I'm always glad for a chance to show off Bruce, my Arduino- and Linux-controlled 6-foot flying robotic shark.

And if anyone reading this happens to be in town for PyCon, Symantec isn't that far from Santa Clara, roughly a 10-minute drive ... and I promise there will be at least two interesting Python scripts presented.

It's free, of course, so come hear the talk! Here are the SVLUG meeting details and directions.

Tags: , , , , ,
[ 19:25 Mar 06, 2012    More speaking | permalink to this entry | ]

Fri, 02 Mar 2012

Music with an Arduino

Working on projects that might be fun for a proposed Arduino high school workshop, I realized I hadn't done much with Arduinos and sound. I'd made clicking noise for my sonar echolocation device, but nothing more than that.

But the Arduino library has a nice function to control a speaker: tone(int pin, int frequency, int length).

tone() works much better than trying to make your own square wave, because it uses interrupts and doesn't glitch when the processor gets busy doing other things. You can leave off the length parameter and the tone will continue until you tell it to stop or change frequency.

Random tones

So you can produce random tones like this (SPEAKER is the pin the speaker is plugged into):

uint8_t SPEAKER = 8;

void setup()
{
    pinMode(SPEAKER, OUTPUT);
    // Seed the random number generator from floating analog pin 0:
    randomSeed(analogRead(0));
}

void loop()
{
    // Random frequency between 20 and 1400 (Hz).
    unsigned long freq = random(20, 1400);
    long duration = random(5, 50);

    tone(SPEAKER, freq, duration);
    delay(random(100, 300));
}

Light theremin

Purely random tones aren't very interesting to listen to, though, as it turns out.

How about taking input from a photo-resistor, to make a light theremin that wails as I move my hand up and down above the sensor? The photoresistor I was using typically reads, on the Arduino, between 110 (with my hand over the sensor) and 800. So I wanted to map that range to audible frequencies the speaker could handle, between about 20 Hz and 5000.

uint8_t LIGHTSENSOR = 0;
void loop()
{
    // Set the frequency according to the light value read off analog pin 0.
#define MAX_SIGNAL 800
#define MAX_FREQ  5000
#define MIN_SIGNAL 380
#define MIN_FREQ    20
    int lightsensor = analogRead(LIGHTSENSOR);
    int freq = (lightsensor - MIN_SIGNAL) 
                * (float)(MAX_FREQ - MIN_FREQ) 
                / (MAX_SIGNAL - MIN_SIGNAL)
               + MIN_FREQ;
    tone(SPEAKER, freq);
}

Random music (chiptunes)

That was fun, but I still wanted to try some random music that actually sounded ... musical. So how about programming the standard scale, and choosing frequencies from that list?

I looked up the frequency for Middle C, then used fractions to calculate the rest of the "just" diatonic scale for C major:

float middle_c = 262.626;
float just[] = { 1., 9./8, 5./4, 4./3, 3./2, 5./3, 15./8 };
#define NUMNOTES (sizeof(just)/sizeof(*just))
float cur_octave = 1.;

Multiplying the frequency by 2 transposes a note up one octave; dividing by two, down one octave. cur_octave will keep track of that.

Now if whichnote is a number from 0 to 7, cur_octave * just[whichnote] * middle_c will give the next frequency to play.

Just choosing notes from this list wasn't all that interesting either. So I adjusted the code to make it more likely to choose a note just one step up or down from the current note, so you'd get more runs.

    rand = random(0, 6);
    if (rand == 0)
        whichnote = (whichnote + 1) % NUMNOTES;
    else if (rand == 1)
        whichnote = (whichnote + 1) % NUMNOTES;
    else
        whichnote = random(0, NUMNOTES);

    float freq = middle_c * just[whichnote];

    // Change octave?
    rand = random(0, 10);
    if (rand == 1 && cur_octave <= 3) {
        cur_octave *= 2.;
    } else if (rand == 2 && cur_octave >= 1) {
        cur_octave /= 2.;
    }
    freq *= cur_octave;

It's still not great music, but it's a fun experiment and I'm looking forward to adding more rules and seeing how the music improves.

Bach

But this left me hungry for real music. What if I wanted to play a real piece of music? Certainly I wouldn't want to type in an array of frequency numbers, or even fractions. I'd like to be able to say A, Ab (for A-flat), Cs (for C-sharp), etc.

So I defined the frequency for each of the notes in the scale:

#define NOTE_Ab 207.652
#define NOTE_A  220.000
#define NOTE_As 233.082
#define NOTE_Bb NOTE_As
#define NOTE_B  246.942
#define NOTE_C  261.626
#define NOTE_Cs 277.183
#define NOTE_Db NOTE_Cs
#define NOTE_D  293.665
#define NOTE_Ds 311.127
#define NOTE_Eb NOTE_Ds
#define NOTE_E  329.628
#define NOTE_F  349.228
#define NOTE_Fs 369.994
#define NOTE_Gb NOTE_Fs
#define NOTE_G  391.995
#define NOTE_Gs 415.305

#define NOTE_REST     0.0
#define NOTE_SUSTAIN -1.0

Then the first part of Bach's 2-part invention #4 in D minor looks like this:

float composition[] = {
    NOTE_D, NOTE_E, NOTE_F, NOTE_G, NOTE_A*2, NOTE_As*2,
    NOTE_Db, NOTE_As*2, NOTE_A*2, NOTE_G, NOTE_F, NOTE_E,
    NOTE_F, NOTE_REST, NOTE_A*2, NOTE_REST, NOTE_D*2, NOTE_REST,
    NOTE_G, NOTE_REST, NOTE_Cs*2, NOTE_REST, NOTE_E*2, NOTE_REST,

    NOTE_D*2, NOTE_E*2, NOTE_F*2, NOTE_G*2, NOTE_A*4, NOTE_As*4,
    NOTE_Db*2, NOTE_As*4, NOTE_A*4, NOTE_G*2, NOTE_F*2, NOTE_E*2,
};

And the code to play it looks like:

    unsigned long note = composition[i++];
    if (note == NOTE_REST)
        noTone(SPEAKER);
    else if (note == NOTE_SUSTAIN)
        ;      // Don't do anything, just let the current tone continue
    else
        tone(SPEAKER, note);

It's a bit tedious to type in the notes one by one like that, which is why I stopped when I did. And as far as I know, the Arduino can only emit one tone at once -- to play the real 2-part invention, you either need a second Arduino, or extra hardware like a wave shield.

Anyway, it was a fun series of experiments, even if none of it produces great music. You can see the source at github: akkana/arduino/music.

Tags: , , ,
[ 19:54 Mar 02, 2012    More hardware | permalink to this entry | ]