ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/router/router.cpp
Revision: 1.1
Committed: 2004-12-05T16:48:36Z (19 years, 11 months ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-17
Log Message:
import NAT-Router code from original Basilisk II for Windows

File Contents

# Content
1 /*
2 * router.cpp - ip router
3 *
4 * Basilisk II (C) 1997-2001 Christian Bauer
5 *
6 * Windows platform specific code copyright (C) Lauri Pesonen
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 /*
24 * This could be implemented by writing three (9x,nt,2k)
25 * NDIS filter drivers. No thanks.
26 * But this is not easy either.
27 */
28
29 #include "sysdeps.h"
30
31 #define WIN32_LEAN_AND_MEAN
32 #include <windows.h>
33 #include <process.h>
34
35 #include "cpu_emulation.h"
36 #include "prefs.h"
37 #include "ether_windows.h"
38 #include "ether.h"
39 #include "router.h"
40 #include "router_types.h"
41 #include "dynsockets.h"
42 #include "ipsocket.h"
43 #include "iphelp.h"
44 #include "arp.h"
45 #include "icmp.h"
46 #include "udp.h"
47 #include "tcp.h"
48 #include "ftp.h"
49 #include "mib/interfaces.h"
50 #include "dump.h"
51
52
53 #if DEBUG
54 #pragma optimize("",off)
55 #endif
56
57 #include "debug.h"
58
59
60 uint16 next_ip_ident_number = 1;
61 uint32 macos_ip_address = 0;
62 const uint8 router_mac_addr[6] = { '4', '2', '6', '7', '7', '9' };
63 uint32 router_ip_address = 0;
64 bool raw_sockets_available = false;
65 bool m_router_enabled = true;
66
67
68
69 // Protected data.
70 CRITICAL_SECTION router_section;
71 bool is_router_shutting_down = false;
72 static HANDLE r_handle = 0;
73 static unsigned int rh_tid = 0;
74
75
76 static void write_ip4( ip_t *ip, int len )
77 {
78 if(len < sizeof(ip_t)) {
79 D(bug("Too small ip packet(%d), dropped\r\n", len));
80 } else {
81 uint8 proto = ip->proto;
82
83 // This is a router, decrement the hop count
84 if( --ip->ttl == 0 ) {
85 // Most likely this is some Mac traceroute app
86 D(bug("ip packet ttl expired, proto=%d.\r\n", proto));
87 error_winsock_2_icmp( WSAETTLEXCEEDED, ip, len );
88 } else {
89 switch( proto ) {
90 case ip_proto_icmp:
91 write_icmp( (icmp_t *)ip, len );
92 break;
93 case ip_proto_tcp:
94 write_tcp( (tcp_t *)ip, len );
95 break;
96 case ip_proto_udp:
97 write_udp( (udp_t *)ip, len );
98 break;
99 default:
100 D(bug("write_ip4() len=%d, proto=%d\r\n", len, proto));
101 break;
102 }
103 }
104 }
105 }
106
107 bool router_write_packet(uint8 *packet, int len)
108 {
109 bool result = false;
110
111 if( len >= 14 ) {
112 switch( ntohs( ((mac_t *)packet)->type ) ) {
113 case mac_type_ip4:
114 write_ip4( (ip_t *)packet, len );
115 result = true;
116 break;
117 case mac_type_ip6:
118 D(bug("write_ip6() len=%d; unsupported.\r\n", len));
119 result = true;
120 break;
121 case mac_type_arp:
122 result = write_arp( (arp_t *)packet, len );
123 break;
124 }
125 }
126 return result;
127 }
128
129 bool router_read_packet(uint8 *packet, int len)
130 {
131 bool result = false;
132
133 if( len >= 14 ) {
134 switch( ntohs( ((mac_t *)packet)->type ) ) {
135 case mac_type_ip4:
136 case mac_type_ip6:
137 case mac_type_arp:
138 result = true;
139 break;
140 }
141 }
142 return result;
143 }
144
145 /*
146 This has nothing to do with TCP TIME_WAITs or CLOSE_WAITs,
147 the thread is needed to close down expired udp sockets.
148 Arguably an ugly hack, but needed since there is no way to
149 listen to all ports w/o writing another ndis filter driver
150 */
151 static WINAPI unsigned int router_expire_thread(void *arg)
152 {
153 while(!is_router_shutting_down) {
154 close_old_sockets();
155 Sleep(1000);
156 }
157 return 0;
158 }
159
160 void router_init(void)
161 {
162 InitializeCriticalSection( &router_section );
163
164 m_router_enabled = PrefsFindBool("routerenabled");
165
166 if(m_router_enabled && dynsockets_init()) {
167 char me[128];
168 if( _gethostname(me, sizeof(me)) == SOCKET_ERROR ) {
169 D(bug("gethostname() failed, error = %d\r\n", _WSAGetLastError()));
170 } else {
171 struct hostent *hent = _gethostbyname(me);
172 if( hent == NULL ) {
173 D(bug("gethostbyname() failed, error = %d\r\n", _WSAGetLastError()));
174 } else {
175 struct in_addr *ina = (struct in_addr *) *hent->h_addr_list;
176 router_ip_address = ntohl(ina->s_addr);
177 D(bug("router protocol address seems to be %s (used only in icmp error messages)\r\n", _inet_ntoa(*ina)));
178 }
179 }
180 is_router_shutting_down = false;
181 r_handle = (HANDLE)_beginthreadex( 0, 0, router_expire_thread, 0, 0, &rh_tid );
182 init_interfaces();
183 init_tcp();
184 init_udp();
185 init_ftp();
186 } else {
187 m_router_enabled = false;
188 }
189 }
190
191 void router_final(void)
192 {
193 final_interfaces();
194 stop_icmp_listen();
195 close_all_sockets();
196 if(r_handle) {
197 is_router_shutting_down = true;
198 WaitForSingleObject( r_handle, INFINITE );
199 final_tcp();
200 final_udp();
201 dynsockets_final();
202 }
203 DeleteCriticalSection( &router_section );
204 }