All posts by fash

Coline’s Persuasion

A trip to Scotland with our band. I wanted to remember the whole night drinking, staying outside on deck .. and getting lost.

So i composed a little tune we could play with the band.

The arches need to be played with slides .. like slipping of the deck. Same in bars 1,3,5 and 7 and second part

Coline persuaded several people to stay up all night. We drank a lot, and in the morning we tried to get down to our cabin’s.
But having to much to drink, apparently we took a wrong turn. We where in the living quarters of the cabin crew! A wrong elevator later .. the kitchen .. how did this happen. Friendly members of the crew showed us the way out.

Ximian Desktop

I’ve bought ximian desktop with the exchange 2000 connector (For work) in the same package was staroffice 6.0.
It was based on Redhat 7.3

Ximian Desktop provides everything you need to put your Linux system to work. It includes a graphical interface based on the GNOME platform, with high-quality applications like the Ximian Evolution® groupware suite.

All editions of Ximian Desktop add the following:

  • A special Ximian edition of the OpenOffice.org office suite.
  • The most advanced Linux* printing system available today, integrated with the entire desktop and based on the CUPS subsystem. CUPS supports more printers and makes it much easier to set them up.
  • Extensive network compatibility for Windows* and UNIX networks.
  • Easy, removable media tools, including CD burning made simple.
  • A “My Computer” tool to help you navigate files, networks, and devices, designed especially for people migrating from Microsoft Windows.
  • The Red CarpetTM software management tool, which makes sure you get critical software updates quickly, easily, and securely.

The Professional Edition of Ximian Desktop includes additional software and services:

  • Agfa Fonts: High-quality licensed fonts, metrically compatible with those used in Microsoft* Office, to help preserve formatting and styles across platforms.
  • RealNetworks* RealPlayer*: Media player for RealAudio and RealVideo formats. Works with or without your Web browser.
  • Macromedia* Flash*: Browser plug-in for display of Flash vector animation on the Web.
  • Sun* Java* Runtime Environment: Allows you to use the broadest range of Java software with the best performance.
  • A year’s subscription to Red Carpet Express, the Ximian high-bandwidth update service.
  • 30 days of personalized Web-based support at support.ximian.com.
Outlook integration (needed for work)
Nice icon set
Red Carpet
Vector graphic icons, one of the first distro’s which got it right

Beer crate bottle counter

Post in 2002 due to screenshot .. dont know when i build it, some years before.

Using 24 pushbuttons and a IO expander, i could count the bottles in a crate. Probably used something like a hef4067 ??

Now i probably use a weight sensor or a beer cap counter using a webcam image.

Notification to email and shopping list printer.

Web Interface

Every bottle had to be placed back upside down so the opening of the bottle would not press down on the button. Later i used springs which could hold a empty bottle elevated above the button. The weight of a full bottle would press on the button.

Web part Dopcounter (screenshot at top of page)

