Using python and bash, I'd like to accomplish two things:
Need to split an ipv6 address and port combination in the format [fec2::10]:80 to fec2::10 and 80.
Given an IP address and port combination, I need to determine if the IP is a v4 or v6 address. Eg: 1.2.3.4:80 and [fec2::10]:80
Please suggest a way to do it.
Thanks!
Sample code:
#!/usr/bin/env python
import optparse
def main():
server = "[fec1::1]:80"
if server.find("[", 0, 2) == -1:
print "IPv4"
ip, port = server.split(':')
else:
print "IPv6"
new_ip, port = server.rsplit(':', 1)
print new_ip
ip = new_ip.strip('[]')
print ip
print port
if __name__ == '__main__':
main()
This works for all cases except when the input is specified without a port. Eg: 10.78.49.50 and [fec2::10]
Any suggestions to address this?
You can use the psutil module. Otherwise, you should just call kill from subprocess.
Another way to check whether a certain port is open or closed is by using the Bash shell /dev/tcp/.. or /dev/udp/.. pseudo-device. When executing a command on a /dev/$PROTOCOL/$HOST/$IP pseudo-device, Bash will open a TCP or UDP connection to the specified host on the specified port.
To use Python to access serial ports: Select a device in Remote Manager that is configured to allow shell access to the admin user, and click Actions > Open Console. Alternatively, log into the IX14 local command line as a user with shell access.
Assuming your_input
is like "[fec2::10]:80"
or "1.2.3.4:80"
, it is easy to split the port and find out the ip address:
#!/usr/bin/env python3
from ipaddress import ip_address
ip, separator, port = your_input.rpartition(':')
assert separator # separator (`:`) must be present
port = int(port) # convert to integer
ip = ip_address(ip.strip("[]")) # convert to `IPv4Address` or `IPv6Address`
print(ip.version) # print ip version: `4` or `6`
You can use urlparse
(called urllib.parse
in 3.x) to separate the URL into each of its components:
>>> from urlparse import urlparse
>>> ipv4address = urlparse("http://1.2.3.4:80")
>>> ipv4address
ParseResult(scheme='http', netloc='1.2.3.4:80', path='', params='', query='', fragment='')
>>> ipv6address = urlparse("http://[fec2::10]:80")
>>> ipv6address
ParseResult(scheme='http', netloc='[fec2::10]:80', path='', params='', query='', fragment='')
Then you can split the port off by finding the index of the last colon using rfind
:
>>> ipv4address.netloc.rfind(':')
7
>>> ipv4address.netloc[:7], ipv4address.netloc[8:]
('1.2.3.4', '80')
>>> ipv6address.netloc.rfind(':')
10
>>> ipv6address.netloc[:10], ipv6address.netloc[11:]
('[fec2::10]', '80')
Identifying which type it is should then be as simple as if ':' in that_split_tuple[0]
, right? (Not 100% sure because it's been a while since I learned about how to write IPv6 addresses in URLs.)
Finally, removing the brackets from your IPv6 address is simple, there are many ways to do it:
>>> ipv6address.netloc[:10].replace('[', '').replace(']', '')
'fec2::10'
>>> ipv6address.netloc[:10].strip('[]')
'fec2::10'
Edit: since you expressed concern about not always having port numbers, you could simplify significantly by using a regular expression:
>>> import re
>>> f = lambda(n): re.split(r"(?<=\]):" if n.startswith('[') else r"(?<=\d):", n)
>>> f(ipv4address.netloc)
['1.2.3.4', '80']
>>> f(ipv6address.netloc)
['[fec2::10]', '80']
>>> f("1.2.3.4")
['1.2.3.4']
>>> f("[fec2::10]")
['[fec2::10]']
(I'm having trouble being more clever with my regular expression, hence the inline ternary.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With