1 /**
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <errno.h>
18 #include <arpa/inet.h>
19 #include <ImsMediaNetworkUtil.h>
20 #include <ImsMediaTrace.h>
21
22 #define V4MAPPED_OFFSET 12
23 #define NUM_OF_BYTES_IPV4 4
24 #define NUM_OF_BYTES_IPV6 6
25
GetIpPortFromSockAddr(const sockaddr_storage & ss,char * ipAddress,int len,unsigned int & port)26 static bool GetIpPortFromSockAddr(
27 const sockaddr_storage& ss, char* ipAddress, int len, unsigned int& port)
28 {
29 const sockaddr_in6& sin6 = reinterpret_cast<const sockaddr_in6&>(ss);
30 if (ss.ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr))
31 {
32 // Copy the IPv6 address into the temporary sockaddr_storage.
33 sockaddr_storage tmp;
34 memset(&tmp, 0, sizeof(tmp));
35 memcpy(&tmp, &ss, sizeof(sockaddr_in6));
36 // Unmap it into an IPv4 address.
37 sockaddr_in& sin = reinterpret_cast<sockaddr_in&>(tmp);
38 sin.sin_family = AF_INET;
39 sin.sin_port = sin6.sin6_port;
40 memcpy(&sin.sin_addr.s_addr, &sin6.sin6_addr.s6_addr[V4MAPPED_OFFSET], NUM_OF_BYTES_IPV4);
41 // Do the regular conversion using the unmapped address.
42 return GetIpPortFromSockAddr(tmp, ipAddress, len, port);
43 }
44
45 if (ss.ss_family == AF_INET)
46 {
47 const sockaddr_in& sin = reinterpret_cast<const sockaddr_in&>(ss);
48 strncpy(ipAddress, inet_ntoa(sin.sin_addr), len);
49 // memcpy(ipAddress, &(sin.sin_addr.s_addr), sizeof(struct in_addr));
50 port = ntohs(sin.sin_port);
51 }
52 else if (ss.ss_family == AF_INET6)
53 {
54 inet_ntop(AF_INET6, sin6.sin6_addr.s6_addr, ipAddress, len);
55 port = ntohs(sin6.sin6_port);
56 }
57 else
58 {
59 return false;
60 }
61
62 IMLOGD2("[GetIpPortFromSockAddr] %s:%u", ipAddress, port);
63 return true;
64 }
65
getLocalIpPortFromSocket(const int nSocketFD,char * pIPAddress,int len,unsigned int & port)66 bool ImsMediaNetworkUtil::getLocalIpPortFromSocket(
67 const int nSocketFD, char* pIPAddress, int len, unsigned int& port)
68 {
69 if (pIPAddress == nullptr)
70 {
71 return false;
72 }
73
74 sockaddr_storage ss;
75 sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
76 socklen_t byteCount = sizeof(ss);
77 errno = 0;
78 int res = getsockname(nSocketFD, sa, &byteCount);
79 if (res == -1)
80 {
81 IMLOGE1("[getLocalIpPortFromSocket] getsockname failed. Error[%d]", errno);
82 return false;
83 }
84
85 return GetIpPortFromSockAddr(ss, pIPAddress, len, port);
86 }
87
getRemoteIpPortFromSocket(const int nSocketFD,char * pIPAddress,int len,unsigned int & port)88 bool ImsMediaNetworkUtil::getRemoteIpPortFromSocket(
89 const int nSocketFD, char* pIPAddress, int len, unsigned int& port)
90 {
91 if (pIPAddress == nullptr)
92 {
93 return false;
94 }
95
96 sockaddr_storage ss;
97 sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);
98 socklen_t byteCount = sizeof(ss);
99 errno = 0;
100 int res = getpeername(nSocketFD, sa, &byteCount);
101 if (res == -1)
102 {
103 IMLOGE1("[getRemoteIpPortFromSocket] getpeername failed. Error[%d]", errno);
104 return false;
105 }
106
107 return GetIpPortFromSockAddr(ss, pIPAddress, len, port);
108 }
109
openSocket(const char * pIPAddr,unsigned int port,int af)110 int ImsMediaNetworkUtil::openSocket(const char* pIPAddr, unsigned int port, int af)
111 {
112 int soc = 0;
113 if ((soc = socket(af, SOCK_DGRAM, IPPROTO_UDP)) < 0)
114 {
115 IMLOGE1("[openSocket] error[%d]", errno);
116 return -1;
117 }
118
119 if (af == AF_INET)
120 {
121 sockaddr_in sin;
122 sin.sin_family = AF_INET;
123 sin.sin_port = htons(port);
124
125 if (inet_pton(AF_INET, pIPAddr, &sin.sin_addr) <= 0)
126 {
127 IMLOGE1("[openSocket] inet_pton error[%d]", errno);
128 return -1;
129 }
130
131 if (bind(soc, (struct sockaddr*)&sin, sizeof(sin)) < 0)
132 {
133 IMLOGE1("[openSocket] bind error[%d]", errno);
134 return -1;
135 }
136 }
137 else if (af == AF_INET6)
138 {
139 sockaddr_in6 sin6;
140 sin6.sin6_family = AF_INET6;
141 sin6.sin6_port = htons(port);
142
143 if (inet_pton(AF_INET6, pIPAddr, &sin6.sin6_addr) <= 0)
144 {
145 IMLOGE1("[openSocket] error[%d]", errno);
146 return -1;
147 }
148
149 if (bind(soc, (struct sockaddr*)&sin6, sizeof(sin6)) < 0)
150 {
151 IMLOGE1("[openSocket] bind error[%d]", errno);
152 return -1;
153 }
154 }
155
156 return soc;
157 }
158
connectSocket(const int socketFd,const char * pIPAddr,unsigned int port,int af)159 bool ImsMediaNetworkUtil::connectSocket(
160 const int socketFd, const char* pIPAddr, unsigned int port, int af)
161 {
162 if (socketFd == -1)
163 {
164 IMLOGE0("[connectSocket] invalid socket fd");
165 return false;
166 }
167
168 if (af == AF_INET)
169 {
170 sockaddr_in sin;
171 sin.sin_family = AF_INET;
172 sin.sin_port = htons(port);
173
174 if (inet_pton(AF_INET, pIPAddr, &sin.sin_addr) <= 0)
175 {
176 IMLOGE1("[connectSocket] inet_pton error[%d]", errno);
177 return -1;
178 }
179
180 if (connect(socketFd, (struct sockaddr*)&sin, sizeof(sockaddr_in)) < 0)
181 {
182 IMLOGE1("[connectSocket] connect error[%d]", errno);
183 return false;
184 }
185 }
186 else if (af == AF_INET6)
187 {
188 sockaddr_in6 sin6;
189 sin6.sin6_family = AF_INET6;
190 sin6.sin6_port = htons(port);
191
192 if (inet_pton(AF_INET6, pIPAddr, &sin6.sin6_addr) <= 0)
193 {
194 IMLOGE1("[connectSocket] error[%d]", errno);
195 return -1;
196 }
197
198 if (connect(socketFd, (struct sockaddr*)&sin6, sizeof(sockaddr_in6)) < 0)
199 {
200 IMLOGE1("[connectSocket] error[%d]", errno);
201 return false;
202 }
203 }
204
205 return true;
206 }
207
closeSocket(int & socketFd)208 void ImsMediaNetworkUtil::closeSocket(int& socketFd)
209 {
210 shutdown(socketFd, SHUT_RDWR);
211 close(socketFd);
212 socketFd = -1;
213 }