comparison dbutil.c @ 568:005530560594

Rearrange getaddrstring() etc
author Matt Johnston <matt@ucc.asn.au>
date Tue, 01 Sep 2009 16:38:26 +0000
parents 61c3513825b0
children a98a2138364a
comparison
equal deleted inserted replaced
567:893a9dd0b9dd 568:005530560594
537 } 537 }
538 538
539 execv(usershell, argv); 539 execv(usershell, argv);
540 } 540 }
541 541
542 void get_socket_address(int fd, char **local_host, char **local_port,
543 char **remote_host, char **remote_port, int host_lookup)
544 {
545 struct sockaddr_storage addr;
546 socklen_t addrlen;
547
548 if (local_host || local_port) {
549 addrlen = sizeof(addr);
550 if (getsockname(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
551 dropbear_exit("Failed socket address: %s", strerror(errno));
552 }
553 getaddrstring(&addr, local_host, local_port, host_lookup);
554 }
555 if (remote_host || remote_port) {
556 addrlen = sizeof(addr);
557 if (getpeername(fd, (struct sockaddr*)&addr, &addrlen) < 0) {
558 dropbear_exit("Failed socket address: %s", strerror(errno));
559 }
560 getaddrstring(&addr, remote_host, remote_port, host_lookup);
561 }
562 }
563
542 /* Return a string representation of the socket address passed. The return 564 /* Return a string representation of the socket address passed. The return
543 * value is allocated with malloc() */ 565 * value is allocated with malloc() */
544 unsigned char * getaddrstring(struct sockaddr_storage* addr, int withport) { 566 void getaddrstring(struct sockaddr_storage* addr,
545 567 char **ret_host, char **ret_port,
546 char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; 568 int host_lookup) {
547 char *retstring = NULL; 569
570 char host[NI_MAXHOST+1], serv[NI_MAXSERV+1];
571 unsigned int len;
548 int ret; 572 int ret;
549 unsigned int len; 573
574 int flags = NI_NUMERICSERV | NI_NUMERICHOST;
575
576 #ifndef DO_HOST_LOOKUP
577 host_lookup = 0;
578 #endif
579
580 if (host_lookup) {
581 flags = NI_NUMERICSERV;
582 }
550 583
551 len = sizeof(struct sockaddr_storage); 584 len = sizeof(struct sockaddr_storage);
552 /* Some platforms such as Solaris 8 require that len is the length 585 /* Some platforms such as Solaris 8 require that len is the length
553 * of the specific structure. Some older linux systems (glibc 2.1.3 586 * of the specific structure. Some older linux systems (glibc 2.1.3
554 * such as debian potato) have sockaddr_storage.__ss_family instead 587 * such as debian potato) have sockaddr_storage.__ss_family instead
562 len = sizeof(struct sockaddr_in6); 595 len = sizeof(struct sockaddr_in6);
563 } 596 }
564 #endif 597 #endif
565 #endif 598 #endif
566 599
567 ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf), 600 ret = getnameinfo((struct sockaddr*)addr, len, host, sizeof(host)-1,
568 sbuf, sizeof(sbuf), NI_NUMERICSERV | NI_NUMERICHOST); 601 serv, sizeof(serv)-1, flags);
569 602
570 if (ret != 0) { 603 if (ret != 0) {
571 /* This is a fairly bad failure - it'll fallback to IP if it 604 if (host_lookup) {
572 * just can't resolve */ 605 /* On some systems (Darwin does it) we get EINTR from getnameinfo
573 dropbear_exit("failed lookup (%d, %d)", ret, errno); 606 * somehow. Eew. So we'll just return the IP, since that doesn't seem
574 } 607 * to exhibit that behaviour. */
575 608 getaddrstring(addr, ret_host, ret_port, 0);
576 if (withport) { 609 return;
577 len = strlen(hbuf) + 2 + strlen(sbuf); 610 } else {
578 retstring = (char*)m_malloc(len); 611 /* if we can't do a numeric lookup, something's gone terribly wrong */
579 snprintf(retstring, len, "%s:%s", hbuf, sbuf); 612 dropbear_exit("Failed lookup: %s", gai_strerror(ret));
580 } else { 613 }
581 retstring = m_strdup(hbuf); 614 }
582 } 615
583 616 if (ret_host) {
584 return retstring; 617 *ret_host = m_strdup(host);
585 } 618 }
586 619 if (ret_port) {
587 /* Get the hostname corresponding to the address addr. On failure, the IP 620 *ret_port = m_strdup(serv);
588 * address is returned. The return value is allocated with strdup() */ 621 }
589 char* getaddrhostname(struct sockaddr_storage * addr) {
590
591 char hbuf[NI_MAXHOST];
592 char sbuf[NI_MAXSERV];
593 int ret;
594 unsigned int len;
595 #ifdef DO_HOST_LOOKUP
596 const int flags = NI_NUMERICSERV;
597 #else
598 const int flags = NI_NUMERICHOST | NI_NUMERICSERV;
599 #endif
600
601 len = sizeof(struct sockaddr_storage);
602 /* Some platforms such as Solaris 8 require that len is the length
603 * of the specific structure. */
604 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
605 if (addr->ss_family == AF_INET) {
606 len = sizeof(struct sockaddr_in);
607 }
608 #ifdef AF_INET6
609 if (addr->ss_family == AF_INET6) {
610 len = sizeof(struct sockaddr_in6);
611 }
612 #endif
613 #endif
614
615
616 ret = getnameinfo((struct sockaddr*)addr, len, hbuf, sizeof(hbuf),
617 sbuf, sizeof(sbuf), flags);
618
619 if (ret != 0) {
620 /* On some systems (Darwin does it) we get EINTR from getnameinfo
621 * somehow. Eew. So we'll just return the IP, since that doesn't seem
622 * to exhibit that behaviour. */
623 return getaddrstring(addr, 0);
624 }
625
626 return m_strdup(hbuf);
627 } 622 }
628 623
629 #ifdef DEBUG_TRACE 624 #ifdef DEBUG_TRACE
630 void printhex(const char * label, const unsigned char * buf, int len) { 625 void printhex(const char * label, const unsigned char * buf, int len) {
631 626