ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/router/router.cpp
Revision: 1.3
Committed: 2008-01-01T09:40:34Z (16 years, 11 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +1 -1 lines
Error occurred while calculating annotation data.
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * router.cpp - ip router
3 *
4 * Basilisk II (C) 1997-2008 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
66
67
68 // Protected data.
69 CRITICAL_SECTION router_section;
70 bool is_router_shutting_down = false;
71 static HANDLE r_handle = 0;
72 static unsigned int rh_tid = 0;
73
74
75 static void write_ip4( ip_t *ip, int len )
76 {
77 if(len < sizeof(ip_t)) {
78 D(bug("Too small ip packet(%d), dropped\r\n", len));
79 } else {
80 uint8 proto = ip->proto;
81
82 // This is a router, decrement the hop count
83 if( --ip->ttl == 0 ) {
84 // Most likely this is some Mac traceroute app
85 D(bug("ip packet ttl expired, proto=%d.\r\n", proto));
86 error_winsock_2_icmp( WSAETTLEXCEEDED, ip, len );
87 } else {
88 switch( proto ) {
89 case ip_proto_icmp:
90 write_icmp( (icmp_t *)ip, len );
91 break;
92 case ip_proto_tcp:
93 write_tcp( (tcp_t *)ip, len );
94 break;
95 case ip_proto_udp:
96 write_udp( (udp_t *)ip, len );
97 break;
98 default:
99 D(bug("write_ip4() len=%d, proto=%d\r\n", len, proto));
100 break;
101 }
102 }
103 }
104 }
105
106 bool router_write_packet(uint8 *packet, int len)
107 {
108 bool result = false;
109
110 if( len >= 14 ) {
111 switch( ntohs( ((mac_t *)packet)->type ) ) {
112 case mac_type_ip4:
113 write_ip4( (ip_t *)packet, len );
114 result = true;
115 break;
116 case mac_type_ip6:
117 D(bug("write_ip6() len=%d; unsupported.\r\n", len));
118 result = true;
119 break;
120 case mac_type_arp:
121 result = write_arp( (arp_t *)packet, len );
122 break;
123 }
124 }
125 return result;
126 }
127
128 bool router_read_packet(uint8 *packet, int len)
129 {
130 bool result = false;
131
132 if( len >= 14 ) {
133 switch( ntohs( ((mac_t *)packet)->type ) ) {
134 case mac_type_ip4:
135 case mac_type_ip6:
136 case mac_type_arp:
137 result = true;
138 break;
139 }
140 }
141 return result;
142 }
143
144 /*
145 This has nothing to do with TCP TIME_WAITs or CLOSE_WAITs,
146 the thread is needed to close down expired udp sockets.
147 Arguably an ugly hack, but needed since there is no way to
148 listen to all ports w/o writing another ndis filter driver
149 */
150 static WINAPI unsigned int router_expire_thread(void *arg)
151 {
152 while(!is_router_shutting_down) {
153 close_old_sockets();
154 Sleep(1000);
155 }
156 return 0;
157 }
158
159 bool router_init(void)
160 {
161 InitializeCriticalSection( &router_section );
162
163 if(dynsockets_init()) {
164 char me[128];
165 if( _gethostname(me, sizeof(me)) == SOCKET_ERROR ) {
166 D(bug("gethostname() failed, error = %d\r\n", _WSAGetLastError()));
167 } else {
168 struct hostent *hent = _gethostbyname(me);
169 if( hent == NULL ) {
170 D(bug("gethostbyname() failed, error = %d\r\n", _WSAGetLastError()));
171 } else {
172 struct in_addr *ina = (struct in_addr *) *hent->h_addr_list;
173 router_ip_address = ntohl(ina->s_addr);
174 D(bug("router protocol address seems to be %s (used only in icmp error messages)\r\n", _inet_ntoa(*ina)));
175 }
176 }
177 is_router_shutting_down = false;
178 r_handle = (HANDLE)_beginthreadex( 0, 0, router_expire_thread, 0, 0, &rh_tid );
179 init_interfaces();
180 init_tcp();
181 init_udp();
182 init_ftp();
183 return true;
184 }
185
186 return false;
187 }
188
189 void router_final(void)
190 {
191 final_interfaces();
192 stop_icmp_listen();
193 close_all_sockets();
194 if(r_handle) {
195 is_router_shutting_down = true;
196 WaitForSingleObject( r_handle, INFINITE );
197 final_tcp();
198 final_udp();
199 dynsockets_final();
200 }
201 DeleteCriticalSection( &router_section );
202 }