<HTML><HEAD><TITLE>dopDB.counter running @ fash's place</TITLE></HEAD><BODY bgcolor=white text=black>
<?
if ($show){
print "<a href='index.php'>Show Last</a>";
}
else {
print "<a href='?show=1'>Show All</a>";
}
?>
<CENTER>
<?
$db = mysql_connect("localhost", "user", "pass");
mysql_select_db("dopDB",$db);
// store voor bargraph
$store=0;
$result2 = mysql_query("SELECT max(timestamp) FROM counter",$db);
$maxtimestamp = mysql_fetch_array($result2);
$result = mysql_query("SELECT * FROM counter",$db);
while ($myrow = mysql_fetch_array($result)) {
$lenght=strlen($myrow[1]);
if ( $lenght = 24)
{
if ($maxtimestamp[0] == $myrow[0] || $show)
 {
 $row1= substr("$myrow[1]", 0, 6);
 $row2= substr("$myrow[1]", 6, 6);
 $row3= substr("$myrow[1]", 12, 6);
 $row4= substr("$myrow[1]", 18, 6);
 $row1 = str_replace("1","<td><img src='dop.jpg'></td>",$row1);
 $row1 = str_replace("0","<td><img src='dopl.jpg'></td>",$row1);
 $row2 = str_replace("1","<td><img src='dop.jpg'></td>",$row2);
 $row2 = str_replace("0","<td><img src='dopl.jpg'></td>",$row2);
 $row3 = str_replace("1","<td><img src='dop.jpg'></td>",$row3);
 $row3 = str_replace("0","<td><img src='dopl.jpg'></td>",$row3);
 $row4 = str_replace("1","<td><img src='dop.jpg'></td>",$row4);
 $row4 = str_replace("0","<td><img src='dopl.jpg'></td>",$row4);
 print "<TABLE border=15 bgcolor='#aaaaaa'><TR>";
 print $row1;
 print "</tr><tr>";
 print $row2;
 print "</tr><tr>";
 print $row3;
 print "</tr><tr>";
 print $row4;
 print "</tr><table>";
 }
$dopcounter=str_replace("0","",$myrow[1]);
$totaldop=strlen($dopcounter);
if ($maxtimestamp[0] == $myrow[0] || $show)
 {
print "<P>";
print date('l dS of F Y H:i:s',$myrow[0]); 
print "<BR><H1>$totaldop bottles left</H1>";
 }
$store = $store + 1;
$storetotals[$store]=$totaldop;
if ($totaldop < 6 && $maxtimestamp[0] == $myrow[0])
 {
 print "<BR>Time to buy some beer again!<BR>";
 }
}
else
{
print "numba bottles error! check code!";
}
}
?>

<table border=0>
<tr>
<?
$storebck=$store;
if ($storebck > 50){ $store=$storebck-50; } else { $store=0; }
while ($store <= $storebck){
print "<td bgcolor=#efefff width=10 valign='bottom'>";
$double=$storetotals[$store]*2;
print "<img src='bar1.gif' width=15 height=$double></td>";
$store = $store +1;
}
?>
</tr>
<tr>
<?
if ($storebck > 50){ $store=$storebck-50; } else { $store=0; }
while ($store <= $storebck){
print "<td bgcolor=#efefff width=10 valign='bottom'>";
print "$storetotals[$store]</td>";
$store = $store +1;
}
?>
</tr>
</table>
</BODY></HTML>

Reverse engineering a alpha ticker led scoller

Cobra from the Icecrew got his hands on some Led scrollers.

But they only had a windows program to controll these, so we started some reverseengineering.

First we had to make a serial cable.
(Now we could easily use a logic analyser with protocol decoding)

Next i made a sniffer .. because we only had a windows program to control the display.
So we used a windows machine to control the display by serial, and using a read line to a linux machine to stiff the serial traffic

After some tinkering .. we got this

So we wrote some software to control it using Linux

Some code

#!/usr/bin/perl
# Get the attention of the sign
print "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
# Tell the sign to print the message
$message = "���������������������    ";
print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " b" . $message . "\004";
#print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " a" . $message . 
#"\004";

::::::::::::::
PERLTESTLED
::::::::::::::
#!/usr/bin/perl
print "\0\0\0\0\0\001" . "Z" . "00" . "\002" . "AA" . "\x1B" . " b" . "Test Message" . "\004";

::::::::::::::
PERLTESTLED2
::::::::::::::
#!/usr/bin/perl
# Get the attention of the sign
print "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
# Tell the sign to print the message
$message = "<<<<<<<<<<<<<<<<";
#print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " b" . $message . "\004";
print "\001" . "Z" . "01" . "\002" . "AA" . "\x1B" . " a" . $message . "\004";

A few days later i wrote a controller using glade. (Could not find more code)

Some time later we found some datasheets which could have helped!

Dartabase

Somewhere start 2002, i made a tool for playing darts.
Well … keeping score and history

I was multiuser, multigame with statistics and undo.
You could click on the little dartboard what your have thrown on a real board. It just kept score and told you best finish options.

Screenshot below was a digitized picture, no way accurate. Versions later the board was realtime drawn with GDlib and pixelperfect.
It even showed you previous throws.

