diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index 57b29cc1052d735a0296a049b3420a21a7c963b8..94ad63e062394eed2a21d97b62deb2d495e1fe6e 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -259,7 +259,7 @@ def InitCluster(cluster_name, mac_prefix,
                                errors.ECODE_NOTUNIQUE)
 
   if secondary_ip:
-    if not utils.IsValidIP(secondary_ip):
+    if not utils.IsValidIP4(secondary_ip):
       raise errors.OpPrereqError("Invalid secondary ip given",
                                  errors.ECODE_INVAL)
     if (secondary_ip != hostname.ip and
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 60f9aed7683618fcb3e23141839d7af6bc07ff65..a8f9d176ea5a9825428530cc9fb2937f7ef1830f 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -3594,7 +3594,7 @@ class LUAddNode(LogicalUnit):
     primary_ip = self.op.primary_ip = dns_data.ip
     if self.op.secondary_ip is None:
       self.op.secondary_ip = primary_ip
-    if not utils.IsValidIP(self.op.secondary_ip):
+    if not utils.IsValidIP4(self.op.secondary_ip):
       raise errors.OpPrereqError("Invalid secondary IP given",
                                  errors.ECODE_INVAL)
     secondary_ip = self.op.secondary_ip
@@ -6839,7 +6839,7 @@ class LUCreateInstance(LogicalUnit):
                                      errors.ECODE_INVAL)
         nic_ip = self.hostname1.ip
       else:
-        if not utils.IsValidIP(ip):
+        if not utils.IsValidIP4(ip):
           raise errors.OpPrereqError("Given IP address '%s' doesn't look"
                                      " like a valid IP" % ip,
                                      errors.ECODE_INVAL)
@@ -8513,7 +8513,7 @@ class LUSetInstanceParams(LogicalUnit):
         if nic_ip.lower() == constants.VALUE_NONE:
           nic_dict['ip'] = None
         else:
-          if not utils.IsValidIP(nic_ip):
+          if not utils.IsValidIP4(nic_ip):
             raise errors.OpPrereqError("Invalid IP address '%s'" % nic_ip,
                                        errors.ECODE_INVAL)
 
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index 67d83cca2e6c48de6185df89ac344bf3464123d7..400cd85ce9f5180b38484806b5a062c9d95b623d 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -71,7 +71,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
     constants.HV_ACPI: hv_base.NO_CHECK,
     constants.HV_SERIAL_CONSOLE: hv_base.NO_CHECK,
     constants.HV_VNC_BIND_ADDRESS:
