The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Monday, May 15, 2000

More MONitoring of the NETwork

comment on monnet—odd stuff you see watching the network So I'm still working on monnet. I basically started over from scratch, reworking the code although the basic structure is the same from the old version. The output from the program looks like:

0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.72.81   TCP     25945    80  A    
00C07B4D7D81 0040332E103C IPv4        205.229.72.81   208.26.72.3     TCP        80 25945  AP   
00C07B4D7D81 0040332E103C IPv4        205.229.72.81   208.26.72.3     TCP        80 25945  AP  F
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.72.81   TCP     25945    80  A    
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.191  TCP     25944    80  A   F
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.190  TCP     25950    80     S 
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.72.81   TCP     25945    80  A   F
00C07B4D7D81 0040332E103C IPv4        205.229.74.218  208.26.72.3     TCP        80 25944    R  
00C07B4D7D81 0040332E103C IPv4        205.229.74.190  208.26.72.3     TCP        80 25950  A  S 
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.190  TCP     25950    80  A    
00C07B4D7D81 0040332E103C IPv4        205.229.72.81   208.26.72.3     TCP        80 25945  A    
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.190  TCP     25950    80  AP   
00C07B4D7D81 0040332E103C IPv4        205.229.74.190  208.26.72.3     TCP        80 25950  A    
00C07B4D7D81 0040332E103C IPv4        205.229.74.190  208.26.72.3     TCP        80 25950  AP   
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.190  TCP     25950    80  A    
00C07B4D7D81 0040332E103C IPv4        205.229.74.190  208.26.72.3     TCP        80 25950  AP   
00C07B4D7D81 0040332E103C IPv4        205.229.74.190  208.26.72.3     TCP        80 25950  A   F
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.190  TCP     25950    80  A    
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.190  TCP     25950    80  A   F
00C07B4D7D81 0040332E103C IPv4        205.229.74.190  208.26.72.3     TCP        80 25950  A    
0040332E103C 00C07B4D7D81 IPv4        208.26.72.3     205.229.74.190  TCP     26000    80     S 
02608CD87517 00C07B4D7D81 ARP         A:request ETH:IPv4 208.26.72.2     208.26.72.1    
00C07B4D7D81 02608CD87517 ARP         A:reply   ETH:IPv4 208.26.72.1     208.26.72.2    
0040332E103C 00C07B4D7D81 ARP         A:request ETH:IPv4 208.26.72.3     208.26.72.1    
00C07B4D7D81 0040332E103C ARP         A:reply   ETH:IPv4 208.26.72.1     208.26.72.3    
00C07B4D7D81 0040332E103C IPv4        208.26.72.1     208.26.72.3     ICMP    redirect host             208.26.72.4    

And the report it can generate:


Total:                                                         64,813   13.45M
    IPv4                                                       64,017   12.55M
        ICMP                                                      245   16.34K
            echo reply                                             18    1.23K
            error                                                 147   10.15K
                host unreachable                                    4     436 
                port unreachable                                  142    9.68K
                comm prohibited by filters                          1      46 
            redirect                                                8     368 
                host                                                8     368 
            echo request                                           18    1.21K
            TTL                                                    54    2.43K
                > 0 during transit                                 54    2.43K
        TCP                                                    58,998   11.66M
        UDP                                                     4,774  516.03K
    ARP                                                           796   33.38K
        A:request                                                 425   17.35K
        A:reply                                                   371   16.03K

Generating that report while the program is running was tricky. I didn't want to loose any packets so creating a thread or process (I am doing this under Unix) to handle that should minimize the number of packets lost. I'll skip threads since personally I don't like the way pthreads works (I think the API sucks but that's me and I really can't quantify it more than that) and that leaves fork() (at least under Unix).

But I don't feel that good about the code, since I'm now dealing with signals, and the semantics of signals under Unix is … well … it sucks. I'm sure I have race conditions in there.


Stripping strips from a website

I started reading a new on-line strip, Player Versus Player. Seems promising but I'd like to read the archive, of which it reaches back to May of 1998, making it two full years of archives to go through.

It's a simple enough matter to write a program that downloads the entire archive of strips:


while(1)
{
  sprintf(filename,"%d%02d%02d.gif",year,month,day);
  sprintf(url,"http://www.pvponline.com/archive/%d/pvp%s",year,filename);
  sprintf(cmd,"lynx -source %s >%s",url,filename);
  system(cmd);
  sleep(10);		/* be nice on their server */
  day ++;
  if (day > daysinmonth(year,month))
  {
    day = 1;
    month++;
    if (month > 12)
    {
      month = 1;
      year ++;
      if (isthistoday(year,month,day)) break;
    }
  }
}

I feel somewhat odd about doing that though, seeing how they get their revenue through advertising (not that I agree that's the best way to make money, but that's beside the point). Well, that and if they check their logs and see a bunch of requests for just the strips, every 10 seconds, well, in case I do end up liking the strip I don't want to be banned from their server.


Elapsed time is …

Okay, in monnet I'm keeping track of how long the program runs so when the report is printed, you can see how much time has elapsed since the program started. I want the display to look something like:


10d 14h 13m 33s

Make it easier to read than something like


915213s

Under ANSI C, you have the various functions under time.h and the “official” way to calculate elapsed time is to call difftime() (as you portably can't assume that time_t is in sections, or even a integral type). That returns, as a double, the number of seconds between the two time values.

The problem is, you can't really take that result, stick it into a struct tm and call mktime() to renormalize it, as the value could overflow an int (which is what each field is defined as in struct tm). An int is defined as a minimum of 16 bits, which isn't even enough to record the number of seconds in a day. Sure, on modern systems ints are probably 32 bits in size, but that only leaves you some 68 years before the seconds overflow (it should be fun in 2038).

So it's more portable to do the math directly.

So, I thought I'd be cute and try to do the minimal amount of math possible, and in looking over math.h I saw modf(), which splits a double into its integral portion and fractional portion. So, I tried:


  diff = difftime(end,start);

  diff /= 60.0;
  tmp   = modf(diff,&diff);
  sec   = tmp * 60.0;

  diff /= 60.0;
  tmp   = modf(diff,&diff);
  min   = tmp * 60.0;

  diff /= 24.0;
  tmp   = modf(diff,&diff);
  hour  = tmp * 24.0;

  diff /= 365.0;
  tmp   = modf(diff,&diff);
  day   = tmp * 365.0;

  year  = diff;

only to have it fail miserably. Even several variations on that didn't work. So I bit the bullet and did it the old fasion way:


#define SECSMIN         (60.0)
#define SECSHOUR        (60.0 * 60.0)
#define SECSDAY         (60.0 * 60.0 * 24.0)
#define SECSYEAR        (60.0 * 60.0 * 24.0 * 365.2422)

  diff = difftime(end,start);

  year = (int)(diff / SECSYEAR);
  diff -= ((double)year) * SECSYEAR;

  day = (int)(diff / SECSDAY);
  diff -= ((double)day) * SECSDAY;

  hour = (int)(diff / SECSHOUR);
  diff -= ((double)hour) * SECSHOUR;

  min = (int)(diff / SECSMIN);
  diff -= ((double)min) * SECSMIN;

  sec = (int)(diff);

Obligatory Picture

[It's the most wonderful time of the year!]

Obligatory Links

Obligatory Miscellaneous

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: http://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

http://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2019 by Sean Conner. All Rights Reserved.