<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Pigstye &#187; General</title>
	<atom:link href="http://www.pigstye.net/category/general/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pigstye.net</link>
	<description>Where only the best pigs wallow.</description>
	<lastBuildDate>Sat, 09 Oct 2010 14:14:15 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>VBA CIDR Subnetting Functions</title>
		<link>http://www.pigstye.net/2010/10/vba-cidr-subnetting-functions/</link>
		<comments>http://www.pigstye.net/2010/10/vba-cidr-subnetting-functions/#comments</comments>
		<pubDate>Sat, 09 Oct 2010 14:13:18 +0000</pubDate>
		<dc:creator>tomw</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.pigstye.net/?p=305</guid>
		<description><![CDATA[For a project I was working on I needed a set of functions that would understand CIDR subnetting. This was on an Access Database and it needed to be very portable or I would have created a dll to do it. Access VBA has a serious limitation for this project, there is no unsigned long. [...]]]></description>
			<content:encoded><![CDATA[<p>For a project I was working on I needed a set of functions that would understand CIDR subnetting.  This was on an Access Database and it needed to be very portable or I would have created a dll to do it.  Access VBA has a serious limitation for this project, there is no unsigned long.  To get around this limitation I converted all the decimal equivalents of ip to doubles and used the ascii representation of the binary to do the necessary masking operations.  Here it is, hope it saves someone else the time of having to recreate this work.</p>
<blockquote><p>&#8216;==================================================<br />
&#8216; Module: SubNetFunctions<br />
&#8216; Author: Tom Willett<br />
&#8216; Date: 9/6/2010<br />
&#8216; License: GPL<br />
&#8216; Description:  This is a collection of subneting functions using cidr subnetting.<br />
&#8216; The subnet functions are a cludge because vba does not have an unsigned long.<br />
&#8216; All of the functions therefore, use the ascii representation of the binary numbers to do<br />
&#8216;    their calculations and store the decimal equivalent of the ip as a double.<br />
&#8216; The functions available are:<br />
&#8216; broadcastIP &#8212; given a subnet in cidr format returns the broadcastIP in dotted format<br />
&#8216; cidr2mask &#8212; given a cidr returns the equivalent mask<br />
&#8216; highestIP &#8212; given a subnet in cidr format returns the highest usable address in dotted format<br />
&#8216; lowestIP &#8212; given a subnet in cidr format returns the first usable address in dotted format<br />
&#8216; subnetID &#8212; given a subnet in cidr format returns the subnet id in dotted format<br />
&#8216; &#8212;&#8212; helper functions &#8212;&#8212;&#8212;-<br />
&#8216; AbinAnd &#8212; binary ands two 8bit ascii binary numbers and returns the ascii binary result<br />
&#8216; Bin2Dec &#8212; given a binary number as a string returns the decimal equivalent as a string<br />
&#8216; Dec2Bin &#8212; given a decimal number as a string returns the binary equivalent as a string<br />
&#8216; ip2long &#8212; given an ip in dotted format returns the long equivalent (actually double)<br />
&#8216; long2ip &#8212; given a ip represented as a long (actually double) returns the ip in dotted format<br />
&#8216;<br />
&#8216; All of these functions have been tested on 64 and 32 bit versions of Access 2010 and 2007<br />
&#8216;=============================================================================================<br />
Option Compare Database<br />
Option Explicit</p>
<p>&#8216;======================================================<br />
&#8216; Bin2Dec<br />
&#8216;<br />
&#8216; Parameter BinNum &#8212; binary number as a string<br />
&#8216; Return Decimal equivalent as a string<br />
&#8216;======================================================<br />
Public Function Bin2Dec(ByVal BinNum As String) As String<br />
   Dim i As Integer<br />
   Dim DecNum As Long</p>
<p>   On Error GoTo ErrorHandler</p>
<p>&#8216;  Loop thru BinString<br />
   For i = Len(BinNum) To 1 Step -1<br />
&#8216;     Check the string for invalid characters<br />
      If Asc(Mid(BinNum, i, 1)) < 48 Or _<br />
         Asc(Mid(BinNum, i, 1)) > 49 Then<br />
         DecNum = &#8220;&#8221;<br />
         Err.Raise 1002, &#8220;BinToDec&#8221;, &#8220;Invalid Input&#8221;<br />
      End If<br />
&#8216;     If bit is 1 then raise 2^LoopCount and add it to DecNum<br />
      If Mid(BinNum, i, 1) And 1 Then<br />
         DecNum = DecNum + 2 ^ (Len(BinNum) &#8211; i)<br />
      End If<br />
   Next i<br />
&#8216;  Return DecNum as a String<br />
   Bin2Dec = CStr(DecNum)<br />
ErrorHandler:<br />
End Function</p>
<p>&#8216;==============================================================<br />
&#8216; Dec2Bin<br />
&#8216;<br />
&#8216; Parameter DecNum &#8212; decimal number as a string<br />
&#8216; Return &#8212; Binary equivalent of DecNum as a string<br />
&#8216;===============================================================<br />
Public Function Dec2Bin(ByVal DecNum As String) As String<br />
   Dim BinNum As String<br />
   Dim lDecNum As Long<br />
   Dim i As Integer</p>
<p>   On Error GoTo ErrorHandler</p>
<p>&#8216;  Check the string for invalid characters<br />
   For i = 1 To Len(DecNum)<br />
      If Asc(Mid(DecNum, i, 1)) < 48 Or _<br />
         Asc(Mid(DecNum, i, 1)) > 57 Then<br />
         BinNum = &#8220;&#8221;<br />
         Err.Raise 1010, &#8220;DecToBin&#8221;, &#8220;Invalid Input&#8221;<br />
      End If<br />
   Next i</p>
<p>   i = 0<br />
   lDecNum = Val(DecNum)</p>
<p>   Do<br />
      If lDecNum And 2 ^ i Then<br />
         BinNum = &#8220;1&#8243; &#038; BinNum<br />
      Else<br />
         BinNum = &#8220;0&#8243; &#038; BinNum<br />
      End If<br />
      i = i + 1<br />
   Loop Until 2 ^ i > lDecNum<br />
&#8216;  Return BinNum as a String<br />
   Dec2Bin = BinNum<br />
ErrorHandler:<br />
End Function</p>
<p>&#8216;===============================================<br />
&#8216; AbinAnd<br />
&#8216;<br />
&#8216; Parameters Bin1 and Bin2 are 8 bit binary numbers represented as strings<br />
&#8216; Return A binary number as a string which is the result of doing a binary AND of Bin1 and Bin2<br />
&#8216;===============================================<br />
Public Function AbinAnd(ByVal bin1 As String, ByVal bin2 As String) As String<br />
    &#8216;  This function takes two binary numbers as strings and returns the string representration of the two anded together<br />
    Dim x As Byte<br />
    Dim nBin As String</p>
<p>    nBin = String(8, &#8220;0&#8243;)<br />
    bin1 = Right(nBin &#038; bin1, 8 )<br />
    bin2 = Right(nBin &#038; bin2, 8 )<br />
    For x = 1 To 8<br />
        If Mid(bin1, x, 1) = &#8220;1&#8243; And Mid(bin2, x, 1) = &#8220;1&#8243; Then<br />
            Mid(nBin, x, 1) = &#8220;1&#8243;<br />
        End If<br />
    Next<br />
    AbinAnd = nBin<br />
End Function</p>
<p>&#8216;===========================================================<br />
&#8216; cidr2mask<br />
&#8216;<br />
&#8216; Parameter &#8212; cidr as a string &#8212; decimal from 1 to 31<br />
&#8216; Return the mask equivalent of the cidr in dotted format<br />
&#8216;===========================================================</p>
<p>Public Function cidr2mask(cidr As String) As String<br />
&#8216;converts the cidr bits to the subnet mask<br />
    Dim BuildBin As String<br />
    Dim octet(3) As String<br />
    Dim x, y As Byte<br />
    Dim cCtr As Byte</p>
<p>    cCtr = CByte(cidr)<br />
    For x = 0 To 3<br />
        BuildBin = &#8220;&#8221;<br />
        For y = 1 To 8<br />
            If cCtr > 0 Then<br />
                BuildBin = BuildBin &#038; &#8220;1&#8243;<br />
            Else<br />
                BuildBin = BuildBin &#038; &#8220;0&#8243;<br />
            End If<br />
            If cCtr > 0 Then<br />
                cCtr = cCtr &#8211; 1<br />
            End If<br />
        Next<br />
        octet(x) = Bin2Dec(BuildBin)<br />
    Next</p>
<p>    cidr2mask = Join(octet, &#8220;.&#8221;)<br />
End Function</p>
<p>&#8216;====================================================<br />
&#8216; subnetID<br />
&#8216;<br />
&#8216;Given a subnet address in cidr format return the subnetID in dotted format<br />
&#8216;====================================================<br />
Public Function subnetID(subnet As String) As String<br />
    Dim BuildBin As String<br />
    Dim Parts As Variant<br />
    Dim octet As Variant<br />
    Dim Mask(3) As String<br />
    Dim x, y As Byte<br />
    Dim cCtr As Byte</p>
<p>    &#8216;split address and cidr<br />
    On Error Resume Next<br />
    Parts = Split(subnet, &#8220;/&#8221;)<br />
    octet = Split(Parts(0), &#8220;.&#8221;)<br />
    cCtr = CByte(Parts(1))<br />
    &#8216;load mask octets<br />
    For x = 0 To 3<br />
        BuildBin = &#8220;&#8221;<br />
        For y = 1 To 8<br />
            If cCtr > 0 Then<br />
                BuildBin = BuildBin &#038; &#8220;1&#8243;<br />
            Else<br />
                BuildBin = BuildBin &#038; &#8220;0&#8243;<br />
            End If<br />
            If cCtr > 0 Then<br />
                cCtr = cCtr &#8211; 1<br />
            End If<br />
        Next<br />
        Mask(x) = BuildBin<br />
    Next<br />
    &#8216;convert ip octets to binary string<br />
    For x = 0 To 3<br />
        octet(x) = Dec2Bin(octet(x))<br />
    Next</p>
<p>    &#8216;AND Binary Expressions.</p>
<p>    For x = 0 To 3<br />
        octet(x) = Bin2Dec(AbinAnd(Mask(x), octet(x)))<br />
    Next</p>
<p>    subnetID = Join(octet, &#8220;.&#8221;)<br />
End Function</p>
<p>&#8216;=======================================================<br />
&#8216; broadcaseIP<br />
&#8216;<br />
&#8216;given a subnet in cidr format return the broadcast address in dotted format<br />
&#8216;=======================================================<br />
Public Function broadcastIP(subnet As String) As String<br />
    Dim BuildBin As String<br />
    Dim Parts As Variant<br />
    Dim octet As Variant<br />
    Dim Mask(3) As String<br />
    Dim IPBin As String<br />
    Dim x, y As Byte<br />
    Dim cCtr As Byte</p>
<p>    &#8216;split address and cidr<br />
    On Error Resume Next<br />
    Parts = Split(subnet, &#8220;/&#8221;)<br />
    octet = Split(Parts(0), &#8220;.&#8221;)<br />
    cCtr = CByte(Parts(1))<br />
    &#8216;convert ip octets to binary string<br />
    For x = 0 To 3<br />
        octet(x) = Right(&#8220;00000000&#8243; &#038; Dec2Bin(octet(x)), 8 )<br />
    Next</p>
<p>    &#8216;Create Full IP as Binary<br />
    IPBin = Join(octet, &#8220;&#8221;)</p>
<p>    BuildBin = &#8220;&#8221;<br />
    For x = 1 To 32<br />
        If x < = cCtr Then<br />
            BuildBin = BuildBin &#038; Mid(IPBin, x, 1)<br />
        Else<br />
            BuildBin = BuildBin &#038; "1"<br />
        End If<br />
    Next</p>
<p>    Mask(0) = Bin2Dec(Mid(BuildBin, 1, 8 ))<br />
    Mask(1) = Bin2Dec(Mid(BuildBin, 9, 8 ))<br />
    Mask(2) = Bin2Dec(Mid(BuildBin, 17, 8 ))<br />
    Mask(3) = Bin2Dec(Mid(BuildBin, 25, 8 ))<br />
    broadcastIP = Join(Mask, ".")<br />
End Function</p>
<p>'==================================================<br />
' lowestIP<br />
'<br />
' Parameter subnet in cidr format as a string<br />
' Return the lowest usable ip in a cidr range<br />
'==================================================</p>
<p>Public Function lowestIP(subnet As String) As String<br />
    Dim BuildBin As String<br />
    Dim Parts As Variant<br />
    Dim octet As Variant<br />
    Dim Mask(3) As String<br />
    Dim x, y As Byte<br />
    Dim cCtr As Byte</p>
<p>    'split address and cidr<br />
    Parts = Split(subnet, "/")<br />
    octet = Split(Parts(0), ".")<br />
    cCtr = CByte(Parts(1))<br />
    'load mask octets<br />
    For x = 0 To 3<br />
        BuildBin = ""<br />
        For y = 1 To 8<br />
            If cCtr > 0 Then<br />
                BuildBin = BuildBin &#038; &#8220;1&#8243;<br />
            Else<br />
                BuildBin = BuildBin &#038; &#8220;0&#8243;<br />
            End If<br />
            If cCtr > 0 Then<br />
                cCtr = cCtr &#8211; 1<br />
            End If<br />
        Next<br />
        Mask(x) = BuildBin<br />
    Next<br />
    &#8216;convert ip octets to binary string<br />
    For x = 0 To 3<br />
        octet(x) = Dec2Bin(octet(x))<br />
    Next</p>
<p>    &#8216;AND Binary Expressions.<br />
    &#8216;convert octets to masked octets<br />
    For x = 0 To 3<br />
        octet(x) = Bin2Dec(AbinAnd(Mask(x), octet(x)))<br />
    Next</p>
<p>    BuildBin = Right(&#8220;00000000&#8243; &#038; Dec2Bin(octet(3)), 8 )<br />
    Mid(BuildBin, 8, 1) = &#8220;1&#8243;<br />
    octet(3) = Bin2Dec(BuildBin)</p>
<p>    lowestIP = Join(octet, &#8220;.&#8221;)</p>
<p>End Function</p>
<p>&#8216;==============================================================<br />
&#8216; highestIP<br />
&#8216;<br />
&#8216; Parameter subnet in cidr format as a string<br />
&#8216; Return highest usable IP for given cidr<br />
&#8216;==============================================================<br />
Public Function highestIP(subnet As String) As String<br />
    Dim BuildBin As String<br />
    Dim Parts As Variant<br />
    Dim octet As Variant<br />
    Dim Mask(3) As String<br />
    Dim IPBin As String<br />
    Dim x, y As Byte<br />
    Dim cCtr As Byte</p>
<p>    &#8216;split address and cidr<br />
    Parts = Split(subnet, &#8220;/&#8221;)<br />
    octet = Split(Parts(0), &#8220;.&#8221;)<br />
    cCtr = CByte(Parts(1))<br />
    &#8216;load mask octets<br />
    For x = 0 To 3<br />
        BuildBin = &#8220;&#8221;<br />
        For y = 1 To 8<br />
            If cCtr > 0 Then<br />
                BuildBin = BuildBin &#038; &#8220;1&#8243;<br />
            Else<br />
                BuildBin = BuildBin &#038; &#8220;0&#8243;<br />
            End If<br />
            If cCtr > 0 Then<br />
                cCtr = cCtr &#8211; 1<br />
            End If<br />
        Next<br />
        Mask(x) = BuildBin<br />
    Next<br />
    &#8216;convert ip octets to binary string<br />
    For x = 0 To 3<br />
        octet(x) = Dec2Bin(octet(x))<br />
    Next</p>
<p>    &#8216;AND Binary Expressions.<br />
    &#8216;convert octets to masked octets<br />
    For x = 0 To 3<br />
        octet(x) = Right(&#8220;00000000&#8243; &#038; AbinAnd(Mask(x), octet(x)), 8 )<br />
    Next</p>
<p>    IPBin = Join(octet, &#8220;&#8221;)<br />
    BuildBin = &#8220;&#8221;</p>
<p>    cCtr = CByte(Parts(1))<br />
    For x = 1 To 32<br />
        If x < = cCtr Then<br />
            BuildBin = BuildBin &#038; Mid(IPBin, x, 1)<br />
        Else<br />
            If x = 32 Then<br />
                BuildBin = BuildBin &#038; "0"<br />
            Else<br />
                BuildBin = BuildBin &#038; "1"<br />
            End If<br />
        End If<br />
    Next</p>
<p>    Mask(0) = Bin2Dec(Mid(BuildBin, 1, 8 ))<br />
    Mask(1) = Bin2Dec(Mid(BuildBin, 9, 8 ))<br />
    Mask(2) = Bin2Dec(Mid(BuildBin, 17, 8 ))<br />
    Mask(3) = Bin2Dec(Mid(BuildBin, 25, 8 ))</p>
<p>    highestIP = Join(Mask, ".")<br />
End Function</p>
<p>'==================================================<br />
' IP2Long<br />
'<br />
' Parameter -- IP in dotted format as a string<br />
' Return - decimal equivalent as a double<br />
' VBA does not have an unsigned long <img src='http://www.pigstye.net/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /><br />
'==================================================<br />
Public Function IP2Long(ByVal IP As String) As Double<br />
         Dim IPLong As Double<br />
         Dim IPpart As Variant<br />
         Dim IPbyte(4) As Double<br />
         'IPpart(0).IPpart(1).IPpart(2).IPpart(3)</p>
<p>         IPpart = Split(IP, ".")<br />
         Dim x As Byte<br />
         For x = 0 To 3<br />
             IPbyte(x) = CByte(IPpart(x))<br />
         Next<br />
         IPLong = ((IPbyte(0) * (256 ^ 3)) + (IPbyte(1) * (256 ^ 2)) + (IPbyte(2) * 256) + IPbyte(3))</p>
<p>         IP2Long = IPLong<br />
End Function</p>
<p>'=====================================================<br />
' Long2IP<br />
'<br />
' Parameter Decimal value of the IP as a double<br />
' Return dotted representation of the IP as a string<br />
'=====================================================</p>
<p>Public Function Long2IP(ByVal LongIP As Double) As String<br />
         Dim ByteIP(4) As String<br />
         Dim x As Byte<br />
         Dim IP As String</p>
<p>         If LongIP < 4294967296# And LongIP >= 0 Then<br />
             ByteIP(0) = Fix(LongIP / (256 ^ 3))<br />
             ByteIP(1) = Fix(((LongIP &#8211; (ByteIP(0) * (256 ^ 3))) / (256 ^ 2)))<br />
             ByteIP(2) = Fix(((LongIP &#8211; (ByteIP(0) * (256 ^ 3)) &#8211; (ByteIP(1) * (256 ^ 2))) / 256))<br />
             ByteIP(3) = ((LongIP &#8211; (ByteIP(0) * (256 ^ 3)) &#8211; (ByteIP(1) * (256 ^ 2)) &#8211; (ByteIP(2) * 256)))<br />
             IP = ByteIP(0) &#038; &#8220;.&#8221; &#038; ByteIP(1) &#038; &#8220;.&#8221; &#038; ByteIP(2) &#038; &#8220;.&#8221; &#038; ByteIP(3)<br />
             Long2IP = IP<br />
         Else<br />
             Long2IP = -1<br />
         End If<br />
  End Function
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.pigstye.net/2010/10/vba-cidr-subnetting-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hello Again</title>
		<link>http://www.pigstye.net/2010/03/hello-again/</link>
		<comments>http://www.pigstye.net/2010/03/hello-again/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 20:59:05 +0000</pubDate>
		<dc:creator>tomw</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://www.pigstye.net/?p=284</guid>
		<description><![CDATA[Starting over again. It seems every few years its time to clean out the old blog and start over.]]></description>
			<content:encoded><![CDATA[<p>Starting over again.  It seems every few years its time to clean out the old blog and start over.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.pigstye.net/2010/03/hello-again/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

