Loading net/dccp/dccp.h +2 −1 Original line number Diff line number Diff line Loading @@ -242,7 +242,8 @@ extern int dccp_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); extern void dccp_shutdown(struct sock *sk, int how); extern int dccp_v4_checksum(struct sk_buff *skb); extern int dccp_v4_checksum(const struct sk_buff *skb, const u32 saddr, const u32 daddr); extern int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code); extern void dccp_send_close(struct sock *sk); Loading net/dccp/ipv4.c +20 −18 Original line number Diff line number Diff line Loading @@ -802,9 +802,9 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) return sk; } int dccp_v4_checksum(struct sk_buff *skb) int dccp_v4_checksum(const struct sk_buff *skb, const u32 saddr, const u32 daddr) { struct dccp_hdr* dh = dccp_hdr(skb); const struct dccp_hdr* dh = dccp_hdr(skb); int checksum_len; u32 tmp; Loading @@ -816,24 +816,24 @@ int dccp_v4_checksum(struct sk_buff *skb) } tmp = csum_partial((unsigned char *)dh, checksum_len, 0); return csum_fold(tmp); return csum_tcpudp_magic(saddr, daddr, checksum_len, IPPROTO_DCCP, tmp); } static int dccp_v4_verify_checksum(struct sk_buff *skb) static int dccp_v4_verify_checksum(struct sk_buff *skb, const u32 saddr, const u32 daddr) { struct dccp_hdr *th = dccp_hdr(skb); const u16 remote_checksum = th->dccph_checksum; u16 local_checksum; /* FIXME: don't mess with skb payload */ th->dccph_checksum = 0; /* zero it for computation */ local_checksum = dccp_v4_checksum(skb); /* FIXME: don't mess with skb payload */ th->dccph_checksum = remote_checksum; /* put it back */ struct dccp_hdr *dh = dccp_hdr(skb); int checksum_len; u32 tmp; return remote_checksum == local_checksum ? 0 : -1; if (dh->dccph_cscov == 0) checksum_len = skb->len; else { checksum_len = (dh->dccph_cscov + dh->dccph_x) * sizeof(u32); checksum_len = checksum_len < skb->len ? checksum_len : skb->len; } tmp = csum_partial((unsigned char *)dh, checksum_len, 0); return csum_tcpudp_magic(saddr, daddr, checksum_len, IPPROTO_DCCP, tmp) == 0 ? 0 : -1; } static struct dst_entry* dccp_v4_route_skb(struct sock *sk, Loading Loading @@ -902,7 +902,8 @@ void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq); dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq); dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr, rxskb->nh.iph->daddr); bh_lock_sock(dccp_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_ctl_socket->sk, Loading Loading @@ -1024,7 +1025,8 @@ static inline int dccp_invalid_packet(struct sk_buff *skb) } /* If the header checksum is incorrect, drop packet and return */ if (dccp_v4_verify_checksum(skb) < 0) { if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr, skb->nh.iph->daddr) < 0) { dccp_pr_debug("header checksum is incorrect\n"); return 1; } Loading net/dccp/output.c +6 −3 Original line number Diff line number Diff line Loading @@ -93,7 +93,8 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) break; } dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr); if (dcb->dccpd_type == DCCP_PKT_ACK || dcb->dccpd_type == DCCP_PKT_DATAACK) Loading Loading @@ -193,7 +194,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, dccp_hdr_set_seq(dh, dccp_rsk(req)->dreq_iss); dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dccp_rsk(req)->dreq_isr); dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, inet_rsk(req)->loc_addr, inet_rsk(req)->rmt_addr); DCCP_INC_STATS(DCCP_MIB_OUTSEGS); return skb; Loading Loading @@ -242,7 +244,8 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, dccp_hdr_reset(skb)->dccph_reset_code = code; dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, inet_sk(sk)->saddr, inet_sk(sk)->daddr); DCCP_INC_STATS(DCCP_MIB_OUTSEGS); return skb; Loading Loading
net/dccp/dccp.h +2 −1 Original line number Diff line number Diff line Loading @@ -242,7 +242,8 @@ extern int dccp_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen); extern void dccp_shutdown(struct sock *sk, int how); extern int dccp_v4_checksum(struct sk_buff *skb); extern int dccp_v4_checksum(const struct sk_buff *skb, const u32 saddr, const u32 daddr); extern int dccp_v4_send_reset(struct sock *sk, enum dccp_reset_codes code); extern void dccp_send_close(struct sock *sk); Loading
net/dccp/ipv4.c +20 −18 Original line number Diff line number Diff line Loading @@ -802,9 +802,9 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb) return sk; } int dccp_v4_checksum(struct sk_buff *skb) int dccp_v4_checksum(const struct sk_buff *skb, const u32 saddr, const u32 daddr) { struct dccp_hdr* dh = dccp_hdr(skb); const struct dccp_hdr* dh = dccp_hdr(skb); int checksum_len; u32 tmp; Loading @@ -816,24 +816,24 @@ int dccp_v4_checksum(struct sk_buff *skb) } tmp = csum_partial((unsigned char *)dh, checksum_len, 0); return csum_fold(tmp); return csum_tcpudp_magic(saddr, daddr, checksum_len, IPPROTO_DCCP, tmp); } static int dccp_v4_verify_checksum(struct sk_buff *skb) static int dccp_v4_verify_checksum(struct sk_buff *skb, const u32 saddr, const u32 daddr) { struct dccp_hdr *th = dccp_hdr(skb); const u16 remote_checksum = th->dccph_checksum; u16 local_checksum; /* FIXME: don't mess with skb payload */ th->dccph_checksum = 0; /* zero it for computation */ local_checksum = dccp_v4_checksum(skb); /* FIXME: don't mess with skb payload */ th->dccph_checksum = remote_checksum; /* put it back */ struct dccp_hdr *dh = dccp_hdr(skb); int checksum_len; u32 tmp; return remote_checksum == local_checksum ? 0 : -1; if (dh->dccph_cscov == 0) checksum_len = skb->len; else { checksum_len = (dh->dccph_cscov + dh->dccph_x) * sizeof(u32); checksum_len = checksum_len < skb->len ? checksum_len : skb->len; } tmp = csum_partial((unsigned char *)dh, checksum_len, 0); return csum_tcpudp_magic(saddr, daddr, checksum_len, IPPROTO_DCCP, tmp) == 0 ? 0 : -1; } static struct dst_entry* dccp_v4_route_skb(struct sock *sk, Loading Loading @@ -902,7 +902,8 @@ void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq); dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq); dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr, rxskb->nh.iph->daddr); bh_lock_sock(dccp_ctl_socket->sk); err = ip_build_and_send_pkt(skb, dccp_ctl_socket->sk, Loading Loading @@ -1024,7 +1025,8 @@ static inline int dccp_invalid_packet(struct sk_buff *skb) } /* If the header checksum is incorrect, drop packet and return */ if (dccp_v4_verify_checksum(skb) < 0) { if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr, skb->nh.iph->daddr) < 0) { dccp_pr_debug("header checksum is incorrect\n"); return 1; } Loading
net/dccp/output.c +6 −3 Original line number Diff line number Diff line Loading @@ -93,7 +93,8 @@ int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) break; } dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr); if (dcb->dccpd_type == DCCP_PKT_ACK || dcb->dccpd_type == DCCP_PKT_DATAACK) Loading Loading @@ -193,7 +194,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst, dccp_hdr_set_seq(dh, dccp_rsk(req)->dreq_iss); dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dccp_rsk(req)->dreq_isr); dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, inet_rsk(req)->loc_addr, inet_rsk(req)->rmt_addr); DCCP_INC_STATS(DCCP_MIB_OUTSEGS); return skb; Loading Loading @@ -242,7 +244,8 @@ struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, dccp_hdr_reset(skb)->dccph_reset_code = code; dh->dccph_checksum = dccp_v4_checksum(skb); dh->dccph_checksum = dccp_v4_checksum(skb, inet_sk(sk)->saddr, inet_sk(sk)->daddr); DCCP_INC_STATS(DCCP_MIB_OUTSEGS); return skb; Loading