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.6 by cebix, 2001-07-13T15:39:21Z vs.
Revision 1.14 by gbeauche, 2005-03-19T17:43:03Z

# 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-2005 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 35 | Line 35
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  
# 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 182 | Line 194 | void EtherReset(void)
194  
195  
196   /*
197 < *  Check whether Ethernet address is AppleTalk broadcast address
197 > *  Check whether Ethernet address is AppleTalk or Ethernet broadcast address
198   */
199  
200   static inline bool is_apple_talk_broadcast(uint8 *p)
# Line 191 | 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 290 | 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 301 | 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
305 <                                        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;
# Line 367 | Line 390 | int16 EtherControl(uint32 pb, uint32 dce
390   *  Ethernet ReadPacket routine
391   */
392  
393 < void EtherReadPacket(uint8 **src, uint32 &dest, uint32 &len, uint32 &remaining)
393 > void EtherReadPacket(uint32 &src, uint32 &dest, uint32 &len, uint32 &remaining)
394   {
395 <        D(bug("EtherReadPacket src %p, dest %08x, len %08x, remaining %08x\n", *src, dest, len, remaining));
395 >        D(bug("EtherReadPacket src %08x, dest %08x, len %08x, remaining %08x\n", src, dest, len, remaining));
396          uint32 todo = len > remaining ? remaining : len;
397 <        Host2Mac_memcpy(dest, *src, todo);
398 <        *src += todo;
397 >        Mac2Mac_memcpy(dest, src, todo);
398 >        src += todo;
399          dest += todo;
400          len -= todo;
401          remaining -= todo;
# Line 384 | Line 407 | void EtherReadPacket(uint8 **src, uint32
407   *  Read packet from UDP socket
408   */
409  
410 < void ether_udp_read(uint8 *packet, int length, struct sockaddr_in *from)
410 > void ether_udp_read(uint32 packet, int length, struct sockaddr_in *from)
411   {
412          // Drop packets sent by us
413 <        if (memcmp(packet + 6, ether_addr, 6) == 0)
413 >        if (memcmp(Mac2HostAddr(packet) + 6, ether_addr, 6) == 0)
414                  return;
415  
416   #if MONITOR
417          bug("Receiving Ethernet packet:\n");
418          for (int i=0; i<length; i++) {
419 <                bug("%02x ", packet[i]);
419 >                bug("%02x ", ReadMacInt8(packet + i));
420          }
421          bug("\n");
422   #endif
423  
424          // Get packet type
425 <        uint16 type = (packet[12] << 8) | packet[13];
425 >        uint16 type = ReadMacInt16(packet + 12);
426  
427          // Look for protocol
428          uint16 search_type = (type <= 1500 ? 0 : type);
# Line 410 | Line 433 | void ether_udp_read(uint8 *packet, int l
433                  return;
434  
435          // Copy header to RHA
436 <        Host2Mac_memcpy(ether_data + ed_RHA, packet, 14);
436 >        Mac2Mac_memcpy(ether_data + ed_RHA, packet, 14);
437          D(bug(" header %08x%04x %08x%04x %04x\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12)));
438  
439          // Call protocol handler
440          M68kRegisters r;
441          r.d[0] = type;                                                                  // Packet type
442          r.d[1] = length - 14;                                                   // Remaining packet length (without header, for ReadPacket)
443 <        r.a[0] = (uint32)packet + 14;                                   // Pointer to packet (host address, for ReadPacket)
443 >        r.a[0] = packet + 14;                                                   // Pointer to packet (Mac address, for ReadPacket)
444          r.a[3] = ether_data + ed_RHA + 14;                              // Pointer behind header in RHA
445          r.a[4] = ether_data + ed_ReadPacket;                    // Pointer to ReadPacket/ReadRest routines
446          D(bug(" calling protocol handler %08x, type %08x, length %08x, data %08x, rha %08x, read_packet %08x\n", handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
447          Execute68k(handler, &r);
448   }
449   #endif
450 +
451 +
452 + /*
453 + *  Ethernet packet allocator
454 + */
455 +
456 + #if SIZEOF_VOID_P == 4 || REAL_ADDRESSING == 0
457 + static uint32 ether_packet = 0;                 // Ethernet packet (cached allocation)
458 + static uint32 n_ether_packets = 0;              // Number of ethernet packets allocated so far (should be at most 1)
459 +
460 + EthernetPacket::EthernetPacket()
461 + {
462 +        ++n_ether_packets;
463 +        if (ether_packet && n_ether_packets == 1)
464 +                packet = ether_packet;
465 +        else {
466 +        M68kRegisters r;
467 +        r.d[0] = 1516;
468 +        Execute68kTrap(0xa71e, &r);             // NewPtrSysClear()
469 +                assert(r.a[0] != 0);
470 +                packet = r.a[0];
471 +                if (ether_packet == 0)
472 +                        ether_packet = packet;
473 +        }
474 + }
475 +
476 + EthernetPacket::~EthernetPacket()
477 + {
478 +        --n_ether_packets;
479 +        if (packet != ether_packet) {
480 +                M68kRegisters r;
481 +                r.a[0] = packet;
482 +                Execute68kTrap(0xa01f, &r);             // DisposePtr
483 +        }
484 +        if (n_ether_packets > 0) {
485 +                bug("WARNING: Nested allocation of ethernet packets!\n");
486 +        }
487 + }
488 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines