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

# User Rev Content
1 gbeauche 1.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     }