updates.
[silc.git] / lib / silcutil / silcnet.c
1 /*
2
3   silcnet.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /* $Id$ */
21
22 #include "silcincludes.h"
23 #include "silcnet.h"
24
25 /* Accepts a connection from a particular socket */
26
27 int silc_net_accept_connection(int sock)
28 {
29   return accept(sock, 0, 0);
30 }
31
32 /* Sets a option for a socket. */
33
34 int silc_net_set_socket_opt(int sock, int level, int option, int on)
35 {
36   return setsockopt(sock, level, option, (void *)&on, sizeof(on));
37 }
38
39 /* Get socket options */
40
41 int silc_net_get_socket_opt(int sock, int level, int option, 
42                             void *optval, int *opt_len)
43 {
44   return getsockopt(sock, level, option, optval, (socklen_t *)opt_len);
45 }
46 /* Checks whether IP address sent as argument is valid IP address. */
47
48 bool silc_net_is_ip(const char *addr)
49 {
50   struct in_addr tmp;
51   int len = sizeof(tmp);
52   return silc_net_addr2bin(addr, (unsigned char *)&tmp.s_addr, len);
53 }
54
55 /* Performs lookups for remote name and IP address. This peforms reverse
56    lookup as well to verify that the IP has FQDN. */
57
58 bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
59 {
60   struct sockaddr_in remote;
61   struct hostent *dest;
62   char *host_ip = NULL;
63   char host_name[1024];
64   int rval, len;
65   int i;
66
67   *hostname = NULL;
68   *ip = NULL;
69
70   SILC_LOG_DEBUG(("Resolving remote hostname and IP address"));
71
72   memset(&remote, 0, sizeof(remote));
73   len = sizeof(remote);
74   rval = getpeername(sock, (struct sockaddr *)&remote, &len);
75   if (rval < 0)
76     return FALSE;
77
78   host_ip = inet_ntoa(remote.sin_addr);
79   if (!host_ip)
80     return FALSE;
81
82   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
83   memcpy(*ip, host_ip, strlen(host_ip));
84
85   /* Get host by address */
86   dest = gethostbyaddr((char *)&remote.sin_addr, 
87                        sizeof(struct in_addr), AF_INET);
88   if (!dest)
89     return FALSE;
90
91   /* Get same host by name to see that the remote host really is
92      the who it says it is */
93   memset(host_name, 0, sizeof(host_name));
94   memcpy(host_name, dest->h_name, strlen(dest->h_name));
95
96   *hostname = silc_calloc(strlen(host_name) + 1, sizeof(char));
97   memcpy(*hostname, host_name, strlen(host_name));
98   SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));
99
100   dest = gethostbyname(host_name);
101   if (!dest)
102     return FALSE;
103
104   /* Find the address from list */
105   for (i = 0; dest->h_addr_list[i]; i++)
106     if (!memcmp(dest->h_addr_list[i], &remote.sin_addr, 
107                sizeof(struct in_addr)))
108       break;
109   if (!dest->h_addr_list[i])
110     return FALSE;
111
112   silc_free(*ip);
113   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
114   memcpy(*ip, host_ip, strlen(host_ip));
115   SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
116
117   return TRUE;
118 }
119
120 /* Performs lookups for local name and IP address. This peforms reverse
121    lookup as well to verify that the IP has FQDN. */
122
123 bool silc_net_check_local_by_sock(int sock, char **hostname, char **ip)
124 {
125   struct sockaddr_in local;
126   struct hostent *dest;
127   char *host_ip = NULL;
128   char host_name[1024];
129   int rval, len;
130   int i;
131
132   *hostname = NULL;
133   *ip = NULL;
134
135   SILC_LOG_DEBUG(("Resolving local hostname and IP address"));
136
137   memset(&local, 0, sizeof(local));
138   len = sizeof(local);
139   rval = getsockname(sock, (struct sockaddr *)&local, &len);
140   if (rval < 0)
141     return FALSE;
142
143   host_ip = inet_ntoa(local.sin_addr);
144   if (!host_ip)
145     return FALSE;
146
147   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
148   memcpy(*ip, host_ip, strlen(host_ip));
149
150   /* Get host by address */
151   dest = gethostbyaddr((char *)&local.sin_addr, 
152                        sizeof(struct in_addr), AF_INET);
153   if (!dest)
154     return FALSE;
155
156   /* Get same host by name to see that the local host really is
157      the who it says it is */
158   memset(host_name, 0, sizeof(host_name));
159   memcpy(host_name, dest->h_name, strlen(dest->h_name));
160
161   *hostname = silc_calloc(strlen(host_name) + 1, sizeof(char));
162   memcpy(*hostname, host_name, strlen(host_name));
163   SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));
164
165   dest = gethostbyname(host_name);
166   if (!dest)
167     return FALSE;
168
169   /* Find the address from list */
170   for (i = 0; dest->h_addr_list[i]; i++)
171     if (!memcmp(dest->h_addr_list[i], &local.sin_addr, 
172                sizeof(struct in_addr)))
173       break;
174   if (!dest->h_addr_list[i])
175     return FALSE;
176
177   silc_free(*ip);
178   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
179   memcpy(*ip, host_ip, strlen(host_ip));
180   SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
181
182   return TRUE;
183 }
184
185 /* Return remote port by socket. */
186
187 uint16 silc_net_get_remote_port(int sock)
188 {
189   struct sockaddr_in remote;
190   int len;
191
192   memset(&remote, 0, sizeof(remote));
193   len = sizeof(remote);
194   if (getpeername(sock, (struct sockaddr *)&remote, &len) < 0)
195     return 0;
196
197   return ntohs(remote.sin_port);
198 }
199
200 /* Return local port by socket. */
201
202 uint16 silc_net_get_local_port(int sock)
203 {
204   struct sockaddr_in local;
205   int len;
206
207   memset(&local, 0, sizeof(local));
208   len = sizeof(local);
209   if (getsockname(sock, (struct sockaddr *)&local, &len) < 0)
210     return 0;
211
212   return ntohs(local.sin_port);
213 }
214
215 /* Return name of localhost. */
216
217 char *silc_net_localhost()
218 {
219   char hostname[256];
220   struct hostent *dest;
221
222   if (gethostname(hostname, sizeof(hostname)))
223     return NULL;
224
225   dest = gethostbyname(hostname);
226   if (!dest)
227     return strdup(hostname);
228
229   return strdup(dest->h_name);
230 }