At the end of the game it should give you the hotspots you have thrown.

Later version

Sound Firewall

See also 2nd Firewall 2013 and Led Firewall
https://www.henriaanstoot.nl/2013/08/03/ohm-2013-hackerevent/

While partying @ HAL2001, a hackers event, Venom and I made a Soundfirewall.

We had a little DMZ, with our servers.
This was protected by a iptables firewall.

Our idea was to get a sound notification on every (interesting) network packet the firewall dropped.

So we made this: (At the bottom are the sound definitions.)
Example of the sound we heared whole day.

#use strict;
#       @(#)    First Edit: Bas
#       @(#)    Last Edit: Fash

use POSIX ":sys_wait_h";
use vars qw(%Msg_Rec);

$SIG{'TERM'} = $SIG{'HUP'} = 'goodbye';
$SIG{'CHLD'} = 'IGNORE';

## Constants
my $BELL   = "";
my $MAILER = "/usr/sbin/sendmail";
my $WRITE  = "/usr/bin/write";
$/ = "
";

autoflush STDOUT;

sub goodbye {
  $| = 0;

  close_pipe_if_open();
  exit(0);
}

#
# in_range($range, $number) 
# returns 1 if $number is inside $range, 0 if not
#
sub in_range {
  my $range = shift;
  my $num = shift;

  foreach my $f (split(/,/, $range)) {
    if ($f =~ /-/) {
      my ($low,$high) = split(/-/, $f);
      return 1 if ($low <= $num and $num <= $high);
    } elsif ($f == $num) {
      return 1;
    }
  }
  return 0;
}

# 
# inside_time_window($days,$hours)
# returns 1 if inside window, 0 if outside window
#
sub inside_time_window {
  my $range = shift;
  my($days, $hours) = split(/:/, $range);

  my ($hr, $wday) = (localtime(time))[2,6];

  if (($days eq '*' or in_range($days, $wday))
      and ($hours eq '*' or in_range($hours, $hr))) {
    return 1;
  } else {
    return 0;
  }
}

  
print "\n*** swatch-3.0.1 (pid:6826) started at " . `/bin/date` . "\n";

  
use Date::Calc qw(:all);

sub parse_dot {
  my $message = shift;
  my $dot_loc = shift;
  my @dot = ();
  my @ranges = split(/:/, $dot_loc);

  foreach my $range (0..$#ranges) {
    if ($ranges[$range] != -1) {
      my ($begin, $end) = split(/-/, $ranges[$range]);
      $dot[$range] = substr($message, $begin, ($end - $begin + 1));
    }
  }

  return @dot;
}

my ($date_loc, $time_loc) = ("-1:0-2:4-5", "7-8:10-11:13-14");
my %months = (
              Jan => 1,
              Feb => 2,
              Mar => 3,
              Apr => 4,
              May => 5,
              Jun => 6,
              Jul => 7,
              Aug => 8,
              Sep => 9,
              Oct => 10,
              Nov => 11,
              Dec => 12
             );

# Returns an array of year, month, day, hours, minutes, and seconds.
#
sub YMDHMS {
  my $string = shift;
  my $year_today = (Today())[0];

  my ($y, $m, $d) = parse_dot($string, $date_loc);
  my ($hrs, $mins, $secs) = parse_dot($string, $time_loc);
  if (length($y) eq 0) { $y = (Today())[0] };

  return ($y, $months{$m}, $d, $hrs, $mins, $secs);
}

sub new_msg {
  my $use = shift;
  my $msg = shift;
  my $count = shift;
  my @delta = @_;
  my $delta;
  if ($delta[0] == 0) {
    $delta = sprintf("%d:%.2d:%.2d", $delta[1], $delta[2], $delta[3]);
  } else {
    $delta = sprintf("$delta[0] day%s %d:%.2d:%.2d", $delta[0] > 1 ? 's' : '',
                    $delta[1], $delta[2], $delta[3]);
  }
  if ($use eq 'regex') {
    return "$count $msg regular expressions in $delta";
  } else {
    return "$count in $delta: $msg";
  }
}