-      (False, lambda x: (utils.IsValidIP(x) or utils.IsNormAbsPath(x)),
+      (False, lambda x: (utils.IsValidIP4(x) or utils.IsNormAbsPath(x)),
        "the VNC bind address must be either a valid IP address or an absolute"
        " pathname", None, None),
     constants.HV_VNC_TLS: hv_base.NO_CHECK,
@@ -514,7 +514,7 @@ class KVMHypervisor(hv_base.BaseHypervisor):
 
     vnc_bind_address = hvp[constants.HV_VNC_BIND_ADDRESS]
     if vnc_bind_address:
-      if utils.IsValidIP(vnc_bind_address):
+      if utils.IsValidIP4(vnc_bind_address):
         if instance.network_port > constants.VNC_BASE_PORT:
           display = instance.network_port - constants.VNC_BASE_PORT
           if vnc_bind_address == constants.IP4_ADDRESS_ANY:
diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index acf5e0b2d65f1afb5ced4b9687fe386d28ed80ee..876e072b03d43c59f2347d052de07fd8d63fbe1b 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -549,7 +549,7 @@ class XenHvmHypervisor(XenHypervisor):
       hv_base.ParamInSet(True, constants.HT_HVM_VALID_NIC_TYPES),
     constants.HV_PAE: hv_base.NO_CHECK,
     constants.HV_VNC_BIND_ADDRESS:
-      (False, utils.IsValidIP,
+      (False, utils.IsValidIP4,
        "VNC bind address is not a valid IP address", None, None),
     constants.HV_KERNEL_PATH: hv_base.REQ_FILE_CHECK,
     constants.HV_DEVICE_MODEL: hv_base.REQ_FILE_CHECK,
diff --git a/lib/utils.py b/lib/utils.py
index ebbde57709bf5005ee6985f73c2de1f4ef62b1d5..2f6d04ea12eb6815c9910c7ded2bc36a5e35628d 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -1292,22 +1292,64 @@ def TryConvert(fn, val):
   return nv
 
 
+def _GenericIsValidIP(family, ip):
+  """Generic internal version of ip validation.
+
+  @type family: int
+  @param family: socket.AF_INET | socket.AF_INET6
+  @type ip: str
+  @param ip: the address to be checked
+  @rtype: boolean
+  @return: True if ip is valid, False otherwise
+
+  """
+  try:
+    socket.inet_pton(family, ip)
+    return True
+  except socket.error:
+    return False
+
+
+def IsValidIP4(ip):
+  """Verifies an IPv4 address.
+
+  This function checks if the given address is a valid IPv4 address.
+
+  @type ip: str
+  @param ip: the address to be checked
+  @rtype: boolean
+  @return: True if ip is valid, False otherwise
+
+  """
+  return _GenericIsValidIP(socket.AF_INET, ip)
+
+
+def IsValidIP6(ip):
+  """Verifies an IPv6 address.
+
+  This function checks if the given address is a valid IPv6 address.
+
+  @type ip: str
+  @param ip: the address to be checked
+  @rtype: boolean
+  @return: True if ip is valid, False otherwise
+
+  """
+  return _GenericIsValidIP(socket.AF_INET6, ip)
+
+
 def IsValidIP(ip):
-  """Verifies the syntax of an IPv4 address.
+  """Verifies an IP address.
 
-  This function checks if the IPv4 address passes is valid or not based
-  on syntax (not IP range, class calculations, etc.).
+  This function checks if the given IP address (both IPv4 and IPv6) is valid.
 
   @type ip: str
   @param ip: the address to be checked
-  @rtype: a regular expression match object
-  @return: a regular expression match object, or None if the
-      address is not valid
+  @rtype: boolean
+  @return: True if ip is valid, False otherwise
 
   """
-  unit = "(0|[1-9]\d{0,2})"
-  #TODO: convert and return only boolean
-  return re.match("^%s\.%s\.%s\.%s$" % (unit, unit, unit, unit), ip)
+  return IsValidIP4(ip) or IsValidIP6(ip)
 
 
 def IsValidShellParam(word):
diff --git a/scripts/gnt-instance b/scripts/gnt-instance
index 521be301e5c2a9b733a264eca2b62751a660fe56..82abc4df184dd9fa27cbe06c813edd84dd93fab7 100755
--- a/scripts/gnt-instance
+++ b/scripts/gnt-instance
@@ -1191,7 +1191,7 @@ def ShowInstanceConfig(opts, args):
         vnc_console_port = "%s:%s (display %s)" % (instance["pnode"],
                                                    port,
                                                    display)
-      elif display > 0 and utils.IsValidIP(vnc_bind_address):
+      elif display > 0 and utils.IsValidIP4(vnc_bind_address):
         vnc_console_port = ("%s:%s (node %s) (display %s)" %
                              (vnc_bind_address, port,
                               instance["pnode"], display))
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index 50ed4e96ea5c831a098b1ffb4740044ce1b8837f..e0cdd0dd633e223c292231dcf8e2d6d609ccf7ed 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -2426,5 +2426,43 @@ class RunIgnoreProcessNotFound(unittest.TestCase):
     self.assertFalse(utils.IgnoreProcessNotFound(os.kill, pid, 0))
 
 
+class TestIsValidIP4(unittest.TestCase):
+  def test(self):
+    self.assert_(utils.IsValidIP4("127.0.0.1"))
+    self.assert_(utils.IsValidIP4("0.0.0.0"))
+    self.assert_(utils.IsValidIP4("255.255.255.255"))
+    self.assertFalse(utils.IsValidIP4("0"))
+    self.assertFalse(utils.IsValidIP4("1"))
+    self.assertFalse(utils.IsValidIP4("1.1.1"))
+    self.assertFalse(utils.IsValidIP4("255.255.255.256"))
+    self.assertFalse(utils.IsValidIP4("::1"))
+
+
+class TestIsValidIP6(unittest.TestCase):
+  def test(self):
+    self.assert_(utils.IsValidIP6("::"))
+    self.assert_(utils.IsValidIP6("::1"))
+    self.assert_(utils.IsValidIP6("1" + (":1" * 7)))
+    self.assert_(utils.IsValidIP6("ffff" + (":ffff" * 7)))
+    self.assertFalse(utils.IsValidIP6("0"))
+    self.assertFalse(utils.IsValidIP6(":1"))
+    self.assertFalse(utils.IsValidIP6("f" + (":f" * 6)))
+    self.assertFalse(utils.IsValidIP6("fffg" + (":ffff" * 7)))
+    self.assertFalse(utils.IsValidIP6("fffff" + (":ffff" * 7)))
+    self.assertFalse(utils.IsValidIP6("1" + (":1" * 8)))
+    self.assertFalse(utils.IsValidIP6("127.0.0.1"))
+
+
+class TestIsValidIP(unittest.TestCase):
+  def test(self):
+    self.assert_(utils.IsValidIP("0.0.0.0"))
+    self.assert_(utils.IsValidIP("127.0.0.1"))
+    self.assert_(utils.IsValidIP("::"))
+    self.assert_(utils.IsValidIP("::1"))
+    self.assertFalse(utils.IsValidIP("0"))
+    self.assertFalse(utils.IsValidIP("1.1.1.256"))
+    self.assertFalse(utils.IsValidIP("a:g::1"))
+
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()