| 110 | extern struct protosw inetsw[]; |
| 111 | |
| 112 | static inline int |
| 113 | ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, int flags, |
| 114 | struct inpcb *inp, struct sockaddr_in *dst, int *fibnum, int *error) |
| 115 | { |
| 116 | struct m_tag *fwd_tag = NULL; |
| 117 | struct mbuf *m; |
| 118 | struct in_addr odst; |
| 119 | struct ip *ip; |
| 120 | int pflags = PFIL_OUT; |
| 121 | |
| 122 | if (flags & IP_FORWARDING) |
| 123 | pflags |= PFIL_FWD; |
| 124 | |
| 125 | m = *mp; |
| 126 | ip = mtod(m, struct ip *); |
| 127 | |
| 128 | /* Run through list of hooks for output packets. */ |
| 129 | odst.s_addr = ip->ip_dst.s_addr; |
| 130 | switch (pfil_run_hooks(V_inet_pfil_head, mp, ifp, pflags, inp)) { |
| 131 | case PFIL_DROPPED: |
| 132 | *error = EACCES; |
| 133 | /* FALLTHROUGH */ |
| 134 | case PFIL_CONSUMED: |
| 135 | return 1; /* Finished */ |
| 136 | case PFIL_PASS: |
| 137 | *error = 0; |
| 138 | } |
| 139 | m = *mp; |
| 140 | ip = mtod(m, struct ip *); |
| 141 | |
| 142 | /* See if destination IP address was changed by packet filter. */ |
| 143 | if (odst.s_addr != ip->ip_dst.s_addr) { |
| 144 | m->m_flags |= M_SKIP_FIREWALL; |
| 145 | /* If destination is now ourself drop to ip_input(). */ |
| 146 | if (in_localip(ip->ip_dst)) { |
| 147 | m->m_flags |= M_FASTFWD_OURS; |
| 148 | if (m->m_pkthdr.rcvif == NULL) |
| 149 | m->m_pkthdr.rcvif = V_loif; |
| 150 | if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { |
| 151 | m->m_pkthdr.csum_flags |= |
| 152 | CSUM_DATA_VALID | CSUM_PSEUDO_HDR; |
| 153 | m->m_pkthdr.csum_data = 0xffff; |
| 154 | } |
| 155 | m->m_pkthdr.csum_flags |= |
| 156 | CSUM_IP_CHECKED | CSUM_IP_VALID; |
| 157 | #if defined(SCTP) || defined(SCTP_SUPPORT) |
| 158 | if (m->m_pkthdr.csum_flags & CSUM_SCTP) |
| 159 | m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID; |
| 160 | #endif |
| 161 | *error = netisr_queue(NETISR_IP, m); |
| 162 | return 1; /* Finished */ |
| 163 | } |
| 164 | |
| 165 | bzero(dst, sizeof(*dst)); |
| 166 | dst->sin_family = AF_INET; |
| 167 | dst->sin_len = sizeof(*dst); |
| 168 | dst->sin_addr = ip->ip_dst; |
| 169 |
no test coverage detected