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