diff --git a/scapy/layers/inet.py b/scapy/layers/inet.py
index 4450df188b68a10f12d7003e1dd4f44960485e0f..e38a0990db288f52d90f3cbfd7d4e601b71d8513 100644
--- a/scapy/layers/inet.py
+++ b/scapy/layers/inet.py
@@ -475,6 +475,33 @@ class IP(Packet, IPTools):
                 lst.append(q)
         return lst
 
+def in4_chksum(proto, u, p):
+    """
+    As Specified in RFC 2460 - 8.1 Upper-Layer Checksums
+
+    Performs IPv4 Upper Layer checksum computation. Provided parameters are:
+    - 'proto' : value of upper layer protocol
+    - 'u'  : IP upper layer instance
+    - 'p'  : the payload of the upper layer provided as a string
+    """
+    if not isinstance(u, IP):
+        warning("No IP underlayer to compute checksum. Leaving null.")
+        return 0
+    if u.len is not None:
+        if u.ihl is None:
+            olen = sum(len(x) for x in u.options)
+            ihl = 5 + olen / 4 + (1 if olen % 4 else 0)
+        else:
+            ihl = u.ihl
+        ln = u.len - 4 * ihl
+    else:
+        ln = len(p)
+    psdhdr = struct.pack("!4s4sHH",
+                         inet_aton(u.src),
+                         inet_aton(u.dst),
+                         proto,
+                         ln)
+    return checksum(psdhdr+p)
 
 class TCP(Packet):
     name = "TCP"
@@ -497,21 +524,7 @@ class TCP(Packet):
             p = p[:12]+chr((dataofs << 4) | ord(p[12])&0x0f)+p[13:]
         if self.chksum is None:
             if isinstance(self.underlayer, IP):
-                if self.underlayer.len is not None:
-                    if self.underlayer.ihl is None:
-                        olen = sum(len(x) for x in self.underlayer.options)
-                        ihl = 5 + olen / 4 + (1 if olen % 4 else 0)
-                    else:
-                        ihl = self.underlayer.ihl
-                    ln = self.underlayer.len - 4 * ihl
-                else:
-                    ln = len(p)
-                psdhdr = struct.pack("!4s4sHH",
-                                     inet_aton(self.underlayer.src),
-                                     inet_aton(self.underlayer.dst),
-                                     self.underlayer.proto,
-                                     ln)
-                ck=checksum(psdhdr+p)
+                ck = in4_chksum(socket.IPPROTO_TCP, self.underlayer, p)
                 p = p[:16]+struct.pack("!H", ck)+p[18:]
             elif conf.ipv6_enabled and isinstance(self.underlayer, scapy.layers.inet6.IPv6) or isinstance(self.underlayer, scapy.layers.inet6._IPv6ExtHdr):
                 ck = scapy.layers.inet6.in6_chksum(socket.IPPROTO_TCP, self.underlayer, p)
@@ -576,21 +589,7 @@ class UDP(Packet):
             p = p[:4]+struct.pack("!H",l)+p[6:]
         if self.chksum is None:
             if isinstance(self.underlayer, IP):
-                if self.underlayer.len is not None:
-                    if self.underlayer.ihl is None:
-                        olen = sum(len(x) for x in self.underlayer.options)
-                        ihl = 5 + olen / 4 + (1 if olen % 4 else 0)
-                    else:
-                        ihl = self.underlayer.ihl
-                    ln = self.underlayer.len - 4 * ihl
-                else:
-                    ln = len(p)
-                psdhdr = struct.pack("!4s4sHH",
-                                     inet_aton(self.underlayer.src),
-                                     inet_aton(self.underlayer.dst),
-                                     self.underlayer.proto,
-                                     ln)
-                ck = checksum(psdhdr+p)
+                ck = in4_chksum(socket.IPPROTO_UDP, self.underlayer, p)
                 # According to RFC768 if the result checksum is 0, it should be set to 0xFFFF
                 if ck == 0:
                     ck = 0xFFFF
diff --git a/scapy/layers/inet6.py b/scapy/layers/inet6.py
index 5c25420ed8b3f9816a5b8599dfdb14650a700c24..e7e73cc48aff8a724a0a9593cbe8d1ed304b8a8c 100644
--- a/scapy/layers/inet6.py
+++ b/scapy/layers/inet6.py
@@ -292,6 +292,7 @@ ipv6nh = { 0:"Hop-by-Hop Option Header",
           58:"ICMPv6",
           59:"No Next Header",
           60:"Destination Option Header",
+         112:"VRRP",
          132:"SCTP",
          135:"Mobility Header"}
 
