Configuring a Cisco 1700 series access router for an ADSL connection with tunneled IPv6

I decided to re-configure my home router from scratch so that I could tidy up the config and ACLs which had been messily generated over time.

The main reason being my old IPv6 ACLs pretty much where non-existent and before properly configuring my lan for auto assigning v6 IPs, I wanted to limit the incoming traffic.

I’ve included an example config below with comments

!! Basic stuff
version 12.4
service timestamps debug datetime msec
service timestamps log datetime msec
service password-encryption
boot-start-marker
boot-end-marker
hostname router1-man !! You probably want to change this to a relevant hostname
!
!! Security stuff
no cdp run
no ip http server
no ip http secure-server
no mmi auto-configure
no mmi pvc
banner exec ^C
Welcome to $(hostname) (:
^
!
banner login ^
##############################################
# THIS SYSTEM IS FOR AUTHORIZED USERS ONLY. #
# !! IF YOU DO NOT HAVE ACCESS DISCONNECT NOW !! #
##############################################
^C
!
!! Access stuff
snmp-server community thisisnotmysnmppassword RO admin !! You probably want to change this to a sensible password
ip domain-name router1-man.nodehost.co.uk !! You probably want to change this to a relevant hostname
crypto key generate rsa
ip ssh time-out 60
ip ssh authentication-retries 2
!
!! Logging stuff
logging on
logging 10.44.200.5 !! You probably want to change this to a server that is listening for syslog traffic
logging trap informational
logging console debug
logging monitor debug
no logging monitor
!
!! NTP stuff
ntp clock-period 17179944
ntp server 83.98.201.133 !! These are the fedora NTP servers, feel free to change them
ntp server 87.98.238.185
ntp server 147.231.100.5
ntp server 193.55.167.1
!
!! Login stuff
no aaa new-model !! I don't use a TACAS server for my house but you can!
enable password enable !! This clearly isn't my enable password but I don't feel like putting the hash of it in public.
username myuser privilege 15 password mypass !! This will login directly to enable access, feel free to change the privilege level.
!
!! IP settings
ipv6 cef
ipv6 unicast-routing
ip cef
ip forward-protocol nd
ip auth-proxy max-nodata-conns 3
ip admission max-nodata-conns 3
!
!! DNS stuff
ip domain name nodehost.co.uk !! You probably want to change this to a domain name that is relevant to you
ip name-server 8.8.8.8 !! These are the google and HE nameservers, feel free to change them
ip name-server 8.8.4.4
ip name-server 2001:470:20::2
!
!! IPv6 Tunnel
interface Tunnel0
 description IPv6 HE Tunnel
 ip access-group IPV6_IN in
 ip access-group IPV6_OUT out
 no ip address
 ipv6 address 2001:470:xx:xx::2/64 !! Change this to your client IPv6 address
 ipv6 enable
 ipv6 virtual-reassembly
 tunnel source Dialer1 !! You can use an IP address here if you have a static IP, I do not.
 tunnel destination xx.xx.xx.xx !! Change this to your server IPv4 address
 tunnel mode ipv6ip
!
!! ADSL interface
interface ATM0
 description ADSL interface
 no shut
 mtu 1432
 no ip address
 no ip mroute-cache
 no atm ilmi-keepalive
 logging event atm pvc state
 logging event atm pvc autoppp
 dsl operating-mode auto
 pvc 0/38 !! Change this to the vpi / vci of your ISP
 encapsulation aal5mux ppp dialer !! Change this if your ISP uses different encapsulation
 dialer pool-member 1
 !
!
!! Dialer interface
interface Dialer1
 description Dialer interface
 ip access-group IPV4_IN in
 ip access-group IPV4_OUT out
 no shut
 mtu 1432
 ip address negotiated !! Change this if you have a static IP
 ip nat outside
 ip virtual-reassembly max-reassemblies 1024
 encapsulation ppp
 dialer pool 1
 ppp chap hostname 00000000000@myisp.com
 ppp chap password myubersecurepasswordhere
 ppp pap sent-username 00000000000@myisp.com password myubersecurepasswordhere
!
!! ISDN interface
interface BRI0
 description ISDN interface
 shut
 no ip address
!
!! Internal FE interface
interface FastEthernet0
 description Internal interface
 ip access-group IPV6_IN in
 ip access-group IPV6_OUT out
 no shut
 ip address 10.44.200.254 255.255.255.0 !! Change this to a relevant IP address
 ip nat inside
 ip virtual-reassembly
 speed 100
 ipv6 enable
 ipv6 nd ra-interval 60 !! You might want to change this, works for me though
 ipv6 nd ra-lifetime 180 !! You might want to change this, works for me though
 ipv6 nd other-config-flag !! You might want to change this, works for me though
 ipv6 address 2001:470:xx:xx::/64 eui-64
!
!! Routes
ipv6 route ::/0 Tunnel0
ip route 0.0.0.0 0.0.0.0 Dialer1
!
!! NAT rules
ip nat inside source list 1 interface Dialer1 overload !! You might want to change this if you have a pool if ips
ip nat inside source static tcp xx.xx.xx.xx 8080 interface Dialer1 8080 !! Probably want to delete this - it's a webserver for my house
ip nat inside source static tcp xx.xx.xx.xx 3406 interface Dialer1 3406 !! Probably want to delete this - it's a vpn endpoint for my house
ip nat inside source static tcp xx.xx.xx.xx 22 interface Dialer1 2020 !! Probably want to delete this - it's a ssh gateway for my house
!
!! ACLs
access-list 1 remark Default traffic
access-list 1 permit any !! You might want to change this to deny all depending on how you care to do your ACLs
dialer-list 1 protocol ip permit
!
ip access-list standard admin
 remark Admin traffic
 permit 10.44.200.0 0.0.0.255 !! Change this to a relevant IP address
 deny any log
!
ipv6 access-list IPV6_IN
 remark Incoming IPv6 Traffic
 permit icmp any any !! Allow ICMP (ping)
 permit tcp any any established !! Allow established TCP connections
 permit tcp any any eq domain !! Allow incoming TCP DNS stuff - might want to delete this
 permit udp any any eq domain !! Allow incoming UDP DNS stuff - might want to delete this
 deny ipv6 any any log !! Drop everything else
!
ipv6 access-list IPV6_OUT
 remark Outgoing IPv6 Traffic
 permit ipv6 any any !! Permit any outgoing traffic - yeah I'm lazy
!
ip access-list extended IPV4_IN
 remark Incoming IPv4 Traffic
permit GRE xx.xx.xx.xx 255.255.255.255 any !! Allow GRE from the IPv6 tunnel server
permit ESP xx.xx.xx.xx 255.255.255.255 any !! Allow ESP from the IPv6 tunnel server
permit 41 xx.xx.xx.xx 255.255.255.255 any !! Allow 41 from the IPv6 tunnel server
 permit icmp any any !! Allow ICMP (ping)
 permit tcp any any established !! Allow established TCP connections
 permit tcp any eq domain any !! Allow incoming TCP DNS stuff - might want to delete this
 permit udp any eq domain any !! Allow incoming UDP DNS stuff - might want to delete this
 permit tcp any any eq 3406 !! Probably want to delete this - it's a vpn endpoint for my house
 permit tcp any any eq 8080 !! Probably want to delete this - it's a webserver for my house
 permit tcp any any eq 2020 !! Probably want to delete this - it's a ssh gateway for my house
 deny ip any any log !! Drop everything else
!
ip access-list extended IPV4_OUT
 remark Outgoing IPv4 Traffic
 permit ip any any !! Permit any outgoing traffic - yeah I'm lazy
!
!! VTY lines
line vty 0 15
 access-class admin in
 privilege level 15
 password mysemiuberawesomepassword
 login local
 transport input ssh
!
end

I might update it to support VPN connections rather than tunnelling them though to a openvpn box, but openvpn + SSL certs just work for when I want lan access (not that often..). For the rest of the time just plain old SSH with a little tunnelling where needed does the job. One thing that does need doing is sending the system logs over to the syslog box - Currently things like NAT table overflow warnings just spam the console. Once I get a bit of time to re-configure rancid I’ll start playing with the configs, for now they work just fine.

Wordpress plugin

Date09 Apr 2011 ContentComments

Hi to anyone that reads this.

I wasn’t going to post about this as it is not something I think it neat or I should be proud of, but I seem to be getting a few links though to this blog so I thought I should post something!

I recently was re-designing (if you can call it that) this blog and was looking to integrate mint. The plugin utilizes;

  • admin_menu & admin_notices wordpress actions for displaying/allowing editing of settings.
  • wp_head wordpress action for outputting the mint integration code into the header.
  • rss_head, rss2_head, atom_header & the_permalink_rss wordpress actions for integration of birdfeeder.

The script goes out of its way to ensure it does not break html or xml output due to PHP errors.

The plugin can be downloaded from here and offers mint integration into the header (tracking code) & bird feeder integration for the rss feeds. Both of these are optional and can be configured from the settings page.

The requirements are;

  • PHP
  • A working wordpress install (use the latest :3)
  • A working mint install (on the same server – due to how birdfeeder integration works this has to be the case without major hacking of the plugin)
  • The ability to read the error messages and fill out the settings page

Why mint? It has an awesome AJAX interface for viewing stats, remains fast on pretty large sites, supports plugins and best of all the code isn’t encoded in any way.

The downside is a 30$ license per site but this is supporting an awesome developer who keeps the product updated. Because the code is open you can also hack it to your needs and release any plugins/themes back into the community.

License? It is licensed under GPLv3 and I take no responsibility if it breaks your site ;) But I might fix it if you tell me it broke something (I’m running it in production and have noticed no issues in testing or live use).

Developing for wordpress was easier than I first though – the action hooks makes life very easy even if it is a little tricky to figure out how plugins are stored and tracked in extend it’s self. I don’t think I’ll be making a habit of developing plugins but will feel happy hacking them up as needed.

canhazip

Date30 Mar 2011 ContentComments

I was a little bored this afternoon so made canhazip.info! Inspired by the awesome service icanhazip.com run by RackerHacker, it basically does the same thing but there are some differences.

Basic Usage

http://canhazip.info/

This will return your public IP - if you have dual stack (IPv4 and IPv6) then it will return your v6 address.

Specific IP type

http://ipv4.canhazip.info/

This will return your public IPv4 address if you are have a working one, else it will time-out (uses an A record).

http://ipv6.canhazip.info/

This will return your public IPv6 address if you are have a working one, else it will time-out (uses an AAAA record).

Output format

By default the output will be plain text however you can optionally pass a format to be returned. To pass a format simply add / to the end of the URL.

Accepted formats are:

  • xml

  • json

  • yaml

  • PHP (serialize of an array)

  • plain

Example usage:

http://canhazip.info/xml

FAQ

icanhazip exists, why another service that does the same thing?
  1. Because I can
  2. Because .info domains were on special offer ($1.87!)
  3. The servers hosting the site are in London and Manchester not the US (latency)
  4. The secondary service I was using previously no longer exists (I like basic redundancy)
Do you keep logs

I have logs from the web server which I keep for a few days just in case there is any abuse. These are not shared with anyone and access to the server is heavily restricted.

Why different formats?

For developers wanting more than plain text. I plan to add in extended information such as GeoIP and the option to specify an IP to get the info for. This will appear in time as I get randomly bored.

Is this reliable

I make no guarantee but the 2 servers are split between two data centres with multiple A/AAAA records per name. The NS servers are also split between 3 providers and in total there are 7.

Example usage

(I currently use this to keep my TunnelBroker endpoint updated) - It could probably be done much nicer but this kinda just works.

#!/usr/bin/php
<?php
 $PASSWORD = "";
 $TUNNELID = 0;
 $USERID = "";
 $currentIP = @file_get_contents('http://ipv4.canhazip.info/');
 if(empty($currentIP)){
 $currentIP = @file_get_contents('http://ipv4.icanhazip.com/');
 }

if(empty($currentIP)){
 die('Could not get current IP'."\n");
 }

$currentIP = trim($currentIP);
 $return = file_get_contents("https://ipv4.tunnelbroker.net/ipv4_end.php?ipv4b=" . $currentIP . "&pass=" . $PASSWORD . "&user_id=" . $USERID . "&tunnel_id=" . $TUNNELID);

if(strpos($return, "That IPv4 endpoint is already in use.") !== False){
 print "IP has not changed";
 print "\n";
 }else if(strpos($return, "Your tunnel endpoint has been updated to:") !== False){
 print "Tunnel endpoint has been updated";
 print "\n";
 }else{
 print "Unknown return!?!?!";
 print $return;
 print "\n";
 }
?>
Another example

Basic screen scraping example (I use this to keep my Cluenet VPN endpoint updated)

#!/usr/bin/php
<?php
 $ACCESSKEY = "";
 $NODENAME = "";

$currentIP = @file_get_contents('http://ipv4.canhazip.info/');
 if(empty($currentIP)){
 $currentIP = @file_get_contents('http://ipv4.icanhazip.com/');
 }

if(empty($currentIP)){
 die('Could not get current IP'."\n");
 }

$currentIP = trim($currentIP);
 $bnlTable = @file_get_contents('http://a.core.cluenet.org/main/cluevpnpanel.php?page=printbnl');
 $bnlTable = explode('<table border=6 class=\"wikitable sortable\">', $bnlTable); $bnlTable = explode('</table>', $bnlTable[0]); $bnlTable = str_replace('</tr>', "", $bnlTable[0]); $bnlTable = explode('<tr>', $bnlTable); unset($bnlTable[0]); unset($bnlTable[1]);
 $nodes = array();

foreach($bnlTable as $entry){
 $entry = str_replace('</td>', "", $entry); $entry = explode('<td align=center>', $entry);
 $nodes[trim($entry[1])] = array(
 'id' => trim($entry[2]),
 'ip' => trim($entry[3]),
 'ipv6′ => trim($entry[4]),
 'port' => trim($entry[5]),
 'ipv6pref' => trim($entry[6]),
 'subnet' => trim($entry[7]),
 );
 }

$currentVPNIP = $nodes[$NODENAME]['ip'];
 if($currentIP != $currentVPNIP){
 /* Update IP */
 $ch = curl_init ("http://a.core.cluenet.org/main/cluevpnpanel.php?page=updateiphandle");
 curl_setopt($ch, CURLOPT_COOKIE, 'clueauth_tokenstack='.$ACCESSKEY);
 curl_setopt($ch, CURLOPT_POSTFIELDS, 'nodename='.$NODENAME.'&newip='.$currentIP.'&newport=3406&submit=Change');
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
 $output = curl_exec ($ch);

if(strpos($output, 'Success.') != 0){
 die('IP Updated Successfully'."\n");
 }else{
 die('IP Not Updated Successfully'."\n");
 }
 }else{
 die('IP has not changed'."\n");
 }
?>

Unix time to human readable?

You can quickly convert Unix time to a human readable format by using the date command. This proves to be very helpful for bash scripts etc when you don’t feel like calling out to Perl.

Quick example:

root@localhost [/]# date -d @1290705757
Thu Nov 25 18:22:37 CET 2010

You can also format the output of date to suit your needs, for example:

root@localhost [/]# date -d@1290705757 +"%H:%M:%S %d/%m/%Y"
18:22:37 25/11/2010

As expect this can very easily be scripted for example I was checking create times on some cPanel accounts:

root@localhost [/var/cpanel/users]# for user in *; do echo -n "$user: "; date -d@$(grep STARTDATE $user | cut -d’=’ -f2); done
damian: Thu Nov 18 21:17:44 CET 2010
test: Mon Nov 8 00:01:04 CET 2010
bob: Mon Nov 15 17:34:18 CET 2010

System activity reporter

Date07 Dec 2010 ContentComments

Ever wanted to be able to get historical performance data on your linux system without setting up an entire rrd based graphing system? Maybe you don’t even want graphs you just want to know that if needed you can find out what your memory usage was last week.

A nice simple program is the system activity reporter or SAR.

To get started you’ll want to install and start sysstat, on a centos box this can be done as below:

# Make sure the system is up to date
yum update

# Install the sysstat program (includes sar and iostat)
sudo yum install sysstat

# Make sure sysstat is enabled
chkconfig sysstat on

# Start sysstat – this starts the system activity data collector
service sysstat start

Ok once we have sysstat installed there are a few programs we can use to get performance data, iostat and sar (there are loads of other things such as mpstat, pidstat, nfsiostat, cifsiostat etc but for this post I’ll only be covering the 2). I’ll give you some basic examples of what we can do with these tools but they are very extensive so I suggest that you check out the man pages (man sar + man iostat)

IOStat

iostat is mainly for reporting CPU statistics and input/output statistics for devices/partitions. Some examples of this can be seen below:

[root@xxx ~]# iostat
Linux my.kernel.version (my.hostname) 12/07/10
avg-cpu: %user %nice %system %iowait %steal %idle
0.35 0.00 0.19 0.61 0.01 98.84
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
xvda 11.04 174.56 96.57 1575022426 871286088
xvdb 0.92 14.90 10.14 134403952 91524480
xvdc 0.91 12.16 10.53 109676480 95014488

The above output is avg history since last boot, now if your debugging a current issue on the system this probably isn’t helpful to you so lets get the current values at 2 second intervals instead:

[root@xxx ~]# iostat -d 2
Linux my.kernel.version (my.hostname) 12/07/10
avg-cpu: %user %nice %system %iowait %steal %idle
0.35 0.00 0.19 0.61 0.01 98.84
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
xvda 11.04 174.56 96.57 1575022426 871286088
xvdb 0.92 14.90 10.14 134403952 91524480
xvdc 0.91 12.16 10.53 109676480 95014488

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
xvda 0.00 0.00 0.00 0 0
xvdb 0.00 0.00 0.00 0 0
xvdc 0.00 0.00 0.00 0 0

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
xvda 0.00 0.00 0.00 0 0
xvdb 0.00 0.00 0.00 0 0
xvdc 0.00 0.00 0.00 0 0

This output actually just carries on adding a new entry every 2 seconds, to limit the entries then just specify the number as below:

[root@xxx ~]# iostat -d 2 2
Linux my.kernel.version (my.hostname) 12/07/10
avg-cpu: %user %nice %system %iowait %steal %idle
0.35 0.00 0.19 0.61 0.01 98.84
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
xvda 11.04 174.56 96.57 1575022426 871286088
xvdb 0.92 14.90 10.14 134403952 91524480
xvdc 0.91 12.16 10.53 109676480 95014488

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
xvda 0.00 0.00 0.00 0 0
xvdb 0.00 0.00 0.00 0 0
xvdc 0.00 0.00 0.00 0 0

As you can see this testing vm is actually currently doing nothing but if I run this on a production machine you can see why this information is helpful for spotting bottle necks etc:

root@xxx:~# iostat -d 2 2
Linux my.kernel.version (my.hostname) 12/07/10 _x86_64_

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 31.14 411.84 757.85 1890371422 3478544478
sda1 31.01 409.90 755.62 1881435002 3468289496
sdb 9.97 88.27 303.57 405165646 1393372152
sdb1 9.97 88.27 303.57 405164878 1393372152
sdc 7.54 57.13 131.10 262215600 601759006
sdc1 7.54 57.13 131.10 262214832 601759006

Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 269.00 4.00 5968.00 8 11936
sda1 269.00 4.00 5968.00 8 11936
sdb 15.00 8.00 416.00 16 832
sdb1 15.00 8.00 416.00 16 832
sdc 71.00 12.00 752.00 24 1504
sdc1 71.00 12.00 752.00 24 1504

Yes I know I started talking about memory, cpu etc at the start of this post but you should care about your disks too! Anyway onto sar..

System activity reporter (Sar) As the name suggests it’s not for reporting io data, it is mainly for reporting system data. What do we mean by “system data”? Well this covers lots of things such as:

  • CPU

  • Load avg

  • Memory usage

  • Inode/file/kernel table usage

  • Swapping stats

  • Process statistics

  • TTY device activity

  • Much much more….

Some common things your probably want to look at; CPU usage:

sar -u

Memory usage:

sar -r

Load avg (and queue length):

sar -q

Now without any other options sar is going to return you information from the current sar file, to get a different days content then specify the file.

Today is the 7th, say I wanted to see CPU data for yesterday I would run:

sar -s -f /var/log/sa/sa06

Now depending on what data you are requesting (please read the man page on what data you can retrive and how you can format it, I am refering to the defaults!) the output will vary, example output for CPU data is as follows:

[root@xxx~]# sar -s | head
Linux my.kernel.version (my.hostname) 12/07/10

08:00:01 CPU %user %nice %system %iowait %steal %idle
08:10:01 all 0.61 0.00 0.40 0.14 0.08 98.78
08:20:01 all 0.29 0.00 0.28 0.01 0.01 99.41
08:30:01 all 0.23 0.00 0.25 0.01 0.01 99.50
08:40:01 all 0.56 0.00 0.36 0.07 0.01 99.00
08:50:01 all 0.29 0.00 0.28 0.04 0.01 99.39
09:00:01 all 0.21 0.00 0.26 0.02 0.01 99.50
09:10:01 all 0.66 0.00 0.41 0.34 0.03 98.57

But I want some graphs! Awesome, let’s make some using gnuplot! We are going to use sadf, this is a program that lets us format/display sar data in different formats really easily. You like excel? I’m sorry to hear that, here is an example of outputting cpu idle data in csv form anyway (just to keep you happy):

sadf -- -u | awk '/%idle/ {print $3","$6}'

Anyway for those geeks among us lets make some pretty stuff in gnuplot:

# Make a tmp file
cpu_data_file=$(mktemp /tmp/cpu_data.XXX);
# Fill the file with stuff
sadf -- -u | awk '/%idle/ {print $3" "$6}' > $cpu_data_file
# Make a pretty graph
echo "set terminal dump;
set title 'CPU usage';
set xdata time;
set timefmt '%s';
set xlabel 'Time';
plot '$cpu_data_file' using 1:2 with lines title 'CPU usage';" | gnuplot
# Remove tmp file
rm -f $cpu_data_file

If your not a ASCII type of guy then change set terminal dump; to set terminal png; and pipe the output to file for some nice images.

If your interested then I hacked up a quick example of making graphs for displaying on the web:

#!/bin/bash
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# sar_graph.sh - Makes pretty web pages from sar
# Written by Damian Zaremba - Released under GPLv3
#
# Please note this is a quick hack to demonstrate it can be done
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

GNU_PLOT=$(whereis gnuplot | cut -d' ' -f2)
SADF=$(whereis sadf | cut -d' ' -f2)
GRAPH_TYPE="image"
#GRAPH_TYPE="ascii"
HTML_DST="/var/www/vhosts/stuff.damianzaremba.co.uk/public/sar_graph/"
POST_COMMANDS='chown www-server:www-data -R '$HTML_DST

# Check gnuplot is all good
if [ ! -x "$GNU_PLOT" ];
then
 echo "Please ensure gnuplot is avaible on \$PATH"
 exit 1;
fi

# Check sadf is all good
if [ ! -x "$SADF" ]
then
 echo "Please ensure sadf is avaible on \$PATH"
 exit 1;
fi

# Check graph type
if [ "$GRAPH_TYPE" != "image" ] && [ "$GRAPH_TYPE" != "ascii" ]
then
 echo "Invalid graph type specified"
 exit 1;
fi

# Some functions for writing out the html, just incase you ever want to make it pretty or something..
function make_header {
 HTML="<html><head><title>Sar graphs!</title></head><body>"$HTML;
}

function make_footer {
 HTML=$HTML"</body></html>";
}

function make_graph {
 if [ -z "$1" ]; then return 1; else title=$1; fi
 if [ -z "$2" ]; then return 1; else format=$2; fi
 if [ -z "$3" ]; then return 1; else field=$3; fi

echo "Making $title"
 output_file=$(echo $title | sed 's/ /_/g')

if [ "$GRAPH_TYPE" == "image" ];
 then
 output_format="png"
 output_file=$output_file".png"
 else
 if [ "$GRAPH_TYPE" == "ascii" ]
 then
 output_format="dumb"
 output_file=$output_file".txt"
 fi
 fi

output_path=$HTML_DST"/"$output_file
 dat_file=$(mktemp /tmp/sar_graph.XXX)
 echo "Data file: $dat_file"
 $SADF -- $format | awk '/'$field'/ {print $3" "$6}' > $dat_file

echo "set terminal $output_format;
 set title '$title';
 set xdata time;
 set timefmt '%s';
 set xlabel 'Time';
 plot '$dat_file' using 1:2 with lines title '$title';" | $GNU_PLOT > $output_path
 echo "Outputted $output_file"

if [ "$GRAPH_TYPE" == "image" ];
 then
 HTML=$HTML'<img src="'$output_file'" alt="'$title'" />'
 else
 if [ "$GRAPH_TYPE" == "ascii" ]
 then
 HTML=$HTML'<iframe src="'$output_file'" width="650px" height="350px" scrolling="no"></iframe>'
 fi
 fi
}

# Main script stuff
test -d "$HTML_DST" || mkdir -p "$HTML_DST"
HTML=""

# CPU stuff
make_graph "CPU usage" "-u" "%idle"

# Swap stuff
make_graph "Swap usage" "-r" "kbbuffers"

# 1min load avg
make_graph "1min Load avg" "-q" "ldavg-1"

# Make the html index
echo "Writing $HTML_DST/index.html"
make_header; make_footer
echo $HTML > "$HTML_DST/index.html"

# Post stuff
`$POST_COMMANDS`

# Tidy
rm -rf "$base_dir"