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

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 = max(u.len - 4 * ihl, 0)
    else:
        ln = len(p)
    psdhdr = struct.pack("!4s4sHH",
                         inet_pton(socket.AF_INET, u.src),
                         inet_pton(socket.AF_INET, u.dst),
                         proto,
                         ln)
    return checksum(psdhdr + p)