Changeset 1585 for pjproject/trunk/pjlib/src/pj/sock_bsd.c
- Timestamp:
- Nov 18, 2007 2:53:47 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/sock_bsd.c
r1515 r1585 24 24 #include <pj/addr_resolv.h> 25 25 #include <pj/errno.h> 26 #include <pj/unicode.h> 26 27 27 28 /* … … 29 30 * The values here are indexed based on pj_addr_family. 30 31 */ 32 const pj_uint16_t PJ_AF_UNSPEC = AF_UNSPEC; 31 33 const pj_uint16_t PJ_AF_UNIX = AF_UNIX; 32 34 const pj_uint16_t PJ_AF_INET = AF_INET; … … 185 187 PJ_DEF(int) pj_inet_aton(const pj_str_t *cp, struct pj_in_addr *inp) 186 188 { 187 char tempaddr[ 16];189 char tempaddr[PJ_INET_ADDRSTRLEN]; 188 190 189 191 /* Initialize output with PJ_INADDR_NONE. … … 198 200 */ 199 201 PJ_ASSERT_RETURN(cp && cp->slen && inp, 0); 200 if (cp->slen >= 16) {202 if (cp->slen >= PJ_INET_ADDRSTRLEN) { 201 203 return 0; 202 204 } … … 210 212 inp->s_addr = inet_addr(tempaddr); 211 213 return inp->s_addr == PJ_INADDR_NONE ? 0 : 1; 214 #endif 215 } 216 217 /* 218 * Convert text to IPv4/IPv6 address. 219 */ 220 PJ_DEF(pj_status_t) pj_inet_pton(int af, const pj_str_t *src, void *dst) 221 { 222 char tempaddr[PJ_INET6_ADDRSTRLEN]; 223 224 PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL); 225 PJ_ASSERT_RETURN(src && src->slen && dst, PJ_EINVAL); 226 227 /* Initialize output with PJ_IN_ADDR_NONE for IPv4 (to be 228 * compatible with pj_inet_aton() 229 */ 230 if (af==PJ_AF_INET) { 231 ((pj_in_addr*)dst)->s_addr = PJ_INADDR_NONE; 232 } 233 234 /* Caution: 235 * this function might be called with cp->slen >= 46 236 * (i.e. when called with hostname to check if it's an IP addr). 237 */ 238 if (src->slen >= PJ_INET6_ADDRSTRLEN) { 239 return PJ_ENAMETOOLONG; 240 } 241 242 pj_memcpy(tempaddr, src->ptr, src->slen); 243 tempaddr[src->slen] = '\0'; 244 245 #if defined(PJ_SOCK_HAS_INET_PTON) && PJ_SOCK_HAS_INET_PTON != 0 246 /* 247 * Implementation using inet_pton() 248 */ 249 if (inet_pton(af, tempaddr, dst) != 1) { 250 pj_status_t status = pj_get_netos_error(); 251 if (status == PJ_SUCCESS) 252 status = PJ_EUNKNOWN; 253 254 return status; 255 } 256 257 return PJ_SUCCESS; 258 259 #elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE) 260 /* 261 * Implementation on Windows, using WSAStringToAddress(). 262 * Should also work on Unicode systems. 263 */ 264 { 265 PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN) 266 pj_sockaddr sock_addr; 267 int addr_len = sizeof(sock_addr); 268 int rc; 269 270 sock_addr.addr.sa_family = (pj_uint16_t)af; 271 rc = WSAStringToAddress( 272 PJ_STRING_TO_NATIVE(tempaddr,wtempaddr,sizeof(wtempaddr)), 273 af, NULL, (LPSOCKADDR)&sock_addr, &addr_len); 274 if (rc != 0) { 275 pj_status_t status = pj_get_netos_error(); 276 if (status == PJ_SUCCESS) 277 status = PJ_EUNKNOWN; 278 279 return status; 280 } 281 282 if (sock_addr.addr.sa_family == PJ_AF_INET) { 283 pj_memcpy(dst, &sock_addr.ipv4.sin_addr, 4); 284 return PJ_SUCCESS; 285 } else if (sock_addr.addr.sa_family == PJ_AF_INET6) { 286 pj_memcpy(dst, &sock_addr.ipv6.sin6_addr, 16); 287 return PJ_SUCCESS; 288 } else { 289 pj_assert(!"Shouldn't happen"); 290 return PJ_EBUG; 291 } 292 } 293 #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0 294 /* IPv6 support is disabled, just return error without raising assertion */ 295 return PJ_EIPV6NOTSUP; 296 #else 297 pj_assert(!"Not supported"); 298 return PJ_EIPV6NOTSUP; 299 #endif 300 } 301 302 /* 303 * Convert IPv4/IPv6 address to text. 304 */ 305 PJ_DEF(pj_status_t) pj_inet_ntop(int af, const void *src, 306 char *dst, int size) 307 308 { 309 PJ_ASSERT_RETURN(src && dst && size, PJ_EINVAL); 310 PJ_ASSERT_RETURN(af==PJ_AF_INET || af==PJ_AF_INET6, PJ_EINVAL); 311 312 #if defined(PJ_SOCK_HAS_INET_NTOP) && PJ_SOCK_HAS_INET_NTOP != 0 313 /* 314 * Implementation using inet_ntop() 315 */ 316 if (inet_ntop(af, src, dst, size) == NULL) { 317 pj_status_t status = pj_get_netos_error(); 318 if (status == PJ_SUCCESS) 319 status = PJ_EUNKNOWN; 320 321 return status; 322 } 323 324 return PJ_SUCCESS; 325 326 #elif defined(PJ_WIN32) || defined(PJ_WIN32_WINCE) 327 /* 328 * Implementation on Windows, using WSAAddressToString(). 329 * Should also work on Unicode systems. 330 */ 331 { 332 PJ_DECL_UNICODE_TEMP_BUF(wtempaddr,PJ_INET6_ADDRSTRLEN) 333 pj_sockaddr sock_addr; 334 DWORD addr_len, addr_str_len; 335 int rc; 336 337 pj_bzero(&sock_addr, sizeof(sock_addr)); 338 sock_addr.addr.sa_family = (pj_uint16_t)af; 339 if (af == PJ_AF_INET) { 340 if (size < PJ_INET_ADDRSTRLEN) 341 return PJ_ETOOSMALL; 342 pj_memcpy(&sock_addr.ipv4.sin_addr, src, 4); 343 addr_len = sizeof(pj_sockaddr_in); 344 addr_str_len = PJ_INET_ADDRSTRLEN; 345 } else if (af == PJ_AF_INET6) { 346 if (size < PJ_INET6_ADDRSTRLEN) 347 return PJ_ETOOSMALL; 348 pj_memcpy(&sock_addr.ipv6.sin6_addr, src, 16); 349 addr_len = sizeof(pj_sockaddr_in6); 350 addr_str_len = PJ_INET6_ADDRSTRLEN; 351 } else { 352 pj_assert(!"Unsupported address family"); 353 return PJ_EINVAL; 354 } 355 356 #if PJ_NATIVE_STRING_IS_UNICODE 357 rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len, 358 NULL, wtempaddr, addr_str_len); 359 if (rc == 0) { 360 pj_unicode_to_ansi(wtempaddr, wcslen(wtempaddr), dst, size); 361 } 362 #else 363 rc = WSAAddressToString((LPSOCKADDR)&sock_addr, addr_len, 364 NULL, dst, &addr_str_len); 365 #endif 366 367 if (rc != 0) { 368 pj_status_t status = pj_get_netos_error(); 369 if (status == PJ_SUCCESS) 370 status = PJ_EUNKNOWN; 371 372 return status; 373 } 374 375 return PJ_SUCCESS; 376 } 377 378 #elif !defined(PJ_HAS_IPV6) || PJ_HAS_IPV6==0 379 /* IPv6 support is disabled, just return error without raising assertion */ 380 return PJ_EIPV6NOTSUP; 381 #else 382 pj_assert(!"Not supported"); 383 return PJ_EIPV6NOTSUP; 212 384 #endif 213 385 }
Note: See TracChangeset
for help on using the changeset viewer.