sctp_input.c (237715) | sctp_input.c (238003) |
---|---|
1/*- 2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved. 3 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 237715 2012-06-28 16:01:08Z tuexen $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 238003 2012-07-02 16:44:09Z tuexen $"); |
35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_var.h> 38#include <netinet/sctp_sysctl.h> 39#include <netinet/sctp_pcb.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp_output.h> --- 5542 unchanged lines hidden (view full) --- 5585 5586/* 5587 * common input chunk processing (v4 and v6) 5588 */ 5589void 5590sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length, 5591 struct sockaddr *src, struct sockaddr *dst, 5592 struct sctphdr *sh, struct sctp_chunkhdr *ch, | 35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_var.h> 38#include <netinet/sctp_sysctl.h> 39#include <netinet/sctp_pcb.h> 40#include <netinet/sctp_header.h> 41#include <netinet/sctputil.h> 42#include <netinet/sctp_output.h> --- 5542 unchanged lines hidden (view full) --- 5585 5586/* 5587 * common input chunk processing (v4 and v6) 5588 */ 5589void 5590sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length, 5591 struct sockaddr *src, struct sockaddr *dst, 5592 struct sctphdr *sh, struct sctp_chunkhdr *ch, |
5593 struct sctp_inpcb *inp, struct sctp_tcb *stcb, 5594 struct sctp_nets *net, uint8_t ecn_bits, | 5593#if !defined(SCTP_WITH_NO_CSUM) 5594 uint8_t compute_crc, 5595#endif 5596 uint8_t ecn_bits, |
5595 uint8_t use_mflowid, uint32_t mflowid, 5596 uint32_t vrf_id, uint16_t port) 5597{ | 5597 uint8_t use_mflowid, uint32_t mflowid, 5598 uint32_t vrf_id, uint16_t port) 5599{ |
5598 /* 5599 * Control chunk processing 5600 */ | |
5601 uint32_t high_tsn; 5602 int fwd_tsn_seen = 0, data_processed = 0; 5603 struct mbuf *m = *mm; 5604 int un_sent; 5605 int cnt_ctrl_ready = 0; | 5600 uint32_t high_tsn; 5601 int fwd_tsn_seen = 0, data_processed = 0; 5602 struct mbuf *m = *mm; 5603 int un_sent; 5604 int cnt_ctrl_ready = 0; |
5605 struct sctp_inpcb *inp, *inp_decr = NULL; 5606 struct sctp_tcb *stcb = NULL; 5607 struct sctp_nets *net; |
|
5606 5607 SCTP_STAT_INCR(sctps_recvdatagrams); 5608#ifdef SCTP_AUDITING_ENABLED 5609 sctp_audit_log(0xE0, 1); 5610 sctp_auditing(0, inp, stcb, net); 5611#endif | 5608 5609 SCTP_STAT_INCR(sctps_recvdatagrams); 5610#ifdef SCTP_AUDITING_ENABLED 5611 sctp_audit_log(0xE0, 1); 5612 sctp_auditing(0, inp, stcb, net); 5613#endif |
5614#if !defined(SCTP_WITH_NO_CSUM) 5615 if (compute_crc != 0) { 5616 uint32_t check, calc_check; |
|
5612 | 5617 |
5618 check = sh->checksum; 5619 sh->checksum = 0; 5620 calc_check = sctp_calculate_cksum(m, iphlen); 5621 sh->checksum = check; 5622 if (calc_check != check) { 5623 SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 5624 calc_check, check, m, length, iphlen); 5625 stcb = sctp_findassociation_addr(m, offset, src, dst, 5626 sh, ch, &inp, &net, vrf_id); 5627 if ((net != NULL) && (port != 0)) { 5628 if (net->port == 0) { 5629 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 5630 } 5631 net->port = port; 5632 } 5633 if ((net != NULL) && (use_mflowid != 0)) { 5634 net->flowid = mflowid; 5635#ifdef INVARIANTS 5636 net->flowidset = 1; 5637#endif 5638 } 5639 if ((inp != NULL) && (stcb != NULL)) { 5640 sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1); 5641 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED); 5642 } else if ((inp != NULL) && (stcb == NULL)) { 5643 inp_decr = inp; 5644 } 5645 SCTP_STAT_INCR(sctps_badsum); 5646 SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors); 5647 goto out; 5648 } 5649 } 5650#endif 5651 /* Destination port of 0 is illegal, based on RFC4960. */ 5652 if (sh->dest_port == 0) { 5653 SCTP_STAT_INCR(sctps_hdrops); 5654 goto out; 5655 } 5656 stcb = sctp_findassociation_addr(m, offset, src, dst, 5657 sh, ch, &inp, &net, vrf_id); 5658 if ((net != NULL) && (port != 0)) { 5659 if (net->port == 0) { 5660 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 5661 } 5662 net->port = port; 5663 } 5664 if ((net != NULL) && (use_mflowid != 0)) { 5665 net->flowid = mflowid; 5666#ifdef INVARIANTS 5667 net->flowidset = 1; 5668#endif 5669 } 5670 if (inp == NULL) { 5671 SCTP_STAT_INCR(sctps_noport); 5672 if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) { 5673 goto out; 5674 } 5675 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { 5676 sctp_send_shutdown_complete2(src, dst, sh, 5677 use_mflowid, mflowid, 5678 vrf_id, port); 5679 goto out; 5680 } 5681 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 5682 goto out; 5683 } 5684 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) { 5685 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 5686 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 5687 (ch->chunk_type != SCTP_INIT))) { 5688 sctp_send_abort(m, iphlen, src, dst, 5689 sh, 0, NULL, 5690 use_mflowid, mflowid, 5691 vrf_id, port); 5692 } 5693 } 5694 goto out; 5695 } else if (stcb == NULL) { 5696 inp_decr = inp; 5697 } 5698#ifdef IPSEC 5699 /*- 5700 * I very much doubt any of the IPSEC stuff will work but I have no 5701 * idea, so I will leave it in place. 5702 */ 5703 if (inp != NULL) { 5704 switch (dst->sa_family) { 5705#ifdef INET 5706 case AF_INET: 5707 if (ipsec4_in_reject(m, &inp->ip_inp.inp)) { 5708 MODULE_GLOBAL(ipsec4stat).in_polvio++; 5709 SCTP_STAT_INCR(sctps_hdrops); 5710 goto out; 5711 } 5712 break; 5713#endif 5714#ifdef INET6 5715 case AF_INET6: 5716 if (ipsec6_in_reject(m, &inp->ip_inp.inp)) { 5717 MODULE_GLOBAL(ipsec6stat).in_polvio++; 5718 SCTP_STAT_INCR(sctps_hdrops); 5719 goto out; 5720 } 5721 break; 5722#endif 5723 default: 5724 break; 5725 } 5726 } 5727#endif |
|
5613 SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n", 5614 m, iphlen, offset, length, stcb); 5615 if (stcb) { 5616 /* always clear this before beginning a packet */ 5617 stcb->asoc.authenticated = 0; 5618 stcb->asoc.seen_a_sack_this_pkt = 0; 5619 SCTPDBG(SCTP_DEBUG_INPUT1, "stcb:%p state:%x\n", 5620 stcb, stcb->asoc.state); 5621 5622 if ((stcb->asoc.state & SCTP_STATE_WAS_ABORTED) || 5623 (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) { 5624 /*- 5625 * If we hit here, we had a ref count 5626 * up when the assoc was aborted and the 5627 * timer is clearing out the assoc, we should 5628 * NOT respond to any packet.. its OOTB. 5629 */ 5630 SCTP_TCB_UNLOCK(stcb); | 5728 SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n", 5729 m, iphlen, offset, length, stcb); 5730 if (stcb) { 5731 /* always clear this before beginning a packet */ 5732 stcb->asoc.authenticated = 0; 5733 stcb->asoc.seen_a_sack_this_pkt = 0; 5734 SCTPDBG(SCTP_DEBUG_INPUT1, "stcb:%p state:%x\n", 5735 stcb, stcb->asoc.state); 5736 5737 if ((stcb->asoc.state & SCTP_STATE_WAS_ABORTED) || 5738 (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED)) { 5739 /*- 5740 * If we hit here, we had a ref count 5741 * up when the assoc was aborted and the 5742 * timer is clearing out the assoc, we should 5743 * NOT respond to any packet.. its OOTB. 5744 */ 5745 SCTP_TCB_UNLOCK(stcb); |
5746 stcb = NULL; |
|
5631 sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, 5632 use_mflowid, mflowid, 5633 vrf_id, port); | 5747 sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, 5748 use_mflowid, mflowid, 5749 vrf_id, port); |
5634 goto out_now; | 5750 goto out; |
5635 } 5636 } 5637 if (IS_SCTP_CONTROL(ch)) { 5638 /* process the control portion of the SCTP packet */ 5639 /* sa_ignore NO_NULL_CHK */ 5640 stcb = sctp_process_control(m, iphlen, &offset, length, 5641 src, dst, sh, ch, 5642 inp, stcb, &net, &fwd_tsn_seen, --- 23 unchanged lines hidden (view full) --- 5666 * can't have authenticated without any AUTH (control) 5667 * chunks 5668 */ 5669 if ((stcb != NULL) && 5670 !SCTP_BASE_SYSCTL(sctp_auth_disable) && 5671 sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) { 5672 /* "silently" ignore */ 5673 SCTP_STAT_INCR(sctps_recvauthmissing); | 5751 } 5752 } 5753 if (IS_SCTP_CONTROL(ch)) { 5754 /* process the control portion of the SCTP packet */ 5755 /* sa_ignore NO_NULL_CHK */ 5756 stcb = sctp_process_control(m, iphlen, &offset, length, 5757 src, dst, sh, ch, 5758 inp, stcb, &net, &fwd_tsn_seen, --- 23 unchanged lines hidden (view full) --- 5782 * can't have authenticated without any AUTH (control) 5783 * chunks 5784 */ 5785 if ((stcb != NULL) && 5786 !SCTP_BASE_SYSCTL(sctp_auth_disable) && 5787 sctp_auth_is_required_chunk(SCTP_DATA, stcb->asoc.local_auth_chunks)) { 5788 /* "silently" ignore */ 5789 SCTP_STAT_INCR(sctps_recvauthmissing); |
5674 SCTP_TCB_UNLOCK(stcb); 5675 goto out_now; | 5790 goto out; |
5676 } 5677 if (stcb == NULL) { 5678 /* out of the blue DATA chunk */ 5679 sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, 5680 use_mflowid, mflowid, 5681 vrf_id, port); | 5791 } 5792 if (stcb == NULL) { 5793 /* out of the blue DATA chunk */ 5794 sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, 5795 use_mflowid, mflowid, 5796 vrf_id, port); |
5682 goto out_now; | 5797 goto out; |
5683 } 5684 if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) { 5685 /* v_tag mismatch! */ 5686 SCTP_STAT_INCR(sctps_badvtag); | 5798 } 5799 if (stcb->asoc.my_vtag != ntohl(sh->v_tag)) { 5800 /* v_tag mismatch! */ 5801 SCTP_STAT_INCR(sctps_badvtag); |
5687 SCTP_TCB_UNLOCK(stcb); 5688 goto out_now; | 5802 goto out; |
5689 } 5690 } 5691 5692 if (stcb == NULL) { 5693 /* 5694 * no valid TCB for this packet, or we found it's a bad 5695 * packet while processing control, or we're done with this 5696 * packet (done or skip rest of data), so we drop it... 5697 */ | 5803 } 5804 } 5805 5806 if (stcb == NULL) { 5807 /* 5808 * no valid TCB for this packet, or we found it's a bad 5809 * packet while processing control, or we're done with this 5810 * packet (done or skip rest of data), so we drop it... 5811 */ |
5698 goto out_now; | 5812 goto out; |
5699 } 5700 /* 5701 * DATA chunk processing 5702 */ 5703 /* plow through the data chunks while length > offset */ 5704 5705 /* 5706 * Rest should be DATA only. Check authentication state if AUTH for --- 37 unchanged lines hidden (view full) --- 5744 break; 5745 case SCTP_STATE_COOKIE_WAIT: 5746 /* 5747 * We consider OOTB any data sent during asoc setup. 5748 */ 5749 sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, 5750 use_mflowid, mflowid, 5751 vrf_id, port); | 5813 } 5814 /* 5815 * DATA chunk processing 5816 */ 5817 /* plow through the data chunks while length > offset */ 5818 5819 /* 5820 * Rest should be DATA only. Check authentication state if AUTH for --- 37 unchanged lines hidden (view full) --- 5858 break; 5859 case SCTP_STATE_COOKIE_WAIT: 5860 /* 5861 * We consider OOTB any data sent during asoc setup. 5862 */ 5863 sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, 5864 use_mflowid, mflowid, 5865 vrf_id, port); |
5752 SCTP_TCB_UNLOCK(stcb); 5753 goto out_now; | 5866 goto out; |
5754 /* sa_ignore NOTREACHED */ 5755 break; 5756 case SCTP_STATE_EMPTY: /* should not happen */ 5757 case SCTP_STATE_INUSE: /* should not happen */ 5758 case SCTP_STATE_SHUTDOWN_RECEIVED: /* This is a peer error */ 5759 case SCTP_STATE_SHUTDOWN_ACK_SENT: 5760 default: | 5867 /* sa_ignore NOTREACHED */ 5868 break; 5869 case SCTP_STATE_EMPTY: /* should not happen */ 5870 case SCTP_STATE_INUSE: /* should not happen */ 5871 case SCTP_STATE_SHUTDOWN_RECEIVED: /* This is a peer error */ 5872 case SCTP_STATE_SHUTDOWN_ACK_SENT: 5873 default: |
5761 SCTP_TCB_UNLOCK(stcb); 5762 goto out_now; | 5874 goto out; |
5763 /* sa_ignore NOTREACHED */ 5764 break; 5765 case SCTP_STATE_OPEN: 5766 case SCTP_STATE_SHUTDOWN_SENT: 5767 break; 5768 } 5769 /* plow through the data chunks while length > offset */ 5770 retval = sctp_process_data(mm, iphlen, &offset, length, 5771 src, dst, sh, 5772 inp, stcb, net, &high_tsn, 5773 use_mflowid, mflowid, 5774 vrf_id, port); 5775 if (retval == 2) { 5776 /* 5777 * The association aborted, NO UNLOCK needed since 5778 * the association is destroyed. 5779 */ | 5875 /* sa_ignore NOTREACHED */ 5876 break; 5877 case SCTP_STATE_OPEN: 5878 case SCTP_STATE_SHUTDOWN_SENT: 5879 break; 5880 } 5881 /* plow through the data chunks while length > offset */ 5882 retval = sctp_process_data(mm, iphlen, &offset, length, 5883 src, dst, sh, 5884 inp, stcb, net, &high_tsn, 5885 use_mflowid, mflowid, 5886 vrf_id, port); 5887 if (retval == 2) { 5888 /* 5889 * The association aborted, NO UNLOCK needed since 5890 * the association is destroyed. 5891 */ |
5780 goto out_now; | 5892 stcb = NULL; 5893 goto out; |
5781 } 5782 data_processed = 1; 5783 /* 5784 * Anything important needs to have been m_copy'ed in 5785 * process_data 5786 */ 5787 } 5788 /* take care of ecn */ --- 40 unchanged lines hidden (view full) --- 5829 SCTPDBG(SCTP_DEBUG_INPUT3, "Calling chunk OUTPUT\n"); 5830 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED); 5831 SCTPDBG(SCTP_DEBUG_INPUT3, "chunk OUTPUT returns\n"); 5832 } 5833#ifdef SCTP_AUDITING_ENABLED 5834 sctp_audit_log(0xE0, 3); 5835 sctp_auditing(2, inp, stcb, net); 5836#endif | 5894 } 5895 data_processed = 1; 5896 /* 5897 * Anything important needs to have been m_copy'ed in 5898 * process_data 5899 */ 5900 } 5901 /* take care of ecn */ --- 40 unchanged lines hidden (view full) --- 5942 SCTPDBG(SCTP_DEBUG_INPUT3, "Calling chunk OUTPUT\n"); 5943 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED); 5944 SCTPDBG(SCTP_DEBUG_INPUT3, "chunk OUTPUT returns\n"); 5945 } 5946#ifdef SCTP_AUDITING_ENABLED 5947 sctp_audit_log(0xE0, 3); 5948 sctp_auditing(2, inp, stcb, net); 5949#endif |
5837 SCTP_TCB_UNLOCK(stcb); 5838out_now: | 5950out: 5951 if (stcb != NULL) { 5952 SCTP_TCB_UNLOCK(stcb); 5953 } 5954 if (inp_decr != NULL) { 5955 /* reduce ref-count */ 5956 SCTP_INP_WLOCK(inp_decr); 5957 SCTP_INP_DECR_REF(inp_decr); 5958 SCTP_INP_WUNLOCK(inp_decr); 5959 } |
5839#ifdef INVARIANTS | 5960#ifdef INVARIANTS |
5840 sctp_validate_no_locks(inp); | 5961 if (inp != NULL) { 5962 sctp_validate_no_locks(inp); 5963 } |
5841#endif 5842 return; 5843} 5844 5845#if 0 5846static void 5847sctp_print_mbuf_chain(struct mbuf *m) 5848{ --- 13 unchanged lines hidden (view full) --- 5862 struct mbuf *m; 5863 int iphlen; 5864 uint32_t vrf_id = 0; 5865 uint8_t ecn_bits; 5866 struct sockaddr_in src, dst; 5867 struct ip *ip; 5868 struct sctphdr *sh; 5869 struct sctp_chunkhdr *ch; | 5964#endif 5965 return; 5966} 5967 5968#if 0 5969static void 5970sctp_print_mbuf_chain(struct mbuf *m) 5971{ --- 13 unchanged lines hidden (view full) --- 5985 struct mbuf *m; 5986 int iphlen; 5987 uint32_t vrf_id = 0; 5988 uint8_t ecn_bits; 5989 struct sockaddr_in src, dst; 5990 struct ip *ip; 5991 struct sctphdr *sh; 5992 struct sctp_chunkhdr *ch; |
5870 struct sctp_inpcb *inp = NULL; 5871 struct sctp_tcb *stcb = NULL; 5872 struct sctp_nets *net = NULL; 5873 int refcount_up = 0; | |
5874 int length, offset; | 5993 int length, offset; |
5875 uint32_t mflowid; 5876 uint8_t use_mflowid; | |
5877 5878#if !defined(SCTP_WITH_NO_CSUM) | 5994 5995#if !defined(SCTP_WITH_NO_CSUM) |
5879 uint32_t check, calc_check; | 5996 uint8_t compute_crc; |
5880 5881#endif | 5997 5998#endif |
5999 uint32_t mflowid; 6000 uint8_t use_mflowid; |
|
5882 5883 iphlen = off; 5884 if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) { 5885 SCTP_RELEASE_PKT(i_pak); 5886 return; 5887 } 5888 m = SCTP_HEADER_TO_CHAIN(i_pak); 5889#ifdef SCTP_MBUF_LOGGING --- 8 unchanged lines hidden (view full) --- 5898 } 5899 } 5900#endif 5901#ifdef SCTP_PACKET_LOGGING 5902 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) { 5903 sctp_packet_log(m); 5904 } 5905#endif | 6001 6002 iphlen = off; 6003 if (SCTP_GET_PKT_VRFID(i_pak, vrf_id)) { 6004 SCTP_RELEASE_PKT(i_pak); 6005 return; 6006 } 6007 m = SCTP_HEADER_TO_CHAIN(i_pak); 6008#ifdef SCTP_MBUF_LOGGING --- 8 unchanged lines hidden (view full) --- 6017 } 6018 } 6019#endif 6020#ifdef SCTP_PACKET_LOGGING 6021 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) { 6022 sctp_packet_log(m); 6023 } 6024#endif |
6025 SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 6026 "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n", 6027 m->m_pkthdr.len, 6028 if_name(m->m_pkthdr.rcvif), 6029 m->m_pkthdr.csum_flags); |
|
5906 if (m->m_flags & M_FLOWID) { 5907 mflowid = m->m_pkthdr.flowid; 5908 use_mflowid = 1; 5909 } else { 5910 mflowid = 0; 5911 use_mflowid = 0; 5912 } 5913 SCTP_STAT_INCR(sctps_recvpackets); --- 17 unchanged lines hidden (view full) --- 5931 src.sin_addr = ip->ip_src; 5932 memset(&dst, 0, sizeof(struct sockaddr_in)); 5933 dst.sin_family = AF_INET; 5934 dst.sin_len = sizeof(struct sockaddr_in); 5935 dst.sin_port = sh->dest_port; 5936 dst.sin_addr = ip->ip_dst; 5937 length = ip->ip_len + iphlen; 5938 /* Validate mbuf chain length with IP payload length. */ | 6030 if (m->m_flags & M_FLOWID) { 6031 mflowid = m->m_pkthdr.flowid; 6032 use_mflowid = 1; 6033 } else { 6034 mflowid = 0; 6035 use_mflowid = 0; 6036 } 6037 SCTP_STAT_INCR(sctps_recvpackets); --- 17 unchanged lines hidden (view full) --- 6055 src.sin_addr = ip->ip_src; 6056 memset(&dst, 0, sizeof(struct sockaddr_in)); 6057 dst.sin_family = AF_INET; 6058 dst.sin_len = sizeof(struct sockaddr_in); 6059 dst.sin_port = sh->dest_port; 6060 dst.sin_addr = ip->ip_dst; 6061 length = ip->ip_len + iphlen; 6062 /* Validate mbuf chain length with IP payload length. */ |
5939 if (SCTP_HEADER_LEN(i_pak) != length) { | 6063 if (SCTP_HEADER_LEN(m) != length) { |
5940 SCTPDBG(SCTP_DEBUG_INPUT1, | 6064 SCTPDBG(SCTP_DEBUG_INPUT1, |
5941 "sctp_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(i_pak)); | 6065 "sctp_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(m)); |
5942 SCTP_STAT_INCR(sctps_hdrops); | 6066 SCTP_STAT_INCR(sctps_hdrops); |
5943 goto bad; | 6067 goto out; |
5944 } 5945 /* SCTP does not allow broadcasts or multicasts */ 5946 if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) { | 6068 } 6069 /* SCTP does not allow broadcasts or multicasts */ 6070 if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) { |
5947 goto bad; | 6071 goto out; |
5948 } 5949 if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) { | 6072 } 6073 if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) { |
5950 goto bad; | 6074 goto out; |
5951 } | 6075 } |
5952 SCTPDBG(SCTP_DEBUG_INPUT1, 5953 "sctp_input() length:%d iphlen:%d\n", length, iphlen); 5954 SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 5955 "sctp_input(): Packet of length %d received on %s with csum_flags 0x%x.\n", 5956 m->m_pkthdr.len, 5957 if_name(m->m_pkthdr.rcvif), 5958 m->m_pkthdr.csum_flags); | 6076 ecn_bits = ip->ip_tos; |
5959#if defined(SCTP_WITH_NO_CSUM) 5960 SCTP_STAT_INCR(sctps_recvnocrc); 5961#else 5962 if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { 5963 SCTP_STAT_INCR(sctps_recvhwcrc); | 6077#if defined(SCTP_WITH_NO_CSUM) 6078 SCTP_STAT_INCR(sctps_recvnocrc); 6079#else 6080 if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { 6081 SCTP_STAT_INCR(sctps_recvhwcrc); |
5964 goto sctp_skip_csum; | 6082 compute_crc = 0; 6083 } else { 6084 SCTP_STAT_INCR(sctps_recvswcrc); 6085 compute_crc = 1; |
5965 } | 6086 } |
5966 check = sh->checksum; 5967 sh->checksum = 0; 5968 calc_check = sctp_calculate_cksum(m, iphlen); 5969 sh->checksum = check; 5970 SCTP_STAT_INCR(sctps_recvswcrc); 5971 if (calc_check != check) { 5972 SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n", 5973 calc_check, check, m, length, iphlen); 5974 stcb = sctp_findassociation_addr(m, offset, 5975 (struct sockaddr *)&src, 5976 (struct sockaddr *)&dst, 5977 sh, ch, &inp, &net, vrf_id); 5978 if ((net) && (port)) { 5979 if (net->port == 0) { 5980 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 5981 } 5982 net->port = port; 5983 } 5984 if ((net != NULL) && (use_mflowid != 0)) { 5985 net->flowid = mflowid; 5986#ifdef INVARIANTS 5987 net->flowidset = 1; | |
5988#endif | 6087#endif |
5989 } 5990 if ((inp) && (stcb)) { 5991 sctp_send_packet_dropped(stcb, net, m, length, iphlen, 1); 5992 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_INPUT_ERROR, SCTP_SO_NOT_LOCKED); 5993 } else if ((inp != NULL) && (stcb == NULL)) { 5994 refcount_up = 1; 5995 } 5996 SCTP_STAT_INCR(sctps_badsum); 5997 SCTP_STAT_INCR_COUNTER32(sctps_checksumerrors); 5998 goto bad; 5999 } 6000sctp_skip_csum: 6001#endif 6002 /* destination port of 0 is illegal, based on RFC2960. */ 6003 if (sh->dest_port == 0) { 6004 SCTP_STAT_INCR(sctps_hdrops); 6005 goto bad; 6006 } 6007 stcb = sctp_findassociation_addr(m, offset, 6008 (struct sockaddr *)&src, 6009 (struct sockaddr *)&dst, 6010 sh, ch, &inp, &net, vrf_id); 6011 if ((net) && (port)) { 6012 if (net->port == 0) { 6013 sctp_pathmtu_adjustment(stcb, net->mtu - sizeof(struct udphdr)); 6014 } 6015 net->port = port; 6016 } 6017 if ((net != NULL) && (use_mflowid != 0)) { 6018 net->flowid = mflowid; 6019#ifdef INVARIANTS 6020 net->flowidset = 1; 6021#endif 6022 } 6023 if (inp == NULL) { 6024 SCTP_STAT_INCR(sctps_noport); 6025 if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0) 6026 goto bad; 6027 if (ch->chunk_type == SCTP_SHUTDOWN_ACK) { 6028 sctp_send_shutdown_complete2((struct sockaddr *)&src, 6029 (struct sockaddr *)&dst, 6030 sh, 6031 use_mflowid, mflowid, 6032 vrf_id, port); 6033 goto bad; 6034 } 6035 if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) { 6036 goto bad; 6037 } 6038 if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) { 6039 if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) || 6040 ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) && 6041 (ch->chunk_type != SCTP_INIT))) { 6042 sctp_send_abort(m, iphlen, 6043 (struct sockaddr *)&src, 6044 (struct sockaddr *)&dst, 6045 sh, 0, NULL, 6046 use_mflowid, mflowid, 6047 vrf_id, port); 6048 } 6049 } 6050 goto bad; 6051 } else if (stcb == NULL) { 6052 refcount_up = 1; 6053 } 6054#ifdef IPSEC 6055 /*- 6056 * I very much doubt any of the IPSEC stuff will work but I have no 6057 * idea, so I will leave it in place. 6058 */ 6059 if (inp && ipsec4_in_reject(m, &inp->ip_inp.inp)) { 6060 MODULE_GLOBAL(ipsec4stat).in_polvio++; 6061 SCTP_STAT_INCR(sctps_hdrops); 6062 goto bad; 6063 } 6064#endif 6065 6066 ecn_bits = ip->ip_tos; 6067 /* sa_ignore NO_NULL_CHK */ | |
6068 sctp_common_input_processing(&m, iphlen, offset, length, 6069 (struct sockaddr *)&src, 6070 (struct sockaddr *)&dst, | 6088 sctp_common_input_processing(&m, iphlen, offset, length, 6089 (struct sockaddr *)&src, 6090 (struct sockaddr *)&dst, |
6071 sh, ch, inp, stcb, net, ecn_bits, | 6091 sh, ch, 6092#if !defined(SCTP_WITH_NO_CSUM) 6093 compute_crc, 6094#endif 6095 ecn_bits, |
6072 use_mflowid, mflowid, 6073 vrf_id, port); | 6096 use_mflowid, mflowid, 6097 vrf_id, port); |
6098out: |
|
6074 if (m) { 6075 sctp_m_freem(m); 6076 } | 6099 if (m) { 6100 sctp_m_freem(m); 6101 } |
6077 if ((inp) && (refcount_up)) { 6078 /* reduce ref-count */ 6079 SCTP_INP_WLOCK(inp); 6080 SCTP_INP_DECR_REF(inp); 6081 SCTP_INP_WUNLOCK(inp); 6082 } | |
6083 return; | 6102 return; |
6084bad: 6085 if (stcb) { 6086 SCTP_TCB_UNLOCK(stcb); 6087 } 6088 if ((inp) && (refcount_up)) { 6089 /* reduce ref-count */ 6090 SCTP_INP_WLOCK(inp); 6091 SCTP_INP_DECR_REF(inp); 6092 SCTP_INP_WUNLOCK(inp); 6093 } 6094 if (m) { 6095 sctp_m_freem(m); 6096 } 6097 return; | |
6098} 6099 6100#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) 6101extern int *sctp_cpuarry; 6102 6103#endif 6104 6105void --- 40 unchanged lines hidden --- | 6103} 6104 6105#if defined(__FreeBSD__) && defined(SCTP_MCORE_INPUT) && defined(SMP) 6106extern int *sctp_cpuarry; 6107 6108#endif 6109 6110void --- 40 unchanged lines hidden --- |