Mercurial > dropbear
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 |