| 1096 | } |
| 1097 | |
| 1098 | static int |
| 1099 | sctp_handle_error(struct sctp_chunkhdr *ch, |
| 1100 | struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t limit) |
| 1101 | { |
| 1102 | struct sctp_error_cause *cause; |
| 1103 | struct sctp_association *asoc; |
| 1104 | uint32_t remaining_length, adjust; |
| 1105 | uint16_t code, cause_code, cause_length; |
| 1106 | |
| 1107 | /* parse through all of the errors and process */ |
| 1108 | asoc = &stcb->asoc; |
| 1109 | cause = (struct sctp_error_cause *)((caddr_t)ch + |
| 1110 | sizeof(struct sctp_chunkhdr)); |
| 1111 | remaining_length = ntohs(ch->chunk_length); |
| 1112 | if (remaining_length > limit) { |
| 1113 | remaining_length = limit; |
| 1114 | } |
| 1115 | if (remaining_length >= sizeof(struct sctp_chunkhdr)) { |
| 1116 | remaining_length -= sizeof(struct sctp_chunkhdr); |
| 1117 | } else { |
| 1118 | remaining_length = 0; |
| 1119 | } |
| 1120 | code = 0; |
| 1121 | while (remaining_length >= sizeof(struct sctp_error_cause)) { |
| 1122 | /* Process an Error Cause */ |
| 1123 | cause_code = ntohs(cause->code); |
| 1124 | cause_length = ntohs(cause->length); |
| 1125 | if ((cause_length > remaining_length) || (cause_length == 0)) { |
| 1126 | /* Invalid cause length, possibly due to truncation. */ |
| 1127 | SCTPDBG(SCTP_DEBUG_INPUT1, "Bogus length in cause - bytes left: %u cause length: %u\n", |
| 1128 | remaining_length, cause_length); |
| 1129 | return (0); |
| 1130 | } |
| 1131 | if (code == 0) { |
| 1132 | /* report the first error cause */ |
| 1133 | code = cause_code; |
| 1134 | } |
| 1135 | switch (cause_code) { |
| 1136 | case SCTP_CAUSE_INVALID_STREAM: |
| 1137 | case SCTP_CAUSE_MISSING_PARAM: |
| 1138 | case SCTP_CAUSE_INVALID_PARAM: |
| 1139 | case SCTP_CAUSE_NO_USER_DATA: |
| 1140 | SCTPDBG(SCTP_DEBUG_INPUT1, "Software error we got a %u back? We have a bug :/ (or do they?)\n", |
| 1141 | cause_code); |
| 1142 | break; |
| 1143 | case SCTP_CAUSE_NAT_COLLIDING_STATE: |
| 1144 | SCTPDBG(SCTP_DEBUG_INPUT2, "Received Colliding state, ERROR flags: %x\n", |
| 1145 | ch->chunk_flags); |
| 1146 | if (sctp_handle_nat_colliding_state(stcb)) { |
| 1147 | return (0); |
| 1148 | } |
| 1149 | break; |
| 1150 | case SCTP_CAUSE_NAT_MISSING_STATE: |
| 1151 | SCTPDBG(SCTP_DEBUG_INPUT2, "Received missing state, ERROR flags: %x\n", |
| 1152 | ch->chunk_flags); |
| 1153 | if (sctp_handle_nat_missing_state(stcb, net)) { |
| 1154 | return (0); |
| 1155 | } |
no test coverage detected