* checks to see if the given address, sa, is one that is currently known by * the kernel note: can't distinguish the same address on multiple interfaces * and doesn't handle multiple addresses with different zone/scope id's note: * ifa_ifwithaddr() compares the entire sockaddr struct */
| 5224 | * ifa_ifwithaddr() compares the entire sockaddr struct |
| 5225 | */ |
| 5226 | struct sctp_ifa * |
| 5227 | sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr, |
| 5228 | int holds_lock) |
| 5229 | { |
| 5230 | struct sctp_laddr *laddr; |
| 5231 | |
| 5232 | if (holds_lock == 0) { |
| 5233 | SCTP_INP_RLOCK(inp); |
| 5234 | } |
| 5235 | |
| 5236 | LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { |
| 5237 | if (laddr->ifa == NULL) |
| 5238 | continue; |
| 5239 | if (addr->sa_family != laddr->ifa->address.sa.sa_family) |
| 5240 | continue; |
| 5241 | #ifdef INET |
| 5242 | if (addr->sa_family == AF_INET) { |
| 5243 | if (((struct sockaddr_in *)addr)->sin_addr.s_addr == |
| 5244 | laddr->ifa->address.sin.sin_addr.s_addr) { |
| 5245 | /* found him. */ |
| 5246 | break; |
| 5247 | } |
| 5248 | } |
| 5249 | #endif |
| 5250 | #ifdef INET6 |
| 5251 | if (addr->sa_family == AF_INET6) { |
| 5252 | if (SCTP6_ARE_ADDR_EQUAL((struct sockaddr_in6 *)addr, |
| 5253 | &laddr->ifa->address.sin6)) { |
| 5254 | /* found him. */ |
| 5255 | break; |
| 5256 | } |
| 5257 | } |
| 5258 | #endif |
| 5259 | } |
| 5260 | if (holds_lock == 0) { |
| 5261 | SCTP_INP_RUNLOCK(inp); |
| 5262 | } |
| 5263 | if (laddr != NULL) { |
| 5264 | return (laddr->ifa); |
| 5265 | } else { |
| 5266 | return (NULL); |
| 5267 | } |
| 5268 | } |
| 5269 | |
| 5270 | uint32_t |
| 5271 | sctp_get_ifa_hash_val(struct sockaddr *addr) |
no test coverage detected