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

Comparing BasiliskII/src/Unix/ether_unix.cpp (file contents):
Revision 1.1 by cebix, 2001-03-29T14:20:53Z vs.
Revision 1.2 by cebix, 2001-07-12T19:48:27Z

# Line 27 | Line 27
27   #include <errno.h>
28   #include <stdio.h>
29  
30 < #if defined(__FreeBSD__)
30 > #include <netinet/in.h>
31   #include <sys/socket.h>
32 +
33 + #if defined(__FreeBSD__)
34   #include <net/if.h>
35   #endif
36  
# Line 63 | Line 65 | static pthread_attr_t ether_thread_attr;
65   static bool thread_active = false;                      // Flag: Packet reception thread installed
66   static sem_t int_ack;                                           // Interrupt acknowledge semaphore
67   static bool is_ethertap;                                        // Flag: Ethernet device is ethertap
68 + static bool udp_tunnel;                                         // Flag: UDP tunnelling active, fd is the socket descriptor
69  
70   // Prototypes
71   static void *receive_func(void *arg);
# Line 107 | Line 110 | static void remove_all_protocols(void)
110  
111  
112   /*
113 + *  Start packet reception thread
114 + */
115 +
116 + static bool start_thread(void)
117 + {
118 +        if (sem_init(&int_ack, 0, 0) < 0) {
119 +                printf("WARNING: Cannot init semaphore");
120 +                return false;
121 +        }
122 +
123 +        pthread_attr_init(&ether_thread_attr);
124 + #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
125 +        if (geteuid() == 0) {
126 +                pthread_attr_setinheritsched(&ether_thread_attr, PTHREAD_EXPLICIT_SCHED);
127 +                pthread_attr_setschedpolicy(&ether_thread_attr, SCHED_FIFO);
128 +                struct sched_param fifo_param;
129 +                fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 + 1;
130 +                pthread_attr_setschedparam(&ether_thread_attr, &fifo_param);
131 +        }
132 + #endif
133 +
134 +        thread_active = (pthread_create(&ether_thread, &ether_thread_attr, receive_func, NULL) == 0);
135 +        if (!thread_active) {
136 +                printf("WARNING: Cannot start Ethernet thread");
137 +                return false;
138 +        }
139 +
140 +        return true;
141 + }
142 +
143 +
144 + /*
145 + *  Stop packet reception thread
146 + */
147 +
148 + static void stop_thread(void)
149 + {
150 +        if (thread_active) {
151 +                pthread_cancel(ether_thread);
152 +                pthread_join(ether_thread, NULL);
153 +                sem_destroy(&int_ack);
154 +                thread_active = false;
155 +        }
156 + }
157 +
158 +
159 + /*
160   *  Initialization
161   */
162  
163 < void EtherInit(void)
163 > bool ether_init(void)
164   {
165          int nonblock = 1;
166          char str[256];
# Line 118 | Line 168 | void EtherInit(void)
168          // Do nothing if no Ethernet device specified
169          const char *name = PrefsFindString("ether");
170          if (name == NULL)
171 <                return;
171 >                return false;
172  
173          // Is it Ethertap?
174          is_ethertap = (strncmp(name, "tap", 3) == 0);
# Line 162 | Line 212 | void EtherInit(void)
212          D(bug("Ethernet address %02x %02x %02x %02x %02x %02x\n", ether_addr[0], ether_addr[1], ether_addr[2], ether_addr[3], ether_addr[4], ether_addr[5]));
213  
214          // Start packet reception thread
215 <        if (sem_init(&int_ack, 0, 0) < 0) {
166 <                printf("WARNING: Cannot init semaphore");
167 <                goto open_error;
168 <        }
169 <        pthread_attr_init(&ether_thread_attr);
170 < #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING)
171 <        if (geteuid() == 0) {
172 <                pthread_attr_setinheritsched(&ether_thread_attr, PTHREAD_EXPLICIT_SCHED);
173 <                pthread_attr_setschedpolicy(&ether_thread_attr, SCHED_FIFO);
174 <                struct sched_param fifo_param;
175 <                fifo_param.sched_priority = (sched_get_priority_min(SCHED_FIFO) + sched_get_priority_max(SCHED_FIFO)) / 2 + 1;
176 <                pthread_attr_setschedparam(&ether_thread_attr, &fifo_param);
177 <        }
178 < #endif
179 <        thread_active = (pthread_create(&ether_thread, &ether_thread_attr, receive_func, NULL) == 0);
180 <        if (!thread_active) {
181 <                printf("WARNING: Cannot start Ethernet thread");
215 >        if (!start_thread())
216                  goto open_error;
183        }
217  
218          // Everything OK
219 <        net_open = true;
187 <        return;
219 >        return true;
220  
221   open_error:
222 <        if (thread_active) {
223 <                pthread_cancel(ether_thread);
192 <                pthread_join(ether_thread, NULL);
193 <                sem_destroy(&int_ack);
194 <                thread_active = false;
195 <        }
222 >        stop_thread();
223 >
224          if (fd > 0) {
225                  close(fd);
226                  fd = -1;
227          }
228 +        return false;
229   }
230  
231  
# Line 204 | Line 233 | open_error:
233   *  Deinitialization
234   */
235  
236 < void EtherExit(void)
236 > void ether_exit(void)
237   {
238          // Stop reception thread
239          if (thread_active) {
# Line 334 | Line 363 | int16 ether_write(uint32 wds)
363                  len += 2;
364          }
365   #endif
366 <        for (;;) {
338 <                int w = ReadMacInt16(wds);
339 <                if (w == 0)
340 <                        break;
341 <                Mac2Host_memcpy(p, ReadMacInt32(wds + 2), w);
342 <                len += w;
343 <                p += w;
344 <                wds += 6;
345 <        }
366 >        len += ether_wds_to_buffer(wds, p);
367  
368   #if MONITOR
369          bug("Sending Ethernet packet:\n");
# Line 362 | Line 383 | int16 ether_write(uint32 wds)
383  
384  
385   /*
386 + *  Start UDP packet reception thread
387 + */
388 +
389 + bool ether_start_udp_thread(int socket_fd)
390 + {
391 +        fd = socket_fd;
392 +        udp_tunnel = true;
393 +        return start_thread();
394 + }
395 +
396 +
397 + /*
398 + *  Stop UDP packet reception thread
399 + */
400 +
401 + void ether_stop_udp_thread(void)
402 + {
403 +        stop_thread();
404 +        fd = -1;
405 + }
406 +
407 +
408 + /*
409   *  Packet reception thread
410   */
411  
# Line 397 | Line 441 | void EtherInterrupt(void)
441  
442          // Call protocol handler for received packets
443          uint8 packet[1516];
444 +        ssize_t length;
445          for (;;) {
446  
447 <                // Read packet from sheep_net device
447 >                if (udp_tunnel) {
448 >
449 >                        // Read packet from socket
450 >                        struct sockaddr_in from;
451 >                        socklen_t from_len = sizeof(from);
452 >                        length = recvfrom(fd, packet, 1514, 0, (struct sockaddr *)&from, &from_len);
453 >                        if (length < 14)
454 >                                break;
455 >                        ether_udp_read(packet, length, &from);
456 >
457 >                } else {
458 >
459 >                        // Read packet from sheep_net device
460   #if defined(__linux__)
461 <                ssize_t length = read(fd, packet, is_ethertap ? 1516 : 1514);
461 >                        length = read(fd, packet, is_ethertap ? 1516 : 1514);
462   #else
463 <                ssize_t length = read(fd, packet, 1514);
463 >                        length = read(fd, packet, 1514);
464   #endif
465 <                if (length < 14)
466 <                        break;
465 >                        if (length < 14)
466 >                                break;
467  
468   #if MONITOR
469 <                bug("Receiving Ethernet packet:\n");
470 <                for (int i=0; i<length; i++) {
471 <                        bug("%02x ", packet[i]);
472 <                }
473 <                bug("\n");
469 >                        bug("Receiving Ethernet packet:\n");
470 >                        for (int i=0; i<length; i++) {
471 >                                bug("%02x ", packet[i]);
472 >                        }
473 >                        bug("\n");
474   #endif
475  
476 <                // Pointer to packet data (Ethernet header)
477 <                uint8 *p = packet;
476 >                        // Pointer to packet data (Ethernet header)
477 >                        uint8 *p = packet;
478   #if defined(__linux__)
479 <                if (is_ethertap) {
480 <                        p += 2;                 // Linux ethertap has two random bytes before the packet
481 <                        length -= 2;
482 <                }
479 >                        if (is_ethertap) {
480 >                                p += 2;                 // Linux ethertap has two random bytes before the packet
481 >                                length -= 2;
482 >                        }
483   #endif
484  
485 <                // Get packet type
486 <                uint16 type = ntohs(*(uint16 *)(p + 12));
485 >                        // Get packet type
486 >                        uint16 type = (p[12] << 8) | p[13];
487  
488 <                // Look for protocol
489 <                NetProtocol *prot = find_protocol(type);
490 <                if (prot == NULL)
491 <                        continue;
492 <
493 <                // No default handler
494 <                if (prot->handler == 0)
495 <                        continue;
496 <
497 <                // Copy header to RHA
498 <                Host2Mac_memcpy(ether_data + ed_RHA, p, 14);
499 <                D(bug(" header %08lx%04lx %08lx%04lx %04lx\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)));
500 <
501 <                // Call protocol handler
502 <                M68kRegisters r;
503 <                r.d[0] = type;                                                                  // Packet type
504 <                r.d[1] = length - 14;                                                   // Remaining packet length (without header, for ReadPacket)
505 <                r.a[0] = (uint32)p + 14;                                                // Pointer to packet (host address, for ReadPacket)
506 <                r.a[3] = ether_data + ed_RHA + 14;                              // Pointer behind header in RHA
507 <                r.a[4] = ether_data + ed_ReadPacket;                    // Pointer to ReadPacket/ReadRest routines
508 <                D(bug(" calling protocol handler %08lx, type %08lx, length %08lx, data %08lx, rha %08lx, read_packet %08lx\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
509 <                Execute68k(prot->handler, &r);
488 >                        // Look for protocol
489 >                        NetProtocol *prot = find_protocol(type);
490 >                        if (prot == NULL)
491 >                                continue;
492 >
493 >                        // No default handler
494 >                        if (prot->handler == 0)
495 >                                continue;
496 >
497 >                        // Copy header to RHA
498 >                        Host2Mac_memcpy(ether_data + ed_RHA, p, 14);
499 >                        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)));
500 >
501 >                        // Call protocol handler
502 >                        M68kRegisters r;
503 >                        r.d[0] = type;                                                                  // Packet type
504 >                        r.d[1] = length - 14;                                                   // Remaining packet length (without header, for ReadPacket)
505 >                        r.a[0] = (uint32)p + 14;                                                // Pointer to packet (host address, for ReadPacket)
506 >                        r.a[3] = ether_data + ed_RHA + 14;                              // Pointer behind header in RHA
507 >                        r.a[4] = ether_data + ed_ReadPacket;                    // Pointer to ReadPacket/ReadRest routines
508 >                        D(bug(" calling protocol handler %08x, type %08x, length %08x, data %08x, rha %08x, read_packet %08x\n", prot->handler, r.d[0], r.d[1], r.a[0], r.a[3], r.a[4]));
509 >                        Execute68k(prot->handler, &r);
510 >                }
511          }
512  
513          // Acknowledge interrupt to reception thread

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines