/**
* skb_checksum - Compute checksum of SKB data
* @skb: socket buffer
* @offset: offset from skb->data to start checksumming
* @len: length of data to checksum
* @seed: initial checksum value (usually 0)
*
* Returns the raw checksum for use in tcp_v4_check().
*/
static inline u32 skb_checksum(struct sk_buff *skb, int offset, int len, u32 seed)
{
const u16 *w = (const u16 *)(skb->data + offset);
u32 sum = seed;
for (; len > 1; len -= 2)
sum += *w++;
if (len)
sum += *(const u8 *)w;
sum = (sum & 0xFFFF) + (sum >> 16);
sum += (sum >> 16);
return sum;
}
tcp_v4_check
c复制代码
/**
* tcp_v4_check - Verify TCP checksum with IPv4 pseudo-header TCP 完整校验和验证
* @len: TCP segment length (header + data)
* @saddr: source IP address (network byte order)
* @daddr: destination IP address (network byte order)
* @csum: pre-computed checksum of TCP segment (from skb_checksum)
*
* Returns 0 if checksum is valid, non-zero if invalid.
*/
static inline u16 tcp_v4_check(int len, u32 saddr, u32 daddr, u32 csum)
{
u32 sum = csum;
/* Add pseudo-header: saddr, daddr are already network order */
sum += (saddr & 0xFFFF) + (saddr >> 16);
sum += (daddr & 0xFFFF) + (daddr >> 16);
sum += htons(IPPROTO_TCP);
sum += htons((u16)len);
/* Fold 32-bit sum to 16 bits */
sum = (sum & 0xFFFF) + (sum >> 16);
sum += (sum >> 16);
/* Return 0 if valid */
return (u16)~sum;
}