1
0
mirror of https://github.com/simh/simh.git synced 2026-03-26 02:05:36 +00:00
Files
simh.simh/Pcap-VMS/pcap-vci/eth_test.c
Bob Supnik f01115606a simh tools
2011-04-15 08:34:16 -07:00

279 lines
8.0 KiB
C

#include <ctype> /* Character type classification macros/routines */
#include <descrip> /* For VMS descriptor manipulation */
#include <iodef> /* I/O function code definitions */
#include <ssdef> /* System service return status code definitions */
#include <starlet> /* System library routine prototypes */
#include <stdio> /* ANSI C Standard Input/Output */
#include <stdlib> /* General utilities */
#include <string> /* String handling */
#include <stsdef> /* VMS status code definitions */
#include "nmadef.h" /* NMA stuff */
#define $SUCCESS(status) (((status) & STS$M_SUCCESS) == SS$_NORMAL)
#define $FAIL(status) (((status) & STS$M_SUCCESS) != SS$_NORMAL)
#pragma nomember_alignment
struct parm_802e
{
short pcli_fmt; /* Format - 802E */
int fmt_value;
short pcli_bfn;
int bnf_value;
// short pcli_acc;
// int acc_value;
short pcli_prm;
int prm_value;
short pcli_pid; /* Protocol ID - 08-00-2B-90-00 */
short pid_length;
unsigned char pid_value[5];
} setparm_802e = {
NMA$C_PCLI_FMT,
NMA$C_LINFM_802E,
NMA$C_PCLI_BFN,
255,
// NMA$C_PCLI_ACC,
// NMA$C_ACC_SHR,
NMA$C_PCLI_PRM,
NMA$C_STATE_ON,
NMA$C_PCLI_PID, 5, 8,0,0x2b,0x80,0x00
};
typedef struct _hdr {
unsigned char dsap;
unsigned char ssap;
unsigned char ctl;
unsigned char pid[5];
unsigned char da[6];
unsigned char sa[6];
unsigned char pty[2];
} hdr, *hdrPtr;
struct setparmdsc
{
int parm_len;
void *parm_buffer;
};
struct setparmdsc setparmdsc_loop = {sizeof(setparm_802e),&setparm_802e};
struct p5_param /* P5 Receive header buffer */
{
unsigned char da[6];
unsigned char sa[6];
char misc[20];
};
struct iosb /* IOSB structure */
{
short w_err; /* Completion Status */
short w_xfer_size; /* Transfer Size */
short w_addl; /* Additional status */
short w_misc; /* Miscellaneous */
};
struct ascid /* Device descriptor for assign */
{
short w_len;
short w_info;
char *a_string;
} devdsc = {4,0,"EWA0"};
struct iosb qio_iosb; /* IOSB structure */
struct p5_param rcv_param; /* Receive header structure */
struct p5_param xmt_param={ /* Transmit header structure */
0xCF,0,0,0,0,0}; /* Loopback Assistant Multicast Address */
char rcv_buffer[2048]; /* Receive buffer */
char xmt_buffer[20]={ /* Transmit buffer */
0,0, /* Skip count */
2,0, /* Forward request */
0,0,0,0,0,0, /* Forward address */
1,0, /* Reply request */
0,0};
char sense_buffer[512]; /* Sensemode buffer */
struct setparmdsc sensedsc_loop = {sizeof(sense_buffer),&sense_buffer};
/*
** Helper routines
*/
char *add_int_value(char *buf, short code, int value)
{
char *tmpptr = buf;
*tmpptr = code;
*tmpptr += 2;
*tmpptr = value;
*tmpptr += 4;
return tmpptr;
}
char *add_counted_value(char *buf, short code, short len, char *value)
{
char *tmpptr = buf;
*tmpptr = code;
*tmpptr += 2;
*tmpptr = len;
*tmpptr += 2;
memcpy(tmpptr,value,len);
return tmpptr;
}
int find_value(int buflen, char *buf, short code, char *retbuf)
{
int i = 0;
int item;
char *tmpbuf = buf;
int value;
int status = 0;
while (i < buflen) {
item = (tmpbuf[i] + (tmpbuf[i+1]<<8));
if (0x1000 & item) {
if ((item & 0xFFF) == code) {
memcpy(retbuf, &tmpbuf[i+4],6);
status = 1;
break;
}
i += (tmpbuf[i+2] + (tmpbuf[i+3]<<8)) + 4;
} else {
// A value, ours?
if ((item & 0xFFF) == code) {
// Yep, return it
memcpy(retbuf, &tmpbuf[i+2], 4);
status = 1;
break;
}
i += 6;
}
}
return status;
}
/*
* MAIN
*/
main(int argc, char *argv[])
{
int i, j; /* Scratch */
int chan; /* Channel assigned */
int status; /* Return status */
char phyaddr[6];
int val;
hdrPtr r_head;
/*
* Start a channel.
*/
status = sys$assign(&devdsc,&chan,0,0);
if ($FAIL(status)) exit(status);
status = sys$qiow(0,chan,IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP,&qio_iosb,0,0,0,
&setparmdsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on startup)\n",qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
/*
* Issue the SENSEMODE QIO to get our physical address for the loopback message.
*/
status = sys$qiow(0,chan,IO$_SENSEMODE|IO$M_CTRL,&qio_iosb,0,0,0,
&sensedsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on sensemode)\n",
qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
status = find_value(qio_iosb.w_xfer_size, sense_buffer,
NMA$C_PCLI_PHA, phyaddr);
/*
* Locate the PHA parameter in the SENSEMODE buffer and copy it into the
* LOOPBACK transmit message. The PHA parameter is a string parameter.
*/
j = 0;
while (j < sizeof(sense_buffer))
{
i = (sense_buffer[j] + (sense_buffer[j+1]<<8));
if (0x1000 & i)
{
if ((i & 0xFFF) == NMA$C_PCLI_PHA)
{
memcpy(&xmt_buffer[4],&sense_buffer[j+4],6);
break;
}
j += (sense_buffer[j+2] + (sense_buffer[j+3]<<8)) + 4;
}
else
{
j += 6; /* Skip over longword parameter */
}
}
/*
* Transmit the loopback message.
*/
status = sys$qiow(0,chan,IO$_WRITEVBLK,&qio_iosb,0,0,&xmt_buffer[0],
sizeof(xmt_buffer),0,0,&xmt_param,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status))
{
printf("IOSB addl status = %04X %04X (on transmit)\n",
qio_iosb.w_addl,qio_iosb.w_misc);
exit(status);
}
/*
* Look for a response. We use the NOW function modifier on the READ so that
* we don't hang here waiting forever if there is no response. If there is no
* response in 1000 receive attempts, we declare no response status.
*/
for (i=0;i<1000;i++)
{
// status = sys$qiow(0,chan,IO$_READVBLK|IO$M_NOW,&qio_iosb,0,0,&rcv_buffer[0],
status = sys$qiow(0,chan,IO$_READVBLK,&qio_iosb,0,0,&rcv_buffer[0],
sizeof(rcv_buffer),0,0,&rcv_param,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($SUCCESS(status)) {
printf("da %02x%02x%02x%02x%02x%02x, sa %02x%02x%02x%02x%02x%02x\n",
rcv_param.da[0],
rcv_param.da[1],
rcv_param.da[2],
rcv_param.da[3],
rcv_param.da[4],
rcv_param.da[5],
rcv_param.sa[0],
rcv_param.sa[1],
rcv_param.sa[2],
rcv_param.sa[3],
rcv_param.sa[4],
rcv_param.sa[5]);
} else {
printf("Error\n");
exit(status);
break;
}
}
if ($SUCCESS(status))
printf("Successful test\n");
else
printf("No response\n");
}