| 777 | |
| 778 | #ifdef INET |
| 779 | static void |
| 780 | udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip, |
| 781 | struct inpcbinfo *pcbinfo) |
| 782 | { |
| 783 | struct ip *ip = vip; |
| 784 | struct udphdr *uh; |
| 785 | struct in_addr faddr; |
| 786 | struct inpcb *inp; |
| 787 | |
| 788 | faddr = ((struct sockaddr_in *)sa)->sin_addr; |
| 789 | if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY) |
| 790 | return; |
| 791 | |
| 792 | if (PRC_IS_REDIRECT(cmd)) { |
| 793 | /* signal EHOSTDOWN, as it flushes the cached route */ |
| 794 | in_pcbnotifyall(&V_udbinfo, faddr, EHOSTDOWN, udp_notify); |
| 795 | return; |
| 796 | } |
| 797 | |
| 798 | /* |
| 799 | * Hostdead is ugly because it goes linearly through all PCBs. |
| 800 | * |
| 801 | * XXX: We never get this from ICMP, otherwise it makes an excellent |
| 802 | * DoS attack on machines with many connections. |
| 803 | */ |
| 804 | if (cmd == PRC_HOSTDEAD) |
| 805 | ip = NULL; |
| 806 | else if ((unsigned)cmd >= PRC_NCMDS || inetctlerrmap[cmd] == 0) |
| 807 | return; |
| 808 | if (ip != NULL) { |
| 809 | uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2)); |
| 810 | inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport, |
| 811 | ip->ip_src, uh->uh_sport, INPLOOKUP_WLOCKPCB, NULL); |
| 812 | if (inp != NULL) { |
| 813 | INP_WLOCK_ASSERT(inp); |
| 814 | if (inp->inp_socket != NULL) { |
| 815 | udp_notify(inp, inetctlerrmap[cmd]); |
| 816 | } |
| 817 | INP_WUNLOCK(inp); |
| 818 | } else { |
| 819 | inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport, |
| 820 | ip->ip_src, uh->uh_sport, |
| 821 | INPLOOKUP_WILDCARD | INPLOOKUP_RLOCKPCB, NULL); |
| 822 | if (inp != NULL) { |
| 823 | struct udpcb *up; |
| 824 | void *ctx; |
| 825 | udp_tun_icmp_t func; |
| 826 | |
| 827 | up = intoudpcb(inp); |
| 828 | ctx = up->u_tun_ctx; |
| 829 | func = up->u_icmp_func; |
| 830 | INP_RUNLOCK(inp); |
| 831 | if (func != NULL) |
| 832 | (*func)(cmd, sa, vip, ctx); |
| 833 | } |
| 834 | } |
| 835 | } else |
| 836 | in_pcbnotifyall(pcbinfo, faddr, inetctlerrmap[cmd], |
no test coverage detected