Sunday, 13 March 2011

Tapdancing cow on a tightrope across Victoria falls whilst playing the banjo.

If you though the Internet covered everything, I was very disappointed to find that there is not a single picture of a tap dancing cow on a tightrope across the Victoria falls whilst playing a banjo.

Can anyone supply one?

Wednesday, 5 January 2011

Too many PC's, home networking and storage is getting complex....

So this can't just be me. I have a couple of PCs and all I want to do is to keep files sychronised between them and keep them backed up. Simple eh? Just dropbox it, live mesh it or something else. Well quite frankly, go jump. I have enough storage, I even have a NAS device so the last thing I want is to sync online (well actually I do but only a small propoartion of the data as I'm a cheapskate).

So here we go, what I want:

Pictures, music and docs to auto sync to my storage hub (Readynas Duo).
Operating system to understand and live with the fact I am doing this, don't tell me I should store something here or there, that's my choice.Music (FLAC format) must be DLNA accessable from Linn Sneaky
Linn must be controllable from Iphone or Android
Ideally cache PC stuff locally. I might not be the cloud with my NAS but I am a practical alternative, so just cache it a bit then everything will be hunky dorey.
Sync some stuff into the cloud, preferably all and preferably free.

After some months I have hit problems and solutions:

Problem #1
Readynas/synctoy on Win 7 64bit incompatability.
Used to work fine on Vista but no good on 7. Well it wasn't, it is now. A few steps that helped me:
1) Upgrade firmware on NAS (4.7 at the mo.)
2) Stop the readynas default DLNA stuff completely. If you don't want to then at least stop it auto-updating on directories and stuff. There's a tickbox for that - look elsewhere on the net if you can't find it.
3) Switch on Jumbo frames on NAS (network, interface, something or other like that)
4) Switch on Jumbo frames on win 7 if not already.
5) Alternatively switch off Jumbo frames on win 7 and NAS
6) Check MTU set to 1500
7) Reboot NAS
8) check your switch/hub or whatever can support 1500 byte frames (we hope so!) and jumbo frames (possibly).
9) Reinstall Windows 7!!! Ok, that's drastic but honestly, I upgraded from Win Vista and had been through all of above but no success, was prepared to quit. Bought a solid state drive for the OS (tip: have original Windows disks and reinstall - that's after a load of research), reinstalled and Synctoy 2.1 worked fine, when previously I had nothing but pain.

Problem #2
Moving the default locations for Windows user files
Important this for SSD converts - it's quite simple but be clear:
Create a random new account with admin rights, preferably have no other accounts
Login with this account
Any account you have, move the files using cut and paste from c:\Users\ to new location. (if you have any accounts, if you do, consider deleting them and creating again)
Edit registry
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
Switch obvious ones to the new location.
Probably best reboot
Any new accounts should now be in the right place

Problem #3 what to sync where, when and how:
Well I want everything working quickly, well and invisibly to my missus so that she can logon wherever and get exactly the same experience (well nearly). Bearing in mind Synctoy working:

Syncing Desktop PC to NAS, trigger 1 min after logon, waiting idle time. Setup with task scheduler using Synctoycmd -R as command line. Syncing via contribution (setup via standard synctoy interface): Public pics, music, etc. Tell missus there is a 30min or so delay between ripping a disk and it appearing on DLNA source (NAS is a Twonky and Squeezebox server too).
Ditto on laptops

Problem #4 Linn - control/streaming
Well I've tried a few and succeeded with fewer but here's my 10 pence for 5th Jan 2011:
Plugplayer (Android and Iphone) - it works and it's cheap, a few issues on Android at the mo, but it does work.
2player - watch it on Android - interface is lovely just got very confused with the equipment
twonky - now when I originally set this up Twonky was the only way to go, to be honest I paid for it and it works a treat. I'm guessing now that you don't need this but who knows......
others - don't bother paying. Try them all but you'll probably come back to what works. I could be wrong, tell me if so.

Problem #5 cloud - what, how where and when
Ideally the NAS would sync with the cloud. I can't see why the PC should have to, I'm busy with it, files are for NAS's.

So that's my task for tomorrow, need Android and IPhone compatability and preferably access via a very well tied down Internet front end at work, must also be free. So that'll be a challenege. I'll sacrifice the work one if necessary as I do have a DSL to my desk that I can always use....

All happy, for the moment.

Thursday, 17 December 2009

VBA - checking for open applications/documents

This was a tricky one to find this but got there in the end.

Basically I wanted Excel/VBA to take a look and see if a PDF file was currently open and if so give me the document title. Code can be easily modified to look for anything. Original code modified from VB from http://www.freevbcode.com/ShowCode.Asp?ID=920

Note that the code below only looks for the first match then backs out - check the VB code above for the structure to continually recurse through until all matches are found.


Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As Any, _
ByVal lpWindowName As Any) As Long
Private Declare Function GetWindow Lib "user32.dll" (ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As Long, _
ByVal lpString As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetParent Lib "user32.dll" (ByVal hwnd As Long) As Long

Dim hwndapp As Long
Dim nret As Long
Dim hwndtmp As Long
Dim titletmp As String
gw_hwndnext = 2
titlepart = "WHAT YOU ARE LOOKING FOR OR LEAVE BLANK MAYBE? I WAS GOING FOR PDF"
titlepart = UCase(titlepart)
hwndtmp = FindWindow(0&, 0&)
Do Until hwndtmp = 0
If GetParent(hwndtmp) = 0 Then
titletmp = Space(256)
nret = GetWindowText(hwndtmp, titletmp, Len(titletmp))
If nret Then
titletmp = UCase(Left(titletmp, nret))
If InStr(titletmp, titlepart) Then
Exit Do
End If
End If
End If
hwndtmp = GetWindow(hwndtmp, gw_hwndnext)
Loop
Title = titletmp ' so title gives you the app/window title you were looking for

Thursday, 30 July 2009

SNMP for CDP Trawling of Cisco devices

The SNMP voyage continued today with a script to discover CDP neighbours via SNMP and then go get their CDP neighbour info and so on (although not too far!). Basically an intelligent network mapping. Couldn't do this via expect or anything due to a SecID front end on logins to the devices, so had to drop back to SNMP.

Obviously all Cisco based stuff, specifically switches but it's fairly generic.

Key things here are the SNMP IDs for the useful information:
1.3.6.1.4.1.9.2.1.3: Device name
1.3.6.1.2.1.47.1.1.1.1.13.1: Model number

To actually get the rest of the CDP data, it all gets a bit messy. Firstly you need the CDP table. This is started with a dump of IDs to uniquely identify each table entry. These can be obtained with an SNMP get of the following ID:

1.3.6.1.4.1.9.9.23.1.2.1.1.3

The bit you need is the last two numbers - The first number represents the local port ID (as a number) and the second represents a unique ID that we can use to get more info.

So once we have these (lets call them our_port and table_ID) we can use:

1.3.6.1.2.1.2.2.1.2.our_port
to get the local port name

and then for your cdp info:
1.3.6.1.4.1.9.9.23.1.2.1.1.4.table_id to get IP address (in hex)
1.3.6.1.4.1.9.9.23.1.2.1.1.6.table_id to get Name
1.3.6.1.4.1.9.9.23.1.2.1.1.7.table_id to get Remote port
1.3.6.1.4.1.9.9.23.1.2.1.1.8.table_id to get Device type

There is other stuff too - best take a look at the SNMP browser on Cisco for more info (see link in previous post).

Tuesday, 23 June 2009

Cisco AP - getting AP transmit power using SNMP

Someone asked me this question and I thought, well simple. Just ask the box.

Then finding the right part of the tree was somewhat harder.

Did find this, which is a bit handy...

http://tools.cisco.com/Support/SNMP/public.jsp

Then I found the most useful tree entries for me to be:
1.3.6.1.4.1.14179.2.6.3.42
and
1.3.6.1.4.1.9.9.272.1.1.2.14.1.6

that's it. I used SNMPGET on a solaris platform to get the info - this isn't necessarily the built in one, I seem to remember downloading it as a standalone binary some time ago but the tree is the key bit for this post.

Cisco deliberately annoying customers

This really made me giggle:




and a screenshot because they are bound to change it......


Wednesday, 17 June 2009

Create a temporary file (automatic name/path generation) in VB.net

Love this one:

myfilename = System.IO.Path.GetTempFileNameSystem.IO.Path.GetTempFileName()

Brilliant.

Spawning an executable from VB.net (using file type association)

Right, this one took longer than it should.

Wanted to:
  • Open webpage using default browser (not necessarily IE)
  • Open a CSV file using Excel

So it should be simple. filename stores "c:\mycsv.csv" or http://www.nowhere.com)

Option 1: Shell(filename)
Didn't work. End of.

Option 2: ShellExecute(0, vbNullString, filename, vbNullString, vbNullString, vbNormalFocus)
Works great on Vista, no good on XP. Didn't do anything.

Option 3: System.Diagnostics.Process.Start(filename)
Works fine on both. Brilliant. Job done.

Wednesday, 27 May 2009

Using registry from VB.net/express

Simple this:

to write:

SaveSetting("yourappname", "section", "key", value)

and to read:

myvar=getsetting("yourappname", "section", "key")

Don't forget to error handle (on error resume next) in case it can't find the app or key or value.

Write stuff best placed in myform.FormClosing.

Textbox handling control-C copy/paste

Another nice easy bit of code for this:

Private Sub outputbox_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles outputbox.KeyPress
If e.KeyChar = Convert.ToChar(1) Then
DirectCast(sender, TextBox).SelectAll()
e.Handled = True
End If
End Sub

Tuesday, 19 May 2009

Multiline Textbox update with autoscroll and less flashing in VB

I'll never remember this one, so here's the scenario.

Flaky code reading single bytes from a network stream, want a multiline textbox to show the output live. Problem is the cursor is at the top and text appends to the bottom. If I force the cursor to the bottom with textbox.scrolltocaret it's well flashy. Simple answer, don't add to the textbox.text, append to the box itself thus:

BAD
textbox.text=textbox.text & "stuff"
textbox.refresh
textbox.scrolltocaret

BETTER
textbox.SelectionStart = outputbox.TextLength
textbox.SelectedText = "stuff"

VB (.net/2008 express) Telnet to SUN Solaris - done! (with code)

Right, for anyone who read the previous post below, an update - the code now works!

It seems that when writing the stream, something was getting a bit carried away. With some assistance from Wireshark I got there in the end! Firstly, the first write request (IAC) was sending two bytes - FF and 00, even though the byte stream only had FF in it. Having tracked this down and forced it to 1 byte we got the IAC ok. Things then got worse as the second byte (IAC_COMMAND) was sending a 4k fragmented packet and the final byte (IAC_OPTION) was sending an 8k fragmented packet. Ouch! Forcing each response to a length of 1 got the right messages through (although I did notice it cocks the odd one up). Happily though it works fine with the Solaris box I am trying to get to and I get a "login:" prompt.

Remember this is not for a fully blown standards compliant Telnet type thing - just a rough job to get us logged into something and get some data back.

Hope this helps all those out there that were struggling!

So (pre-tidyup) the code now looks like (apologies for blog removing my indents):

Imports System.Net
Imports System.Net.Sockets

Public IAC As Integer = 255
Public IAC_WILL As Integer = 251
Public IAC_WONT As Integer = 252
Public IAC_DO As Integer = 253
Public IAC_DONT As Integer = 254

Dim returndata As String = Encoding.Unicode.GetString(bytes) ' data that comes back
Dim threebits As String = Chr(255) & Chr(255) & Chr(255) ' variable to keep track of the last three bytes
Dim command As Integer ' variable to store the IAC Command (well the integer equiv for CHR)
command = 0
' now a nasty while - basically we are saying that if any byte in the last three is a control byte
' (i.e. above 250) or any byte is a stream of 0's (found this needed trapping for reasons beyond me)
' we keep reading data and treating this as negotiation
While (Asc(Mid(threebits, 1, 1)) > 250 Or Asc(Mid(threebits, 2, 1)) > 250 Or Asc(Mid(threebits, 3, 1)) > 250) Or _
(Asc(Mid(threebits, 1, 1)) = 0 Or Asc(Mid(threebits, 2, 1)) = 0 Or Asc(Mid(threebits, 3, 1)) = 0)
Try ' just try it - if it fails, we'll handle it
networkStream.ReadTimeout = 1000 ' 1 second timeout (can skip this if you like but it
' does allow for interaction with the user
networkStream.Read(bytes, 0, 1) ' read 1 byte
returndata = Encoding.Unicode.GetString(bytes) ' store the byte as a string
threebits = Mid(threebits & returndata, 2, 3) ' sort out the three bytes
Catch
returndata = Chr(1) ' if we didn't get any data then let's call it chr(1)
End Try
Application.DoEvents() ' give the user some control
' I have a button called get_data that initiates the get. when it is clicked it
' changes it's text to "Stop". before any of this runs, when the user clicks it it checks
' to see what it's current text is and changs it to the inverse. So if it says
' get data, it changes it to stop and vice versa. Here in the loop (and in any other
' collection loop) we check to see if it has been changed to "get data" - if it has the
' user must have clicked stop - therefore we exit the sub
If get_data.Text = "Get data" Then
Exit Sub
End If
' now we decide on actions - basically act dumb - say no to everything!
Select Case Asc(returndata)
Case IAC_WILL ' will
command = IAC_WILL
Case IAC_WONT ' won't
command = IAC_WONT
Case IAC_DO ' do
command = IAC_WONT
Case IAC_DONT ' don't
command = IAC_WONT
Case IAC ' control req.
command = IAC
Case 1 ' this is our dummy case - ie no data read
Case Else ' traps the option value case, or plain text case
If command > 0 Then ' make sure we have a command to reply to - if not its just text
sendBytes = Encoding.Unicode.GetBytes(Chr(IAC)) ' IAC
networkStream.Write(sendBytes, 0, 1) ' 1 byte!
sendBytes = Encoding.Unicode.GetBytes(Chr(command)) ' command
networkStream.Write(sendBytes, 0, 1) ' 1 byte
sendBytes = Encoding.Unicode.GetBytes(returndata) ' return the option sent
networkStream.Write(sendBytes, 0, 1)
End If
command = 0
End Select
End While ' and loop but exit if we get three bytes of normal data



' that's the end of telnet negotiation (in the initial instance anyhow)
' and your code goes here, loop reading the data 1 byte (or more at a time) and do what you will.
' something like below might help
dim usernamedone as system.boolean = false
Do Until jobdone = True
Application.DoEvents()
If get_data.Text = "Get data" Then
Exit Sub
End If
Dim returndata As String = Encoding.Unicode.GetString(bytes)
Try
networkStream.ReadTimeout = 1000
networkStream.Read(bytes, 0, 1)
returndata = Encoding.Unicode.GetString(bytes)
Catch
returndata = ""
End Try
' outputbox is a multi-line text box on my form - shows the user the interaction in progress
' more for my diagnostics than anything else!
outputbox.Text = outputbox.Text & returndata
' note that username_prompt and password_prompt are textboxes on my form
If InStr(outputbox.Text, username_prompt.Text) and not usernamedone Then
! NOTE CHANGE TO ASCII ENCODE
sendBytes = Encoding.ASCII.GetBytes(username.Text & vbCrLf)
networkStream.Write(sendBytes, 0, sendBytes.Length)
usernamedone=true
statusupdate("Username sent")
End If
If InStr(outputbox.Text, Password_prompt.Text) Then
sendBytes = Encoding.ASCII.GetBytes(password.Text & vbCrLf)
networkStream.Write(sendBytes, 0, sendBytes.Length)
statusupdate("Password sent")
jobdone = True
End If
Loop

Monday, 18 May 2009

VB (2008/.net but anything really)- Telnet

(Update! This code fixed here:
http://myhead-online.blogspot.com/2009/05/vb-net2008-express-telnet-to-sun.html)

Ok, so I'm still distracted by VB. It's all just so easy to get great results, that's the problem!

Anyhow this week's project is Cisco device output collation into useful stuff. Got some great stuff going for switches to collate MAC/Port/VLAN/ARP/CDP information into a single sheet from multiple (or single) log files of a terminal session but then I thought, why not automate the Telnet portion? So off we go.

Now some things to note:

Telnet is not as simple as we would like
Negotiation of options may be required
Devices I want to access are a hop that requires logon (or more complex operations) away from my client PC, on different networks
I have no control over the clinet PC build and I have to assume nothing.

If you are anything like me then the first thing is to just steam headlong into it and see what breaks. So my approach is to open a socket and start reading/writing as required.

Dim tcpClient As New System.Net.Sockets.TcpClient()
tcpClient.Connect(host_ip.Text, IPport.Text)
Dim networkStream As NetworkStream = tcpClient.GetStream()
Dim sendBytes As [Byte]()
Dim returndata As String
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
If networkStream.CanWrite And networkStream.CanRead Then ' check a ok
' read data
networkStream.Read(bytes, 0, 1)
returndata = Encoding.Unicode.GetString(bytes)
' write data
sendBytes = Encoding.Unicode.GetBytes(command & returndata)
networkStream.Write(sendBytes, 0, sendBytes.Length)
End If
tcpClient.Close()

Great, now I can read and write and do what I want - or so I thought. Actually, no - the code will work with many Cisco type products (and many others) but is unlikely to work with IBM/UNIX/Msoft/anything else, specifically anything that adheres to thet Telnet standard. So we need some tweaks.

Now I stop here to say that Telnet negotiation is an arse and it would be great to just say bugger it and keep away. Unfortunately the Telnet server has a different opinion and will sit waiting for you to negotiate with it if you just ignore the problem. Net result being no session.

So first thing is to take a look at how to negotiate. I'm not going into this but you need to know that every command starts with IAC (chr(255)).

KEYPOINT! Do not encode response as/with ASCII - there aren't enough bits to represent 255. Hence Unicode in code above. ASCII coding will result in a load of CHR(63)'s responding. Took me bloody ages to work that out - couldn't get why I was geting 63s when I was expecting 255s!

So basically we get a whole stream of

IAC - WILL/WONT/DO/DONT - OPTIONS

In text this will show as gibberish but it is critical! What you need to know is the following codes:
251 - WILL
252 - WONT
253 - DO
254 - DONT

Then there are stacks of others for the options. Look elsewhere for these. So what I want to do is to look at what comes in and basically say bugger off, I'm stupid. So comms go:

Server sends Client Sends
DO (option) WONT (option)
DONT (option) WONT (option)
WILL (option) DONT (option)
WONT (option) WONT (option)

But we don't know what we are going to have to negotiate so we need code that will handle any of this. this can all happen multiple times too. Great news is that the commands (at this level) are always sequences of 3 bytes. So basically get three bytes then respond (or as below get any command things, then when we get a non command option, send a response). Some code:

Public IAC As Integer = 255
Public IAC_WILL As Integer = 251
Public IAC_WONT As Integer = 252
Public IAC_DO As Integer = 253
Public IAC_DONT As Integer = 254
Select Case Asc(returndata)
Case IAC_WILL ' will
command = Chr(IAC_DONT)
Case IAC_WONT ' won't
command = Chr(IAC_WONT)
Case IAC_DO ' do
command = Chr(IAC_WONT)
Case IAC_DONT ' don't
command = Chr(IAC_WONT)
Case IAC ' control req.
command = command & Chr(IAC)
Case Else
sendBytes = Encoding.Unicode.GetBytes(command & returndata) ' return sent byte
statusupdate(status_line.Text & "IAC Response sent")
networkStream.Write(sendBytes, 0, sendBytes.Length)
command = ""
End Select

So now we can run a loop with the code in and send 'stupid' responses. Problem I have is that the response being sent is not being understood. A network capture shows that when I say send IAC & IAC_DONT, (option) it may or may not send something but it won't be the net result I want. Not sure whay but otherwise the theory is ok (I think!). Same holds for all bytes I send. Hmmm.....

Monday, 11 May 2009

Sourceforge - how to upload web pages to a project (finally!)

OK, this did my head in. It is a case of RTFM (very carefully) but with the exception that you have to be a mind reader and also ignore some contradictions in the existing docs.

Key points:

Server name is different from file access

web.sourceforge.net NOT frs.sourceforge.net

Username is different, use:
username,projectname NOT username

Then put your gumf in htdocs folder as per usual.....

Phew! That took blooming ages to diagnose!

Friday, 1 May 2009

Todays challenge - learning C or C++ or something

Right well I know a bit about programming, with a history of Visual Basic, VBA, PERL, shell script, TCL and a few others but I don't know jack about C or C++ so I have decided to learn something about them.

First port of call from a google search was here: http://www.programmingtutorials.com/c.aspx, nice easy tutorials. Head for the C++ one first but that assumes some knowledge of C so redirect to the C tutorials.

Ahh just what I need. Now, first I know I need a compiler so I go to find a free one. Stumble across this useful post http://www.codeproject.com/KB/cpp/altvcc.aspx

So I go to get GCC from here: http://gcc.gnu.org/ and end up here: http://www.mingw.org/. Right I now have a compiler installed.

Next stage, I reckon a GUI would be good, I'm assuming that it's a bit necessary for a good ol Windows app design. Everything points me to wxWidgets from here: http://www.wxwidgets.org/, then some things say install MSYS (no idea what that is) so I do that. Then I can download and install visualwx from here:http://visualwx.altervista.org/

Ok, all downloaded. Where to start?? Hmm. Fire up visualwx - crashes, can't find python25.dll. Ok, hmm, python. Right well find python for download, http://www.python.org/download/releases/3.0.1/.

Ok, so in the install I notice it also installs TCL hmm, so now I have C compilers, TCL and Python but still not started yet!

Right, back to python to get python 2.5. Can't find 2.5 but got a 2.5.4 - that must be close enough. And no, it still doesn't run, can't find python25.dll. Odd, I can, it's sitting in system32. Copy file to \windows and then the same folder as the .exe and no results, same error. Right, I quit on that one. Python uninstall and visualwx uninstall and back to google.

A bit of searching throws up something called QT - looks like it's worth a stab. Nice big download too.

Arrgh no idea where to start here, chucked in some basic C++ code and all of the build options are greyed out - no idea why and the help is about as useful as a wet fish.

Ok, now in my travels I did spot that there is Visual C available for free in an 'express' version. Now I am familiar with visual basic so maybe this is my way forwards.....
Welcome to my head - online!

This is basically what is going on in my head. Not of any intertest to most but at least I'll be able to remember what was in my head a few days ago!