2

I have a large set of strings which I already know it holds an IP address and I want to determine if it's IPv4 or IPv6. Currently I'm checking whether the string contains a colon:

version = 4
if ':' in ip_string:
    version = 6

Is there a faster way to determine the IP version, given that we already know it's an IP address. Is there any possibility that the above simple check can return the wrong result (for example is it possible to have an IPv6 address without a colon)?

Vasilis
  • 2,721
  • 7
  • 33
  • 54
  • What version of Python are you using? – idjaw Mar 03 '16 at 02:23
  • 3
    IPv6 addresses use colons `:`, not semicolons `;`. A string representation of an IPv6 address will contain a colon. – Ron Maupin Mar 03 '16 at 02:24
  • @idjaw python 2.7, I also edited the tags to add it – Vasilis Mar 03 '16 at 02:26
  • @RonMaupin Thanks, I edited the question. English isn't my mother tongue and I mix some things up! – Vasilis Mar 03 '16 at 02:26
  • Off the top of my head, there is surely regex patterns to do a simple match to check for one or the other. The reason why I asked for your version, was because Python 3 has `ipaddress` which might be able to help you with your validation. – idjaw Mar 03 '16 at 02:27
  • 1
    Practice makes perfect. :) – Ron Maupin Mar 03 '16 at 02:28
  • @idjaw I'll try to do a benchmark using IPv4 regex and I'll update the question, although I'd imagine that regex should be slower – Vasilis Mar 03 '16 at 02:31
  • 1
    @Vasilis I don't disagree with that. Read this. Might lead to something or give you some more hints. http://stackoverflow.com/a/3462840/1832539 – idjaw Mar 03 '16 at 02:32
  • IPv6 addresses will always contain a colon, so no worries … but as what do you want to interpret the following address: “::ffff:192.0.2.123”? Actually this is the address of a IPv4 peer but in IPv6 notation. You get them, when you accept a IPv4 connection on a dual stack socket. When you just check for the colon your code would detect this as an IPv6 address. – Matthias Wimmer Mar 03 '16 at 09:05
  • @MatthiasWimmer that's interesting, can such an address appear in a traceroute? – Vasilis Mar 03 '16 at 15:14
  • @Vasilis Are there any operating systems where you don't use different tools for tracerouting IPv6 and IPv4 paths!? When you are tracerouting an IPv4 path you always get (only) IPv4 addresses. And when you are tracrouting an IPv6 path you always get (only) IPv6 addresses. The routing between these two internet protocols is separated from each other, you will always only have the one or the other. – Matthias Wimmer Mar 03 '16 at 16:32
  • @MatthiasWimmer, You only use the `tracert` and `ping` commands in Windows for either IPv4 or IPv6. Also, most enterprise-grade network equipment uses `traceroute` and `ping` for both. I always found it disconcerting that you need to specifically distinguish between these sorts of commands on some OSes. Heck, if Microsoft can figure it out, surely the Linux guys can, too. I would have thought it would be the other way around where the smart Linux programmers had the single commands, and you had to use separate commands on Windows because Microsoft couldn't figure it out. – Ron Maupin Mar 03 '16 at 19:54
  • @RonMaupin Thanks for the information. I didn't know that. Havn't used Windows for a long time. Interesting point of view anyway. For me it seems normal to have different tools as what the tools are doing is quite different. I guess it's the Unix philosophy of a tool doing only one thing but doing that right. – Matthias Wimmer Mar 03 '16 at 20:00
  • @MatthiasWimmer, you could be right. My background is enterprise networking, and the big vendors have single commands for these things, but separate configuration commands. For instance, you can use `ping` for IPv4, IPX, IPv6, etc. on Cisco devices. It figures out which to use by the address. – Ron Maupin Mar 03 '16 at 20:04

1 Answers1

2

Use ipaddress in python to check the version. Below is the example-

import ipaddress
#str1='10.10.10.2/24'
str1 = '2b11::327a:7b00/120'
[address, netmask] = str1.split('/')
ip_ver = ipaddress.ip_address(str(address))
if ip_ver.version == 4:
    print('IPv4')
else:
    print('IPv6')

Output:

IPv6

Note: Tested in Python 3.7.2

IRSHAD
  • 2,855
  • 30
  • 39