home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 3
/
PDCD_3.iso
/
internet
/
netlite
/
NET
/
c
/
ETHERNET
< prev
next >
Wrap
Text File
|
1993-04-26
|
4KB
|
166 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "werr.h"
#include "kernel.h"
#include "global.h"
#include "mbuf.h"
#include "internet.h"
#include "iface.h"
#include "cmdparse.h"
#include "misc.h"
#include "ethernet.h"
#include "arc.h"
#include "os.h"
#include "swis.h"
#include "timer.h"
#include "ip.h"
struct ether ether[ETHER_MAX];
unsigned int nether;
extern struct interface *ifaces;
extern char nospace[];
static int ether_init(int16, struct interface *, int);
static int ether_stop(struct interface *);
static int ether_send(struct mbuf *, struct interface *, int32, int, int, int, int);
static int ether_recv(struct interface *);
/* Attach an ethernet interface to the system
* argv[0]: hardware type, must be "ether"
* argv[1]: port number
* argv[2]: interface label, e.g., "et0"
* argv[3]: maximum transmission unit, bytes
*/
int ether_attach(int argc, char **argv)
{
struct interface *if_ether;
int16 dev;
argc = argc;
if (nether >= ETHER_MAX){
werr(1,"Too many ethernet controllers\n");
return -1;
}
dev = nether++;
/* Create interface structure and fill in details */
if_ether = (struct interface *)calloc(1,sizeof(struct interface));
if_ether->name = strdup(argv[2]);
if_ether->mtu = atoi(argv[3]);
if_ether->dev = dev;
if_ether->recv = ether_recv;
if_ether->stop = ether_stop;
if_ether->send = ether_send;
if_ether->raw = NULLFP;
if_ether->put = NULLFP;
if_ether->get = NULLFP;
if_ether->next = ifaces;
ifaces = if_ether;
ether_init(dev, if_ether, atoi(argv[1]));
return 0;
}
/* Initialize ether port "dev" */
static int ether_init(int16 dev, struct interface *iface, int port)
{
_kernel_swi_regs rin, rout;
ether[dev].iface = iface;
ether[dev].port = port;
rin.r[0] = port;
rin.r[1] = ip_addr;
_kernel_swi(ETHER_OPEN, &rin, &rout);
if (rout.r[1] != ETHER_ERR_OK)
{
werr(1, "Error %d when opening DCI driver", rout.r[1]);
return(0);
}
return(1);
}
static int ether_stop(struct interface *iface)
{
_kernel_swi_regs rin, rout;
rin.r[0] = ether[iface->dev].port;
_kernel_swi(ETHER_CLOSE, &rin, &rout);
return(0);
}
/* Send a packet to transmitter */
static int ether_send(struct mbuf *bp, struct interface *iface, int32 gateway, int precedence, int delay, int throughput, int reliability)
{
_kernel_swi_regs rin, rout;
char buffer[1500];
int size;
precedence = precedence;
delay = delay;
throughput = throughput;
reliability = reliability;
size = dqdata(bp, buffer, 1500);
rin.r[0] = ether[iface->dev].port;
rin.r[1] = (int)buffer;
rin.r[2] = size;
rin.r[3] = gateway;
_kernel_swi(ETHER_WRITE, &rin, &rout);
if (rout.r[3] != ETHER_ERR_OK)
{
werr(0, "Error %d when writing to DCI driver", rout.r[3]);
return(0);
}
return(0);
}
/* Receive characters from line
* Returns count of characters read
*/
static int ether_recv(struct interface *iface)
{
_kernel_swi_regs rin, rout;
struct mbuf *bp;
while (1)
{
if ((bp = alloc_mbuf(1500)) == NULLBUF) return(0);
rin.r[0] = ether[iface->dev].port;
rin.r[1] = (int)bp->data;
rin.r[2] = 1500;
_kernel_swi(ETHER_READ, &rin, &rout);
if (rout.r[4] != ETHER_ERR_OK)
{
werr(0, "Error %d when reading from DCI driver", rout.r[4]);
free_p(bp);
return(0);
}
if ((bp->cnt = rout.r[2]) == 0)
{
free_p(bp);
return(0);
}
ip_route(bp, rout.r[3]);
}
return(0);
}