* Issue RST and make ACK acceptable to originator of segment. * The mbuf must still include the original packet header. * tp may be NULL. */
| 3348 | * tp may be NULL. |
| 3349 | */ |
| 3350 | void |
| 3351 | tcp_dropwithreset(struct mbuf *m, struct tcphdr *th, struct tcpcb *tp, |
| 3352 | int tlen, int rstreason) |
| 3353 | { |
| 3354 | #ifdef INET |
| 3355 | struct ip *ip; |
| 3356 | #endif |
| 3357 | #ifdef INET6 |
| 3358 | struct ip6_hdr *ip6; |
| 3359 | #endif |
| 3360 | |
| 3361 | if (tp != NULL) { |
| 3362 | INP_WLOCK_ASSERT(tp->t_inpcb); |
| 3363 | } |
| 3364 | |
| 3365 | /* Don't bother if destination was broadcast/multicast. */ |
| 3366 | if ((th->th_flags & TH_RST) || m->m_flags & (M_BCAST|M_MCAST)) |
| 3367 | goto drop; |
| 3368 | #ifdef INET6 |
| 3369 | if (mtod(m, struct ip *)->ip_v == 6) { |
| 3370 | ip6 = mtod(m, struct ip6_hdr *); |
| 3371 | if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || |
| 3372 | IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) |
| 3373 | goto drop; |
| 3374 | /* IPv6 anycast check is done at tcp6_input() */ |
| 3375 | } |
| 3376 | #endif |
| 3377 | #if defined(INET) && defined(INET6) |
| 3378 | else |
| 3379 | #endif |
| 3380 | #ifdef INET |
| 3381 | { |
| 3382 | ip = mtod(m, struct ip *); |
| 3383 | if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) || |
| 3384 | IN_MULTICAST(ntohl(ip->ip_src.s_addr)) || |
| 3385 | ip->ip_src.s_addr == htonl(INADDR_BROADCAST) || |
| 3386 | in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) |
| 3387 | goto drop; |
| 3388 | } |
| 3389 | #endif |
| 3390 | |
| 3391 | /* Perform bandwidth limiting. */ |
| 3392 | if (badport_bandlim(rstreason) < 0) |
| 3393 | goto drop; |
| 3394 | |
| 3395 | /* tcp_respond consumes the mbuf chain. */ |
| 3396 | if (th->th_flags & TH_ACK) { |
| 3397 | tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0, |
| 3398 | th->th_ack, TH_RST); |
| 3399 | } else { |
| 3400 | if (th->th_flags & TH_SYN) |
| 3401 | tlen++; |
| 3402 | if (th->th_flags & TH_FIN) |
| 3403 | tlen++; |
| 3404 | tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, |
| 3405 | (tcp_seq)0, TH_RST|TH_ACK); |
| 3406 | } |
| 3407 | return; |
no test coverage detected