#
# Stores message information in 
#    $Msg_Rec = (
#      {<truncated message>|<pattern>} => {
#        dhms => [ array ], # days,hours,minutes,seconds
#        count => integer,

sub throttle {
  my %opts = (
              KEY       => $_,
              CUT_MARKS => [ "0:16" ], # not used yet
              USE       => 'message',
              @_
             );

  my $msg = $opts{'KEY'};
  my $use = $opts{'USE'};
  my @ymdhms = YMDHMS($msg);
  my $key;
  my @min_dhms_delta = split(/(\s+|:)/, $opts{'MIN_DELTA'});

  foreach my $i (0..$#min_dhms_delta) {
    # strip out unwanted element
    splice (@min_dhms_delta, $i, 1) if ($min_dhms_delta[$i] eq ":");
  }

  if ($use eq 'regex') {
    $key = $opts{'REGEX'};
  } else {
    $key = substr($msg, 16);
    $key =~ s/\[\d+\]/[PID]/;
  }

  while ($#min_dhms_delta < 3) {
    unshift(@min_dhms_delta, 0); # make sure that the dhms array is full
  }

  if (exists $Msg_Rec{$key} and defined $Msg_Rec{$key}->{ymdhms}) {
    my $passed = 1;
    $Msg_Rec{$key}->{count}++;
    if ($ymdhms[1] > $Msg_Rec{$key}->{ymdhms}[1]) { $ymdhms[0]--; }

    my @delta_dhms = Delta_DHMS(@{$Msg_Rec{$key}->{ymdhms}}, @ymdhms);
    foreach my $i (0..$#min_dhms_delta) {
      $passed = 0 if ($delta_dhms[$i] < $min_dhms_delta[$i]);
      last unless ($delta_dhms[$i] == $min_dhms_delta[$i]);
    }    
    if ($passed) {
      my $new = '';
      $new = new_msg($use, $key, $Msg_Rec{$key}->{count}, @delta_dhms);
      $Msg_Rec{$key}->{ymdhms} = [ @ymdhms ];
      $Msg_Rec{$key}->{count} = 1;
      return $new;
    } else {
      return '';
    }
  } else {
    my $rec;
    $rec->{ymdhms} = [ @ymdhms ];
    $Msg_Rec{$key} = $rec;
    return $msg;
  }
}


##
## ACTION SUBROUTINES
##

my %text_modes = (
  "black"       => "\033[30;1m",
  "red"         => "\033[31;1m",
  "green"       => "\033[32;1m",
  "yellow"      => "\033[33;1m",
  "blue"        => "\033[34;1m",
  "magenta"     => "\033[35;1m",
  "cyan"        => "\033[36;1m",
  "white"       => "\033[37;1m",
  "black_h"     => "\033[40;1m",
  "red_h"       => "\033[41;1m",
  "green_h"     => "\033[42;1m",
  "yellow_h"    => "\033[43;1m",
  "blue_h"      => "\033[44;1m",
  "magenta_h"   => "\033[45;1m",
  "cyan_h"      => "\033[46;1m",
  "white_h"     => "\033[47;1m",
  "bold"        => "\033[1m",
  "blink"       => "\033[5m",
  "inverse"     => "\033[7m",
  "normal"      => "\033[0m",
  "underscore"  => "\033[4m",
);
  
