mirror of
https://github.com/Interlisp/maiko.git
synced 2026-01-27 20:27:45 +00:00
Maiko sources matching state as of 020102 prior to initial patching for Mac OSX
This commit is contained in:
720
src/dlpi.c
Executable file
720
src/dlpi.c
Executable file
@@ -0,0 +1,720 @@
|
||||
/* $Id: dlpi.c,v 1.3 2001/12/24 01:09:00 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved */
|
||||
static char *id = "$Id: dlpi.c,v 1.3 2001/12/24 01:09:00 sybalsky Exp $ Copyright (C) Venue";
|
||||
#ifndef lint
|
||||
static char *RCSid = "$Header: /disk/disk3/cvsroot/medley/src/dlpi.c,v 1.3 2001/12/24 01:09:00 sybalsky Exp $";
|
||||
#endif
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#ifdef USE_DLPI
|
||||
/*
|
||||
* dpli.c - routines for messing with the Data Link Provider Interface.
|
||||
*
|
||||
* The code in this module is based in large part (especially the dl*
|
||||
* routines) on the example code provided with the document "How to Use
|
||||
* DLPI", by Neal Nuckolls of Sun Internet Engineering. Gotta give credit
|
||||
* where credit is due. If it weren't for Neal's excellent document,
|
||||
* this module just plain wouldn't exist.
|
||||
*
|
||||
* David A. Curry
|
||||
* Purdue University
|
||||
* Engineering Computer Network
|
||||
* 1285 Electrical Engineering Building
|
||||
* West Lafayette, IN 47907-1285
|
||||
* davy@ecn.purdue.edu
|
||||
*
|
||||
* $Log: dlpi.c,v $
|
||||
* Revision 1.3 2001/12/24 01:09:00 sybalsky
|
||||
* past changes
|
||||
*
|
||||
* Revision 1.2 1999/01/03 02:06:54 sybalsky
|
||||
* Add ID comments / static to files for CVS use
|
||||
*
|
||||
* Revision 1.1.1.1 1998/12/17 05:03:20 sybalsky
|
||||
* Import of Medley 3.5 emulator
|
||||
*
|
||||
* Revision 4.1 1993/09/15 20:50:44 davy
|
||||
* GCC fixes from Guy Harris.
|
||||
*
|
||||
* Revision 4.1 1993/09/15 20:50:44 davy
|
||||
* GCC fixes from Guy Harris.
|
||||
*
|
||||
* Revision 4.0 1993/03/01 19:59:00 davy
|
||||
* NFSWATCH Version 4.0.
|
||||
*
|
||||
* Revision 1.5 1993/02/19 19:54:36 davy
|
||||
* Another change in hopes of making things work on SVR4.
|
||||
*
|
||||
* Revision 1.4 1993/01/26 13:19:05 davy
|
||||
* Fixed a goof in passing buffer size.
|
||||
*
|
||||
* Revision 1.3 1993/01/26 13:18:39 davy
|
||||
* Added ifdef's to make it work on DLPI 1.3.
|
||||
*
|
||||
* Revision 1.2 1993/01/15 19:33:39 davy
|
||||
* Miscellaneous cleanups.
|
||||
*
|
||||
* Revision 1.1 1993/01/15 15:42:32 davy
|
||||
* Initial revision
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/stropts.h>
|
||||
#include <sys/stream.h>
|
||||
#include <sys/dlpi.h>
|
||||
#ifdef OS5
|
||||
#include <sys/bufmod.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <net/if.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "nfswatch.h"
|
||||
#include "externs.h"
|
||||
|
||||
static void dlbindreq();
|
||||
static void dlinforeq();
|
||||
static void dlattachreq();
|
||||
static void dlpromisconreq();
|
||||
static void sigalrm();
|
||||
static int dlokack();
|
||||
static int dlinfoack();
|
||||
static int dlbindack();
|
||||
static int expecting();
|
||||
static int strgetmsg();
|
||||
static char *pname;
|
||||
|
||||
extern unsigned char ether_host[6];
|
||||
|
||||
int truncation = 1500;
|
||||
/*
|
||||
* setup_dlpi_dev - set up the data link provider interface.
|
||||
*/
|
||||
int
|
||||
setup_dlpi_dev(device)
|
||||
char *device;
|
||||
{
|
||||
char *p;
|
||||
u_int chunksz;
|
||||
char cbuf[BUFSIZ];
|
||||
struct ifconf ifc;
|
||||
struct ifreq *ifrp;
|
||||
struct strioctl si;
|
||||
char devname[BUFSIZ];
|
||||
int n, s, fd, devppa;
|
||||
struct timeval timeout;
|
||||
long buf[DLPI_MAXDLBUF];
|
||||
|
||||
/*
|
||||
* If the interface device was not specified,
|
||||
* get the default one.
|
||||
*/
|
||||
if ((device == NULL) || *device == NULL) {
|
||||
/*
|
||||
* Grab a socket.
|
||||
*/
|
||||
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
perror("socket");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ifc.ifc_buf = cbuf;
|
||||
ifc.ifc_len = sizeof(cbuf);
|
||||
|
||||
/*
|
||||
* See what devices we've got.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0) {
|
||||
perror("ioctl: SIOCGIFCONF");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Take the first device we encounter.
|
||||
*/
|
||||
ifrp = ifc.ifc_req;
|
||||
for (n = ifc.ifc_len/sizeof(struct ifreq); n > 0; n--,ifrp++) {
|
||||
/*
|
||||
* Skip the loopback interface.
|
||||
*/
|
||||
if (strcmp(ifrp->ifr_name, "lo0") == 0)
|
||||
continue;
|
||||
|
||||
device = savestr(ifrp->ifr_name);
|
||||
break;
|
||||
}
|
||||
|
||||
(void) close(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Split the device name into type and unit number.
|
||||
*/
|
||||
if ((p = strpbrk(device, "0123456789")) == NULL)
|
||||
return(-1);
|
||||
|
||||
strcpy(devname, DLPI_DEVDIR);
|
||||
strncat(devname, device, p - device);
|
||||
devppa = atoi(p);
|
||||
|
||||
/*
|
||||
* Open the device.
|
||||
*/
|
||||
if ((fd = open(devname, O_RDWR)) < 0) {
|
||||
if (errno == ENOENT || errno == ENXIO)
|
||||
return(-1);
|
||||
|
||||
/*perror(devname);*/
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach to the device. If this fails, the device
|
||||
* does not exist.
|
||||
*/
|
||||
dlattachreq(fd, devppa);
|
||||
|
||||
if (dlokack(fd, buf) < 0) {
|
||||
close(fd);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Bind to the specific unit.
|
||||
*/
|
||||
dlbindreq(fd, 0x0600 , 0, DL_CLDLS, 0, 0);
|
||||
|
||||
if (dlbindack(fd, buf) < 0) {
|
||||
fprintf(stderr, "%s: dlbindack failed.\n", pname);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#ifdef OS5
|
||||
/*
|
||||
* We really want all types of packets. However, the SVR4 DLPI does
|
||||
* not let you have the packet frame header, so we won't be able to
|
||||
* distinguish protocol types. But SunOS5 gives you the DLIOCRAW
|
||||
* ioctl to get the frame headers, so we can do this on SunOS5.
|
||||
*/
|
||||
dlpromisconreq(fd, DL_PROMISC_SAP);
|
||||
|
||||
if (dlokack(fd, buf) < 0) {
|
||||
fprintf(stderr, "%s: DL_PROMISC_SAP failed.\n", pname);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
dlpromisconreq(fd, DL_PROMISC_MULTI);
|
||||
|
||||
if (dlokack(fd, buf) < 0) {
|
||||
fprintf(stderr, "%s: DL_PROMISC_MULTI failed.\n", pname);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* We want raw packets with the packet frame header. But we can
|
||||
* only get this in SunOS5 with the DLIOCRAW ioctl; it's not in
|
||||
* standard SVR4.
|
||||
*/
|
||||
si.ic_cmd = DLIOCRAW;
|
||||
si.ic_timout = -1;
|
||||
si.ic_len = 0;
|
||||
si.ic_dp = 0;
|
||||
|
||||
if (ioctl(fd, I_STR, &si) < 0) {
|
||||
perror("ioctl: I_STR DLIOCRAW");
|
||||
return(-1);
|
||||
}
|
||||
#endif /* OS5 */
|
||||
|
||||
/*
|
||||
* Arrange to get discrete messages.
|
||||
*/
|
||||
if (ioctl(fd, I_SRDOPT, (char *) RMSGD) < 0) {
|
||||
perror("ioctl: I_SRDOPT RMSGD");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
#ifdef OS5
|
||||
/*
|
||||
* Push and configure the streams buffering module. This is once
|
||||
* again SunOS-specific.
|
||||
*/
|
||||
#ifdef NEVER
|
||||
if (ioctl(fd, I_PUSH, DLPI_BUFMOD) < 0) {
|
||||
perror("ioctl: I_PUSH BUFMOD");
|
||||
return(-1);
|
||||
}
|
||||
/*
|
||||
* Set the read timeout.
|
||||
*/
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
si.ic_cmd = SBIOCSTIME;
|
||||
si.ic_timout = INFTIM;
|
||||
si.ic_len = sizeof(timeout);
|
||||
si.ic_dp = (char *) &timeout;
|
||||
|
||||
if (ioctl(fd, I_STR, (char *) &si) < 0) {
|
||||
perror("ioctl: I_STR SBIOCSTIME");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the chunk size.
|
||||
*/
|
||||
chunksz = DLPI_CHUNKSIZE;
|
||||
|
||||
si.ic_cmd = SBIOCSCHUNK;
|
||||
si.ic_len = sizeof(chunksz);
|
||||
si.ic_dp = (char *) &chunksz;
|
||||
|
||||
if (ioctl(fd, I_STR, (char *) &si) < 0) {
|
||||
perror("ioctl: I_STR SBIOCSCHUNK");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set snapshot mode.
|
||||
*/
|
||||
si.ic_cmd = SBIOCSSNAP;
|
||||
si.ic_len = sizeof(truncation);
|
||||
si.ic_dp = (char *) &truncation;
|
||||
|
||||
if (ioctl(fd, I_STR, (char *) &si) < 0) {
|
||||
perror("ioctl: I_STR SBIOCSSNAP");
|
||||
return(-1);
|
||||
}
|
||||
#endif /* NEVER */
|
||||
|
||||
#endif /* OS5 */
|
||||
|
||||
return(fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* flush_dlpi - flush data from the dlpi.
|
||||
*/
|
||||
void
|
||||
flush_dlpi(fd)
|
||||
int fd;
|
||||
{
|
||||
if (ioctl(fd, I_FLUSH, (char *) FLUSHR) < 0) {
|
||||
perror("ioctl: I_FLUSH");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dlpi_devtype - determine the type of device we're looking at.
|
||||
*/
|
||||
int
|
||||
dlpi_devtype(fd)
|
||||
int fd;
|
||||
{
|
||||
long buf[DLPI_MAXDLBUF];
|
||||
union DL_primitives *dlp;
|
||||
|
||||
dlp = (union DL_primitives *) buf;
|
||||
|
||||
dlinforeq(fd);
|
||||
|
||||
if (dlinfoack(fd, buf) < 0)
|
||||
return(DLT_EN10MB);
|
||||
|
||||
bcopy((char *)dlp+dlp->info_ack.dl_addr_offset, ether_host, 6);
|
||||
|
||||
switch (dlp->info_ack.dl_mac_type) {
|
||||
case DL_CSMACD:
|
||||
case DL_ETHER:
|
||||
return(DLT_EN10MB);
|
||||
#ifdef DL_FDDI
|
||||
case DL_FDDI:
|
||||
return(DLT_FDDI);
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr, "%s: DLPI MACtype %d unknown, ", pname,
|
||||
dlp->info_ack.dl_mac_type);
|
||||
fprintf(stderr, "assuming ethernet.\n");
|
||||
return(DLT_EN10MB);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dlinforeq - request information about the data link provider.
|
||||
*/
|
||||
static void
|
||||
dlinforeq(fd)
|
||||
int fd;
|
||||
{
|
||||
dl_info_req_t info_req;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
|
||||
info_req.dl_primitive = DL_INFO_REQ;
|
||||
|
||||
ctl.maxlen = 0;
|
||||
ctl.len = sizeof (info_req);
|
||||
ctl.buf = (char *) &info_req;
|
||||
|
||||
flags = RS_HIPRI;
|
||||
|
||||
if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {
|
||||
perror("putmsg");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dlattachreq - send a request to attach.
|
||||
*/
|
||||
static void
|
||||
dlattachreq(fd, ppa)
|
||||
u_long ppa;
|
||||
int fd;
|
||||
{
|
||||
dl_attach_req_t attach_req;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
|
||||
attach_req.dl_primitive = DL_ATTACH_REQ;
|
||||
attach_req.dl_ppa = ppa;
|
||||
|
||||
ctl.maxlen = 0;
|
||||
ctl.len = sizeof (attach_req);
|
||||
ctl.buf = (char *) &attach_req;
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) {
|
||||
perror("putmsg");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DL_PROMISCON_REQ
|
||||
/*
|
||||
* dlpromisconreq - send a request to turn promiscuous mode on.
|
||||
*/
|
||||
static void
|
||||
dlpromisconreq(fd, level)
|
||||
u_long level;
|
||||
int fd;
|
||||
{
|
||||
dl_promiscon_req_t promiscon_req;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
|
||||
promiscon_req.dl_primitive = DL_PROMISCON_REQ;
|
||||
promiscon_req.dl_level = level;
|
||||
|
||||
ctl.maxlen = 0;
|
||||
ctl.len = sizeof (promiscon_req);
|
||||
ctl.buf = (char *) &promiscon_req;
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) {
|
||||
perror("putmsg");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* DL_PROMISCON_REQ */
|
||||
|
||||
/*
|
||||
* dlbindreq - send a request to bind.
|
||||
*/
|
||||
static void
|
||||
dlbindreq(fd, sap, max_conind, service_mode, conn_mgmt, xidtest)
|
||||
u_long sap, max_conind, service_mode, conn_mgmt, xidtest;
|
||||
int fd;
|
||||
{
|
||||
dl_bind_req_t bind_req;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
|
||||
bind_req.dl_primitive = DL_BIND_REQ;
|
||||
bind_req.dl_sap = sap;
|
||||
bind_req.dl_max_conind = max_conind;
|
||||
bind_req.dl_service_mode = service_mode;
|
||||
bind_req.dl_conn_mgmt = conn_mgmt;
|
||||
#ifdef DL_PROMISC_PHYS
|
||||
/*
|
||||
* DLPI 2.0 only?
|
||||
*/
|
||||
bind_req.dl_xidtest_flg = xidtest;
|
||||
#endif
|
||||
|
||||
ctl.maxlen = 0;
|
||||
ctl.len = sizeof (bind_req);
|
||||
ctl.buf = (char *) &bind_req;
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (putmsg(fd, &ctl, (struct strbuf*) NULL, flags) < 0) {
|
||||
perror("putmsg");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dlokack - general acknowledgement reception.
|
||||
*/
|
||||
static int
|
||||
dlokack(fd, bufp)
|
||||
char *bufp;
|
||||
int fd;
|
||||
{
|
||||
union DL_primitives *dlp;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
|
||||
ctl.maxlen = DLPI_MAXDLBUF;
|
||||
ctl.len = 0;
|
||||
ctl.buf = bufp;
|
||||
|
||||
if (strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlokack") < 0)
|
||||
return(-1);
|
||||
|
||||
dlp = (union DL_primitives *) ctl.buf;
|
||||
|
||||
if (expecting(DL_OK_ACK, dlp) < 0)
|
||||
return(-1);
|
||||
|
||||
if (ctl.len < sizeof (dl_ok_ack_t))
|
||||
return(-1);
|
||||
|
||||
if (flags != RS_HIPRI)
|
||||
return(-1);
|
||||
|
||||
if (ctl.len < sizeof (dl_ok_ack_t))
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* dlinfoack - receive an ack to a dlinforeq.
|
||||
*/
|
||||
static int
|
||||
dlinfoack(fd, bufp)
|
||||
char *bufp;
|
||||
int fd;
|
||||
{
|
||||
union DL_primitives *dlp;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
|
||||
ctl.maxlen = DLPI_MAXDLBUF;
|
||||
ctl.len = 0;
|
||||
ctl.buf = bufp;
|
||||
|
||||
if (strgetmsg(fd, &ctl, (struct strbuf *)NULL, &flags, "dlinfoack") < 0)
|
||||
return(-1);
|
||||
|
||||
dlp = (union DL_primitives *) ctl.buf;
|
||||
|
||||
if (expecting(DL_INFO_ACK, dlp) < 0)
|
||||
return(-1);
|
||||
|
||||
if (ctl.len < sizeof (dl_info_ack_t))
|
||||
return(-1);
|
||||
|
||||
if (flags != RS_HIPRI)
|
||||
return(-1);
|
||||
|
||||
if (ctl.len < sizeof (dl_info_ack_t))
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* dlbindack - receive an ack to a dlbindreq.
|
||||
*/
|
||||
static int
|
||||
dlbindack(fd, bufp)
|
||||
char *bufp;
|
||||
int fd;
|
||||
{
|
||||
union DL_primitives *dlp;
|
||||
struct strbuf ctl;
|
||||
int flags;
|
||||
|
||||
ctl.maxlen = DLPI_MAXDLBUF;
|
||||
ctl.len = 0;
|
||||
ctl.buf = bufp;
|
||||
|
||||
if (strgetmsg(fd, &ctl, (struct strbuf*)NULL, &flags, "dlbindack") < 0)
|
||||
return(-1);
|
||||
|
||||
dlp = (union DL_primitives *) ctl.buf;
|
||||
|
||||
if (expecting(DL_BIND_ACK, dlp) < 0)
|
||||
return(-1);
|
||||
|
||||
if (flags != RS_HIPRI)
|
||||
return(-1);
|
||||
|
||||
if (ctl.len < sizeof (dl_bind_ack_t))
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* expecting - see if we got what we wanted.
|
||||
*/
|
||||
static int
|
||||
expecting(prim, dlp)
|
||||
union DL_primitives *dlp;
|
||||
int prim;
|
||||
{
|
||||
if (dlp->dl_primitive != (u_long)prim)
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* strgetmsg - get a message from a stream, with timeout.
|
||||
*/
|
||||
static int
|
||||
strgetmsg(fd, ctlp, datap, flagsp, caller)
|
||||
struct strbuf *ctlp, *datap;
|
||||
char *caller;
|
||||
int *flagsp;
|
||||
int fd;
|
||||
{
|
||||
int rc;
|
||||
void sigalrm();
|
||||
|
||||
/*
|
||||
* Start timer.
|
||||
*/
|
||||
(void) sigset(SIGALRM, sigalrm);
|
||||
|
||||
if (alarm(DLPI_MAXWAIT) < 0) {
|
||||
perror("alarm");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set flags argument and issue getmsg().
|
||||
*/
|
||||
*flagsp = 0;
|
||||
if ((rc = getmsg(fd, ctlp, datap, flagsp)) < 0) {
|
||||
perror("getmsg");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop timer.
|
||||
*/
|
||||
if (alarm(0) < 0) {
|
||||
perror("alarm");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for MOREDATA and/or MORECTL.
|
||||
*/
|
||||
if ((rc & (MORECTL | MOREDATA)) == (MORECTL | MOREDATA))
|
||||
return(-1);
|
||||
if (rc & MORECTL)
|
||||
return(-1);
|
||||
if (rc & MOREDATA)
|
||||
return(-1);
|
||||
|
||||
/*
|
||||
* Check for at least sizeof (long) control data portion.
|
||||
*/
|
||||
if (ctlp->len < sizeof (long))
|
||||
return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* sigalrm - handle alarms.
|
||||
*/
|
||||
static void
|
||||
sigalrm()
|
||||
{
|
||||
(void) fprintf(stderr, "dlpi: timeout\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* savestr - save string in dynamic memory.
|
||||
*/
|
||||
char *
|
||||
savestr(s)
|
||||
char *s;
|
||||
{
|
||||
char *t;
|
||||
char *malloc();
|
||||
|
||||
if ((t = malloc(strlen(s) + 1)) == NULL) {
|
||||
(void) fprintf(stderr, "%s: out of memory.\n", pname);
|
||||
(void) exit(1);
|
||||
}
|
||||
|
||||
(void) strcpy(t, s);
|
||||
|
||||
return(t);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
dlunitdatareq(fd, addrp, addrlen, minpri, maxpri, datap, datalen)
|
||||
int fd;
|
||||
u_char *addrp;
|
||||
int addrlen;
|
||||
u_long minpri, maxpri;
|
||||
u_char *datap;
|
||||
int datalen;
|
||||
{
|
||||
long buf[DLPI_MAXDLBUF];
|
||||
union DL_primitives *dlp;
|
||||
struct strbuf data, ctl;
|
||||
|
||||
dlp = (union DL_primitives*) buf;
|
||||
|
||||
dlp->unitdata_req.dl_primitive = DL_UNITDATA_REQ;
|
||||
dlp->unitdata_req.dl_dest_addr_length = addrlen+2;
|
||||
dlp->unitdata_req.dl_dest_addr_offset = sizeof (dl_unitdata_req_t);
|
||||
dlp->unitdata_req.dl_priority.dl_min = minpri;
|
||||
dlp->unitdata_req.dl_priority.dl_max = maxpri;
|
||||
|
||||
(void) memcpy(OFFADDR(dlp, sizeof (dl_unitdata_req_t)), addrp, addrlen);
|
||||
(void) memcpy(OFFADDR(dlp, sizeof (dl_unitdata_req_t)+addrlen), (char *)addrp + 12, 2);
|
||||
|
||||
ctl.maxlen = 0;
|
||||
ctl.len = sizeof (dl_unitdata_req_t) + addrlen +2;
|
||||
ctl.buf = (char *) buf;
|
||||
|
||||
data.maxlen = 0;
|
||||
data.len = datalen;
|
||||
data.buf = (char *) datap;
|
||||
|
||||
#ifdef NEVER
|
||||
if (putmsg(fd, &ctl, &data, 0) < 0)
|
||||
#else
|
||||
if (putmsg(fd, (char *) NULL, &data, 0) < 0)
|
||||
#endif /* NEVER tst on 9/30/96 jds to see if raw out works */
|
||||
return -1; else return 0;
|
||||
}
|
||||
#endif /* USE_DLPI */
|
||||
|
||||
Reference in New Issue
Block a user