@@ -643,8 +644,9 @@ class PseudoIPv6(Packet): # IPv6 Pseudo-header for checksum computation
 
 def in6_chksum(nh, u, p):
     """
-    Performs IPv6 Upper Layer checksum computation. Provided parameters are:
+    As Specified in RFC 2460 - 8.1 Upper-Layer Checksums
 
+    Performs IPv6 Upper Layer checksum computation. Provided parameters are:
     - 'nh' : value of upper layer protocol
     - 'u'  : upper layer instance (TCP, UDP, ICMPv6*, ). Instance must be
              provided with all under layers (IPv6 and all extension headers,
diff --git a/scapy/layers/vrrp.py b/scapy/layers/vrrp.py
index f874b352ab8c2ef6a2e03e4d303acd5a23af8e6c..bd50e45b23bb1b226862f04c0a76e49b7a4db5ff 100644
--- a/scapy/layers/vrrp.py
+++ b/scapy/layers/vrrp.py
@@ -10,15 +10,17 @@ VRRP (Virtual Router Redundancy Protocol).
 
 from scapy.packet import *
 from scapy.fields import *
-from scapy.layers.inet import IP
+from scapy.layers.inet import *
+from scapy.layers.inet6 import *
+from scapy.error import warning
 
 IPPROTO_VRRP=112
 
 # RFC 3768 - Virtual Router Redundancy Protocol (VRRP)
 class VRRP(Packet):
     fields_desc = [
-        BitField("version" , 2, 4),
-        BitField("type" , 1, 4),
+        BitField("version", 2, 4),
+        BitField("type", 1, 4),
         ByteField("vrid", 1),
         ByteField("priority", 100),
         FieldLenField("ipcount", None, count_of="addrlist", fmt="B"),
@@ -36,4 +38,51 @@ class VRRP(Packet):
             p = p[:6]+chr(ck>>8)+chr(ck&0xff)+p[8:]
         return p
 
+    @classmethod
+    def dispatch_hook(cls, _pkt=None, *args, **kargs):
+        if _pkt and len(_pkt) >= 9:
+            ver_n_type = ord(_pkt[0])
+            if ver_n_type >= 48 and ver_n_type <= 57: # Version == 3
+                return VRRPv3
+        return VRRP
+
+
+# RFC 5798 -  Virtual Router Redundancy Protocol (VRRP) Version 3
+class VRRPv3(Packet):
+    fields_desc = [
+        BitField("version", 3, 4),
+        BitField("type", 1, 4),
+        ByteField("vrid", 1),
+        ByteField("priority", 100),
+        FieldLenField("ipcount", None, count_of="addrlist", fmt="B"),
+        BitField("res", 0, 4),
+        BitField("adv", 100, 12),
+        XShortField("chksum", None),
+        # FIXME: addrlist should also allow IPv6 addresses :/
+        FieldListField("addrlist", [], IPField("", "0.0.0.0"),
+                       count_from = lambda pkt: pkt.ipcount)]
+
+    def post_build(self, p, pay):
+        if self.chksum is None:
+            if isinstance(self.underlayer, IP):
+                ck = in4_chksum(112, self.underlayer, p)
+            elif isinstance(self.underlayer, IPv6):
+                ck = in6_chksum(112, self.underlayer, p)
+            else:
+                warning("No IP(v6) layer to compute checksum on VRRP. Leaving null")
+                ck = 0
+            p = p[:6]+chr(ck>>8)+chr(ck&0xff)+p[8:]
+        return p
+
+    @classmethod
+    def dispatch_hook(cls, _pkt=None, *args, **kargs):
+        if _pkt and len(_pkt) >= 16:
+            ver_n_type = ord(_pkt[0])
+            if ver_n_type < 48 or ver_n_type > 57: # Version != 3
+                return VRRP
+        return VRRPv3
+
+# IPv6 is supported only on VRRPv3
 bind_layers( IP,            VRRP,          proto=IPPROTO_VRRP)
+bind_layers( IP,            VRRPv3,        proto=IPPROTO_VRRP)
+bind_layers( IPv6,          VRRPv3,        nh=IPPROTO_VRRP)