| 2326 | } |
| 2327 | |
| 2328 | int |
| 2329 | sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa) |
| 2330 | { |
| 2331 | struct sctp_tmit_chunk *chk, *nchk; |
| 2332 | unsigned int offset, asconf_limit; |
| 2333 | struct sctp_asconf_chunk *acp; |
| 2334 | struct sctp_asconf_paramhdr *aph; |
| 2335 | uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE]; |
| 2336 | struct sctp_paramhdr *ph; |
| 2337 | int add_cnt, del_cnt; |
| 2338 | uint16_t last_param_type; |
| 2339 | |
| 2340 | add_cnt = del_cnt = 0; |
| 2341 | last_param_type = 0; |
| 2342 | TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) { |
| 2343 | if (chk->data == NULL) { |
| 2344 | SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n"); |
| 2345 | continue; |
| 2346 | } |
| 2347 | offset = 0; |
| 2348 | acp = mtod(chk->data, struct sctp_asconf_chunk *); |
| 2349 | offset += sizeof(struct sctp_asconf_chunk); |
| 2350 | asconf_limit = ntohs(acp->ch.chunk_length); |
| 2351 | ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf); |
| 2352 | if (ph == NULL) { |
| 2353 | SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n"); |
| 2354 | continue; |
| 2355 | } |
| 2356 | offset += ntohs(ph->param_length); |
| 2357 | |
| 2358 | aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf); |
| 2359 | if (aph == NULL) { |
| 2360 | SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n"); |
| 2361 | continue; |
| 2362 | } |
| 2363 | while (aph != NULL) { |
| 2364 | unsigned int param_length, param_type; |
| 2365 | |
| 2366 | param_type = ntohs(aph->ph.param_type); |
| 2367 | param_length = ntohs(aph->ph.param_length); |
| 2368 | if (offset + param_length > asconf_limit) { |
| 2369 | /* parameter goes beyond end of chunk! */ |
| 2370 | break; |
| 2371 | } |
| 2372 | if (param_length > sizeof(aparam_buf)) { |
| 2373 | SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length); |
| 2374 | break; |
| 2375 | } |
| 2376 | if (param_length <= sizeof(struct sctp_paramhdr)) { |
| 2377 | SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length); |
| 2378 | break; |
| 2379 | } |
| 2380 | |
| 2381 | aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf); |
| 2382 | if (aph == NULL) { |
| 2383 | SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n"); |
| 2384 | break; |
| 2385 | } |
no test coverage detected