* ipsec_common_input gets called when an IPsec-protected packet * is received by IPv4 or IPv6. Its job is to find the right SA * and call the appropriate transform. The transform callback * takes care of further processing (like ingress filtering). */
| 114 | * takes care of further processing (like ingress filtering). |
| 115 | */ |
| 116 | static int |
| 117 | ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto) |
| 118 | { |
| 119 | IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]); |
| 120 | union sockaddr_union dst_address; |
| 121 | struct secasvar *sav; |
| 122 | uint32_t spi; |
| 123 | int error; |
| 124 | |
| 125 | IPSEC_ISTAT(sproto, input); |
| 126 | |
| 127 | IPSEC_ASSERT(m != NULL, ("null packet")); |
| 128 | |
| 129 | IPSEC_ASSERT(sproto == IPPROTO_ESP || sproto == IPPROTO_AH || |
| 130 | sproto == IPPROTO_IPCOMP, |
| 131 | ("unexpected security protocol %u", sproto)); |
| 132 | |
| 133 | if ((sproto == IPPROTO_ESP && !V_esp_enable) || |
| 134 | (sproto == IPPROTO_AH && !V_ah_enable) || |
| 135 | (sproto == IPPROTO_IPCOMP && !V_ipcomp_enable)) { |
| 136 | m_freem(m); |
| 137 | IPSEC_ISTAT(sproto, pdrops); |
| 138 | return EOPNOTSUPP; |
| 139 | } |
| 140 | |
| 141 | if (m->m_pkthdr.len - skip < 2 * sizeof (u_int32_t)) { |
| 142 | m_freem(m); |
| 143 | IPSEC_ISTAT(sproto, hdrops); |
| 144 | DPRINTF(("%s: packet too small\n", __func__)); |
| 145 | return EINVAL; |
| 146 | } |
| 147 | |
| 148 | /* Retrieve the SPI from the relevant IPsec header */ |
| 149 | if (sproto == IPPROTO_ESP) |
| 150 | m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi); |
| 151 | else if (sproto == IPPROTO_AH) |
| 152 | m_copydata(m, skip + sizeof(u_int32_t), sizeof(u_int32_t), |
| 153 | (caddr_t) &spi); |
| 154 | else if (sproto == IPPROTO_IPCOMP) { |
| 155 | u_int16_t cpi; |
| 156 | m_copydata(m, skip + sizeof(u_int16_t), sizeof(u_int16_t), |
| 157 | (caddr_t) &cpi); |
| 158 | spi = ntohl(htons(cpi)); |
| 159 | } |
| 160 | |
| 161 | /* |
| 162 | * Find the SA and (indirectly) call the appropriate |
| 163 | * kernel crypto routine. The resulting mbuf chain is a valid |
| 164 | * IP packet ready to go through input processing. |
| 165 | */ |
| 166 | bzero(&dst_address, sizeof (dst_address)); |
| 167 | dst_address.sa.sa_family = af; |
| 168 | switch (af) { |
| 169 | #ifdef INET |
| 170 | case AF_INET: |
| 171 | dst_address.sin.sin_len = sizeof(struct sockaddr_in); |
| 172 | m_copydata(m, offsetof(struct ip, ip_dst), |
| 173 | sizeof(struct in_addr), |
no test coverage detected