sub echo {
  my %args = (
              'MODES' => [ 'normal' ],
              @_
             );

  return if (exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'}));
  
  if ($args{'MODES'}[0] eq 'random') {
    my @mode_names = keys %text_modes;
    print $text_modes{$mode_names[rand $#mode_names]};
  } else {
    foreach my $mode (@{$args{'MODES'}}) {
      print $text_modes{$mode};
    }
  }
  print $args{'MESSAGE'};
  print $text_modes{'normal'};
  print "\n";
}

#
# ring_bell(args) -- send x number of control-G characters to the output.
#
sub ring_bell {
  my %args = (
              'RINGS' => 1,
              @_
             );
  my $sun_terminal = (`uname -s` eq 'SunOS\n');
  
  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});
  
  my $bells = $args{'RINGS'};
  for ( ; $bells > 0 ; $bells-- ) {
    print $BELL;
    sleep 1 if $sun_terminal; # SunOS needed this. Not sure about Solaris though
  }
}

#
# exec_command(args) -- fork and execute a command
#
sub exec_command {
  my %args = (@_);
  my $exec_pid;
  my $command;

  if (exists $args{'COMMAND'}) {
    $command = $args{'COMMAND'};
  } else {
    warn "$0: No command was specified in exec action.\n";
    return;
  }

  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

 EXECFORK: {
    if ($exec_pid = fork) {
      waitpid(-1, WNOHANG);
      return;
    } elsif (defined $exec_pid) {
      exec($command);
      } elsif ($! =~ /No more processes/) {
        # EAGAIN, supposedly recoverable fork error
        sleep 5;
        redo EXECFORK;
      } else {
        warn "$0: Can't fork to exec $command: $!\n";
      }
  }
  return;
}


{
  my $pipe_is_open;
  my $current_command_name;
  #
  # send_message_to_pipe -- send text to a pipe.
  #
  # usage: &send_message_to_pipe($program_to_pipe_to_including_the_vertical_bar_symbol,
  #               $message_to_send_to_the_pipe);
  # 
  
  sub send_message_to_pipe {
    my %args = (@_);
    my $command;

    if (exists $args{'COMMAND'}) {
      $command = $args{'COMMAND'};
    } else {
      warn "$0: No command was specified in pipe action.\n";
      return;
    }

    return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

    # open a new pipe if necessary
    if ( !$pipe_is_open or $current_command_name ne $command ) {
      # first close an open pipe
      close(PIPE) if $pipe_is_open;
      $pipe_is_open = 0;
      open(PIPE, "| $command") 
        or warn "$0: cannot open pipe to $command: $!\n" && return;
      PIPE->autoflush(1);
      $pipe_is_open = 1;
      $current_command_name = $command;
    }
    # send the text
    print PIPE "$args{'MESSAGE'}";

    if (not exists $args{'KEEP_OPEN'}) {
      close(PIPE) if $pipe_is_open;
      $pipe_is_open = 0;
    }
  }

  #
  # close_pipe_if_open -- used at the end of a script to close a pipe
  #     opened by &pipe_it().
  #
  # usage: &close_pipe_if_open();
  #
  sub close_pipe_if_open {
    if ($pipe_is_open) {
      close(PIPE);
    }
  }
}


#
# send_email -- send some mail using $MAILER.
#
# usage: &send_email($addresses_to_mail_to);
#
sub send_email {
  my $login = (getpwuid($<))[0];
  my %args = (
              'ADDRESSES' => $login,
              'SUBJECT' => 'Message from Swatch',
              @_
             );

  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

  my $addresses = $args{'ADDRESSES'};
  $addresses =~ s/:/,/g;

  if ($MAILER eq '') {
    warn "ERROR: $0 cannot find a mail delivery program\n";
    return;
  }

  open(MAIL, "| $MAILER $addresses")
    or warn "$0: cannot open pipe to $MAILER: $!\n" && return;

  print MAIL "To: $addresses\n";
  print MAIL "Subject: $args{SUBJECT}\n\n";
  print MAIL "$args{'MESSAGE'}\n";
  close(MAIL);
}


#
# write_message -- use $WRITE to send a message logged on users.
#
sub write_message {
  my %args = (@_);

  return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'});

  if ($WRITE eq '') {
    warn "ERROR: $0 cannot find the write(1) program\n";
    return;
  }

  if (exists($args{'USERS'})) {
    foreach my $user (split(/:/, $args{'USERS'})) {
      send_message_to_pipe(COMMAND => "$WRITE $user 2>/dev/null", 
                           MESSAGE => "$args{'MESSAGE'}\n");
    }
  }
}

use File::Tail;
my $Filename = '/var/log/ulog/syslogemu.log';
my $File = File::Tail->new(name=>$Filename, maxinterval => 1, interval => 1);
if (not defined $File) {
    die "/usr/local/bin/swatch: cannot read input \"$Filename\": $!\n";
}

LOOP: while (defined($_=$File->read)) {

    chomp;
    my $sanitized_ = $_;
    @_ = split;
    
    # quote all special shell chars
    $sanitized_ =~ s/([;&\(\)\|\^><\$`'\\])/\\$1/g;
    my @sanitized_ = split(/\s+/, $sanitized_);
    if (/INVALID|REPEATED|INCOMPLETE:LOGIN/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        ring_bell('RINGS' => "3", );
        next;
    }

    if (/(panic|halt)/) {
        echo('MESSAGE' => "$_", );
        ring_bell();
        next;
    }

    if (/Regents/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        ring_bell();
        next;
    }

    if (/ipfw:.*Deny ICMP:8.0/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/drip.wav &", );
        next;
    }

    if (/ipfw:.*Deny TCP .*:6000/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/camera.wav &", );
        next;
    }

    if (/ipfw:.*Deny UDP .*:513/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/flush.wav &", );
        next;
    }

    if (/ipfw:.*Deny TCP .*:21/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 -q /root/wavs/vault.wav &", );
        next;
    }

    if (/PROTO=TCP .*DPT=80/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/tcp80.mp3 &", );
        next;
    }
    if (/PROTO=TCP .*DPT=23/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/tcp23.mp3 &", );
        next;
    }

    if (/UDP .*=1300007/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/udp137.mp3 &", );
        next;
    }

    if (/PROTO=ICMP/) {
        echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", );
        exec_command('COMMAND' => "mpg123 /root/wavs/ping.mp3 &", );
        next;
    }

    if (/.*/) {
        echo('MESSAGE' => "$_", );
        next;
    }

}

Led Firewall (netled)

FW led box without labels

Above is a picture of a Box with leds which lightup when certain network packets are seen on the network.

It is connected to the parallel port of a PC (using port 0x3bc)

Makefile:

CC=gcc
CCOPT=-O2 -I/usr/include/pcap
LIBS=-lpcap

all:	netled

netled:	netled.c
	$(CC) $(CCOPT) -o netled netled.c $(LIBS)

netled.c code ( older version, i will upload a newer if found)

#include <stdio.h>
#include <pcap.h>
#include <netinet/in.h>
#include <sys/io.h>
#include <sys/time.h>
#include <signal.h>
#include "ether.h"
#include "ethertype.h"
#include "ip.h"
#include "tcp.h"

#define LP_PORT 0x3bc
#define CAPLEN 64
#define DELAY 30000

char *program_name;
static pcap_t *pd;
const u_char *snapend;
u_char leds = 0;
int mode = 0;
long packets;

void do_leds() {
    mode ^= 1;

    if(!leds && mode) return;

    if(mode) {
	outb(leds, LP_PORT);
	leds = 0;
    }
    else {
	outb(0, LP_PORT);
    }
}

int do_tcp(register const u_char *bp) {
    register const struct tcphdr *tp;
    u_int16_t sport, dport;

    tp = (struct tcphdr *)bp;
    sport = ntohs(tp->th_sport);
    dport = ntohs(tp->th_dport);

    if (sport == 22 || dport == 22) {
	leds |= 8;
    }

    return;
}

int do_ip(register const u_char *bp, register u_int length) {
    register const struct ip *ip;
    register u_int hlen, len, len0, off;
    register const u_char *cp;

    ip = (const struct ip *)bp;

    if ((u_char *)(ip + 1) > snapend ||
	length < sizeof (struct ip)) {
	return;
    }

    hlen = IP_HL(ip) * 4;
    if (hlen < sizeof (struct ip)) {
	fprintf(stderr, "bad-hlen %d\n", hlen);
	return;
    }

    len = ntohs(ip->ip_len);
    if (length < len)
	(void)printf("truncated-ip - %d bytes missing!",
	    len - length);
    len -= hlen;
    len0 = len;


    off = ntohs(ip->ip_off);
    if ((off & 0x1fff) == 0) {
	cp = (const u_char *)ip + hlen;

	switch(ip->ip_p) {

	    case IPPROTO_TCP:
		// fprintf(stderr, "TCP!\n");
		leds |= 128;
		do_tcp(cp);
		break;

	    case IPPROTO_UDP:
		// fprintf(stderr, "UDP!\n");
		leds |= 64;
		break;

	    case IPPROTO_ICMP:
		// fprintf(stderr, "ICMP!\n");
		leds |= 32;
		break;

	    default:
		fprintf(stderr, "HUH? [ip_proto: %i]\n", ip->ip_p);
		break;
	}
    }
}

void handler(u_char *user, const struct pcap_pkthdr *h, const u_char *p) {
    u_int caplen = h->caplen;
    u_int length = h->len;
    u_short ether_type;
    register const struct ether_header *ep;
    u_short extracted_ethertype;

    if (caplen < ETHER_HDRLEN) {
	printf("c: [%d] e: [%d]\n", caplen, ETHER_HDRLEN);
	return;
    }

    ep = (struct ether_header *)p;
    ether_type = ntohs(ep->ether_type);

    snapend = p + caplen;
    p += ETHER_HDRLEN;
    length -= ETHER_HDRLEN;
    if (ether_type > ETHERMTU) {


	switch (ether_type) {

	    case ETHERTYPE_ARP:
	    case ETHERTYPE_REVARP:
		// leds |= 8;
                // fprintf(stderr, "(R)ARP\n");
		break;

	    case ETHERTYPE_IP:
		// fprintf(stderr, "IP!\n");
		do_ip(p, length);
		break;

	    default:
		fprintf(stderr, "HUH? [et: %i]\n", ether_type);

	}
    }
}

int main(int argc, char *argv[]) {
    char *device;
    char ebuf[PCAP_ERRBUF_SIZE];
    register char *cp;
    u_char *pcap_userdata;
    void *sig_old;
    struct itimerval timer_old, timer_new;

    if ((cp = (char *)strrchr(argv[0], '/')) != NULL)
	program_name = cp + 1;
    else
	program_name = argv[0];

    if(ioperm(LP_PORT,3,1))
	error("IOPEEEEERM!\n");

    sig_old = signal(SIGALRM, do_leds);
    if (sig_old == SIG_ERR)
	error("SIGNAAAAAAAAAAAAAL!\n");
    timer_new.it_value.tv_usec = DELAY;
    timer_new.it_value.tv_sec = 0;
    timer_new.it_interval.tv_usec = DELAY;
    timer_new.it_interval.tv_sec = 0;
    if(setitimer(ITIMER_REAL, &timer_new, &timer_old))
	error("SETITIMEEEEEER!\n");

    device = pcap_lookupdev(ebuf);
    if (device == NULL)
	error("%s", ebuf);

    pd = pcap_open_live(device, CAPLEN, 1, 1000, ebuf);
    if (pd == NULL)
	error("%s", ebuf);

    if (pcap_loop(pd, -1, handler, pcap_userdata) < 0) {
	(void)fprintf(stderr, "%s: pcap_loop: %s\n",
	    program_name, pcap_geterr(pd));
	exit(1);
    }

    return 0;
}

Fireworks disaster Enschede

I lived in Enschede at that moment.

A book about the disaster

It was a beautiful day in May, and a lot of people were outside enjoying themselves.

Monique was working in the garden, and i was sitting in the living room.

We heard some commotion and saw the smoke.
Some people said that the Chinese restaurant in that neighbourhood (containing illegal fireworks) was burning.

We heard a big explosion and Monique was blown off her feet, and sat down in the garden.

I saw the large livingroom window bulging to the inside and moving outside again. (This had loosen the mortar around the window)

When seeing the now black smoke, we went inside, to the opposite site of our home, and turned on the news/checked websites.

We were lucky that there was a large factory between us and the blast (Polaroid factory)

Large pieces of cement where found 100m further than our house was.

Below some of my own media, for a better understanding of the destruction and aftermath of the disaster check the divers websites.

A scary time.