diff --git a/lib/ipaddress.rb b/lib/ipaddress.rb
index 4f8c71f6a647dfd856ba32b2c0b84ffb1c0adda9..99591d76c727c4f21b65d622b2f0e60161d269c7 100644
--- a/lib/ipaddress.rb
+++ b/lib/ipaddress.rb
@@ -102,22 +102,88 @@ module IPAddress
     self.kind_of? IPAddress::IPv6
   end
 
+
+  #
+  # Checks if the given string is either a valid IP, either a valid IPv4 subnet
+  #
+  # Example:
+  #
+  #   IPAddress::valid? "10.0.0.0/24"
+  #     #=> true
+  #
+  #   IPAddress::valid? "2002::1"
+  #     #=> true
+  #
+  #   IPAddress::valid? "10.0.0.256"
+  #     #=> false
+  #
+  #   IPAddress::valid? "10.0.0.0/999"
+  #     #=> false
+  #
+  def self.valid?(addr)
+    valid_ip?(addr) || valid_ipv4_subnet?(addr) || valid_ipv6_subnet?(addr)
+  end
+
   # 
   # Checks if the given string is a valid IP address,
   # either IPv4 or IPv6
   #
   # Example:
   #
-  #   IPAddress::valid? "2002::1"
+  #   IPAddress::valid_ip? "2002::1"
   #     #=> true
   #
-  #   IPAddress::valid? "10.0.0.256"   
+  #   IPAddress::valid_ip? "10.0.0.256"
   #     #=> false
   #
-  def self.valid?(addr)
+  def self.valid_ip?(addr)
     valid_ipv4?(addr) || valid_ipv6?(addr)
   end
-  
+
+  #
+  # Checks if the given string is a valid IPv4 subnet
+  #
+  # Example:
+  #
+  #   IPAdress::valid_ipv4_subnet? "10.0.0.0/24"
+  #     #=> true
+  #
+  #   IPAdress::valid_ipv4_subnet? "10.0.0.0/255.255.255.0"
+  #     #=> true
+  #
+  #   IPAdress::valid_ipv4_subnet? "10.0.0.0/64"
+  #     #=> false
+  #
+  def self.valid_ipv4_subnet?(addr)
+    ip, netmask = addr.split("/")
+
+    valid_ipv4?(ip) && (!(netmask =~ /\A([12]?\d|3[0-2])\z/).nil? || valid_ipv4_netmask?(netmask))
+  end
+
+  #
+  # Checks if the given string is a valid IPv6 subnet
+  #
+  # Example:
+  #
+  #   IPAdress::valid_ipv6_subnet? "::/0"
+  #     #=> true
+  #
+  #   IPAdress::valid_ipv6_subnet? "dead:beef:cafe:babe::/64"
+  #     #=> true
+  #
+  #   IPAdress::valid_ipv6_subnet? "2001::1/129"
+  #     #=> false
+  #
+  def self.valid_ipv6_subnet?(addr)
+    ip, netmask = addr.split("/")
+
+    netmask = Integer(netmask, 10)
+
+    valid_ipv6?(ip) && netmask >= 0 && netmask <= 128
+  rescue ArgumentError
+    false
+  end
+
   #
   # Checks if the given string is a valid IPv4 address
   #
diff --git a/test/ipaddress_test.rb b/test/ipaddress_test.rb
index 862c88941f2cd8ae5c0c03ff6678d79928f085e4..d5bdf60c6b8e009d1c897ecd8912257e0b7c15d9 100644
--- a/test/ipaddress_test.rb
+++ b/test/ipaddress_test.rb
@@ -59,6 +59,17 @@ class IPAddressTest < Minitest::Test
   end
 
   def test_module_method_valid?
+    assert_equal true, IPAddress::valid?("10.0.0.0/24")
+    assert_equal true, IPAddress::valid?("10.0.0.0/255.255.255.0")
+    assert_equal false, IPAddress::valid?("10.0.0.0/64")
+    assert_equal false, IPAddress::valid?("10.0.0.0/255.255.255.256")
+    assert_equal true, IPAddress::valid?("::/0")
+    assert_equal true, IPAddress::valid?("2002::1/128")
+    assert_equal true, IPAddress::valid?("dead:beef:cafe:babe::/64")
+    assert_equal false, IPAddress::valid?("2002::1/129")
+  end
+
+  def test_module_method_valid_ip?
     assert_equal true, IPAddress::valid?("10.0.0.1")
     assert_equal true, IPAddress::valid?("10.0.0.0")
     assert_equal true, IPAddress::valid?("2002::1")
@@ -69,14 +80,30 @@ class IPAddressTest < Minitest::Test
     assert_equal false, IPAddress::valid?("10.0")
     assert_equal false, IPAddress::valid?("2002:::1")
     assert_equal false, IPAddress::valid?("2002:516:2:200")
-
   end
 
-  def test_module_method_valid_ipv4_netmark?
+  def test_module_method_valid_ipv4_netmask?
     assert_equal true, IPAddress::valid_ipv4_netmask?("255.255.255.0")
     assert_equal false, IPAddress::valid_ipv4_netmask?("10.0.0.1")
   end
 
+  def test_module_method_valid_ipv4_subnet?
+    assert_equal true, IPAddress::valid_ipv4_subnet?("10.0.0.0/255.255.255.0")
+    assert_equal true, IPAddress::valid_ipv4_subnet?("10.0.0.0/0")
+    assert_equal true, IPAddress::valid_ipv4_subnet?("10.0.0.0/32")
+    assert_equal false, IPAddress::valid_ipv4_subnet?("10.0.0.0/ABC")
+    assert_equal false, IPAddress::valid_ipv4_subnet?("10.0.0.1")
+    assert_equal false, IPAddress::valid_ipv4_subnet?("10.0.0.0/33")
+    assert_equal false, IPAddress::valid_ipv4_subnet?("10.0.0.256/24")
+    assert_equal false, IPAddress::valid_ipv4_subnet?("10.0.0.0/255.255.255.256")
+  end
+
+  def test_module_method_valid_ipv6_subnet?
+    assert_equal true, IPAddress::valid_ipv6_subnet?("::/0")
+    assert_equal true, IPAddress::valid_ipv6_subnet?("2002::1/128")
+    assert_equal true, IPAddress::valid_ipv6_subnet?("dead:beef:cafe:babe::/64")
+    assert_equal false, IPAddress::valid_ipv6_subnet?("2002::1/129")
+  end
 end