aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp/ipv4.c')
-rw-r--r--net/dccp/ipv4.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 61c09014dade..34d6d197c3b2 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -518,7 +518,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
518 sizeof(struct dccp_hdr_reset); 518 sizeof(struct dccp_hdr_reset);
519 struct sk_buff *skb; 519 struct sk_buff *skb;
520 struct dst_entry *dst; 520 struct dst_entry *dst;
521 u64 seqno; 521 u64 seqno = 0;
522 522
523 /* Never send a reset in response to a reset. */ 523 /* Never send a reset in response to a reset. */
524 if (rxdh->dccph_type == DCCP_PKT_RESET) 524 if (rxdh->dccph_type == DCCP_PKT_RESET)
@@ -552,13 +552,11 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
552 DCCP_SKB_CB(rxskb)->dccpd_reset_code; 552 DCCP_SKB_CB(rxskb)->dccpd_reset_code;
553 553
554 /* See "8.3.1. Abnormal Termination" in RFC 4340 */ 554 /* See "8.3.1. Abnormal Termination" in RFC 4340 */
555 seqno = 0;
556 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 555 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
557 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); 556 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
558 557
559 dccp_hdr_set_seq(dh, seqno); 558 dccp_hdr_set_seq(dh, seqno);
560 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), 559 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq);
561 DCCP_SKB_CB(rxskb)->dccpd_seq);
562 560
563 dccp_csum_outgoing(skb); 561 dccp_csum_outgoing(skb);
564 dh->dccph_checksum = dccp_v4_csum_finish(skb, rxskb->nh.iph->saddr, 562 dh->dccph_checksum = dccp_v4_csum_finish(skb, rxskb->nh.iph->saddr,
@@ -734,6 +732,11 @@ discard:
734 732
735EXPORT_SYMBOL_GPL(dccp_v4_do_rcv); 733EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
736 734
735/**
736 * dccp_invalid_packet - check for malformed packets
737 * Implements RFC 4340, 8.5: Step 1: Check header basics
738 * Packets that fail these checks are ignored and do not receive Resets.
739 */
737int dccp_invalid_packet(struct sk_buff *skb) 740int dccp_invalid_packet(struct sk_buff *skb)
738{ 741{
739 const struct dccp_hdr *dh; 742 const struct dccp_hdr *dh;
@@ -742,6 +745,7 @@ int dccp_invalid_packet(struct sk_buff *skb)
742 if (skb->pkt_type != PACKET_HOST) 745 if (skb->pkt_type != PACKET_HOST)
743 return 1; 746 return 1;
744 747
748 /* If the packet is shorter than 12 bytes, drop packet and return */
745 if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) { 749 if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) {
746 LIMIT_NETDEBUG(KERN_WARNING "DCCP: pskb_may_pull failed\n"); 750 LIMIT_NETDEBUG(KERN_WARNING "DCCP: pskb_may_pull failed\n");
747 return 1; 751 return 1;
@@ -749,42 +753,37 @@ int dccp_invalid_packet(struct sk_buff *skb)
749 753
750 dh = dccp_hdr(skb); 754 dh = dccp_hdr(skb);
751 755
752 /* If the packet type is not understood, drop packet and return */ 756 /* If P.type is not understood, drop packet and return */
753 if (dh->dccph_type >= DCCP_PKT_INVALID) { 757 if (dh->dccph_type >= DCCP_PKT_INVALID) {
754 LIMIT_NETDEBUG(KERN_WARNING "DCCP: invalid packet type\n"); 758 LIMIT_NETDEBUG(KERN_WARNING "DCCP: invalid packet type\n");
755 return 1; 759 return 1;
756 } 760 }
757 761
758 /* 762 /*
759 * If P.Data Offset is too small for packet type, or too large for 763 * If P.Data Offset is too small for packet type, drop packet and return
760 * packet, drop packet and return
761 */ 764 */
762 if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { 765 if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
763 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " 766 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) "
764 "too small 1\n", 767 "too small\n", dh->dccph_doff);
765 dh->dccph_doff);
766 return 1; 768 return 1;
767 } 769 }
768 770 /*
771 * If P.Data Offset is too too large for packet, drop packet and return
772 */
769 if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { 773 if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
770 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " 774 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) "
771 "too small 2\n", 775 "too large\n", dh->dccph_doff);
772 dh->dccph_doff);
773 return 1; 776 return 1;
774 } 777 }
775 778
776 dh = dccp_hdr(skb);
777
778 /* 779 /*
779 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet 780 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
780 * has short sequence numbers), drop packet and return 781 * has short sequence numbers), drop packet and return
781 */ 782 */
782 if (dh->dccph_x == 0 && 783 if (dh->dccph_type >= DCCP_PKT_DATA &&
783 dh->dccph_type != DCCP_PKT_DATA && 784 dh->dccph_type <= DCCP_PKT_DATAACK && dh->dccph_x == 0) {
784 dh->dccph_type != DCCP_PKT_ACK && 785 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.type (%s) not Data||Ack||"
785 dh->dccph_type != DCCP_PKT_DATAACK) { 786 "DataAck, while P.X == 0\n",
786 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.type (%s) not Data, Ack "
787 "nor DataAck and P.X == 0\n",
788 dccp_packet_name(dh->dccph_type)); 787 dccp_packet_name(dh->dccph_type));
789 return 1; 788 return 1;
790 } 789 }