Subnet Calculator

Recently, I’ve decided to begin working toward the CCNP certification and have required significant review of CCNA material. As such, in order to review some of the subnet math, I decided to write a subnet calculator in PHP.

I’ve spent most of today working on it and hopefully it works well in all cases. However, the form handler may still allow some improper values. As long as proper input is provided, the calculator should produce accurate results. To view the calculator, visit the ‘Subnet Calculator‘ via the link provided above.

As always, I’m providing the source to my program. It’s currently set up to be used as a page template. Paste the code into a .php file and place it in the directory of a¬†WordPress¬†template to use it. Click here to download the source or ‘Continue Reading’ to view the source.

<?php
/*
Template Name: Subnet Page
*/
?>
 
<?php get_header(); ?>
 
    <div id="content">
 
        <div id="main">
 
            <div class="box1 clearfix">
                    <div class="post clearfix">
<?php
//Shows Input form until the subnet button is clicked.
	if (!isset($_POST['submit'])) {
?>
		<h2 class="hd-page">Subnet Calculator</h2>
				<form name="subnet-calculator" action="<?php get_permalink()?>" method="post">
					<table width="100%">
						<tr>
							<td width="40%" align="left"><p>IP Address</p><p><input type="text" size="3" name="subOctet1">.<input type="text" size="3" name="subOctet2">.<input type="text" size="3" name="subOctet3">.<input type="text" size="3" name="subOctet4"></p></td>
							<td width="30%" align="left"><p>/ Mask</p> <p>/ <input type="text" size="2" name="bits"></p></td>
							<td width="30" valign="middle"><br /><p><button type="submit" name="submit">Results</button></p></td>
						</tr>
					</table>
				</form>
		<?php
	}
	else {
				//Variables
				$subArray = array($_POST['subOctet1'], $_POST['subOctet2'], $_POST['subOctet3'], $_POST['subOctet4']);
				$bits = $_POST['bits'];
 
					function formCheck($subArray, $bits){
						//FORM CHECK Subnet
						foreach ($subArray as $i => $value) {
							if (($subArray[$i] != null) && ($subArray[$i] > 255 || $subArray[$i] < 0)) {
								echo '<h3>You have entered an incorrect value. Subnet octet values must be between 0 and 255.</h3>';
								return false;
							}
						}
						//FORM CHECK bits
						if (($bits != null) && ($bits > 30 || $bits < 0)) {
							echo '<h3>You have entered an incorrect value. Subnet bits must be less than 30 and greater than 0 </h3>';
							return false;
						}
						else { return true;}
					}
 
 
				//Functions for calculation of subnet information.
					//Returns Subnet Mask as String
					function getSubnetMask($bits){
						$subnetMask = array();
						for($i = 0; $i < 4; $i++){
							if($bits >= 8){
								$subnetMask[$i] = 255;
								$bits -= 8;
							}
							else{
								$subnetMask[$i] = (string)(256 - (pow(2,(8 - $bits))));
								$bits = 0;
							}
						}
						return implode('.', $subnetMask);
					}
					//Returns Wildcard Mask as String
					function getWildCardMask($bits){
						$wildcardMask = '';
						for($i = 0; $i < 4; $i++){
							if($bits >= 8){
								$wildcardMask[$i] = 0;
								$bits -= 8;
							}
							else{
								$wildcardMask[$i] = (string)(pow(2,(8 - $bits)) - 1);
								$bits = 0;
							}
						}
						return implode('.', $wildcardMask);
					}
					//Returns Class of IP Address/Subnet as String based on first octet.
					function getSubnetClass($subArray){
					$subclass = '';
						if($subArray[0] > 0 && $subArray[1] < 128){
							$subClass = 'A';
						}
						if($subArray[0] > 127 && $subArray[1] < 192){
							$subClass = 'B';
						}
						if($subArray[0] > 191 && $subArray[1] < 224){
							$subClass = 'C';
						}
						if($subArray[0] > 223){
							$subClass = 'D (multicast)';
						}
						if($subArray[0] > 239){
							$subClass = 'E (reserved)';
						}
						return $subClass;
					}
					//Gets number of subnets ignoring class rules (Subnet/Hosts). Returns Integer as String.
					function getClasslessSubnets($bits){
						return pow(2,$bits);
					}
					//Gets number of subnets using class rules (Class/Subnet/Hosts). Returns Integer as String.
					function getClassfulSubnets($bits, $subArray){
						if(getSubnetClass($subArray) == "A" && $bits > 7){
							$bits -= 8;
							return pow(2,$bits);
						}
						if(getSubnetClass($subArray) == "B" && $bits > 15){
							$bits -= 16;
							return pow(2,$bits);
						}
						if(getSubnetClass($subArray) == "C" && $bits > 23){
							$bits -= 24;
							return pow(2,$bits);
						}
						else{
							return 'Classful rules may not be applied to this subnet.';
						}
					}
					//Gets number of hosts using bits after prefix length. Returns Integer as String.
					function getHosts($bits){
						return pow(2,(32 - $bits)) - 2;
					}
					//Returns the subnet which contains the input IP as String.
					function getSubnet($mask, $subArray){
						$subnetMask = explode('.', $mask);
						$subnet = array();
						for($i = 0; $i < 4; $i++){
							if($subnetMask[$i] == 255){
								$subnet[$i] = $subArray[$i];
							}
							elseif($subnetMask[$i] == 0){
								$subnet[$i] = 0;
							}
							else{
								while($subArray[$i] >= $subnet[$i]){
									$subnet[$i] += (255 - $subnetMask[$i]);
								}
								$subnet[$i] -= (255- $subnetMask[$i]);
							}
						}
						return implode('.', $subnet);
					}
					//Returns the broadcast address of subnet which contains the input IP as String.
					function getBroadcast($mask, $subArray){
						$subnetMask = explode('.', $mask);
						$broadcast = array();
						for($i = 0; $i < 4; $i++){
							if($subnetMask[$i] == 255){
								$broadcast[$i] = $subArray[$i];
							}
							elseif($subnetMask[$i] == 0){
								$broadcast[$i] = 255;
							}
							else{
								while($subArray[$i] >= $broadcast[$i]){
									$broadcast[$i] += (255 - $subnetMask[$i]);
								}
							}
						}
						return implode('.', $broadcast);
					}
					//Returns the first usable host in subnet as String.
					function getLowRange($subnet){
						$lowRange = explode('.', $subnet);
						$lowRange[3]++;
						return implode('.', $lowRange);
					}
					//Returns the last usable host in subnet as String.
					function getHighRange($broadcast){
						$highRange = explode('.', $broadcast);
						$highRange[3]--;
						return implode('.', $highRange);
					}
//If the formc check returns true. Display results.
				if (formCheck($subArray, $bits) == true){
				?>
						<table width="100%">
							<tr>
								<td width="50%" valign="top">
									<h3>Subnet Information</h3>
									<p>
										Class: <strong class="value"><?php echo getSubnetClass($subArray); ?></strong><br />
										Subnet: <strong class="value"><?php echo getSubnet(getSubnetMask($bits), $subArray); ?></strong><br />
										Host-range: <strong class="value"><?php echo getLowRange(getSubnet(getSubnetMask($bits), $subArray)) . ' - ' . getHighRange(getBroadcast(getSubnetMask($bits), $subArray)); ?></strong><br />
										Broadcast-address: <strong class="value"><?php echo getBroadcast(getSubnetMask($bits), $subArray); ?></strong><br />
										Classful-subnets: <strong class="value"><?php echo getClassfulSubnets($bits, $subArray); ?></strong>
									</p>
								</td>
 
								<td width="50%" valign="top">
									<h3>Prefix Information</h3>
									<p>
										Prefix-length: <strong class="value"><?php echo "/" . $bits; ?></strong><br />
										Subnet-mask: <strong class="value"><?php echo getSubnetMask($bits); ?></strong><br />
										Wildcard-mask: <strong class="value"><?php echo getWildCardMask($bits); ?></strong><br />
										Hosts-per-subnet: <strong class="value"><?php echo getHosts($bits); ?></strong><br />
										Classless-subnets: <strong class="value"><?php echo getClasslessSubnets($bits, $subArray); ?></strong>
									</p>
								</td>
							</tr>
						</table>
 
 
            <?php
			}
		}
					edit_post_link(__('Edit this entry.',woothemes), '<p>', '</p>');
			?>
                </div>
            </div>
 
        </div><!-- / #main -->
 
<?php get_sidebar(); ?>
 
	</div><!-- / #content -->
<?php get_footer(); ?>
This entry was posted in Professional, Programming. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *