LCOV - code coverage report
Current view: top level - media/mtransport/third_party/nICEr/src/net - transport_addr.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 219 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             : Copyright (c) 2007, Adobe Systems, Incorporated
       3             : All rights reserved.
       4             : 
       5             : Redistribution and use in source and binary forms, with or without
       6             : modification, are permitted provided that the following conditions are
       7             : met:
       8             : 
       9             : * Redistributions of source code must retain the above copyright
      10             :   notice, this list of conditions and the following disclaimer.
      11             : 
      12             : * Redistributions in binary form must reproduce the above copyright
      13             :   notice, this list of conditions and the following disclaimer in the
      14             :   documentation and/or other materials provided with the distribution.
      15             : 
      16             : * Neither the name of Adobe Systems, Network Resonance nor the names of its
      17             :   contributors may be used to endorse or promote products derived from
      18             :   this software without specific prior written permission.
      19             : 
      20             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      21             : "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      22             : LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      23             : A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      24             : OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      25             : SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      26             : LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      27             : DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      28             : THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      29             : (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      30             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      31             : */
      32             : 
      33             : 
      34             : 
      35             : static char *RCSSTRING __UNUSED__="$Id: transport_addr.c,v 1.2 2008/04/28 17:59:03 ekr Exp $";
      36             : 
      37             : 
      38             : #include <csi_platform.h>
      39             : #include <stdio.h>
      40             : #include <memory.h>
      41             : #include <sys/types.h>
      42             : #include <errno.h>
      43             : #ifdef WIN32
      44             : #include <winsock2.h>
      45             : #else
      46             : #include <unistd.h>
      47             : #include <sys/socket.h>
      48             : #include <netinet/in.h>
      49             : #include <arpa/inet.h>
      50             : #endif
      51             : #include <assert.h>
      52             : #include "nr_api.h"
      53             : #include "util.h"
      54             : #include "transport_addr.h"
      55             : 
      56           0 : int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr)
      57             :   {
      58             :     int _status;
      59             :     /* Max length for normalized IPv6 address string representation is 39 */
      60             :     char buffer[40];
      61             :     const char *protocol;
      62             : 
      63           0 :     switch(addr->protocol){
      64             :       case IPPROTO_TCP:
      65           0 :         if (addr->tls_host[0]) {
      66           0 :           protocol = "TLS";
      67             :         } else {
      68           0 :           protocol = "TCP";
      69             :         }
      70           0 :         break;
      71             :       case IPPROTO_UDP:
      72           0 :         protocol = "UDP";
      73           0 :         break;
      74             :       default:
      75           0 :         ABORT(R_INTERNAL);
      76             :     }
      77             : 
      78           0 :     switch(addr->ip_version){
      79             :       case NR_IPV4:
      80           0 :         if (!inet_ntop(AF_INET, &addr->u.addr4.sin_addr,buffer,sizeof(buffer)))
      81           0 :           strcpy(buffer, "[error]");
      82           0 :         snprintf(addr->as_string,sizeof(addr->as_string),"IP4:%s:%d/%s",buffer,(int)ntohs(addr->u.addr4.sin_port),protocol);
      83           0 :         break;
      84             :       case NR_IPV6:
      85           0 :         if (!inet_ntop(AF_INET6, &addr->u.addr6.sin6_addr,buffer,sizeof(buffer)))
      86           0 :           strcpy(buffer, "[error]");
      87           0 :         snprintf(addr->as_string,sizeof(addr->as_string),"IP6:[%s]:%d/%s",buffer,(int)ntohs(addr->u.addr6.sin6_port),protocol);
      88           0 :         break;
      89             :       default:
      90           0 :         ABORT(R_INTERNAL);
      91             :     }
      92             : 
      93           0 :     _status=0;
      94             :   abort:
      95           0 :     return(_status);
      96             :   }
      97             : 
      98           0 : int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len)
      99             :   {
     100             :     int _status;
     101             :     char buffer[40];
     102             : 
     103           0 :     switch(addr->ip_version){
     104             :       case NR_IPV4:
     105           0 :         if (!inet_ntop(AF_INET, &addr->u.addr4.sin_addr,buffer,sizeof(buffer))) {
     106           0 :            strncpy(buffer, "[error]", len);
     107             :         }
     108           0 :         break;
     109             :       case NR_IPV6:
     110           0 :         if (!inet_ntop(AF_INET6, &addr->u.addr6.sin6_addr,buffer,sizeof(buffer))) {
     111           0 :            strncpy(buffer, "[error]", len);
     112             :         }
     113           0 :         break;
     114             :       default:
     115           0 :         ABORT(R_INTERNAL);
     116             :     }
     117           0 :     snprintf(buf,len,"%s:%s",addr->ifname,buffer);
     118             : 
     119           0 :     _status=0;
     120             :   abort:
     121           0 :     return(_status);
     122             :   }
     123             : 
     124           0 : int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int protocol, int keep, nr_transport_addr *addr)
     125             :   {
     126             :     int r,_status;
     127             : 
     128           0 :     if(!keep) memset(addr,0,sizeof(nr_transport_addr));
     129             : 
     130           0 :     switch(protocol){
     131             :       case IPPROTO_TCP:
     132             :       case IPPROTO_UDP:
     133           0 :         break;
     134             :       default:
     135           0 :         ABORT(R_BAD_ARGS);
     136             :     }
     137             : 
     138           0 :     addr->protocol=protocol;
     139             : 
     140           0 :     if(saddr->sa_family==AF_INET){
     141           0 :       addr->ip_version=NR_IPV4;
     142             : 
     143           0 :       memcpy(&addr->u.addr4,saddr,sizeof(struct sockaddr_in));
     144           0 :       addr->addr=(struct sockaddr *)&addr->u.addr4;
     145           0 :       addr->addr_len=sizeof(struct sockaddr_in);
     146             :     }
     147           0 :     else if(saddr->sa_family==AF_INET6){
     148           0 :       addr->ip_version=NR_IPV6;
     149             : 
     150           0 :       memcpy(&addr->u.addr6, saddr, sizeof(struct sockaddr_in6));
     151           0 :       addr->addr=(struct sockaddr *)&addr->u.addr6;
     152           0 :       addr->addr_len=sizeof(struct sockaddr_in6);
     153             :     }
     154             :     else
     155           0 :       ABORT(R_BAD_ARGS);
     156             : 
     157           0 :     if(r=nr_transport_addr_fmt_addr_string(addr))
     158           0 :       ABORT(r);
     159             : 
     160           0 :     _status=0;
     161             :   abort:
     162           0 :     return(_status);
     163             :   }
     164             : 
     165             : 
     166           0 : int nr_transport_addr_copy(nr_transport_addr *to, nr_transport_addr *from)
     167             :   {
     168             :     int _status;
     169             : 
     170           0 :     memcpy(to,from,sizeof(nr_transport_addr));
     171             : 
     172             :     // with IPC serialization, we should not assume that the pointer
     173             :     // in from->addr is correct
     174           0 :     switch (to->ip_version) {
     175             :       case NR_IPV4:
     176           0 :         to->addr=(struct sockaddr *)&to->u.addr4;
     177           0 :         break;
     178             :       case NR_IPV6:
     179           0 :         to->addr=(struct sockaddr *)&to->u.addr6;
     180           0 :         break;
     181             :       default:
     182           0 :         ABORT(R_BAD_ARGS);
     183             :     }
     184             : 
     185           0 :     _status=0;
     186             :   abort:
     187           0 :     return(_status);
     188             :   }
     189             : 
     190           0 : int nr_transport_addr_copy_keep_ifname(nr_transport_addr *to, nr_transport_addr *from)
     191             :   {
     192             :     int r,_status;
     193             :     char save_ifname[MAXIFNAME];
     194             : 
     195           0 :     strncpy(save_ifname, to->ifname, MAXIFNAME);
     196           0 :     save_ifname[MAXIFNAME-1]=0;  /* Ensure null termination */
     197             : 
     198           0 :     if (r=nr_transport_addr_copy(to, from))
     199           0 :       ABORT(r);
     200             : 
     201           0 :     strncpy(to->ifname, save_ifname, MAXIFNAME);
     202             : 
     203           0 :     if (r=nr_transport_addr_fmt_addr_string(to))
     204           0 :       ABORT(r);
     205             : 
     206           0 :     _status=0;
     207             :  abort:
     208           0 :     return _status;
     209             :   }
     210             : 
     211             : /* Convenience fxn. Is this the right API?*/
     212           0 : int nr_ip4_port_to_transport_addr(UINT4 ip4, UINT2 port, int protocol, nr_transport_addr *addr)
     213             :   {
     214             :     int r,_status;
     215             : 
     216           0 :     memset(addr, 0, sizeof(nr_transport_addr));
     217             : 
     218           0 :     addr->ip_version=NR_IPV4;
     219           0 :     addr->protocol=protocol;
     220             : #ifdef HAVE_SIN_LEN
     221             :     addr->u.addr4.sin_len=sizeof(struct sockaddr_in);
     222             : #endif
     223           0 :     addr->u.addr4.sin_family=PF_INET;
     224           0 :     addr->u.addr4.sin_port=htons(port);
     225           0 :     addr->u.addr4.sin_addr.s_addr=htonl(ip4);
     226           0 :     addr->addr=(struct sockaddr *)&addr->u.addr4;
     227           0 :     addr->addr_len=sizeof(struct sockaddr_in);
     228             : 
     229           0 :     if(r=nr_transport_addr_fmt_addr_string(addr))
     230           0 :       ABORT(r);
     231             : 
     232           0 :     _status=0;
     233             :   abort:
     234           0 :     return(_status);
     235             :   }
     236             : 
     237           0 : int nr_str_port_to_transport_addr(const char *ip, UINT2 port, int protocol, nr_transport_addr *addr_out)
     238             :   {
     239             :     int r,_status;
     240             :     struct in_addr addr;
     241             :     struct in6_addr addr6;
     242             : 
     243           0 :     if (inet_pton(AF_INET, ip, &addr) == 1) {
     244           0 :       if(r=nr_ip4_port_to_transport_addr(ntohl(addr.s_addr),port,protocol,addr_out))
     245           0 :         ABORT(r);
     246           0 :     } else if (inet_pton(AF_INET6, ip, &addr6) == 1) {
     247           0 :       if(r=nr_ip6_port_to_transport_addr(&addr6,port,protocol,addr_out))
     248           0 :         ABORT(r);
     249             :     } else {
     250           0 :       ABORT(R_BAD_DATA);
     251             :     }
     252             : 
     253           0 :     _status=0;
     254             :   abort:
     255           0 :     return(_status);
     256             :   }
     257             : 
     258           0 : int nr_ip6_port_to_transport_addr(struct in6_addr* addr6, UINT2 port, int protocol, nr_transport_addr *addr)
     259             :   {
     260             :     int r,_status;
     261             : 
     262           0 :     memset(addr, 0, sizeof(nr_transport_addr));
     263             : 
     264           0 :     addr->ip_version=NR_IPV6;
     265           0 :     addr->protocol=protocol;
     266           0 :     addr->u.addr6.sin6_family=PF_INET6;
     267           0 :     addr->u.addr6.sin6_port=htons(port);
     268           0 :     memcpy(addr->u.addr6.sin6_addr.s6_addr, addr6->s6_addr, sizeof(addr6->s6_addr));
     269           0 :     addr->addr=(struct sockaddr *)&addr->u.addr6;
     270           0 :     addr->addr_len=sizeof(struct sockaddr_in6);
     271             : 
     272           0 :     if(r=nr_transport_addr_fmt_addr_string(addr))
     273           0 :       ABORT(r);
     274             : 
     275           0 :     _status=0;
     276             :   abort:
     277           0 :     return(_status);
     278             :   }
     279             : 
     280           0 : int nr_transport_addr_get_addrstring(const nr_transport_addr *addr, char *str, int maxlen)
     281             :   {
     282             :     int _status;
     283             :     const char *res;
     284             : 
     285           0 :     switch(addr->ip_version){
     286             :       case NR_IPV4:
     287           0 :         res = inet_ntop(AF_INET, &addr->u.addr4.sin_addr,str,maxlen);
     288           0 :         break;
     289             :       case NR_IPV6:
     290           0 :         res = inet_ntop(AF_INET6, &addr->u.addr6.sin6_addr,str,maxlen);
     291           0 :         break;
     292             :       default:
     293           0 :         ABORT(R_INTERNAL);
     294             :     }
     295             : 
     296           0 :     if(!res){
     297           0 :       if (errno == ENOSPC){
     298           0 :         ABORT(R_BAD_ARGS);
     299             :       }
     300           0 :       ABORT(R_INTERNAL);
     301             :     }
     302             : 
     303           0 :     _status=0;
     304             :   abort:
     305           0 :     return(_status);
     306             :   }
     307             : 
     308           0 : int nr_transport_addr_get_port(nr_transport_addr *addr, int *port)
     309             :   {
     310             :     int _status;
     311             : 
     312           0 :     switch(addr->ip_version){
     313             :       case NR_IPV4:
     314           0 :         *port=ntohs(addr->u.addr4.sin_port);
     315           0 :         break;
     316             :       case NR_IPV6:
     317           0 :         *port=ntohs(addr->u.addr6.sin6_port);
     318           0 :         break;
     319             :       default:
     320           0 :         ABORT(R_INTERNAL);
     321             :     }
     322             : 
     323           0 :     _status=0;
     324             :   abort:
     325           0 :     return(_status);
     326             :   }
     327             : 
     328           0 : int nr_transport_addr_set_port(nr_transport_addr *addr, int port)
     329             :   {
     330             :     int _status;
     331             : 
     332           0 :     switch(addr->ip_version){
     333             :       case NR_IPV4:
     334           0 :         addr->u.addr4.sin_port=htons(port);
     335           0 :         break;
     336             :       case NR_IPV6:
     337           0 :         addr->u.addr6.sin6_port=htons(port);
     338           0 :         break;
     339             :       default:
     340           0 :         ABORT(R_INTERNAL);
     341             :     }
     342             : 
     343           0 :     _status=0;
     344             :   abort:
     345           0 :     return(_status);
     346             :   }
     347             : 
     348             : /* memcmp() may not work if, for instance, the string or interface
     349             :    haven't been made. Hmmm.. */
     350           0 : int nr_transport_addr_cmp(nr_transport_addr *addr1,nr_transport_addr *addr2,int mode)
     351             :   {
     352           0 :     assert(mode);
     353             : 
     354           0 :     if(addr1->ip_version != addr2->ip_version)
     355           0 :       return(1);
     356             : 
     357           0 :     if(mode < NR_TRANSPORT_ADDR_CMP_MODE_PROTOCOL)
     358           0 :       return(0);
     359             : 
     360           0 :     if(addr1->protocol != addr2->protocol)
     361           0 :       return(1);
     362             : 
     363           0 :     if(mode < NR_TRANSPORT_ADDR_CMP_MODE_ADDR)
     364           0 :       return(0);
     365             : 
     366           0 :     assert(addr1->addr_len == addr2->addr_len);
     367           0 :     switch(addr1->ip_version){
     368             :       case NR_IPV4:
     369           0 :         if(addr1->u.addr4.sin_addr.s_addr != addr2->u.addr4.sin_addr.s_addr)
     370           0 :           return(1);
     371           0 :         if(mode < NR_TRANSPORT_ADDR_CMP_MODE_ALL)
     372           0 :           return(0);
     373           0 :         if(addr1->u.addr4.sin_port != addr2->u.addr4.sin_port)
     374           0 :           return(1);
     375           0 :         break;
     376             :       case NR_IPV6:
     377           0 :         if(memcmp(addr1->u.addr6.sin6_addr.s6_addr,addr2->u.addr6.sin6_addr.s6_addr,sizeof(struct in6_addr)))
     378           0 :           return(1);
     379           0 :         if(mode < NR_TRANSPORT_ADDR_CMP_MODE_ALL)
     380           0 :           return(0);
     381           0 :         if(addr1->u.addr6.sin6_port != addr2->u.addr6.sin6_port)
     382           0 :           return(1);
     383           0 :         break;
     384             :       default:
     385           0 :         abort();
     386             :     }
     387             : 
     388           0 :     return(0);
     389             :   }
     390             : 
     391           0 : int nr_transport_addr_is_loopback(nr_transport_addr *addr)
     392             :   {
     393           0 :     switch(addr->ip_version){
     394             :       case NR_IPV4:
     395           0 :         switch(addr->u.addr4.sin_family){
     396             :           case AF_INET:
     397           0 :             if (((ntohl(addr->u.addr4.sin_addr.s_addr)>>24)&0xff)==0x7f)
     398           0 :               return 1;
     399           0 :             break;
     400             :           default:
     401           0 :             UNIMPLEMENTED;
     402             :             break;
     403             :         }
     404           0 :         break;
     405             : 
     406             :       case NR_IPV6:
     407           0 :         if(!memcmp(addr->u.addr6.sin6_addr.s6_addr,in6addr_loopback.s6_addr,sizeof(struct in6_addr)))
     408           0 :           return(1);
     409           0 :         break;
     410             :       default:
     411           0 :         UNIMPLEMENTED;
     412             :     }
     413             : 
     414           0 :     return(0);
     415             :   }
     416             : 
     417           0 : int nr_transport_addr_is_link_local(nr_transport_addr *addr)
     418             :   {
     419           0 :     switch(addr->ip_version){
     420             :       case NR_IPV4:
     421             :         /* RFC3927: 169.254/16 */
     422           0 :         if ((ntohl(addr->u.addr4.sin_addr.s_addr) & 0xFFFF0000) == 0xA9FE0000)
     423           0 :           return(1);
     424           0 :         break;
     425             :       case NR_IPV6:
     426             :         {
     427           0 :           UINT4* addrTop = (UINT4*)(addr->u.addr6.sin6_addr.s6_addr);
     428           0 :           if ((*addrTop & htonl(0xFFC00000)) == htonl(0xFE800000))
     429           0 :             return(2);
     430             :         }
     431           0 :         break;
     432             :       default:
     433           0 :         UNIMPLEMENTED;
     434             :     }
     435             : 
     436           0 :     return(0);
     437             :   }
     438             : 
     439           0 : int nr_transport_addr_is_wildcard(nr_transport_addr *addr)
     440             :   {
     441           0 :     switch(addr->ip_version){
     442             :       case NR_IPV4:
     443           0 :         if(addr->u.addr4.sin_addr.s_addr==INADDR_ANY)
     444           0 :           return(1);
     445           0 :         if(addr->u.addr4.sin_port==0)
     446           0 :           return(1);
     447           0 :         break;
     448             :       case NR_IPV6:
     449           0 :         if(!memcmp(addr->u.addr6.sin6_addr.s6_addr,in6addr_any.s6_addr,sizeof(struct in6_addr)))
     450           0 :           return(1);
     451           0 :         if(addr->u.addr6.sin6_port==0)
     452           0 :           return(1);
     453           0 :         break;
     454             :       default:
     455           0 :         UNIMPLEMENTED;
     456             :     }
     457             : 
     458           0 :     return(0);
     459             :   }
     460             : 
     461             : nr_transport_addr_mask nr_private_ipv4_addrs[] = {
     462             :   /* RFC1918: 10/8 */
     463             :   {0x0A000000, 0xFF000000},
     464             :   /* RFC1918: 172.16/12 */
     465             :   {0xAC100000, 0xFFF00000},
     466             :   /* RFC1918: 192.168/16 */
     467             :   {0xC0A80000, 0xFFFF0000},
     468             :   /* RFC6598: 100.64/10 */
     469             :   {0x64400000, 0xFFC00000}
     470             : };
     471             : 
     472           0 : int nr_transport_addr_get_private_addr_range(nr_transport_addr *addr)
     473             :   {
     474           0 :     switch(addr->ip_version){
     475             :       case NR_IPV4:
     476             :         {
     477           0 :           UINT4 ip = ntohl(addr->u.addr4.sin_addr.s_addr);
     478           0 :           for (int i=0; i<(sizeof(nr_private_ipv4_addrs)/sizeof(nr_transport_addr_mask)); i++) {
     479           0 :             if ((ip & nr_private_ipv4_addrs[i].mask) == nr_private_ipv4_addrs[i].addr)
     480           0 :               return i + 1;
     481             :           }
     482             :         }
     483           0 :         break;
     484             :       case NR_IPV6:
     485           0 :         return(0);
     486             :       default:
     487           0 :         UNIMPLEMENTED;
     488             :     }
     489             : 
     490           0 :     return(0);
     491             :   }
     492             : 
     493           0 : int nr_transport_addr_is_reliable_transport(nr_transport_addr *addr)
     494             :   {
     495           0 :     return addr->protocol == IPPROTO_TCP;
     496             :   }

Generated by: LCOV version 1.13