Updates from August, 2011 Toggle Comment Threads | Keyboard Shortcuts

  • danw 10:54 am on 2011-08-16 Permalink | Reply
    Tags: perl,   

    sarpipe.pl – machine readable solaris sar output 

    I’ve been scripting somewhat with sar on Solaris 10. The major problem is that for some reason there is no flag to output machine readable output (ie. make it easy to import into spreadsheets or other script). The most imporant part was adding a time field to each and every block device to make it much easier to create disk statistics.

    So I threw one together sarpipe.pl:

    #!/usr/bin/perl -w
    use strict;
    
    #default field delimiter/separator
    my $delim = "|";
    
    while($_ = shift @ARGV) {
            if($_ =~ m/--delim/) {
                    #change the default field delimter
                    $delim = shift(@ARGV);
            }
            else {
                    die "Usage: sar [-A...] | $0 [--delim seperator]n";
            }
    }
    
    #preset so we don't get any concat empty val errors
    my $latesttime = "";
    #loop through the sar output
    while(<>) {
            chomp;
            #catch time field of output, remove from line
            if($_ =~ s/^(dd[:]dd[:]dd|Average)//) {
                    $latesttime = $1 . $delim;
            }
            #remove leading and tailing whitespace
            $_ =~ s/(^s+|s+$)//;
            #replace spaces with field delimiter
            $_ =~ s/s+/$delim/g;
            #if the line contains any content, print time field and line
            print $latesttime  . $_ if($_ =~ m/^.+$/);
            print "n";
    }
    

    In use:

    user@example$ ./sarpipe.pl  -h
    Usage: sar [-A...] | ./sarpipe.pl [--delim seperator]
    user@example$ sar -d | ./sarpipe.pl | more
    
    SunOS|bcaeao|5.10|Generic_144488-10|sun4u|08/16/2011
    
    00:00:00|device|%busy|avque|r+w/s|blks/s|avwait|avserv
    
    00:10:01|md110|0|0.0|0|1|0.0|29.9
    00:10:01|md111|0|0.0|0|0|0.0|0.0
    00:10:01|md115|1|0.0|2|30|0.0|15.3
    00:10:01|md116|0|0.0|0|0|0.0|12.8
    00:10:01|md120|0|0.0|0|1|0.0|27.4
    00:10:01|md121|0|0.0|0|0|0.0|0.0
    00:10:01|md125|1|0.0|2|30|0.0|13.4
    00:10:01|md126|0|0.0|0|0|0.0|13.0
    00:10:01|md130|0|0.0|0|1|0.0|0.0
    ...
    Average|ssd35,c|0|0.0|0|0|0.0|0.0
    Average|ssd35,g|1|0.0|2|179|0.0|10.1
    Average|ssd36|0|0.0|0|0|0.0|0.0
    Average|ssd36,a|0|0.0|0|0|0.0|0.0
    Average|ssd36,b|0|0.0|0|0|0.0|0.0
    Average|ssd36,c|0|0.0|0|0|0.0|0.0
    Average|ssd36,f|0|0.0|0|0|0.0|0.0
    Average|ssd36,g|0|0.0|0|0|0.0|0.0
    Average|ssd36,h|0|0.0|0|0|0.0|0.0
    Average|ssd38|0|0.0|1|5|0.0|2.2
    Average|ssd38,c|0|0.0|0|0|0.0|0.0
    Average|ssd38,g|0|0.0|1|5|0.0|2.2
    user@example$ 
    

    As you can see, it just formats the sar output to be easily used. It does not remove empty lines or remove annoying psudo block devices (ssd36,h). The default delimiter is a pipe because a comma would interfere with device names with a comma. If you change the delimiter via command line (–delim) be sure to be aware of shell escapes (eg –delim ! not –delim !).

     
  • danw 10:42 pm on 2009-11-01 Permalink | Reply
    Tags: networking   

    dhcpdump and patch 

    I was at work the other day and the whole network went down. DHCP and upstream routers went out and the network went kinda nuts. I tried dhcpdump to get a look at the traffic on the local network segment.

    Sadly it doesn’t work with pcap files (from tcpdump or wireshark), it only works with live network interfaces and must be run as rroot. So I decided to add pcap file to dhcpdump 1.8. I tried contacting the author but didn’t hear back, so I decided to put it up here.

    pcapfile.patch

    • add option to read from pcap file
    • change to read time from pcap packet header
    --- dhcpdump-1.8/dhcpdump.c     2008-06-23 20:26:52.000000000 -0700
    +++ dhcpdump.c  2009-09-30 15:22:10.000000000 -0700
    @@ -71,7 +71,7 @@
     void   printHexString(u_char *data, int len);
    
     void usage() {
    -       printf("Usage: $0 <-i interface> [-h macaddress]n");
    +       printf("Usage: $0 <-i interface|-f pcapfile> [-h macaddress]n");
            exit(0);
     }
    
    @@ -80,6 +80,7 @@
            pcap_t *cap;
            struct bpf_program fp;
            char    *interface = NULL;
    +       char    *pcap_file = NULL;
    
            for (i = 1; i < argc; i++) {
                    if (argv[i] == NULL || argv[i][0] != '-') break;
    @@ -90,6 +91,9 @@
                    case 'i':
                            interface = argv[++i];
                            break;
    +               case 'f':
    +                       pcap_file = argv[++i];
    +                       break;
                    default:
                            fprintf(stderr, "%s: %c: uknown optionn",
                                argv[0], argv[i][1]);
    @@ -97,13 +101,24 @@
                    }
            }
    
    -       if (interface == NULL) usage();
    +       if (    //no interface or pcap file specified
    +               ((interface == NULL) && (pcap_file == NULL)) ||
    +               //both an interface and a pcap file specified
    +               ((interface != NULL) && (pcap_file != NULL))
    +               )
    +               usage();
    
            if (hmask)
                    regcomp(&preg, hmask, REG_EXTENDED | REG_ICASE | REG_NOSUB);
    
    -       if ((cap = pcap_open_live(interface, 1500, 1, 100, errbuf)) == NULL)
    -               errx(1, "pcap_open_live(): %s", errbuf);
    +       if (interface != NULL) {
    +               if ((cap = pcap_open_live(interface, 1500, 1, 100, errbuf)) == NULL)
    +                       errx(1, "pcap_open_live(): %s", errbuf);
    +       }
    +       else {
    +               if ((cap = pcap_open_offline(pcap_file,errbuf)) == NULL)
    +                       errx(1, "pcap_open_offline(): %s", errbuf);
    +       }
            if (pcap_compile(cap, &fp, "udp and (port bootpc or port bootps)", 0, 0) < 0)
                    errx(1,"pcap_compile: %s", pcap_geterr(cap));
            if (pcap_setfilter(cap, &fp) < 0)
    @@ -148,12 +163,11 @@
            offset += sizeof(struct udphdr);
    
            {
    -               struct timeval tp;
    -               gettimeofday(&tp, NULL);
    +               //get time from pcap to enable reading from capture file
                    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S.",
    -                   localtime(&(tp.tv_sec)));
    +                   localtime(&(h->ts.tv_sec)));
                    sprintf(timestamp + strlen(timestamp), "%03ld",
    -                   tp.tv_usec / 1000);
    +                   h->ts.tv_usec / 1000);
            }
    
            strcpy(mac_origin, ether_ntoa((struct ether_addr *)eh->ether_shost));
    
     
c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel