ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/sockinfo.C
Revision: 1.30
Committed: Tue Dec 4 13:51:45 2012 UTC (11 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-3_0, rel-2_25, HEAD
Changes since 1.29: +2 -7 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 sockinfo.C -- socket address management
3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4
5 This file is part of GVPE.
6
7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, see <http://www.gnu.org/licenses/>.
19
20 Additional permission under GNU GPL version 3 section 7
21
22 If you modify this Program, or any covered work, by linking or
23 combining it with the OpenSSL project's OpenSSL library (or a modified
24 version of that library), containing parts covered by the terms of the
25 OpenSSL or SSLeay licenses, the licensors of this Program grant you
26 additional permission to convey the resulting work. Corresponding
27 Source for a non-source form of such a combination shall include the
28 source code for the parts of OpenSSL used as well as that of the
29 covered work.
30 */
31
32 #include "config.h"
33
34 // for gethostbyname
35 #include <netdb.h>
36
37 // for inet_aton
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <arpa/inet.h>
41
42 #include "gettext.h"
43
44 #include "sockinfo.h"
45 #include "slog.h"
46
47 #include <cstring>
48 #include <cstdio>
49
50 // all ipv4-based protocols
51 #define PROTv4 (PROT_UDPv4 | PROT_TCPv4 | PROT_ICMPv4 | PROT_IPv4 | PROT_DNSv4)
52
53 void
54 sockinfo::set (const sockaddr_in *sa, u8 prot_)
55 {
56 host = sa->sin_addr.s_addr;
57 port = prot_ & (PROT_IPv4 | PROT_ICMPv4) ? 0 : sa->sin_port;
58 prot = prot_;
59 }
60
61 void
62 sockinfo::set (const char *hostname, u16 port_, u8 prot_)
63 {
64 prot = prot_;
65 host = 0;
66 port = htons (port_);
67
68 if (prot & PROTv4
69 && hostname)
70 {
71 struct in_addr in;
72 struct hostent *he;
73
74 if (inet_aton (hostname, &in))
75 host = in.s_addr;
76 else if ((he = gethostbyname (hostname))
77 && he->h_addrtype == AF_INET
78 && he->h_length == 4
79 && he->h_addr_list[0])
80 memcpy (&host, he->h_addr_list[0], 4); //sa->sin_family = he->h_addrtype;
81 else
82 slog (L_NOTICE, _("unable to resolve host '%s'"), hostname);
83 }
84 }
85
86 void
87 sockinfo::set (const conf_node *conf, u8 prot_)
88 {
89 if (prot_ == PROT_DNSv4)
90 {
91 host = htonl (conf->id); port = 0; prot = prot_;
92 }
93 else
94 set (conf->hostname,
95 prot_ == PROT_UDPv4 ? conf->udp_port
96 : prot_ == PROT_TCPv4 ? conf->tcp_port
97 : prot_ == PROT_DNSv4 ? conf->dns_port
98 : 0,
99 prot_);
100 }
101
102 const sockaddr *
103 sockinfo::sav4() const
104 {
105 static sockaddr_in sa;
106
107 sa.sin_family = AF_INET;
108 sa.sin_port = port;
109 sa.sin_addr.s_addr = host;
110
111 return (const sockaddr *)&sa;
112 }
113
114 static char hostport[10 + 15 + 1 + 5 + 1]; // proto / IPv4 : port
115
116 const char *
117 sockinfo::ntoa () const
118 {
119 in_addr ia = { host };
120
121 sprintf (hostport, "%.15s", inet_ntoa (ia));
122
123 return hostport;
124 }
125
126 bool
127 sockinfo::valid () const
128 {
129 return (prot & THISNODE->protocols) && host;
130 }
131
132 sockinfo::operator const char *() const
133 {
134 in_addr ia = { host };
135
136 sprintf (hostport, "%s/%.15s:%d", strprotocol (prot), inet_ntoa (ia), ntohs (port) & 0xffff);
137
138 return hostport;
139 }
140
141 u8
142 sockinfo::supported_protocols (conf_node *conf)
143 {
144 u8 protocols = prot;
145
146 if (prot & (PROT_IPv4 | PROT_ICMPv4 | PROT_UDPv4 | PROT_TCPv4))
147 protocols |= PROT_IPv4 | PROT_ICMPv4;
148
149 if (conf && prot & PROTv4)
150 {
151 if (conf->protocols & PROT_UDPv4 && conf->udp_port)
152 protocols |= PROT_UDPv4;
153
154 if (conf->protocols & PROT_TCPv4 && conf->tcp_port)
155 protocols |= PROT_TCPv4;
156
157 if (conf->protocols & PROT_DNSv4 && conf->dns_port)
158 protocols |= PROT_DNSv4;
159 }
160
161 return protocols;
162 }
163
164 bool
165 sockinfo::upgrade_protocol (u8 prot_, conf_node *conf)
166 {
167 if (prot_ == prot)
168 return true;
169
170 if (prot & PROTv4
171 && prot_ & PROTv4)
172 {
173 if (prot_ & (PROT_IPv4 | PROT_ICMPv4))
174 {
175 prot = prot_;
176 port = 0;
177 return true;
178 }
179
180 if (conf
181 && prot_ & PROT_UDPv4
182 && conf->protocols & PROT_UDPv4
183 && conf->udp_port)
184 {
185 prot = prot_;
186 port = htons (conf->udp_port);
187 return true;
188 }
189
190 if (conf
191 && prot_ & PROT_TCPv4
192 && conf->protocols & PROT_TCPv4
193 && conf->tcp_port)
194 {
195 prot = prot_;
196 port = htons (conf->tcp_port);
197 return true;
198 }
199 }
200
201 return false;
202 }
203
204 bool
205 operator == (const sockinfo &a, const sockinfo &b)
206 {
207 return a.host == b.host && a.port == b.port && a.prot == b.prot;
208 }
209
210 bool
211 operator < (const sockinfo &a, const sockinfo &b)
212 {
213 return a.host < b.host
214 || (a.host == b.host && (a.port < b.port
215 || (a.port == b.port && a.prot < b.prot)));
216 }
217