ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/ether.cpp
(Generate patch)

Comparing BasiliskII/src/ether.cpp (file contents):
Revision 1.5 by cebix, 2001-07-12T19:48:25Z vs.
Revision 1.12 by cebix, 2004-01-12T15:29:21Z

# Line 1 | Line 1
1   /*
2   *  ether.cpp - Ethernet device driver
3   *
4 < *  Basilisk II (C) 1997-2001 Christian Bauer
4 > *  Basilisk II (C) 1997-2004 Christian Bauer
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 25 | Line 25
25   *    Inside AppleTalk, chapter 3 "Ethernet and TokenTalk Link Access Protocols"
26   */
27  
28 #include <string.h>
29
28   #include "sysdeps.h"
29 < #include "cpu_emulation.h"
30 < #include "main.h"
31 < #include "macos_util.h"
34 < #include "emul_op.h"
35 < #include "prefs.h"
36 < #include "ether.h"
37 < #include "ether_defs.h"
29 >
30 > #include <string.h>
31 > #include <map>
32  
33   #if SUPPORTS_UDP_TUNNEL
34   #include <netinet/in.h>
35   #include <sys/socket.h>
36   #include <sys/ioctl.h>
37   #include <netdb.h>
38 + #include <unistd.h>
39   #include <errno.h>
40   #endif
41  
42 < #include <map>
42 > #include "cpu_emulation.h"
43 > #include "main.h"
44 > #include "macos_util.h"
45 > #include "emul_op.h"
46 > #include "prefs.h"
47 > #include "ether.h"
48 > #include "ether_defs.h"
49  
50   #ifndef NO_STD_NAMESPACE
51   using std::map;
# Line 56 | Line 57 | using std::map;
57   #define MONITOR 0
58  
59  
60 + #ifdef __BEOS__
61 + #define CLOSESOCKET closesocket
62 + #else
63 + #define CLOSESOCKET close
64 + #endif
65 +
66 +
67   // Global variables
68   uint8 ether_addr[6];                    // Ethernet address (set by ether_init())
69   static bool net_open = false;   // Flag: initialization succeeded, network device open (set by EtherInit())
# Line 101 | Line 109 | void EtherInit(void)
109                  sa.sin_port = htons(udp_port);
110                  if (bind(udp_socket, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
111                          perror("bind");
112 <                        close(udp_socket);
112 >                        CLOSESOCKET(udp_socket);
113                          udp_socket = -1;
114                          return;
115                  }
116  
117                  // Retrieve local IP address (or at least one of them)
118 <                socklen_t sa_len = sizeof(sa);
119 <                getsockname(udp_socket, (struct sockaddr *)&sa, &sa_len);
118 >                socklen_t sa_length = sizeof(sa);
119 >                getsockname(udp_socket, (struct sockaddr *)&sa, &sa_length);
120                  uint32 udp_ip = sa.sin_addr.s_addr;
121                  if (udp_ip == INADDR_ANY || udp_ip == INADDR_LOOPBACK) {
122                          char name[256];
# Line 130 | Line 138 | void EtherInit(void)
138  
139                  // Set socket options
140                  int on = 1;
141 + #ifdef __BEOS__
142 +                setsockopt(udp_socket, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(on));
143 + #else
144                  setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
145                  ioctl(udp_socket, FIONBIO, &on);
146 + #endif
147  
148                  // Start thread for packet reception
149                  if (!ether_start_udp_thread(udp_socket)) {
150 <                        close(udp_socket);
150 >                        CLOSESOCKET(udp_socket);
151                          udp_socket = -1;
152                          return;
153                  }
# Line 159 | Line 171 | void EtherExit(void)
171                  if (udp_tunnel) {
172                          if (udp_socket >= 0) {
173                                  ether_stop_udp_thread();
174 <                                close(udp_socket);
174 >                                CLOSESOCKET(udp_socket);
175                                  udp_socket = -1;
176                          }
177                  } else
# Line 171 | Line 183 | void EtherExit(void)
183  
184  
185   /*
186 < *  Check whether Ethernet address is AppleTalk broadcast address
186 > *  Reset
187 > */
188 >
189 > void EtherReset(void)
190 > {
191 >        udp_protocols.clear();
192 >        ether_reset();
193 > }
194 >
195 >
196 > /*
197 > *  Check whether Ethernet address is AppleTalk or Ethernet broadcast address
198   */
199  
200   static inline bool is_apple_talk_broadcast(uint8 *p)
# Line 180 | Line 203 | static inline bool is_apple_talk_broadca
203              && p[3] == 0xff && p[4] == 0xff && p[5] == 0xff;
204   }
205  
206 + static inline bool is_ethernet_broadcast(uint8 *p)
207 + {
208 +        return p[0] == 0xff && p[1] == 0xff && p[2] == 0xff
209 +            && p[3] == 0xff && p[4] == 0xff && p[5] == 0xff;
210 + }
211 +
212  
213   /*
214   *  Driver Open() routine
# Line 279 | Line 308 | int16 EtherControl(uint32 pb, uint32 dce
308  
309                  case kENetWrite: {              // Transmit raw Ethernet packet
310                          uint32 wds = ReadMacInt32(pb + ePointer);
311 <                        D(bug(" EtherWrite\n"));
311 >                        D(bug(" EtherWrite "));
312                          if (ReadMacInt16(wds) < 14)
313                                  return eLenErr; // Header incomplete
314 +
315 +                        // Set source address
316 +                        uint32 hdr = ReadMacInt32(wds + 2);
317 +                        Host2Mac_memcpy(hdr + 6, ether_addr, 6);
318 +                        D(bug("to %08x%04x, type %04x\n", ReadMacInt32(hdr), ReadMacInt16(hdr + 4), ReadMacInt16(hdr + 12)));
319 +
320                          if (net_open) {
321   #if SUPPORTS_UDP_TUNNEL
322                                  if (udp_tunnel) {
# Line 290 | Line 325 | int16 EtherControl(uint32 pb, uint32 dce
325                                          uint8 packet[1514];
326                                          int len = ether_wds_to_buffer(wds, packet);
327  
328 <                                        // Set source address and extract destination address
294 <                                        memcpy(packet + 6, ether_addr, 6);
328 >                                        // Extract destination address
329                                          uint32 dest_ip;
330                                          if (packet[0] == 'B' && packet[1] == '2')
331                                                  dest_ip = (packet[2] << 24) | (packet[3] << 16) | (packet[4] << 8) | packet[5];
332 <                                        else if (is_apple_talk_broadcast(packet))
332 >                                        else if (is_apple_talk_broadcast(packet) || is_ethernet_broadcast(packet))
333                                                  dest_ip = INADDR_BROADCAST;
334                                          else
335                                                  return eMultiErr;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines