<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1299962197741377807</id><updated>2024-09-11T19:13:36.692-07:00</updated><category term="bsd"/><category term="carp"/><category term="cloud computing"/><category term="openbsd"/><category term="qemu"/><category term="virtualization"/><category term="4.7 perl converter"/><category term="WAN emulation"/><category term="annotated"/><category term="api"/><category term="chart"/><category term="google"/><category term="graph"/><category term="login"/><category term="pf.conf"/><category term="tcl.pm demo createcommand perl tcl interaction"/><category term="timeline"/><category term="tmux"/><title type='text'>Jim&#39;s Random Code</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1299962197741377807.post-410072183777468851</id><published>2010-07-30T12:19:00.000-07:00</published><updated>2010-07-30T12:31:52.774-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="tcl.pm demo createcommand perl tcl interaction"/><title type='text'>Tcl.pm Perl &lt;&gt; Tcl Interaction.</title><content type='html'>I don&#39;t really like to work in Tcl, but a lot of the devices I use for work have Tcl API&#39;s.  Here&#39;s some demo&#39;s of how I use perl to interact with the Tcl Api&#39;s of these devices, using the Tcl.pm module from cpan:&lt;br /&gt;&lt;br /&gt;http://search.cpan.org/~vkon/Tcl-0.98/Tcl.pm&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using a perl subroutine from within tcl code:&lt;br /&gt;&lt;br /&gt;########################################################&lt;br /&gt;test.pl:&lt;br /&gt;########################################################&lt;br /&gt;&lt;pre class=&quot;brush: php&quot;&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use Tcl;&lt;br /&gt;&lt;br /&gt;sub log_out {&lt;br /&gt;   print &quot;Hello, @_!\n&quot;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#create a function to be used called logOut in tcl but have it reference the perl log_out function &lt;br /&gt;$interp = new Tcl; &lt;br /&gt;$interp-&gt;CreateCommand(&quot;logOut&quot;, \&amp;log_out,undef,undef,&#39;1&#39;); &lt;br /&gt;$interp-&gt;Eval(&quot;source test.tcl&quot;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;########################################################&lt;br /&gt;test.tcl:&lt;br /&gt;########################################################&lt;br /&gt;&lt;pre class=&quot;brush: php&quot;&gt;&lt;br /&gt;puts &quot;calling logOut&quot;&lt;br /&gt;&lt;br /&gt;logOut &quot;FRED&quot;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;########################################################&lt;br /&gt;output:&lt;br /&gt;########################################################&lt;br /&gt;&lt;br /&gt;calling logOut&lt;br /&gt;Hello, FRED!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#########################################################&lt;br /&gt;Sharing Variables between Tcl &lt;&gt; perl:&lt;br /&gt;#########################################################&lt;br /&gt;&lt;br /&gt;#########################################################&lt;br /&gt;test2.pl&lt;br /&gt;#########################################################&lt;br /&gt;&lt;pre class=&quot;brush: php&quot;&gt;&lt;br /&gt;use Tcl;&lt;br /&gt;use strict; &lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;my $scalar = &#39;&#39;;&lt;br /&gt;my $name = &#39;&#39;;&lt;br /&gt;&lt;br /&gt;print &quot;Examples manipulating TCL variables\n&quot;;&lt;br /&gt;&lt;br /&gt;# Initiate a new tclsh instance&lt;br /&gt;my $interp = Tcl-&gt;new;&lt;br /&gt;&lt;br /&gt;# bind the tcl and perl variables together&lt;br /&gt;tie($scalar, &#39;Tcl::Var&#39;, $interp, &#39;tclscalar&#39;);&lt;br /&gt;&lt;br /&gt;#set value in tcl get it from tcl and perl &lt;br /&gt;$interp-&gt;SetVar (&#39;tclscalar&#39;, &#39;45&#39;);&lt;br /&gt;$interp-&gt;Eval(&#39;puts &quot;$tclscalar, Got from TCL&quot;&#39;);&lt;br /&gt;print &quot;$scalar Got from Perl\n&quot;;&lt;br /&gt;&lt;br /&gt;#set value in perl get it from tcl and perl&lt;br /&gt;$scalar = &#39;50&#39;;&lt;br /&gt;$interp-&gt;Eval(&#39;puts &quot;$tclscalar, Got from TCL&quot;&#39;);&lt;br /&gt;print &quot;$scalar Got from Perl\n&quot;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;#########################################################&lt;br /&gt;output:&lt;br /&gt;#########################################################&lt;br /&gt;&lt;br /&gt;Examples manipulating TCL variables&lt;br /&gt;45, Got from TCL&lt;br /&gt;45 Got from Perl&lt;br /&gt;50, Got from TCL&lt;br /&gt;50 Got from Perl</content><link rel='replies' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/410072183777468851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jim-code-rand.blogspot.com/2010/07/tclpm-perl-tcl-interaction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/410072183777468851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/410072183777468851'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/2010/07/tclpm-perl-tcl-interaction.html' title='Tcl.pm Perl &lt;&gt; Tcl Interaction.'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1299962197741377807.post-5551381620683601960</id><published>2010-06-01T21:33:00.000-07:00</published><updated>2010-08-18T15:31:39.470-07:00</updated><title type='text'>Blocking hostile ssh login attempts</title><content type='html'>We want to block users who attempt to login to our box via ssh with bad intentions, you can see these in the logs coming all day long they look like the following (/var/log/authlog):&lt;br /&gt;&lt;br /&gt;May 31 03:17:31 cm47 sshd[3517]: Failed password for root from 218.25.68.9 port 54014 ssh2&lt;br /&gt;May 31 03:17:31 cm47 sshd[20855]: Received disconnect from 218.25.68.9: 11: Bye Bye&lt;br /&gt;May 31 03:17:33 cm47 sshd[20600]: Failed password for root from 218.25.68.9 port 54112 ssh2&lt;br /&gt;May 31 03:17:34 cm47 sshd[8641]: Received disconnect from 218.25.68.9: 11: Bye Bye&lt;br /&gt;May 31 03:17:36 cm47 sshd[19515]: Failed password for root from 218.25.68.9 port 42841 ssh2&lt;br /&gt;May 31 03:17:36 cm47 sshd[25534]: Received disconnect from 218.25.68.9: 11: Bye Bye&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Jun  1 11:21:23 cm47 sshd[16250]: Failed password for invalid user webmaster from 88.191.80.193 port 51163 ssh2&lt;br /&gt;Jun  1 11:21:23 cm47 sshd[13312]: Received disconnect from 88.191.80.193: 11: Bye Bye&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Jun  1 03:39:01 cm47 sshd[26899]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!&lt;br /&gt;Jun  1 03:39:02 cm47 sshd[16507]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!&lt;br /&gt;Jun  1 03:39:03 cm47 sshd[10347]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!&lt;br /&gt;Jun  1 03:39:04 cm47 sshd[17923]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!&lt;br /&gt;Jun  1 03:39:04 cm47 sshd[29303]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!&lt;br /&gt;Jun  1 03:39:05 cm47 sshd[12674]: reverse mapping checking getaddrinfo for 173.1.44.30.reverse.gogrid.com [173.1.44.30] failed - POSSIBLE BREAK-IN ATTEMPT!&lt;br /&gt;&lt;br /&gt;So here&#39;s how we do this:&lt;br /&gt;sshd will deny these logins, but after we already know someone has attempted something we don&#39;t like its usually a good idea block these script kiddies from everything that we can, so to do that, we&#39;ll use swatch to read our authlog file and add these IP&#39;s to the ssh-badguys table so that they are blocked by pf.&lt;br /&gt;&lt;br /&gt;Add the following to your pf.conf file:&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: php&quot;&gt;&lt;br /&gt;#rules for &quot;hostile ssh login attempts&quot;&lt;br /&gt;table &amp;lt;sshd-badguys&amp;gt; persist&lt;br /&gt;anchor &quot;sshd_hostiles&quot; {&lt;br /&gt;      block in log quick from &amp;lt;sshd-badguys&amp;gt; to any&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You&#39;ll need to install the swatch (syslog-watcher) package&lt;br /&gt;#pkg_add -i swatch&lt;br /&gt;&lt;br /&gt;Copy the following into your /etc/swatch.conf file&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:monospace;font-size:100%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot; white-space: pre;font-size:13px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:Georgia, serif;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot; white-space: normal;font-size:16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre class=&quot;brush: php&quot;&gt;&lt;br /&gt;watchfor /\[(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\] failed - POSSIBLE BREAK-IN ATTEMPT!/&lt;br /&gt;      exec /sbin/pfctl -T add -t sshd-badguys $1&lt;br /&gt;      exec /sbin/pfctl -k $1&lt;br /&gt;&lt;br /&gt;watchfor /Failed password for root from (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})/&lt;br /&gt;      exec /sbin/pfctl -T add -t sshd-badguys $1&lt;br /&gt;      exec /sbin/pfctl -k $1&lt;br /&gt;&lt;br /&gt;watchfor /Failed password for invalid user .+ from (\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})/&lt;br /&gt;      exec /sbin/pfctl -T add -t sshd-badguys $1&lt;br /&gt;      exec /sbin/pfctl -k $1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then to run swatch, issue the following command:&lt;br /&gt;/usr/local/bin/swatch --config-file /etc/swatch.conf --daemon --tail-file /var/log/authlogin&lt;br /&gt;to make this happen on boot, stick this line in your /etc/rc.local&lt;br /&gt;&lt;br /&gt;This will start working immediatly, you can check the table to see what addresses have been added to it by issuing the following command:&lt;br /&gt;&lt;br /&gt;pfctl -T show -t sshd-badguys&lt;br /&gt;&lt;br /&gt;If you want these entries to expire after a certain amount of time, you can setup something like the following in your crontab file to run every 30 mins or so (this will expire all entries older than a day, if your really concerned about accuracy, you may want to run this every minute or so:&lt;br /&gt;&lt;br /&gt;pfctl -t sshd-badguys -T expire 86400</content><link rel='replies' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/5551381620683601960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jim-code-rand.blogspot.com/2010/06/blocking-rouge-ssh-login-attempts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/5551381620683601960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/5551381620683601960'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/2010/06/blocking-rouge-ssh-login-attempts.html' title='Blocking hostile ssh login attempts'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1299962197741377807.post-5468925070716602919</id><published>2010-05-23T21:57:00.000-07:00</published><updated>2010-05-25T18:40:12.564-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bsd"/><category scheme="http://www.blogger.com/atom/ns#" term="carp"/><category scheme="http://www.blogger.com/atom/ns#" term="cloud computing"/><category scheme="http://www.blogger.com/atom/ns#" term="openbsd"/><category scheme="http://www.blogger.com/atom/ns#" term="qemu"/><category scheme="http://www.blogger.com/atom/ns#" term="virtualization"/><title type='text'>OpenBSD QEMU setup scripts</title><content type='html'>&lt;div&gt;Here is a pair of scripts I&#39;ve used to setup harnesses for some testing of custom images I&#39;ve made, these will require that you have sudo access to ifconfig, as well as have qemu installed.  I also use non default tun interfaces, (not installed by default), to get these working go to /dev and run &quot;./MAKEDEV tun10 tun11 tun12 tun13 tun14 tun15&quot;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This first on is a harness setup script.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To run the setup script simply do &quot;sh setup-vharness.sh&quot;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This will configure 6 tun interfaces for the image to use, I use them as WAN/LAN/DMZ, but you can use however you want, change ip&#39;s in the script to suite your needs.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;pre class=&quot;brush: perl&quot;&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;# setup-vharness.sh&lt;br /&gt;# script to setup qemu guest carp setup on an obsd box&lt;br /&gt;&lt;br /&gt;SUDO=/usr/bin/sudo&lt;br /&gt;MODE=ENABLE&lt;br /&gt;&lt;br /&gt;usage() {&lt;br /&gt;  echo &quot;usage: $0 [-d]&quot; 1&gt;&amp;2&lt;br /&gt;  exit 2&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;start() {&lt;br /&gt; echo MODE: $MODE&lt;br /&gt; if [ $MODE = &quot;DISABLE&quot; ]; then&lt;br /&gt;         echo DeConfiguring CARP Harness&lt;br /&gt;         echo DeConfiguring tun10:&lt;br /&gt;         echo ${SUDO} ifconfig tun10 destroy&lt;br /&gt;         ${SUDO} ifconfig tun10 destroy&lt;br /&gt;         echo DeConfiguring tun11:&lt;br /&gt;         echo ${SUDO} ifconfig tun11 destroy&lt;br /&gt;         ${SUDO} ifconfig tun11 destroy&lt;br /&gt;         echo DeConfiguring tun12:&lt;br /&gt;         echo ${SUDO} ifconfig tun12 destroy&lt;br /&gt;         ${SUDO} ifconfig tun12 destroy&lt;br /&gt;         echo DeConfiguring tun13:&lt;br /&gt;         echo ${SUDO} ifconfig tun13 destroy&lt;br /&gt;         ${SUDO} ifconfig tun13 destroy&lt;br /&gt;         echo DeConfiguring tun14:&lt;br /&gt;         echo ${SUDO} ifconfig tun14 destroy&lt;br /&gt;         ${SUDO} ifconfig tun14 destroy&lt;br /&gt;         echo DeConfiguring tun15:&lt;br /&gt;         echo ${SUDO} ifconfig tun15 destroy&lt;br /&gt;         ${SUDO} ifconfig tun15 destroy&lt;br /&gt;         echo DeConfiguring bridge0:&lt;br /&gt;         echo ${SUDO} ifconfig bridge0 destroy&lt;br /&gt;         ${SUDO} ifconfig bridge0 destroy&lt;br /&gt;         echo DeConfiguring bridge1:&lt;br /&gt;         echo ${SUDO} ifconfig bridge1 destroy&lt;br /&gt;         ${SUDO} ifconfig bridge1 destroy&lt;br /&gt;         echo DeConfiguring bridge2:&lt;br /&gt;         echo ${SUDO} ifconfig bridge2 destroy&lt;br /&gt;         ${SUDO} ifconfig bridge2 destroy&lt;br /&gt; else&lt;br /&gt;         # make sure a tun interface is available&lt;br /&gt;         echo Configuring CARP Harness &lt;br /&gt;         echo Configuring tun10:&lt;br /&gt;         echo ${SUDO} ifconfig tun10 192.168.1.254 link0&lt;br /&gt;         ${SUDO} ifconfig tun10 192.168.1.254 link0   &lt;br /&gt;         echo Configuring tun11:&lt;br /&gt;         echo ${SUDO} ifconfig tun11 192.168.254.254 link0&lt;br /&gt;         ${SUDO} ifconfig tun11 192.168.254.254 link0&lt;br /&gt;         echo Configuring tun12:&lt;br /&gt;         echo ${SUDO} ifconfig tun12 192.168.253.254 link0&lt;br /&gt;         ${SUDO} ifconfig tun12 192.168.253.254 link0&lt;br /&gt;         echo Configuring tun13:&lt;br /&gt;         echo ${SUDO} ifconfig tun13 link0&lt;br /&gt;         ${SUDO} ifconfig tun13 link0 up&lt;br /&gt;         echo Configuring bridge0:&lt;br /&gt;         echo ${SUDO} ifconfig bridge0 create&lt;br /&gt;         ${SUDO} ifconfig bridge0 create&lt;br /&gt;         echo ${SUDO} brconfig bridge0 add tun10 add tun13 up&lt;br /&gt;         ${SUDO} brconfig bridge0 add tun10 add tun13 up &lt;br /&gt;         echo Configuring tun14:&lt;br /&gt;         echo ${SUDO} ifconfig tun14 link0&lt;br /&gt;         ${SUDO} ifconfig tun14 link0 up&lt;br /&gt;         echo Configuring bridge1:&lt;br /&gt;         echo ${SUDO} ifconfig bridge1 create&lt;br /&gt;         ${SUDO} ifconfig bridge1 create&lt;br /&gt;         echo ${SUDO} brconfig bridge1 add tun11 add tun14 up&lt;br /&gt;         ${SUDO} brconfig bridge1 add tun11 add tun14 up&lt;br /&gt;         echo Configuring tun15:&lt;br /&gt;         echo ${SUDO} ifconfig tun15 link0 &lt;br /&gt;         ${SUDO} ifconfig tun15 link0 up&lt;br /&gt;         echo Configuring bridge2:&lt;br /&gt;         echo ${SUDO} ifconfig bridge2 create&lt;br /&gt;         ${SUDO} ifconfig bridge2 create&lt;br /&gt;         echo ${SUDO} brconfig bridge2 add tun12 add tun15 up&lt;br /&gt;         ${SUDO} brconfig bridge2 add tun12 add tun15 up&lt;br /&gt; fi&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;args=`getopt d $*`&lt;br /&gt;&lt;br /&gt; set -- $args&lt;br /&gt; while [ $# -gt 0 ]; do&lt;br /&gt;  case &quot;$1&quot; in&lt;br /&gt;  -d) MODE=&quot;DISABLE&quot;&lt;br /&gt;  echo &quot;Disable Mode&quot;&lt;br /&gt;  ;;&lt;br /&gt;     --) shift;&lt;br /&gt;  break&lt;br /&gt;  ;;&lt;br /&gt;  esac&lt;br /&gt;  shift&lt;br /&gt; done&lt;br /&gt;&lt;br /&gt;start $1&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;This next script actually brings up the image file, it sets up the serial port to be redirected to a telnet session (all my firewall images use console port, you&#39;ll need to change this if you want to see the actual screen output: man qemu).  This will also dump you into a telnet session connected to the serial of the device, be aware of that.  To get this one to work, just do &quot;sh setup-qemu-img.sh &lt;imagename&gt; &lt;offset&gt;&quot;  The offset is to tell the script which CARP host your using, offset is where to start the nic configs at for this host.&lt;br /&gt;&lt;br /&gt;So after running the above script to configure this, I just do the following:&lt;br /&gt;&lt;br /&gt;sh setup-qemu.sh &lt;imagefile&gt; 0&lt;br /&gt;&lt;br /&gt;Then I split my window in two using tmux &quot;Ctrl-B S&quot;&lt;br /&gt;&lt;br /&gt;sh setup-qemu.sh &lt;imagefile&gt; 3&lt;br /&gt;&lt;br /&gt;At this point I have both images running side by side, and can configure the individual guests to suit my needs.&lt;br /&gt;&lt;br /&gt;!!!You may want to change some of the arguments you give to qemu to suit your needs, again see the qemu man page.&lt;pre class=&quot;brush: perl&quot;&gt;&lt;br /&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;# setup-qemu.sh&lt;br /&gt;# script to start multiple qemus on a single box&lt;br /&gt;&lt;br /&gt;SUDO=/usr/bin/sudo&lt;br /&gt;&lt;br /&gt;# qemu args&lt;br /&gt;IMAGE=$1&lt;br /&gt;MEMORY=128&lt;br /&gt;FLAGS=&quot; -daemonize -no-kqemu -nographic -serial telnet:127.0.0.1:$((1010 + $2)),server,nowait -no-fd-bootchk&quot;&lt;br /&gt;&lt;br /&gt;NICFLAGS=&quot;-net nic,vlan=\$id,macaddr=\$mac -net tap,vlan=\$id,ifname=\$id,fd=\$fd&quot;&lt;br /&gt;&lt;br /&gt;getmac() {&lt;br /&gt; mac=&quot;00:bd:`printf %02x $(($RANDOM % 256))`:&quot;&lt;br /&gt; mac=&quot;$mac`printf %02x $(($RANDOM % 256))`:&quot;&lt;br /&gt; mac=&quot;$mac`printf %02x $(($1 % 256))`:`printf %02x $(($2 % 255 + 4))`&quot;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;start() {&lt;br /&gt;        for id in 0 1 2; do&lt;br /&gt;                fd=$(($id + 3))&lt;br /&gt;                tun=tun$(($id + 10 + $2))&lt;br /&gt;    getmac 3 id&lt;br /&gt;                eval &quot;nics=\&quot;$nics $NICFLAGS\&quot;&quot;&lt;br /&gt;                fds=&quot;$fds $fd&lt;&gt; /dev/$tun&quot;&lt;br /&gt;&lt;br /&gt;        done&lt;br /&gt;        &lt;br /&gt;  cmd=&quot;${SUDO} -C 5 qemu -m ${MEMORY} -hda ${IMAGE}${FLAGS}$nics$fds&quot;&lt;br /&gt;     echo Running: ${SUDO} sh -c &quot;$cmd&quot;&lt;br /&gt;  ${SUDO} sh -c &quot;$cmd&quot;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;start $1 $2&lt;br /&gt;&lt;br /&gt;telnet localhost $((1010 + $2))&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To tear down the setup script simply do &quot;sh setup-vharness.sh -d&quot; after you&#39;ve quit the qemu instance(s).  &lt;/imagename&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/5468925070716602919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/openbsd-qemu-setup-scripts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/5468925070716602919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/5468925070716602919'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/openbsd-qemu-setup-scripts.html' title='OpenBSD QEMU setup scripts'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1299962197741377807.post-253712883455765776</id><published>2010-05-18T23:31:00.000-07:00</published><updated>2010-05-25T18:40:43.017-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="4.7 perl converter"/><category scheme="http://www.blogger.com/atom/ns#" term="bsd"/><category scheme="http://www.blogger.com/atom/ns#" term="carp"/><category scheme="http://www.blogger.com/atom/ns#" term="cloud computing"/><category scheme="http://www.blogger.com/atom/ns#" term="openbsd"/><category scheme="http://www.blogger.com/atom/ns#" term="pf.conf"/><category scheme="http://www.blogger.com/atom/ns#" term="qemu"/><category scheme="http://www.blogger.com/atom/ns#" term="virtualization"/><title type='text'>OpenBSD 4.7 Release pf.conf conversion tool</title><content type='html'>Today marks the release of OpenBSD 4.7, with this are many new changes outlined here.  One of the changes requires pre 4.7 pf.conf files to be modified before they will load, changes to the nat/rdr/route-to/reply-to syntax are the reason for this.  These changes are outlined here, normally these can be edited by hand fairly easily, but with many boxes to manage the following script seemed to save me a little time, this hasn&#39;t been tested extensively, but seems to work for me.  If you find a bug let me know and I&#39;ll fix it.&lt;br /&gt;&lt;br /&gt;Usage:  prompt&gt; perl pfconvert.pl /etc/pf.conf &gt; /etc/pf.conf.new&lt;br /&gt;&lt;br /&gt;!!! Note, make sure you verify the converted file will work, ie &quot;pfctl -nf /etc/pf.conf.new&quot;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:monospace;font-size:100%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot; white-space: pre;font-size:13px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:Georgia, serif;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot; white-space: normal;font-size:16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;pre class=&quot;brush: php&quot;&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;# Read the config into a scaler&lt;br /&gt;my $pfconf = do { local( @PFCONF, $/ ) = $ARGV[0] ; &lt;&gt; } ;&lt;br /&gt;&lt;br /&gt;# Merge any multiline rules into a single line&lt;br /&gt;$pfconf =~ s/\\\n/+multilinebreak+/g;&lt;br /&gt;&lt;br /&gt;# Read the file into an array so we can process line by line&lt;br /&gt;@PFCONF = split(&#39;\n&#39;, $pfconf);&lt;br /&gt;&lt;br /&gt;foreach $line (@PFCONF) {&lt;br /&gt;# Remove rdr-anchors for relayd ftp-proxy and tftp-proxy&lt;br /&gt;if ($line =~ m/^nat-anchor|^rdr-anchor/) {&lt;br /&gt;   if ($line =~ m/relayd|ftp-proxy|tftp-proxy/) {&lt;br /&gt;       next;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Convert rdr rules to new 4.7 syntax&lt;br /&gt;if ($line =~ m/^rdr on/) {&lt;br /&gt;   $line =~ s/^rdr/match in/;&lt;br /&gt;   $line =~ s/-&gt;/rdr-to/;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Convert nat rules to new 4.7 syntax&lt;br /&gt;if ($line =~ m/^nat on/) {&lt;br /&gt;   $line =~ s/^nat/match out/;&lt;br /&gt;   $line =~ s/-&gt;/nat-to/;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Convert binat rules to new 4.7 syntax&lt;br /&gt;if ($line =~ m/^binat on/) {&lt;br /&gt;   $line =~ s/^binat/match/;&lt;br /&gt;   $line =~ s/-&gt;/binat-to/;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Convert reply-to rules to new 4.7 syntax&lt;br /&gt;if ($line =~ m/reply-to/) {&lt;br /&gt;   if ($line =~ m/\sto\s+(.*)/) {&lt;br /&gt;       $dest = $1;&lt;br /&gt;   }&lt;br /&gt;   if ($line =~ m/\s(\(.*\))/) {&lt;br /&gt;       $ifaddr = $1;&lt;br /&gt;   }&lt;br /&gt;   $line =~ s/reply-to .+/to $dest reply-to $ifaddr/;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Convert route-to rules to new 4.7 syntax&lt;br /&gt;if ($line =~ m/route-to/) {&lt;br /&gt;   if ($line =~ m/\sfrom\s+(.*)/) {&lt;br /&gt;       $dest = $1;&lt;br /&gt;   }&lt;br /&gt;   if ($line =~ m/\s(\(.*\))/) {&lt;br /&gt;       $ifaddr = $1;&lt;br /&gt;   }&lt;br /&gt;   $line =~ s/route-to .+/from $dest route-to $ifaddr/;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;# Unmerge any multiline rules&lt;br /&gt;$line =~ s/\+multilinebreak\+/\\\n/g;&lt;br /&gt;print &quot;$line\n&quot;;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/253712883455765776/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/openbsd-47-release-pfconf-conversion.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/253712883455765776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/253712883455765776'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/openbsd-47-release-pfconf-conversion.html' title='OpenBSD 4.7 Release pf.conf conversion tool'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1299962197741377807.post-2862660751963644926</id><published>2010-05-12T19:17:00.000-07:00</published><updated>2010-05-25T18:40:57.703-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bsd"/><category scheme="http://www.blogger.com/atom/ns#" term="carp"/><category scheme="http://www.blogger.com/atom/ns#" term="cloud computing"/><category scheme="http://www.blogger.com/atom/ns#" term="login"/><category scheme="http://www.blogger.com/atom/ns#" term="openbsd"/><category scheme="http://www.blogger.com/atom/ns#" term="qemu"/><category scheme="http://www.blogger.com/atom/ns#" term="tmux"/><category scheme="http://www.blogger.com/atom/ns#" term="virtualization"/><title type='text'>OpenBSD Terminal Colors and tmux session on login</title><content type='html'>This is my .profile for my account on my OpenBSD boxes, this requires that you have the colorls and vim packages installed, but this will give you color coded directory listings, and syntax highlighted vim as well as dump you into a tmux session on login, this is very handy, allowing your session to get disconnected and not lose your work.  Pretty simple really just replace your .profile with this in your home directory:&lt;br /&gt;&lt;pre class=&quot;brush: php&quot;&gt;&lt;br /&gt;# $OpenBSD: dot.profile,v 1.4 2005/02/16 06:56:57 matthieu Exp $&lt;br /&gt;#&lt;br /&gt;# sh/ksh initialization&lt;br /&gt;&lt;br /&gt;alias ls=&#39;colorls -G&#39;&lt;br /&gt;alias vi=vim&lt;br /&gt;&lt;br /&gt;PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin:/usr/games:.&lt;br /&gt;export PATH HOME TERM=xterm-256color&lt;br /&gt;&lt;br /&gt;tmux attach || tmux new&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/2862660751963644926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/openbsd-terminal-colors-and-tmux.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/2862660751963644926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/2862660751963644926'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/openbsd-terminal-colors-and-tmux.html' title='OpenBSD Terminal Colors and tmux session on login'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1299962197741377807.post-6162061895303960286</id><published>2010-05-11T22:19:00.000-07:00</published><updated>2010-05-25T18:41:20.466-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bsd"/><category scheme="http://www.blogger.com/atom/ns#" term="carp"/><category scheme="http://www.blogger.com/atom/ns#" term="cloud computing"/><category scheme="http://www.blogger.com/atom/ns#" term="openbsd"/><category scheme="http://www.blogger.com/atom/ns#" term="qemu"/><category scheme="http://www.blogger.com/atom/ns#" term="virtualization"/><category scheme="http://www.blogger.com/atom/ns#" term="WAN emulation"/><title type='text'>Open  Source WAN Emulation Howto</title><content type='html'>This is old, but I see people asking for it every now and then.&lt;br /&gt;&lt;br /&gt;Quick Dummynet howto...&lt;br /&gt;&lt;br /&gt;I needed to emulate a real wan connection for some testing I&#39;m doing.  This was a PITA to find out on my own, so I&#39;m documenting everything. &lt;br /&gt;&lt;br /&gt;This is just on a livecd right now, so you have to issue these commands every time you reboot, which sucks, but luckily it runs on BSD which, hardly ever needs to reboot.&lt;br /&gt;&lt;br /&gt;First you&#39;ll want to grab a copy of the Frenzy Freebsd Live CD here:&lt;br /&gt;&lt;br /&gt;http://frenzy.org.ua/en/index.shtml&lt;br /&gt;&lt;br /&gt;After it boots, I issue these commands (note, i&#39;m running this on a box with 3 nics, 1 for managment, 2 for the bridge)  You could pull it off with just two nics as well, later I&#39;m going to turn it into a router too, so it will do routing as well as introducing bw settings latency, loss, etc.  Also on the Todo list is make a vmware image of all of this with scripts to easily change settings for the bridge/router...&lt;br /&gt;&lt;br /&gt;For right now this is what I do to get it up and running:&lt;br /&gt;&lt;br /&gt;#setup networking&lt;br /&gt;ifconfig em0 172.16.62.11 up&lt;br /&gt;route add default 172.16.62.254&lt;br /&gt;ifconfig bridge create&lt;br /&gt;ifconfig bridge0 addm em1 addm em2 up&lt;br /&gt;ifconfig em1 up&lt;br /&gt;ifconfig em2 up&lt;br /&gt;&lt;br /&gt;#load dummynet&lt;br /&gt;kldload dummynet&lt;br /&gt;&lt;br /&gt;#ipfw commands&lt;br /&gt;sysctl net.link.bridge.ipfw=1&lt;br /&gt;ipfw add pipe 1 ip from any to any&lt;br /&gt;ipfw pipe 1 config bw 2Mbits/s delay 30ms plr .01&lt;br /&gt;ipfw list&lt;br /&gt;&lt;br /&gt;# we need to make sure that the any to any rule with the pipe is the highest any to any rule..&lt;br /&gt;ipfw delete 65000&lt;br /&gt;ipfw list&lt;br /&gt;&lt;br /&gt;# From Lucas: adds memory for network buffers&lt;br /&gt;#the queue for dummynet can take a lot of memory and it behaves badly when it runs out &lt;br /&gt;&lt;br /&gt;sysctl kern.ipc.nmbclusters=32768&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#To watch traffic on the bridge, simply type&lt;br /&gt;tcpdump -i bridge0&lt;br /&gt;&lt;br /&gt;Nice, just found this to backup settings to a floppy:&lt;br /&gt;&lt;br /&gt;http://frenzy.org.ua/en/releases/1.0/doc/doc_en-backup.html&lt;br /&gt;&lt;br /&gt;Here are some links that I found helpful when figuring all this out:&lt;br /&gt;&lt;br /&gt;http://info.iet.unipi.it/~luigi/ip_dummynet/&lt;br /&gt;http://www.freebsd-howto.com/HOWTO/Ipfw-HOWTO&lt;br /&gt;http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-bridging.html&lt;br /&gt;http://www.freebsd.org/cgi/man.cgi?query=if_bridge&amp;sektion=4</content><link rel='replies' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/6162061895303960286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/open-source-wan-emulation-howto.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/6162061895303960286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/6162061895303960286'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/open-source-wan-emulation-howto.html' title='Open  Source WAN Emulation Howto'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1299962197741377807.post-7950432259492476779</id><published>2010-05-11T20:13:00.000-07:00</published><updated>2010-05-13T08:30:43.533-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="annotated"/><category scheme="http://www.blogger.com/atom/ns#" term="api"/><category scheme="http://www.blogger.com/atom/ns#" term="chart"/><category scheme="http://www.blogger.com/atom/ns#" term="google"/><category scheme="http://www.blogger.com/atom/ns#" term="graph"/><category scheme="http://www.blogger.com/atom/ns#" term="timeline"/><title type='text'>Google&#39;s Annotated Timeline Chart and Sql Server 2005</title><content type='html'>I had a small project where I needed to use the functionality of the Google Timeline Annotated Chart from the &lt;a href=&quot;http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html&quot;&gt;Google API&lt;/a&gt;.   The provided charts in the API are pretty nifty, but most of the data that I would want to display is kept in a DB somewhere, I needed a way to have simple SQL queries build a chart for me on the fly, below is what I came up with.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First attempt was to use php to query the DB format all my data in a way that Google wanted and then spit out the html into a div, this worked but was an extra step that was unnecessary.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For this example we&#39;ll go ahead and say I have a table of cities and their high temperatures for a given day in the last week, this will be a very simple table with 3 columns consisting of Timestamp, City, Temp.  (In reality my table structure was a little more complicated, but for this example, a simple table called TempData should suffice).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The following stored procedure will get all the values needed from our database and return a varchar that consists of the html needed to display the graph, we can then put that value into a div and the graph will be displayed.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;brush: sql&quot;&gt;&lt;br /&gt;USE [DATABASENAME]&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;SET ANSI_NULLS ON&lt;br /&gt;GO&lt;br /&gt;SET QUOTED_IDENTIFIER ON&lt;br /&gt;GO&lt;br /&gt;ALTER PROCEDURE [dbo].[sp_google_temperature_trends]&lt;br /&gt;&lt;br /&gt;AS&lt;br /&gt;&lt;br /&gt;DECLARE&lt;br /&gt;@Timestamp varchar(50),&lt;br /&gt;@Year varchar(50),&lt;br /&gt;@Month varchar(50),&lt;br /&gt;@Day varchar(50),&lt;br /&gt;@Hour varchar(50),&lt;br /&gt;@Min varchar(50),&lt;br /&gt;@City varchar(50),&lt;br /&gt;@Temp varchar(50),&lt;br /&gt;@avgTemp varchar(50),&lt;br /&gt;@t int,&lt;br /&gt;@html varchar(max),&lt;br /&gt;@hideCityHtml varchar(max)&lt;br /&gt;&lt;br /&gt;/* First We&#39;ll print out the top of the container info for the goolge annotated timeline graph, for google api info see:&lt;br /&gt;  http://code.google.com/apis/visualization/documentation/gallery/annotatedtimeline.html&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;SET @html = &#39;&lt;br /&gt;       &lt;br /&gt;          &lt;script type=&quot;&quot; text=&quot;&quot; src=&quot;&quot; com=&quot;&quot;&gt;&lt;/script&gt;&lt;br /&gt;          &lt;script type=&quot;&quot; text=&quot;&quot;&gt;&lt;br /&gt;               google.load(&#39;&#39;visualization&#39;&#39;, &#39;&#39;1&#39;&#39;, {&#39;&#39;packages&#39;&#39;:[&#39;&#39;annotatedtimeline&#39;&#39;]});&lt;br /&gt;               google.setOnLoadCallback(drawChart);&lt;br /&gt;               function drawChart() {&lt;br /&gt;                  var data = new google.visualization.DataTable();&lt;br /&gt;                    data.addColumn(&#39;&#39;datetime&#39;&#39;, &#39;&#39;Date&#39;&#39;);&#39;&lt;br /&gt;&lt;br /&gt;/* Next we define our columns, we have one set for each city, the set contains timeline, temp, and annotation html columns. We also setup a temp table to keep an index of each city so we know where to put the values later when we use addRows */&lt;br /&gt;&lt;br /&gt;DECLARE @tmpCity TABLE (&lt;br /&gt;CityID int,&lt;br /&gt;CityName varchar(50) )&lt;br /&gt;SET @cityIteration = 1;&lt;br /&gt;SET @hideCityHtml  = &#39;&#39;        &lt;br /&gt;&lt;br /&gt;DECLARE query_cursor CURSOR&lt;br /&gt;    FOR &lt;br /&gt;	SELECT DISTINCT City FROM TempData&lt;br /&gt;&lt;br /&gt;OPEN query_cursor&lt;br /&gt;FETCH NEXT FROM query_cursor into @City&lt;br /&gt;WHILE @@FETCH_STATUS = 0&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;INSERT INTO @tmpCity &lt;br /&gt;    (CityID, CityName) VALUES(@cityIteration, @City)&lt;br /&gt;&lt;br /&gt;SET @html = @html + &#39;          data.addColumn(&#39;&#39;number&#39;&#39;, &#39;&#39;&#39; + @City + &#39; TPS&#39;&#39;);&lt;br /&gt;          data.addColumn(&#39;&#39;string&#39;&#39;, &#39;&#39;title-&#39; + @City + &#39;&#39;&#39;);&lt;br /&gt;          data.addColumn(&#39;&#39;string&#39;&#39;, &#39;&#39;text-&#39; + @City + &#39;&#39;&#39;);&#39;&lt;br /&gt;&lt;br /&gt;SET @hideCityHtml  = @hideCityHtml + @City + &#39;&lt;input type=&quot;&#39;&#39;checkBox&#39;&#39;&quot; checked=&quot;&#39;&#39;yes&#39;&#39;&quot; name=&quot;&#39;&#39;&#39;&quot; onclick=&quot;&#39;&#39;if&quot; value=&quot;&#39;&#39;ON&#39;&#39;&quot;&gt;&lt;br /&gt;		  &#39;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SET @CityIteration = @CityIteration + 1;&lt;br /&gt;&lt;br /&gt;FETCH NEXT FROM query_cursor into @City&lt;br /&gt;&lt;br /&gt;END&lt;br /&gt;CLOSE query_cursor&lt;br /&gt;DEALLOCATE query_cursor&lt;br /&gt;&lt;br /&gt;/* Now we loop through this query and get all the values for the datapoints */&lt;br /&gt;SET @html = @html + &#39;&lt;br /&gt;          data.addRows([&#39;&lt;br /&gt;&lt;br /&gt;DECLARE query_cursor CURSOR&lt;br /&gt;    FOR &lt;br /&gt;    SELECT Timestamp, City, AVG(Convert(bigint,Temp)) as avgTemp&lt;br /&gt;    FROM TempData&lt;br /&gt;    GROUP BY Timestamp, City&lt;br /&gt;    ORDER BY City&lt;br /&gt;&lt;br /&gt;OPEN query_cursor&lt;br /&gt;FETCH NEXT FROM query_cursor into @Timestamp, @City, @avgTemp&lt;br /&gt;WHILE @@FETCH_STATUS = 0&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;SET @Year =  DATEPART(year, @Timestamp)&lt;br /&gt;SET @Month = DATEPART(month, @Timestamp) - 1 /* For some reason months appear to be a 0 index */&lt;br /&gt;SET @Day =   RIGHT(&#39;0&#39; + RTRIM(DATEPART(day, @Timestamp)), 2)&lt;br /&gt;SET @Hour =  RIGHT(&#39;0&#39; + RTRIM(DATEPART(hour, @Timestamp)), 2)&lt;br /&gt;SET @Min =   RIGHT(&#39;0&#39; + RTRIM(DATEPART(minute, @Timestamp)), 2)&lt;br /&gt;&lt;br /&gt;SET @html = @html + &#39;&lt;br /&gt;        [new Date(&#39; + @Year + &#39;, &#39; + @Month + &#39;, &#39; + @Day + &#39;, &#39; + @Hour + &#39;, &#39; + @Min + &#39;), &#39;&lt;br /&gt;SET @t = 0&lt;br /&gt;WHILE ( @t &lt; (SELECT MAX(CityID) FROM @tmpCity) ) BEGIN    SET @t = @t + 1    IF (@t = (SELECT MAX(CityID) FROM @tmpCity WHERE CityName = @City)) BEGIN       SET @html = @html + @avgTemp + &#39;, &#39;&#39;City &#39; + @City + &#39;&#39;&#39;, &#39;&#39;&lt;br /&gt;City: &#39; + @City + &#39;&lt;br /&gt;Temperature: &#39; + @avgTemp + &#39;&lt;/a&gt;&#39; + &#39;&#39;&#39;,&#39;&lt;br /&gt;   END &lt;br /&gt;   ELSE BEGIN&lt;br /&gt;      SET @html = @html + &#39;undefined, undefined, undefined, &#39;&lt;br /&gt;   END&lt;br /&gt;END&lt;br /&gt;SET @html = @html + &#39;],&#39;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;*/&lt;br /&gt;&lt;br /&gt;FETCH NEXT FROM query_cursor into @TestID, @avgTPS, @Timestamp, @RunID, @branch, @build&lt;br /&gt;&lt;br /&gt;END&lt;br /&gt;CLOSE query_cursor&lt;br /&gt;DEALLOCATE query_cursor&lt;br /&gt;&lt;br /&gt;/* Now that we have all the datarows we close out the js function and define the container to put the graph into */&lt;br /&gt;&lt;br /&gt;SET @html = @html + &lt;br /&gt;&#39;          ]);      &lt;br /&gt;          chart = new google.visualization.AnnotatedTimeLine(document.getElementById(&#39;&#39;mydiv&#39;&#39;));&lt;br /&gt;          chart.draw(data, {displayAnnotations: true,&lt;br /&gt;            annotationsWidth: 10,&lt;br /&gt;            displayAnnotationsFilter: true,&lt;br /&gt;            allowHtml: true,&lt;br /&gt;            displayExactValues: true,    &lt;br /&gt;            scaleType: &#39;&#39;fixed&#39;&#39;,&lt;br /&gt;            thickness: 3});&lt;br /&gt;        }&lt;br /&gt;            function hide(city){&lt;br /&gt;                chart.hideDataColumns(city);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            function show(city){&lt;br /&gt;                chart.showDataColumns(city);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;        &lt;/script&gt;&lt;br /&gt;     &lt;br /&gt;&lt;br /&gt;       &lt;br /&gt;              &lt;br /&gt;         &lt;div id=&quot;&quot; style=&quot;&quot;&gt;&lt;/div&gt;&lt;br /&gt;		  &#39; + @hideCityHtml +&#39;           &lt;br /&gt;&#39;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;text-align: auto;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px;  font-size:medium;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:-webkit-xxx-large;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-size:16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;white-space: pre-wrap; font-size:medium;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:Georgia, serif;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot; white-space: normal;font-size:16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;font-family:monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot;white-space: pre-wrap; font-size:medium;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;   style=&quot;font-family:Georgia, serif;font-size:130%;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot;  style=&quot; white-space: normal;font-size:16px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jim-code-rand.blogspot.com/feeds/7950432259492476779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/googles-annotated-timeline-chart-and.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/7950432259492476779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1299962197741377807/posts/default/7950432259492476779'/><link rel='alternate' type='text/html' href='http://jim-code-rand.blogspot.com/2010/05/googles-annotated-timeline-chart-and.html' title='Google&#39;s Annotated Timeline Chart and Sql Server 2005'/><author><name>jimanda</name><uri>http://www.blogger.com/profile/09251225207872377526</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>