📄 net.c
字号:
}
/* Put packet onto network, given length */
WORD put_net(GENFRAME *gfp, WORD len)
{
WORD dtype;
SNAPFRAME *sfp;
LWORD mstim;
#if TXDROP
if (++txfcount % TXDROP == 0)
{
printf(" Tx frame dropped for debug\n");
return(len);
}
#endif
dtype = gfp->g.dtype;
len = mini(len, getframe_maxlen(gfp)); /* Truncate if too big */
gfp->g.len = len;
if (dtype&DTYPE_SNAP && len+sizeof(SNAPHDR)<=MAXFRAME)
{ /* If 802.3 SNAP.. */
sfp = (SNAPFRAME *)gfp->buff; /* Make room for new header */
memmove(&sfp->s.ptype, &sfp->e.ptype, len);
len += sizeof(SNAPHDR); /* Set for 802.3 802.2 & SNAP */
sfp->e.ptype = swapw((WORD)(len-sizeof(ETHERHDR)));
sfp->s.lsap = 0xaaaa;
sfp->s.ctrl = 3;
memset(sfp->s.oui, 0, 3);
}
if (dtype & DTYPE_PKTD) /* If pkt drvr, send direct */
len = put_pktd(dtype, gfp->buff, len);
else if (dtype & DTYPE_ETHER) /* If an Ethernet frame.. */
{ /* ..check space in pkt buffer.. */
if (buff_freelen(&txpkts) >= len+sizeof(GENHDR))
buff_in(&txpkts, (BYTE *)gfp, (WORD)(len+sizeof(GENHDR)));
}
else if (dtype & DTYPE_SLIP) /* Send SLIP direct to driver */
len = put_slip(gfp->buff, len, dtype);
else
len = 0;
if (netdebug)
disp_frame(gfp, len, 1);
if (len>0 && logfile)
{
mstim = mstime();
fwrite("PUT ", 1, 4, logfile);
fwrite(&mstim, 1, 4, logfile);
fwrite(gfp, 1, gfp->g.len+sizeof(GENHDR), logfile);
}
return(len);
}
/* Poll the given network interface to keep it alive */
void poll_net(WORD dtype)
{
if (dtype & DTYPE_NE)
poll_etherne(dtype);
else if (dtype & DTYPE_3C)
poll_ether3c(dtype);
else if (dtype & DTYPE_SLIP)
receive_slip(dtype);
}
/* Rx upcall from network driver; store a received frame, return 0 if no room
** If buffer pointer is null, only check if the required space is available
** Beware: this function may be called by an interrupt handler */
WORD receive_upcall(WORD dtype, void *buff, WORD len)
{
static GENHDR gh; /* Static for BC 4.5 interrupts! */
len = minw(len, MAXFRAME); /* Truncate to max size */
if (len>0 && buff_freelen(&rxpkts) >= len+sizeof(GENHDR))
{ /* If space in circ buffer..*/
if (buff)
{
gh.len = len; /* Store general frame hdr */
gh.dtype = dtype;
buff_in(&rxpkts, (BYTE *)&gh, sizeof(gh));
buff_in(&rxpkts, buff, len); /* ..and frame */
}
}
else /* If no space, discard frame */
len = 0;
return(len);
}
/* Tx upcall from network driver; get frame for Tx, return len or 0 if none */
WORD transmit_upcall(WORD dtype, void *buff, WORD maxlen)
{
WORD len=0;
GENHDR gh;
if (buff_dlen(&txpkts) >=4)
{
buff_try(&txpkts, (BYTE *)&gh, sizeof(gh)); /* Check frame hdr */
len = minw(gh.len, maxlen); /* Truncate as necessary */
if (gh.dtype==dtype) /* If frame type matches..*/
{
buff_out(&txpkts, 0, sizeof(GENHDR)); /* ..remove hdr from buff */
buff_out(&txpkts, buff, len); /* .. and also the frame */
if (len < gh.len) /* .. discard overbytes */
buff_out(&txpkts, 0, (WORD)(gh.len-len));
}
else /* If wrong driver type */
{
buff_retry(&txpkts, sizeof(gh)); /* ..push header back */
len = 0;
}
}
return(len);
}
/* Open Ethernet hardware driver, given config string. Return frame type */
WORD open_etherne(char *str, WORD dtype)
{
char *s;
WORD addr;
/* Address value in hex */
addr = (WORD)strtoul(skippunct(str), &s, 16);
if (!addr || !init_etherne(dtype, addr))
dtype = 0;
return(dtype);
}
/* Open Ethernet hardware driver, given config string. Return frame type */
WORD open_ether3c(char *str, WORD dtype)
{
char *s;
WORD addr;
/* Address value in hex */
addr = (WORD)strtoul(skippunct(str), &s, 16);
if (!addr || !init_ether3c(dtype, addr))
dtype = 0;
return(dtype);
}
#if SLIP_SUPPORT
/* Initialise SLIP link */
WORD open_slip(char *str, WORD dtype)
{
int com, lite;
long baud;
char *s;
WORD ret=0;
selectuart(dtype & NETNUM_MASK);
lite = (strstr(str, "litelink") != 0);
if ((s = strstr(str, "com")) != 0)
{
com = (int)strtoul(s+3, &s, 10); /* COM port number */
baud = strtoul(skippunct(s), &s, 10); /* Initialise hardware.. */
if ((com>=1 || com<=9) && setuart(com, baud, 0))
{
ret = dtype;
if (lite)
litelink(baud);
}
}
return(ret);
}
/* Shut down SLIP link */
void close_slip(WORD dtype)
{
selectuart(dtype & NETNUM_MASK);
clearuart();
}
/* Get a packet from the SLIP link into Rx buffer, return frame count */
int receive_slip(WORD dtype)
{
WORD w;
static WORD lastw=0;
int count=0, chan;
static int modem=0;
BYTE *slipbuff;
selectuart(chan = dtype & NETNUM_MASK);
slipbuff = slipbuffs[chan];
while ((w = rxchar()) != NOCHAR) /* While Rx chars available.. */
{
if (lastw == SLIP_ESC) /* Last char was Escape? */
{
lastw = 0;
w = w==ESC_END ? SLIP_END : w==ESC_ESC ? SLIP_ESC : w;
}
else if (w == SLIP_ESC) /* This char is Escape? */
{
lastw = SLIP_ESC;
w = NOCHAR;
}
else if (w == SLIP_END) /* No escape; maybe End? */
{
w = NOCHAR;
if (sliplens[chan] > 0) /* Do upcall to save packet */
receive_upcall(dtype, slipbuff, sliplens[chan]);
sliplens[chan] = lastw = modem = 0;
count = 1;
}
if (sliplens[chan]==0 && !modem) /* If start of new message.. */
modem = (w=='A' || w=='+'); /* ..check if start of modem cmd */
if (w!=NOCHAR && modem) /* If in modem mode.. */
do_modem((char)w); /* ..send char to modem handler */
else if (w!=NOCHAR && sliplens[chan]<MAXSLIP) /* Save in SLIP buff */
slipbuff[sliplens[chan]++] = (BYTE)w; /* ..if no overflow! */
}
return(count);
}
/* Send packet out of the SLIP link, return zero if failed */
WORD put_slip(BYTE *pack, WORD len, WORD dtype)
{
int n;
n = len;
selectuart(dtype & NETNUM_MASK);
txchar(SLIP_END); /* Start with End */
while (n--) /* (to clear modem line noise) */
{
if (*pack == SLIP_END) /* Trap End code */
{
txchar(SLIP_ESC);
txchar(ESC_END);
}
else if (*pack == SLIP_ESC) /* ..and Escape code */
{
txchar(SLIP_ESC);
txchar(ESC_ESC);
}
else /* Default; just send char */
txchar(*pack);
pack++;
}
txchar(SLIP_END); /* End with End */
return(len);
}
/* Handle incoming modem command character */
void do_modem(char c)
{
static char cmds[41];
static int cmdlen=0;
if (c=='\r' || (cmdlen==3 && cmds[0]=='+'))
{
cmds[cmdlen] = 0;
if (netdebug)
printf("Modem command: %s\n", cmds);
txstr("OK\r\n");
if (cmds[2] == 'D')
txstr("CONNECT\r\n");
cmdlen = 0;
}
else if (cmdlen<sizeof(cmds)-1)
cmds[cmdlen++] = c;
}
#endif // if SLIP_SUPPORT
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -