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, opt_len);
45 }
46
47 /* Checks whether IP address sent as argument is valid IP address. */
48
49 bool silc_net_is_ip(const char *addr)
50 {
51   struct in_addr tmp;
52   int len = sizeof(tmp);
53   return silc_net_addr2bin(addr, (unsigned char *)&tmp.s_addr, len);
54 }
55
56 /* Performs lookups for remote name and IP address. This peforms reverse
57    lookup as well to verify that the IP has FQDN. */
58
59 bool silc_net_check_host_by_sock(int sock, char **hostname, char **ip)
60 {
61   struct sockaddr_in remote;
62   struct hostent *dest;
63   char *host_ip = NULL;
64   char host_name[1024];
65   int rval, len;
66   int i;
67
68   *hostname = NULL;
69   *ip = NULL;
70
71   SILC_LOG_DEBUG(("Resolving remote hostname and IP address"));
72
73   memset(&remote, 0, sizeof(remote));
74   len = sizeof(remote);
75   rval = getpeername(sock, (struct sockaddr *)&remote, &len);
76   if (rval < 0)
77     return FALSE;
78
79   host_ip = inet_ntoa(remote.sin_addr);
80   if (!host_ip)
81     return FALSE;
82
83   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
84   memcpy(*ip, host_ip, strlen(host_ip));
85
86   /* Get host by address */
87   dest = gethostbyaddr((char *)&remote.sin_addr, 
88                        sizeof(struct in_addr), AF_INET);
89   if (!dest)
90     return FALSE;
91
92   /* Get same host by name to see that the remote host really is
93      the who it says it is */
94   memset(host_name, 0, sizeof(host_name));
95   memcpy(host_name, dest->h_name, strlen(dest->h_name));
96
97   *hostname = silc_calloc(strlen(host_name) + 1, sizeof(char));
98   memcpy(*hostname, host_name, strlen(host_name));
99   SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));
100
101   dest = gethostbyname(host_name);
102   if (!dest)
103     return FALSE;
104
105   /* Find the address from list */
106   for (i = 0; dest->h_addr_list[i]; i++)
107     if (!memcmp(dest->h_addr_list[i], &remote.sin_addr, 
108                 sizeof(struct in_addr)))
109       break;
110   if (!dest->h_addr_list[i])
111     return FALSE;
112
113   silc_free(*ip);
114   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
115   memcpy(*ip, host_ip, strlen(host_ip));
116   SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
117
118   return TRUE;
119 }
120
121 /* Performs lookups for local name and IP address. This peforms reverse
122    lookup as well to verify that the IP has FQDN. */
123
124 bool silc_net_check_local_by_sock(int sock, char **hostname, char **ip)
125 {
126   struct sockaddr_in local;
127   struct hostent *dest;
128   char *host_ip = NULL;
129   char host_name[1024];
130   int rval, len;
131   int i;
132
133   *hostname = NULL;
134   *ip = NULL;
135
136   SILC_LOG_DEBUG(("Resolving local hostname and IP address"));
137
138   memset(&local, 0, sizeof(local));
139   len = sizeof(local);
140   rval = getsockname(sock, (struct sockaddr *)&local, &len);
141   if (rval < 0)
142     return FALSE;
143
144   host_ip = inet_ntoa(local.sin_addr);
145   if (!host_ip)
146     return FALSE;
147
148   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
149   memcpy(*ip, host_ip, strlen(host_ip));
150
151   /* Get host by address */
152   dest = gethostbyaddr((char *)&local.sin_addr, 
153                        sizeof(struct in_addr), AF_INET);
154   if (!dest)
155     return FALSE;
156
157   /* Get same host by name to see that the local host really is
158      the who it says it is */
159   memset(host_name, 0, sizeof(host_name));
160   memcpy(host_name, dest->h_name, strlen(dest->h_name));
161
162   *hostname = silc_calloc(strlen(host_name) + 1, sizeof(char));
163   memcpy(*hostname, host_name, strlen(host_name));
164   SILC_LOG_DEBUG(("Resolved hostname `%s'", *hostname));
165
166   dest = gethostbyname(host_name);
167   if (!dest)
168     return FALSE;
169
170   /* Find the address from list */
171   for (i = 0; dest->h_addr_list[i]; i++)
172     if (!memcmp(dest->h_addr_list[i], &local.sin_addr, 
173                sizeof(struct in_addr)))
174       break;
175   if (!dest->h_addr_list[i])
176     return FALSE;
177
178   silc_free(*ip);
179   *ip = silc_calloc(strlen(host_ip) + 1, sizeof(char));
180   memcpy(*ip, host_ip, strlen(host_ip));
181   SILC_LOG_DEBUG(("Resolved IP address `%s'", *ip));
182
183   return TRUE;
184 }
185
186 /* Return remote port by socket. */
187
188 uint16 silc_net_get_remote_port(int sock)
189 {
190   struct sockaddr_in remote;
191   int len;
192
193   memset(&remote, 0, sizeof(remote));
194   len = sizeof(remote);
195   if (getpeername(sock, (struct sockaddr *)&remote, &len) < 0)
196     return 0;
197
198   return ntohs(remote.sin_port);
199 }
200
201 /* Return local port by socket. */
202
203 uint16 silc_net_get_local_port(int sock)
204 {
205   struct sockaddr_in local;
206   int len;
207
208   memset(&local, 0, sizeof(local));
209   len = sizeof(local);
210   if (getsockname(sock, (struct sockaddr *)&local, &len) < 0)
211     return 0;
212
213   return ntohs(local.sin_port);
214 }
215
216 /* Return name of localhost. */
217
218 char *silc_net_localhost(void)
219 {
220   char hostname[256];
221   struct hostent *dest;
222
223   if (gethostname(hostname, sizeof(hostname)))
224     return NULL;
225
226   dest = gethostbyname(hostname);
227   if (!dest)
228     return strdup(hostname);
229
230   return strdup(dest->h_name);
231 }
232
233 /* Returns local IP address */
234
235 char *silc_net_localip(void)
236 {
237   char hostname[256];
238   struct hostent *dest;
239   struct in_addr ip;
240   char *ips;
241
242   if (gethostname(hostname, sizeof(hostname)))
243     return NULL;
244
245   dest = gethostbyname(hostname);
246   if (!dest)
247     return NULL;
248
249   memcpy(&ip.s_addr, dest->h_addr_list[0], 4);
250   ips = inet_ntoa(ip);
251
252   return strdup(ips);
253 }