* compare two secindex structure with mask. * IN: * spidx0: source, it is often in SPD. * spidx1: object, it is often from IP header. * OUT: * 1 : equal * 0 : not equal */
| 4197 | * 0 : not equal |
| 4198 | */ |
| 4199 | static int |
| 4200 | key_cmpspidx_withmask(struct secpolicyindex *spidx0, |
| 4201 | struct secpolicyindex *spidx1) |
| 4202 | { |
| 4203 | /* sanity */ |
| 4204 | if (spidx0 == NULL && spidx1 == NULL) |
| 4205 | return 1; |
| 4206 | |
| 4207 | if (spidx0 == NULL || spidx1 == NULL) |
| 4208 | return 0; |
| 4209 | |
| 4210 | if (spidx0->src.sa.sa_family != spidx1->src.sa.sa_family || |
| 4211 | spidx0->dst.sa.sa_family != spidx1->dst.sa.sa_family || |
| 4212 | spidx0->src.sa.sa_len != spidx1->src.sa.sa_len || |
| 4213 | spidx0->dst.sa.sa_len != spidx1->dst.sa.sa_len) |
| 4214 | return 0; |
| 4215 | |
| 4216 | /* if spidx.ul_proto == IPSEC_ULPROTO_ANY, ignore. */ |
| 4217 | if (spidx0->ul_proto != (u_int16_t)IPSEC_ULPROTO_ANY |
| 4218 | && spidx0->ul_proto != spidx1->ul_proto) |
| 4219 | return 0; |
| 4220 | |
| 4221 | switch (spidx0->src.sa.sa_family) { |
| 4222 | case AF_INET: |
| 4223 | if (spidx0->src.sin.sin_port != IPSEC_PORT_ANY |
| 4224 | && spidx0->src.sin.sin_port != spidx1->src.sin.sin_port) |
| 4225 | return 0; |
| 4226 | if (!key_bbcmp(&spidx0->src.sin.sin_addr, |
| 4227 | &spidx1->src.sin.sin_addr, spidx0->prefs)) |
| 4228 | return 0; |
| 4229 | break; |
| 4230 | case AF_INET6: |
| 4231 | if (spidx0->src.sin6.sin6_port != IPSEC_PORT_ANY |
| 4232 | && spidx0->src.sin6.sin6_port != spidx1->src.sin6.sin6_port) |
| 4233 | return 0; |
| 4234 | /* |
| 4235 | * scope_id check. if sin6_scope_id is 0, we regard it |
| 4236 | * as a wildcard scope, which matches any scope zone ID. |
| 4237 | */ |
| 4238 | if (spidx0->src.sin6.sin6_scope_id && |
| 4239 | spidx1->src.sin6.sin6_scope_id && |
| 4240 | spidx0->src.sin6.sin6_scope_id != spidx1->src.sin6.sin6_scope_id) |
| 4241 | return 0; |
| 4242 | if (!key_bbcmp(&spidx0->src.sin6.sin6_addr, |
| 4243 | &spidx1->src.sin6.sin6_addr, spidx0->prefs)) |
| 4244 | return 0; |
| 4245 | break; |
| 4246 | default: |
| 4247 | /* XXX */ |
| 4248 | if (bcmp(&spidx0->src, &spidx1->src, spidx0->src.sa.sa_len) != 0) |
| 4249 | return 0; |
| 4250 | break; |
| 4251 | } |
| 4252 | |
| 4253 | switch (spidx0->dst.sa.sa_family) { |
| 4254 | case AF_INET: |
| 4255 | if (spidx0->dst.sin.sin_port != IPSEC_PORT_ANY |
| 4256 | && spidx0->dst.sin.sin_port != spidx1->dst.sin.sin_port) |
no test coverage detected