* returns the valid local address count for an assoc, taking into account * all scoping rules */
| 6903 | * all scoping rules |
| 6904 | */ |
| 6905 | int |
| 6906 | sctp_local_addr_count(struct sctp_tcb *stcb) |
| 6907 | { |
| 6908 | int loopback_scope; |
| 6909 | #if defined(INET) |
| 6910 | int ipv4_local_scope, ipv4_addr_legal; |
| 6911 | #endif |
| 6912 | #if defined(INET6) |
| 6913 | int local_scope, site_scope, ipv6_addr_legal; |
| 6914 | #endif |
| 6915 | struct sctp_vrf *vrf; |
| 6916 | struct sctp_ifn *sctp_ifn; |
| 6917 | struct sctp_ifa *sctp_ifa; |
| 6918 | int count = 0; |
| 6919 | |
| 6920 | /* Turn on all the appropriate scopes */ |
| 6921 | loopback_scope = stcb->asoc.scope.loopback_scope; |
| 6922 | #if defined(INET) |
| 6923 | ipv4_local_scope = stcb->asoc.scope.ipv4_local_scope; |
| 6924 | ipv4_addr_legal = stcb->asoc.scope.ipv4_addr_legal; |
| 6925 | #endif |
| 6926 | #if defined(INET6) |
| 6927 | local_scope = stcb->asoc.scope.local_scope; |
| 6928 | site_scope = stcb->asoc.scope.site_scope; |
| 6929 | ipv6_addr_legal = stcb->asoc.scope.ipv6_addr_legal; |
| 6930 | #endif |
| 6931 | SCTP_IPI_ADDR_RLOCK(); |
| 6932 | vrf = sctp_find_vrf(stcb->asoc.vrf_id); |
| 6933 | if (vrf == NULL) { |
| 6934 | /* no vrf, no addresses */ |
| 6935 | SCTP_IPI_ADDR_RUNLOCK(); |
| 6936 | return (0); |
| 6937 | } |
| 6938 | |
| 6939 | if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { |
| 6940 | /* |
| 6941 | * bound all case: go through all ifns on the vrf |
| 6942 | */ |
| 6943 | LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) { |
| 6944 | if ((loopback_scope == 0) && |
| 6945 | SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) { |
| 6946 | continue; |
| 6947 | } |
| 6948 | LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) { |
| 6949 | if (sctp_is_addr_restricted(stcb, sctp_ifa)) |
| 6950 | continue; |
| 6951 | switch (sctp_ifa->address.sa.sa_family) { |
| 6952 | #ifdef INET |
| 6953 | case AF_INET: |
| 6954 | if (ipv4_addr_legal) { |
| 6955 | struct sockaddr_in *sin; |
| 6956 | |
| 6957 | sin = &sctp_ifa->address.sin; |
| 6958 | if (sin->sin_addr.s_addr == 0) { |
| 6959 | /* |
| 6960 | * skip unspecified |
| 6961 | * addrs |
| 6962 | */ |
no test coverage detected