- UDP tunneling works under BeOS

- fixed BeOS compilation problems
This commit is contained in:
cebix 2001-07-15 14:19:08 +00:00
parent 3e27acb9d4
commit 52ad76b49e
8 changed files with 175 additions and 47 deletions

View File

@ -68,7 +68,7 @@ RSRCS=
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS=be game media device textencoding tracker
LIBS=be game media device textencoding tracker net
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths

View File

@ -19,6 +19,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <KernelKit.h>
#include <AppKit.h>
#include <StorageKit.h>
@ -27,8 +29,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "prefs.h"
@ -64,6 +66,9 @@ static uint32 rd_pos; // Current read position in packet buffer
static uint32 wr_pos; // Current write position in packet buffer
static sem_id read_sem, write_sem; // Semaphores to trigger packet reading/writing
static int fd = -1; // UDP socket fd
static bool udp_tunnel = false;
// Prototypes
static status_t receive_proc(void *data);
@ -382,7 +387,7 @@ int16 ether_write(uint32 wds)
/*
* Packet reception thread
* Packet reception thread (non-UDP)
*/
static status_t receive_proc(void *data)
@ -399,6 +404,56 @@ static status_t receive_proc(void *data)
}
/*
* Packet reception thread (UDP)
*/
static status_t receive_proc_udp(void *data)
{
while (ether_thread_active) {
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if (select(fd+1, &readfds, NULL, NULL, &timeout) > 0) {
D(bug(" packet received, triggering Ethernet interrupt\n"));
SetInterruptFlag(INTFLAG_ETHER);
TriggerInterrupt();
}
}
return 0;
}
/*
* Start UDP packet reception thread
*/
bool ether_start_udp_thread(int socket_fd)
{
fd = socket_fd;
udp_tunnel = true;
ether_thread_active = true;
read_thread = spawn_thread(receive_proc_udp, "UDP Receiver", B_URGENT_DISPLAY_PRIORITY, NULL);
resume_thread(read_thread);
return true;
}
/*
* Stop UDP packet reception thread
*/
void ether_stop_udp_thread(void)
{
ether_thread_active = false;
status_t result;
wait_for_thread(read_thread, &result);
}
/*
* Ethernet interrupt - activate deferred tasks to call IODone or protocol handlers
*/
@ -407,46 +462,64 @@ void EtherInterrupt(void)
{
D(bug("EtherIRQ\n"));
// Call protocol handler for received packets
net_packet *p = &net_buffer_ptr->read[rd_pos];
while (p->cmd & IN_USE) {
if ((p->cmd >> 8) == SHEEP_PACKET) {
#if MONITOR
bug("Receiving Ethernet packet:\n");
for (int i=0; i<p->length; i++) {
bug("%02x ", p->data[i]);
}
bug("\n");
#endif
// Get packet type
uint16 type = ntohs(*(uint16 *)(p->data + 12));
if (udp_tunnel) {
// Look for protocol
NetProtocol *prot = find_protocol(type);
if (prot == NULL)
goto next;
uint8 packet[1514];
ssize_t length;
// No default handler
if (prot->handler == 0)
goto next;
// Copy header to RHA
Host2Mac_memcpy(ether_data + ed_RHA, p->data, 14);
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)));
// Call protocol handler
M68kRegisters r;
r.d[0] = type; // Packet type
r.d[1] = p->length - 14; // Remaining packet length (without header, for ReadPacket)
r.a[0] = (uint32)p->data + 14; // Pointer to packet (host address, for ReadPacket)
r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA
r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines
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]));
Execute68k(prot->handler, &r);
// Read packets from socket and hand to ether_udp_read() for processing
while (true) {
struct sockaddr_in from;
socklen_t from_len = sizeof(from);
length = recvfrom(fd, packet, 1514, 0, (struct sockaddr *)&from, &from_len);
if (length < 14)
break;
ether_udp_read(packet, length, &from);
}
} else {
// Call protocol handler for received packets
net_packet *p = &net_buffer_ptr->read[rd_pos];
while (p->cmd & IN_USE) {
if ((p->cmd >> 8) == SHEEP_PACKET) {
#if MONITOR
bug("Receiving Ethernet packet:\n");
for (int i=0; i<p->length; i++) {
bug("%02x ", p->data[i]);
}
bug("\n");
#endif
// Get packet type
uint16 type = ntohs(*(uint16 *)(p->data + 12));
// Look for protocol
NetProtocol *prot = find_protocol(type);
if (prot == NULL)
goto next;
// No default handler
if (prot->handler == 0)
goto next;
// Copy header to RHA
Host2Mac_memcpy(ether_data + ed_RHA, p->data, 14);
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)));
// Call protocol handler
M68kRegisters r;
r.d[0] = type; // Packet type
r.d[1] = p->length - 14; // Remaining packet length (without header, for ReadPacket)
r.a[0] = (uint32)p->data + 14; // Pointer to packet (host address, for ReadPacket)
r.a[3] = ether_data + ed_RHA + 14; // Pointer behind header in RHA
r.a[4] = ether_data + ed_ReadPacket; // Pointer to ReadPacket/ReadRest routines
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]));
Execute68k(prot->handler, &r);
}
next: p->cmd = 0; // Free packet
rd_pos = (rd_pos + 1) % READ_PACKET_COUNT;
p = &net_buffer_ptr->read[rd_pos];
}
next: p->cmd = 0; // Free packet
rd_pos = (rd_pos + 1) % READ_PACKET_COUNT;
p = &net_buffer_ptr->read[rd_pos];
}
D(bug(" EtherIRQ done\n"));
}

View File

@ -80,6 +80,7 @@ const uint32 MSG_NOSOUND = 'nosn';
const uint32 MSG_SER_A = 'sera'; // "Serial/Network" pane
const uint32 MSG_SER_B = 'serb';
const uint32 MSG_ETHER = 'ethr';
const uint32 MSG_UDPTUNNEL = 'udpt';
const uint32 MSG_RAMSIZE = 'rmsz'; // "Memory/Misc" pane
const uint32 MSG_MODELID_5 = 'mi05';
@ -221,6 +222,8 @@ private:
void read_volumes_prefs(void);
void hide_show_graphics_ctrls(void);
void read_graphics_prefs(void);
void hide_show_serial_ctrls(void);
void read_serial_prefs(void);
void add_serial_names(BPopUpMenu *menu, uint32 msg);
void read_memory_prefs(void);
@ -248,6 +251,8 @@ private:
BMenuField *scr_mode_menu;
BCheckBox *nosound_checkbox;
BCheckBox *ether_checkbox;
BCheckBox *udptunnel_checkbox;
NumberControl *udpport_ctrl;
RAMSlider *ramsize_slider;
PathControl *extfs_control;
PathControl *rom_control;
@ -593,9 +598,25 @@ BView *PrefsWindow::create_graphics_pane(void)
/*
* Create "Serial Ports" pane
* Create "Serial/Network" pane
*/
void PrefsWindow::hide_show_serial_ctrls(void)
{
if (udptunnel_checkbox->Value() == B_CONTROL_ON) {
ether_checkbox->SetEnabled(false);
udpport_ctrl->SetEnabled(true);
} else {
ether_checkbox->SetEnabled(true);
udpport_ctrl->SetEnabled(false);
}
}
void PrefsWindow::read_serial_prefs(void)
{
PrefsReplaceInt32("udpport", udpport_ctrl->Value());
}
void PrefsWindow::add_serial_names(BPopUpMenu *menu, uint32 msg)
{
BSerialPort *port = new BSerialPort;
@ -655,6 +676,14 @@ BView *PrefsWindow::create_serial_pane(void)
pane->AddChild(ether_checkbox);
ether_checkbox->SetValue(PrefsFindString("ether") ? B_CONTROL_ON : B_CONTROL_OFF);
udptunnel_checkbox = new BCheckBox(BRect(10, 67, right, 72), "udptunnel", GetString(STR_UDPTUNNEL_CTRL), new BMessage(MSG_UDPTUNNEL));
pane->AddChild(udptunnel_checkbox);
udptunnel_checkbox->SetValue(PrefsFindBool("udptunnel") ? B_CONTROL_ON : B_CONTROL_OFF);
udpport_ctrl = new NumberControl(BRect(10, 87, right / 2, 105), 118, "udpport", GetString(STR_UDPPORT_CTRL), PrefsFindInt32("udpport"), NULL);
pane->AddChild(udpport_ctrl);
hide_show_serial_ctrls();
return pane;
}
@ -938,6 +967,11 @@ void PrefsWindow::MessageReceived(BMessage *msg)
PrefsRemoveItem("ether");
break;
case MSG_UDPTUNNEL:
PrefsReplaceBool("udptunnel", udptunnel_checkbox->Value() == B_CONTROL_ON);
hide_show_serial_ctrls();
break;
case MSG_RAMSIZE:
PrefsReplaceInt32("ramsize", ramsize_slider->Value() * 1024 * 1024);
break;

View File

@ -49,6 +49,9 @@
// ExtFS is supported
#define SUPPORTS_EXTFS 1
// BSD socket API is supported
#define SUPPORTS_UDP_TUNNEL 1
// mon is not supported
#undef ENABLE_MON
@ -58,6 +61,10 @@ typedef bigtime_t tm_time_t;
// 64 bit file offsets
typedef off_t loff_t;
// Networking types
#define PF_INET AF_INET
typedef int socklen_t;
// UAE CPU data types
#define uae_s8 int8
#define uae_u8 uint8

View File

@ -28,6 +28,8 @@
* Technote FL 36: "Apple Extensions to ISO 9660"
*/
#include "sysdeps.h"
#include <string.h>
#include <vector>
@ -35,7 +37,6 @@
using std::vector;
#endif
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"

View File

@ -26,6 +26,8 @@
* Technote FL 24: "Don't Look at ioPosOffset for Devices"
*/
#include "sysdeps.h"
#include <string.h>
#include <vector>
@ -33,7 +35,6 @@
using std::vector;
#endif
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"

View File

@ -56,6 +56,13 @@ using std::map;
#define MONITOR 0
#ifdef __BEOS__
#define CLOSESOCKET closesocket
#else
#define CLOSESOCKET close
#endif
// Global variables
uint8 ether_addr[6]; // Ethernet address (set by ether_init())
static bool net_open = false; // Flag: initialization succeeded, network device open (set by EtherInit())
@ -101,7 +108,7 @@ void EtherInit(void)
sa.sin_port = htons(udp_port);
if (bind(udp_socket, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
perror("bind");
close(udp_socket);
CLOSESOCKET(udp_socket);
udp_socket = -1;
return;
}
@ -130,12 +137,16 @@ void EtherInit(void)
// Set socket options
int on = 1;
#ifdef __BEOS__
setsockopt(udp_socket, SOL_SOCKET, SO_NONBLOCK, &on, sizeof(on));
#else
setsockopt(udp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
ioctl(udp_socket, FIONBIO, &on);
#endif
// Start thread for packet reception
if (!ether_start_udp_thread(udp_socket)) {
close(udp_socket);
CLOSESOCKET(udp_socket);
udp_socket = -1;
return;
}
@ -159,7 +170,7 @@ void EtherExit(void)
if (udp_tunnel) {
if (udp_socket >= 0) {
ether_stop_udp_thread();
close(udp_socket);
CLOSESOCKET(udp_socket);
udp_socket = -1;
}
} else

View File

@ -28,6 +28,8 @@
* Technote FL 24: "Don't Look at ioPosOffset for Devices"
*/
#include "sysdeps.h"
#include <string.h>
#include <vector>
@ -35,7 +37,6 @@
using std::vector;
#endif
#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"