flamer Posted September 3, 2015 Share Posted September 3, 2015 Hi guys, I have searched google but surprised I didnt come across a working example in the wild already. I want the user to input a valid IP -network- address and subnet mask (keyword is "network address" not just a valid IP address). This is to generate router configuration. An easy sample is ip add: 192.168.10.0 mask: 255.255.255.0 (valid) ip add: 192.168.10.1 mask: 255.255.255.0 (not a valid subnet address because there is a bit in the non network bits) I'm not sure how difficult it is to code, What needs to happen is to first crack open the subnet mask: 255.255.255.0 = 1111111.1111111.111111.0000000 then crack open the ip address 192.168.10.0 = 11000000.10101000.00001010.00000000 From this we deduce that this is valid, as there are no '1's in the ip address where there are zeros in the subnet mask. 192.168.10.1 = 11000000.10101000.00001010.00000001 This in invalid, there is a "1" in the ip address where the matching bit in the subnet mask is a 0. Thanks for any help! Quote Link to comment Share on other sites More sharing options...
requinix Posted September 3, 2015 Share Posted September 3, 2015 This is definitely not a job for a regular expression. Is there any particular reason you want to use one? Because the normal answer is $valid = ((ip2long($ipaddress) & ip2long($netmask)) == ip2long($ipaddress)); 1 Quote Link to comment Share on other sites More sharing options...
flamer Posted September 3, 2015 Author Share Posted September 3, 2015 This is definitely not a job for a regular expression. Is there any particular reason you want to use one? Because the normal answer is $valid = ((ip2long($ipaddress) & ip2long($netmask)) == ip2long($ipaddress)); Sorry, I put in the wrong category!! are you able to move it to maths? Quote Link to comment Share on other sites More sharing options...
requinix Posted September 3, 2015 Share Posted September 3, 2015 (edited) Yup. So is this still a question about how to do the check using PHP code? (What about the code I posted?) Or something else? Edited September 3, 2015 by requinix Quote Link to comment Share on other sites More sharing options...
flamer Posted September 3, 2015 Author Share Posted September 3, 2015 Yes its still needs to be completed in php. I believe your code is validating the IP address and mask, that script (im not near my server to test) I believe would still return this as valid: 192.168.10.1 255.255.255.0 which in my case should be returned as invalid. thanks! Quote Link to comment Share on other sites More sharing options...
flamer Posted September 3, 2015 Author Share Posted September 3, 2015 Sorry I actually see what you are saying now, your code is quite valid for most uses, you will return me the network address for a given IP and subnet. What I am trying to achieve is check that the given IP *is* the valid network address for a given subnet mask. I think I will require decbin function then compare the two strings somehow.. Quote Link to comment Share on other sites More sharing options...
requinix Posted September 3, 2015 Share Posted September 3, 2015 Let's establish some terminology: - 192.168.12.34 is your IP address - 255.255.255.0 is the netmask - 192.168.12.0 is the network prefix = IP address & netmask - 0.0.0.34 is the host part = IP address & ~netmask If you're trying to determine whether an IP address matches the network prefix then you'd want the code I posted. If you're trying to determine whether an IP address belongs within the network then you need to know the correct network prefix too. Now, what are you trying to get? Quote Link to comment Share on other sites More sharing options...
flamer Posted September 3, 2015 Author Share Posted September 3, 2015 Let's establish some terminology: - 192.168.12.34 is your IP address - 255.255.255.0 is the netmask - 192.168.12.0 is the network prefix = IP address & netmask - 0.0.0.34 is the host part = IP address & ~netmask If you're trying to determine whether an IP address matches the network prefix then you'd want the code I posted. If you're trying to determine whether an IP address belongs within the network then you need to know the correct network prefix too. Now, what are you trying to get? I am not asking the user for an IP address! I am asking them for the network prefix. I'll explain why, my script generates network device configuration, so I will be outputting a command that can be pasted into a cisco router etc. The command would be ip route 192.168.1.0 255.255.255.0 next-hop 1.1.1.1 metric 1 The Router itself has built in logic to stop me doing this: ip route 192.168.1.5 255.255.255.0 next-hop 1.1.1.1 metric 1 it will return an error such as invalid subnet ID for mask. (Because what I have given it, is a host address, that is determined by the subnet mask I have given it) So in my logic, a network address (or network prefix as you refer to it) is an address where there are no "1"s set in the host bits. In a subnet mask the host bits are indicated with "0"s and the network bits indicated with all "1"s so subnet mask (/24) equals this in binary 11111111.1111111.1111111.00000000 is this a valid network address for the above mask: 10101010.10101010.01010101.00010000 - no there is a 1 bit in the host portion (we only care about the last octet). is this a valid network address for the above mask: 10101010.10101010.01010101.00000000 - yes all host bits are set to zero. (we only care about the last octet) Hope that helps to clear up what I am trying to achieve Quote Link to comment Share on other sites More sharing options...
requinix Posted September 3, 2015 Share Posted September 3, 2015 (edited) Okay, so you have a subnet mask and you want to check whether a given network address is valid for the mask? Pretty much everything to do with IP addresses is easier to do with straight numbers. Check that (ip2long(mask) | ip2long(address)) == ip2long(mask). - The mask has all network address bits set and all host address bits unset - Bitwise OR will only set bits - If the result differs then it must be because new bits were set, and those bits must have been in the host address portion, and those bits needed to remain unset to stay valid Edited September 3, 2015 by requinix Quote Link to comment Share on other sites More sharing options...
gizmola Posted September 3, 2015 Share Posted September 3, 2015 I think the point here is that there isn't really a reason to check is there? If someone gives you an IP and a net mask, you can utilize the net mask to determine the host# regardless of what they provided for IP. Requinix has provided the functions and bit operators to do that. This makes your tool simpler and more useful in my opinion --> regardless of what they provide you, you return an acceptable route command. Quote Link to comment Share on other sites More sharing options...
flamer Posted September 4, 2015 Author Share Posted September 4, 2015 I think the point here is that there isn't really a reason to check is there? If someone gives you an IP and a net mask, you can utilize the net mask to determine the host# regardless of what they provided for IP. Requinix has provided the functions and bit operators to do that. This makes your tool simpler and more useful in my opinion --> regardless of what they provide you, you return an acceptable route command. yes and no, we can't guarantee that any of the inputs the user gives us are correct, we are asking them to input two pieces of information, network prefix and subnet mask, if the network prefix does not match the subnet mask, it would be wrong to assume the subnet mask given was correct and to spit out the correct network prefix for that mask. Instead it would be better to prompt the user they have given us incorrect information and to go back and reinput the correct values. With classful addressing its not so much of an issue but with classless subnetting its very easy to get wrong. Well I made some working code, maybe its clumsy but it works $address = "172.16.0.65"; $mask = "255.255.255.240"; $binary_mask = sprintf("%032b",ip2long($mask)); //break the mask into 32 bit base2 $mask_hostbits = substr_count($binary_mask, '0'); // count the number of zeros in the mask $binary_address = sprintf("%032b",ip2long($address)); //convert the ip address to 32 bit base2 $address_hostbits = substr($binary_address, -$mask_hostbits); //we only care about the bits in the host bits portion and we know the number of host bits, so lets pull them out from the network address if (strpos($address_hostbits, '1') !== false) { echo 'this is not a network address'; } else { echo "this is a valid network address"; } //lets see if any of the host bits in the address are set to 1 Quote Link to comment Share on other sites More sharing options...
scootstah Posted September 4, 2015 Share Posted September 4, 2015 What was wrong with requinix's one liner? Isn't that what you wanted to do? Quote Link to comment Share on other sites More sharing options...
flamer Posted September 4, 2015 Author Share Posted September 4, 2015 What was wrong with requinix's one liner? Isn't that what you wanted to do? Well I ran it but it gave me a syntax error, as I didn't really understand the function I wasn't able to get it working.. so maybe it does? Quote Link to comment Share on other sites More sharing options...
requinix Posted September 4, 2015 Share Posted September 4, 2015 I didn't put the variables in this time but otherwise it's correct. $valid = ((ip2long($mask) | ip2long($address)) == ip2long($mask)); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.