mirror of
https://github.com/Interlisp/maiko.git
synced 2026-05-02 06:36:04 +00:00
Dodo Nethub support (#445)
* added support for XNS networking via Dodo-Nethub
* NetHub connection now optional (only if -nh-host is given); released NetHub-related changes to 'ether.c' to the public domain
* Added file using-dodo-networking-with-maiko.md
Documentation for building and using the Dodo-networking addition to Maiko
* Added support for running Maiko unter cygwin/x86_64-x
* Migrate Addr68k/NativeAlignment{2,4} in Nethub code, move timer/async defines to platform.h
* added missing include <netinet/in.h> for FreeBSD
* updated 'compile-flags' with added flags
* splitted ether.c in 3 (_common, _sunos, _nethub)
* reworks/modifications for nbriggs' pull-request review comments
* addintional additions for nbriggs' pull-request review comments
* get the Lisp packet lengths with 'LispInt2CInt'
* renamed variables in dblwordsSwap to indicate it's about double-words
* fixed wrong preprocessor directive unnoticed by clang
* added networking choice option to cmake build, fix to printf warning
- for cmake specify the networking to use with -DMAIKO_NETWORK_TYPE=<type>
- with <type> one of: NONE, SUN_DLPI, SUN_NIT, NETHUB
- e.g.: cmake .. -DMAIKO_NETWORK_TYPE=NETHUB
* integrated improvement to sendPacket() proposed by nbriggs
* integrated fix for SIGBUS on 32-bit big-endian, provided by nbriggs
* MAIKO_ENABLE_ETHERNET should not be unconditionally set on Solaris systems
* Receiving an ethernet packet is an ether interrupt but not an i/o interrupt.
Co-authored-by: dev hawala <devhawala@x.y>
Co-authored-by: Nick Briggs <nicholas.h.briggs@gmail.com>
This commit is contained in:
598
src/ether_nethub.c
Normal file
598
src/ether_nethub.c
Normal file
@@ -0,0 +1,598 @@
|
||||
/*******************************************************************************/
|
||||
/* */
|
||||
/* Support for Dodo Nethub networking (see: https://github.com/devhawala/dodo) */
|
||||
/* */
|
||||
/* Copyright (c) 2022, Dr. Hans-Walter Latz. All rights reserved. */
|
||||
/* Released to the Public Domain. */
|
||||
/* */
|
||||
/*******************************************************************************/
|
||||
|
||||
#if defined(MAIKO_ENABLE_NETHUB) && !defined(MAIKO_ENABLE_ETHERNET)
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/poll.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "commondefs.h"
|
||||
#include "lispemul.h"
|
||||
#include "lispmap.h"
|
||||
#include "emlglob.h"
|
||||
#include "lsptypes.h"
|
||||
#include "lspglob.h"
|
||||
#include "adr68k.h"
|
||||
#include "ether.h"
|
||||
#include "dbprint.h"
|
||||
#include "etherdefs.h"
|
||||
#include "ifpage.h"
|
||||
#include "iopage.h"
|
||||
#include "byteswapdefs.h"
|
||||
#include "dbprint.h"
|
||||
#include "timerdefs.h"
|
||||
#include "lisp2cdefs.h"
|
||||
|
||||
/*
|
||||
** --- ether implementation common data -------------------------------------------
|
||||
*/
|
||||
|
||||
extern int ether_fd; /* file descriptor for ether socket */
|
||||
extern u_char ether_host[6]; /* 48 bit address of this node */
|
||||
extern u_char broadcast[6];
|
||||
extern int ether_bsize; /* if nonzero then a receive is pending */
|
||||
extern u_char *ether_buf; /* address of receive buffer */
|
||||
extern LispPTR *PENDINGINTERRUPT68k;
|
||||
extern fd_set LispReadFds;
|
||||
|
||||
extern int ETHEREventCount;
|
||||
|
||||
/*
|
||||
** --- nethub configuration data --------------------------------------------------
|
||||
*/
|
||||
|
||||
static char* nethubHost = NULL;
|
||||
static int nethubPort = 3333;
|
||||
static int mac0 = 0xCA;
|
||||
static int mac1 = 0xFF;
|
||||
static int mac2 = 0xEE;
|
||||
static int mac3 = 0x12;
|
||||
static int mac4 = 0x34;
|
||||
static int mac5 = 0x56;
|
||||
|
||||
void setNethubHost(char* host) {
|
||||
if (host && *host) {
|
||||
nethubHost = host;
|
||||
DBPRINT(("nh :: host now: '%s'\n", nethubHost));
|
||||
}
|
||||
}
|
||||
|
||||
void setNethubPort(int port) {
|
||||
if (port > 0 && port <= 65535) {
|
||||
nethubPort = port;
|
||||
DBPRINT(("nh :: port now: %d\n", nethubPort));
|
||||
}
|
||||
}
|
||||
|
||||
void setNethubMac(int m0, int m1, int m2, int m3, int m4, int m5) {
|
||||
if ( m0 >= 0 && m0 <= 255
|
||||
&& m1 >= 0 && m1 <= 255
|
||||
&& m2 >= 0 && m2 <= 255
|
||||
&& m3 >= 0 && m3 <= 255
|
||||
&& m4 >= 0 && m4 <= 255
|
||||
&& m5 >= 0 && m5 <= 255) {
|
||||
mac0 = m0;
|
||||
mac1 = m1;
|
||||
mac2 = m2;
|
||||
mac3 = m3;
|
||||
mac4 = m4;
|
||||
mac5 = m5;
|
||||
DBPRINT(("nh :: mac now: %02X-%02X-%02X-%02X-%02X-%02X\n", mac0, mac1, mac2, mac3, mac4, mac5));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** --- very simple logging --------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int loglevel = 0;
|
||||
static int logcnt = 0;
|
||||
|
||||
void setNethubLogLevel(int ll) {
|
||||
loglevel = ll;
|
||||
DBPRINT(("nh :: loglevel now: %d\n", loglevel));
|
||||
}
|
||||
|
||||
#define log_info(line) { if (loglevel == 1) \
|
||||
{ printf("nh-info[%d]: ", logcnt++); printf line; }}
|
||||
#define log_debug(line) { if (loglevel >= 2) \
|
||||
{ printf("nh-debug[%d]: ", logcnt++); printf line; }}
|
||||
#define log_all(line) { if (loglevel < 1) \
|
||||
{ printf("nh[%d]: ", logcnt++); printf line; }}
|
||||
|
||||
/*
|
||||
** --- utilities ------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define LONG_PTR_MASK ((long)(~((long)3)))
|
||||
|
||||
static void dblwordsSwap(u_char* basePtr, int forBytes) {
|
||||
u_char* dblwordPtr = (u_char*)((long)basePtr & LONG_PTR_MASK);
|
||||
int neededBytes = forBytes + (basePtr - dblwordPtr);
|
||||
int dblwordCount = (neededBytes + 3) / 4;
|
||||
word_swap_page((unsigned short*)dblwordPtr, dblwordCount);
|
||||
}
|
||||
|
||||
/*
|
||||
** --- connect, disconnect and transmit packets -----------------------------------
|
||||
*/
|
||||
|
||||
void connectToHub() {
|
||||
if (nethubHost == NULL) {
|
||||
return;
|
||||
}
|
||||
if (ether_fd > -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug(("connectToHub() - begin\n"));
|
||||
|
||||
ether_host[0] = mac0;
|
||||
ether_host[1] = mac1;
|
||||
ether_host[2] = mac2;
|
||||
ether_host[3] = mac3;
|
||||
ether_host[4] = mac4;
|
||||
ether_host[5] = mac5;
|
||||
|
||||
log_debug((" resolving nethub hostname\n"));
|
||||
|
||||
struct hostent *host = gethostbyname(nethubHost);
|
||||
if (host == NULL || host->h_addr_list == NULL) {
|
||||
log_debug(("connectToHub(): hostname '%s' cannot be resolved\n", nethubHost));
|
||||
log_info(("connectToHub(): hostname '%s' cannot be resolved\n", nethubHost));
|
||||
log_all(("connectToHub(): hostname '%s' cannot be resolved\n", nethubHost));
|
||||
return;
|
||||
}
|
||||
|
||||
log_debug((" connecting to nethub\n"));
|
||||
|
||||
struct sockaddr_in hubaddr;
|
||||
hubaddr.sin_family = AF_INET;
|
||||
hubaddr.sin_addr.s_addr = *(in_addr_t *)host->h_addr_list[0];
|
||||
hubaddr.sin_port = htons(nethubPort);
|
||||
|
||||
ether_fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (ether_fd < 0) {
|
||||
log_info(("connectToHub(): FAILED to create AF_INET/SOCK_STREAM socket\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (connect(ether_fd, (struct sockaddr*)&hubaddr, sizeof(hubaddr)) < 0) {
|
||||
perror("connectToHub() - connect failed");
|
||||
close(ether_fd);
|
||||
ether_fd = -1;
|
||||
log_info(("connectToHub(): FAILED to connect to nethub\n"));
|
||||
return;
|
||||
}
|
||||
log_debug((" connected to nethub, ether_fd = %d\n", ether_fd));
|
||||
|
||||
FD_SET(ether_fd, &LispReadFds);
|
||||
log_debug((" added ether_fd to LispReadFds\n"));
|
||||
|
||||
log_debug(("connectToHub() - end\n\n"));
|
||||
log_info(("connectToHub() - connected to nethub\n"));
|
||||
log_all(("connectToHub() - connected to nethub\n"));
|
||||
}
|
||||
|
||||
static void disconnectFromHub() {
|
||||
if (ether_fd > -1) {
|
||||
close(ether_fd);
|
||||
ether_fd = -1;
|
||||
log_debug(("disconnectFromHub() - disconnected from nethub\n"));
|
||||
log_info(("disconnectFromHub() - disconnected from nethub\n"));
|
||||
log_all(("disconnectFromHub() - disconnected from nethub\n"));
|
||||
}
|
||||
}
|
||||
|
||||
/* buffering for multipe packets:
|
||||
** if interrupts are'nt processed fast enough, recv() may deliver >1 packets at once
|
||||
*/
|
||||
static u_char multiBuffer[65536]; /* should be enough for > 100 IDP packets with ~ 600 bytes */
|
||||
static u_char* nextPacket = NULL;
|
||||
static u_char* rcvBuffer = multiBuffer;
|
||||
static int rcvLen = 0;
|
||||
|
||||
/* -1: failed/not connected, 0: no packet available, > 0: received byte count */
|
||||
static int recvPacket() {
|
||||
if (ether_fd < 0) {
|
||||
log_debug((" recvPacket() :: not connected to hub !!!\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ether_bsize < 1) {
|
||||
log_debug((" recvPacket() :: no receive buffer present -> return 0\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (nextPacket == NULL) {
|
||||
|
||||
/* try to get the next packet(s) from network */
|
||||
rcvLen = recv(ether_fd, multiBuffer, sizeof(multiBuffer), MSG_DONTWAIT);
|
||||
if (rcvLen < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
perror("recvPacket() :: recv(ether_fd, rcvBuffer, sizeof(rcvBuffer), MSG_DONTWAIT)");
|
||||
disconnectFromHub();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rcvLen <= 0) {
|
||||
log_debug((" recvPacket() :: no network packet available -> return 0\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
rcvBuffer = multiBuffer;
|
||||
|
||||
} else {
|
||||
|
||||
/* move to next packet in multi packet buffer */
|
||||
rcvBuffer = nextPacket;
|
||||
|
||||
}
|
||||
nextPacket = NULL;
|
||||
|
||||
int bLen = ((rcvBuffer[0] << 8) & 0xFF00) | (rcvBuffer[1] & 0x00FF);
|
||||
log_debug((" recvPacket() :: received %d bytes, logical packet length = %d bytes\n", rcvLen, bLen));
|
||||
if (bLen & 0x0001) {
|
||||
log_debug(("recvPacket() ERROR :: odd byte byte length of logical packet -> disconnecting from nethub\n"));
|
||||
log_info(("recvPacket() ERROR :: odd byte byte length of logical packet -> disconnecting from nethub\n"));
|
||||
log_all(("recvPacket() ERROR :: odd byte byte length of logical packet -> disconnecting from nethub\n"));
|
||||
disconnectFromHub();
|
||||
return -1;
|
||||
}
|
||||
if (bLen > (rcvLen - 2)) {
|
||||
log_debug((" recvPacket() ERROR :: logical packet larger than packet -> disconnecting from nethub\n"));
|
||||
log_info(("recvPacket() ERROR :: logical packet larger than packet -> disconnecting from nethub\n"));
|
||||
log_all(("recvPacket() ERROR :: logical packet larger than packet -> disconnecting from nethub\n"));
|
||||
disconnectFromHub();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bLen < 14) {
|
||||
/* not even enough bytes for the ethernet header */
|
||||
/* -> discard packet */
|
||||
log_debug((" recvPacket() WARNING :: packet too small -> discard packet -> return 0\n"));
|
||||
log_info(("recvPacket() WARNING :: packet too small -> discard packet -> return 0\n"));
|
||||
log_all(("recvPacket() WARNING :: packet too small -> discard packet -> return 0\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((bLen + 2) != rcvLen) {
|
||||
log_debug((" recvPacket() ***** :: logical/physical length differ -> preserving next packet in multiBuffer\n"));
|
||||
log_info(("recvPacket() ***** :: logical/physical length differ -> preserving next packet in multiBuffer\n"));
|
||||
nextPacket = &rcvBuffer[bLen + 2];
|
||||
rcvLen -= bLen + 2;
|
||||
log_debug((" recvPacket() ***** :: next packet in multiBuffer at +%d , remaining length = %d\n",
|
||||
(int)(nextPacket - multiBuffer), rcvLen));
|
||||
log_info(("recvPacket() ***** :: next packet in multiBuffer at +%d , remaining length = %d\n",
|
||||
(int)(nextPacket - multiBuffer), rcvLen));
|
||||
}
|
||||
|
||||
if ( memcmp(&rcvBuffer[2], ether_host, 6) != 0
|
||||
&& memcmp(&rcvBuffer[2], broadcast, 6) != 0) {
|
||||
log_debug((" recvPacket() :: packet is not for us and not a broadcast, ignoring packet\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DLword copyLen = (bLen < ether_bsize) ? bLen : ether_bsize;
|
||||
|
||||
#if defined(BYTESWAP)
|
||||
log_debug((" recvPacket() :: byte-swap copying %d bytes to 0x%016lX\n", copyLen, (unsigned long)ether_buf));
|
||||
|
||||
dblwordsSwap(ether_buf, copyLen);
|
||||
memcpy(ether_buf, &rcvBuffer[2], copyLen);
|
||||
dblwordsSwap(ether_buf, copyLen);
|
||||
|
||||
#else
|
||||
log_debug((" recvPacket() :: copying %d bytes to 0x%016X\n", copyLen, (unsigned long)ether_buf));
|
||||
|
||||
memcpy(ether_buf, &rcvBuffer[2], copyLen);
|
||||
|
||||
#endif
|
||||
|
||||
ether_bsize = 0;
|
||||
|
||||
#if defined(BYTESWAP)
|
||||
log_debug((" recvPacket() :: IOPage->dlethernet[2] = 0x%04X (before)\n", IOPage->dlethernet[2]));
|
||||
|
||||
/* byte-order in IOPage->dlethernet[2] does not seem to matter ... boolean ? */
|
||||
IOPage->dlethernet[2] = copyLen;
|
||||
|
||||
log_debug((" recvPacket() :: IOPage->dlethernet[2] = 0x%04X (after)\n", IOPage->dlethernet[2]));
|
||||
#else
|
||||
|
||||
log_debug((" recvPacket() :: IOPage->dlethernet[3] = 0x%04X (before)\n", IOPage->dlethernet[3]));
|
||||
IOPage->dlethernet[3] = copyLen;
|
||||
log_debug((" recvPacket() :: IOPage->dlethernet[3] = 0x%04X (after)\n", IOPage->dlethernet[3]));
|
||||
|
||||
#endif
|
||||
|
||||
return copyLen;
|
||||
}
|
||||
|
||||
|
||||
/* -1: failed/not connected; >= 0: packet bytes sent */
|
||||
static int sendPacket(u_char *source, int sourceLen) {
|
||||
struct msghdr msg = {0};
|
||||
struct iovec iov[2];
|
||||
uint16_t nhlength;
|
||||
|
||||
if (ether_fd < 0) {
|
||||
log_debug((" sendPacket() :: not connected to hub !!!\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sourceLen < 14) {
|
||||
log_debug((" sendPacket() :: invalid packet length: %d !!!\n", sourceLen));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sourceLen & 0x0001) {
|
||||
log_debug((" sendPacket() :: packet length not even (mutiple of 2) !!!\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
nhlength = htons(sourceLen);
|
||||
iov[0].iov_base = &nhlength;
|
||||
iov[0].iov_len = 2;
|
||||
iov[1].iov_base = source;
|
||||
iov[1].iov_len = sourceLen;
|
||||
msg.msg_iov = iov;
|
||||
msg.msg_iovlen = 2;
|
||||
|
||||
int result = sendmsg(ether_fd, &msg, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
** --- SUBR implementations -------------------------------------------------------
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* e t h e r _ s u s p e n d */
|
||||
/* */
|
||||
/* Suspend receiving packets. */
|
||||
/* 175/70/0 */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
LispPTR ether_suspend(LispPTR args[])
|
||||
{
|
||||
if (nethubHost == NULL) {
|
||||
return (ATOM_T);
|
||||
}
|
||||
log_debug(("ether_suspend() -- ignored!\n\n"));
|
||||
log_info(("ether_suspend()\n"));
|
||||
return (ATOM_T);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* e t h e r _ r e s u m e */
|
||||
/* */
|
||||
/* resume nit socket to receive all types of packets 175/71/0 */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
LispPTR ether_resume(LispPTR args[])
|
||||
{
|
||||
if (nethubHost == NULL) {
|
||||
return (ATOM_T);
|
||||
}
|
||||
log_debug(("ether_resume() - begin\n"));
|
||||
int_io_open(ether_fd);
|
||||
log_debug(("ether_resume() - end\n\n"));
|
||||
log_info(("ether_resume()\n"));
|
||||
return (ATOM_T);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* e t h e r _ c t r l r */
|
||||
/* */
|
||||
/* return T if ether controller is available 175/72/0 */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
LispPTR ether_ctrlr(LispPTR args[])
|
||||
{
|
||||
if (nethubHost == NULL) {
|
||||
return (NIL);
|
||||
}
|
||||
log_debug(("ether_ctrlr() - begin\n"));
|
||||
|
||||
connectToHub();
|
||||
|
||||
if (ether_fd < 0) {
|
||||
log_debug(("ether_ctrlr() - end -> NIL\n\n"));
|
||||
log_info(("ether_ctrlr() -> NIL\n"));
|
||||
return (NIL);
|
||||
} else {
|
||||
int_io_open(ether_fd);
|
||||
log_debug(("ether_ctrlr() - end -> ATOM_T\n\n"));
|
||||
log_info(("ether_ctrlr() -> ATOM_T\n"));
|
||||
return (ATOM_T);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* ether_reset(args) 175/73/0
|
||||
* reset ether controller and disable receipt of packets
|
||||
**********************************************************************/
|
||||
LispPTR ether_reset(LispPTR args[])
|
||||
{
|
||||
if (nethubHost == NULL) {
|
||||
return (NIL);
|
||||
}
|
||||
log_debug(("ether_reset() - begin\n"));
|
||||
|
||||
if (ether_fd < 0) {
|
||||
log_debug(("ether_reset() - end -> NIL\n\n"));
|
||||
log_info(("ether_reset() -> NIL\n"));
|
||||
return (NIL);
|
||||
}
|
||||
ether_bsize = 0; /* deactivate receiver */
|
||||
log_debug(("ether_reset() - end -> ATOM_T\n\n"));
|
||||
log_info(("ether_reset() -> ATOM_T\n"));
|
||||
return (ATOM_T);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* e t h e r _ g e t (175/74/2) */
|
||||
/* */
|
||||
/* Set up the Ethernet driver to receive a packet. The driver */
|
||||
/* first tries to read any pending packet from the net, and if */
|
||||
/* there is one, ether_get returns T. If there is no pending */
|
||||
/* packet, the failing read sets us up to get an interrupt when */
|
||||
/* a packet DOES arrive, and ether_get returns NIL. */
|
||||
/* */
|
||||
/* args[0] Length of the buffer we're passed */
|
||||
/* args[1] LISP address of a packet buffer */
|
||||
/* */
|
||||
/* sets ether_buf to the buffer address, for check_ether's use */
|
||||
/* sets ether_bsize to the buffer size. ether_bsize>0 means */
|
||||
/* it's OK to read packets from the network on interrupt. */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
LispPTR ether_get(LispPTR args[])
|
||||
{
|
||||
if (nethubHost == NULL) {
|
||||
return (NIL);
|
||||
}
|
||||
log_debug(("ether_get() - begin\n"));
|
||||
|
||||
u_char *target = (u_char *)NativeAligned2FromLAddr(args[1]);
|
||||
int maxByteCount = 2 * LispIntToCInt(args[0]); /* words to bytes */
|
||||
log_debug((" target = 0x%016lX maxBytecount: %d bytes\n", (unsigned long)target, maxByteCount));
|
||||
|
||||
sigset_t signals;
|
||||
sigemptyset(&signals);
|
||||
sigaddset(&signals, SIGIO);
|
||||
sigprocmask(SIG_BLOCK, &signals, NULL);
|
||||
|
||||
ether_buf = target;
|
||||
ether_bsize = maxByteCount;
|
||||
|
||||
int receivedBytes = recvPacket();
|
||||
|
||||
sigprocmask(SIG_UNBLOCK, &signals, NULL);
|
||||
|
||||
log_debug(("ether_get() :: receivedBytes: %d bytes\n", receivedBytes));
|
||||
if (receivedBytes <= 0) {
|
||||
log_debug(("ether_get() - end -> NIL\n\n"));
|
||||
return (NIL);
|
||||
}
|
||||
|
||||
log_debug(("ether_get() - end -> ATOM_T\n\n"));
|
||||
log_info(("ether_get(): received packet, len = %d bytes\n", receivedBytes));
|
||||
return (ATOM_T);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* ether_send(args) 175/75/2 max_words,buffer_addr
|
||||
* send a packet
|
||||
**********************************************************************/
|
||||
LispPTR ether_send(LispPTR args[])
|
||||
{
|
||||
if (nethubHost == NULL) {
|
||||
return (NIL);
|
||||
}
|
||||
log_debug(("ether_send() - begin\n"));
|
||||
|
||||
u_char *source = (u_char *)NativeAligned2FromLAddr(args[1]);
|
||||
int byteCount = 2 * LispIntToCInt(args[0]); /* words to bytes */
|
||||
|
||||
log_debug((" source = 0x%08lX , bytecount: %d bytes\n", (unsigned long)source, byteCount));
|
||||
|
||||
#if defined(BYTESWAP)
|
||||
dblwordsSwap(source, byteCount);
|
||||
int bytesSent = sendPacket(source, byteCount);
|
||||
dblwordsSwap(source, byteCount);
|
||||
#else
|
||||
int bytesSent = sendPacket(source, byteCount);
|
||||
#endif
|
||||
|
||||
if (bytesSent < 0) {
|
||||
log_debug(("ether_send() - failed (bytesSent: %d bytes) -> NIL\n\n", bytesSent));
|
||||
log_info(("ether_send(): FAILED to send packet, len = %d\n", byteCount));
|
||||
return (NIL);
|
||||
}
|
||||
|
||||
log_debug(("ether_send() - end -> ATOM_T\n\n"));
|
||||
log_info(("ether_send(): sent packet, len = %d\n", bytesSent));
|
||||
return (ATOM_T);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* ether_setfilter(args) 175/76/1 filterbits
|
||||
* check whether a packet has come. if does, notify iocb
|
||||
**********************************************************************/
|
||||
LispPTR ether_setfilter(LispPTR args[])
|
||||
{
|
||||
log_debug(("ether_setfilter() - ????\n\n"));
|
||||
return (NIL);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* check_ether() 175/77/0
|
||||
* checks an incoming packet
|
||||
**********************************************************************/
|
||||
LispPTR check_ether()
|
||||
{
|
||||
LispPTR result = (NIL);
|
||||
|
||||
if (ether_fd < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
struct pollfd pfds[1];
|
||||
pfds[0].fd = ether_fd;
|
||||
pfds[0].events = POLLIN;
|
||||
pfds[0].revents = 0;
|
||||
poll(pfds, 1, 0);
|
||||
if (pfds[0].revents & POLLIN) {
|
||||
log_debug(("check_ether() - begin\n"));
|
||||
int receivedBytes = recvPacket();
|
||||
if (receivedBytes > 0) {
|
||||
((INTSTAT *)NativeAligned4FromLAddr(*INTERRUPTSTATE_word))->ETHERInterrupt = 1;
|
||||
ETHEREventCount++;
|
||||
Irq_Stk_Check = Irq_Stk_End = 0; /* ??? */
|
||||
*PENDINGINTERRUPT68k = (ATOM_T);
|
||||
log_debug(("check_ether() :: raised LISP interrupt\n"));
|
||||
log_debug(("check_ether() :: INTERRUPTSTATE_word = 0x%08X\n",
|
||||
*((int*)NativeAligned4FromLAddr(*INTERRUPTSTATE_word))));
|
||||
log_debug(("check_ether() :: PENDINGINTERRUPT_word = 0x%08X\n",
|
||||
*((int*)PENDINGINTERRUPT68k)));
|
||||
result = (ATOM_T);
|
||||
log_debug(("check_ether() - end -> ATOM_T\n\n"));
|
||||
log_info(("check_ether(): received packet, len = %d bytes\n", receivedBytes));
|
||||
} else {
|
||||
log_debug(("check_ether() - end -> NIL\n\n"));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* MAIKO_ENABLE_NETHUB */
|
||||
|
||||
Reference in New Issue
Block a user