Annotation of src/usr.bin/ssh/canohost.c, Revision 1.75
1.75 ! djm 1: /* $OpenBSD: canohost.c,v 1.74 2019/06/28 13:35:04 deraadt Exp $ */
1.1 deraadt 2: /*
1.7 deraadt 3: * Author: Tatu Ylonen <ylo@cs.hut.fi>
4: * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5: * All rights reserved
6: * Functions for returning the canonical host name of the remote site.
1.12 markus 7: *
1.14 deraadt 8: * As far as I am concerned, the code I have written for this software
9: * can be used freely for any purpose. Any derived versions of this
10: * software must be clearly marked as such, and if the derived work is
11: * incompatible with the protocol description in the RFC file, it must be
12: * called by a name other than "ssh" or "Secure Shell".
1.7 deraadt 13: */
1.1 deraadt 14:
1.55 stevesk 15: #include <sys/types.h>
1.54 stevesk 16: #include <sys/socket.h>
1.71 millert 17: #include <sys/un.h>
1.54 stevesk 18:
19: #include <netinet/in.h>
1.49 stevesk 20:
1.56 stevesk 21: #include <errno.h>
1.57 stevesk 22: #include <netdb.h>
1.60 stevesk 23: #include <stdio.h>
1.59 stevesk 24: #include <stdlib.h>
1.58 stevesk 25: #include <string.h>
1.61 deraadt 26: #include <stdarg.h>
1.66 dtucker 27: #include <unistd.h>
1.1 deraadt 28:
1.61 deraadt 29: #include "xmalloc.h"
1.1 deraadt 30: #include "packet.h"
1.18 markus 31: #include "log.h"
1.21 itojun 32: #include "canohost.h"
1.62 dtucker 33: #include "misc.h"
1.1 deraadt 34:
1.8 markus 35: /*
1.35 stevesk 36: * Returns the local/remote IP-address/hostname of socket as a string.
37: * The returned string must be freed.
1.8 markus 38: */
1.27 itojun 39: static char *
1.40 avsm 40: get_socket_address(int sock, int remote, int flags)
1.1 deraadt 41: {
1.25 markus 42: struct sockaddr_storage addr;
43: socklen_t addrlen;
1.10 markus 44: char ntop[NI_MAXHOST];
1.42 djm 45: int r;
1.1 deraadt 46:
1.6 markus 47: /* Get IP address of client. */
1.25 markus 48: addrlen = sizeof(addr);
49: memset(&addr, 0, sizeof(addr));
50:
51: if (remote) {
1.73 djm 52: if (getpeername(sock, (struct sockaddr *)&addr, &addrlen) != 0)
1.25 markus 53: return NULL;
54: } else {
1.73 djm 55: if (getsockname(sock, (struct sockaddr *)&addr, &addrlen) != 0)
1.25 markus 56: return NULL;
57: }
1.71 millert 58:
1.72 millert 59: switch (addr.ss_family) {
60: case AF_INET:
61: case AF_INET6:
62: /* Get the address in ascii. */
63: if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
64: sizeof(ntop), NULL, 0, flags)) != 0) {
1.75 ! djm 65: error_f("getnameinfo %d failed: %s",
1.72 millert 66: flags, ssh_gai_strerror(r));
67: return NULL;
68: }
69: return xstrdup(ntop);
70: case AF_UNIX:
1.71 millert 71: /* Get the Unix domain socket path. */
72: return xstrdup(((struct sockaddr_un *)&addr)->sun_path);
1.72 millert 73: default:
74: /* We can't look up remote Unix domain sockets. */
1.19 markus 75: return NULL;
76: }
1.25 markus 77: }
78:
79: char *
1.40 avsm 80: get_peer_ipaddr(int sock)
1.25 markus 81: {
1.34 stevesk 82: char *p;
83:
1.40 avsm 84: if ((p = get_socket_address(sock, 1, NI_NUMERICHOST)) != NULL)
1.34 stevesk 85: return p;
86: return xstrdup("UNKNOWN");
1.25 markus 87: }
88:
89: char *
1.40 avsm 90: get_local_ipaddr(int sock)
1.25 markus 91: {
1.34 stevesk 92: char *p;
93:
1.40 avsm 94: if ((p = get_socket_address(sock, 0, NI_NUMERICHOST)) != NULL)
1.34 stevesk 95: return p;
96: return xstrdup("UNKNOWN");
1.25 markus 97: }
98:
99: char *
1.66 dtucker 100: get_local_name(int fd)
1.25 markus 101: {
1.66 dtucker 102: char *host, myname[NI_MAXHOST];
103:
104: /* Assume we were passed a socket */
105: if ((host = get_socket_address(fd, 0, NI_NAMEREQD)) != NULL)
106: return host;
107:
108: /* Handle the case where we were passed a pipe */
109: if (gethostname(myname, sizeof(myname)) == -1) {
1.75 ! djm 110: verbose_f("gethostname: %s", strerror(errno));
1.73 djm 111: host = xstrdup("UNKNOWN");
1.66 dtucker 112: } else {
113: host = xstrdup(myname);
114: }
115:
116: return host;
1.19 markus 117: }
118:
1.10 markus 119: /* Returns the local/remote port for the socket. */
1.1 deraadt 120:
1.73 djm 121: static int
1.10 markus 122: get_sock_port(int sock, int local)
1.1 deraadt 123: {
1.10 markus 124: struct sockaddr_storage from;
125: socklen_t fromlen;
126: char strport[NI_MAXSERV];
1.42 djm 127: int r;
1.1 deraadt 128:
1.6 markus 129: /* Get IP address of client. */
130: fromlen = sizeof(from);
131: memset(&from, 0, sizeof(from));
1.10 markus 132: if (local) {
1.74 deraadt 133: if (getsockname(sock, (struct sockaddr *)&from, &fromlen) == -1) {
1.10 markus 134: error("getsockname failed: %.100s", strerror(errno));
135: return 0;
136: }
137: } else {
1.74 deraadt 138: if (getpeername(sock, (struct sockaddr *)&from, &fromlen) == -1) {
1.10 markus 139: debug("getpeername failed: %.100s", strerror(errno));
1.43 markus 140: return -1;
1.10 markus 141: }
1.6 markus 142: }
1.71 millert 143:
1.72 millert 144: /* Non-inet sockets don't have a port number. */
145: if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
1.71 millert 146: return 0;
147:
1.6 markus 148: /* Return port number. */
1.42 djm 149: if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
150: strport, sizeof(strport), NI_NUMERICSERV)) != 0)
1.75 ! djm 151: fatal_f("getnameinfo NI_NUMERICSERV failed: %s",
1.62 dtucker 152: ssh_gai_strerror(r));
1.10 markus 153: return atoi(strport);
1.1 deraadt 154: }
155:
1.12 markus 156: int
1.10 markus 157: get_peer_port(int sock)
158: {
159: return get_sock_port(sock, 0);
160: }
161:
1.12 markus 162: int
1.73 djm 163: get_local_port(int sock)
1.10 markus 164: {
1.73 djm 165: return get_sock_port(sock, 1);
1.1 deraadt 166: }