home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1988 Dave Settle. All rights reserved.
- * Permission is granted to use, copy and modify this software, providing
- * that it is not sold for profit, and that this copyright notice is retained
- * in any copies of the source.
- */
- /*
- * eth.c: various useful routines to talk to the ethernet.
- */
- #include <sys/types.h>
- #include <sys/errno.h>
- #include <stdio.h>
-
- #include "ni.h"
-
- #define MINBUF 64 + 64 /* min 128 bytes data */
-
- char *panicstr; /* cause (if any) of a SIGTERM */
-
- /*
- * configure the 'ethernet' fd so that we appear as node 'thisnode'
- * Allocate 'nbufs' to cope with expected data.
- */
- configure(thisnode, nbufs, pid)
- char *thisnode;
- {
- if((ethernet = open("/dev/ni", 2)) == -1) {
- perror("/dev/ni");
- return(-1);
- }
- if(ioctl(ethernet, NIGETA, &port)) {
- perror("NIGETA");
- return(-1);
- }
- thisnode[NODE] = port.srcaddr[LSB];
- thisnode[PIDMSB] = (pid & 0xff00) >> 8;
- thisnode[PIDLSB] = pid & 0xff;
- #ifdef DEBUG
- printf("Running on node %s\n", ipaddr(port.srcaddr));
- #endif
- port.type = ETHERTYPE;
- if(nbufs) port.rcvq_sz = nbufs;
- port.rcvb_sz = (sizeof (struct request) + 3) & ~3;
- memcpy(port.srcaddr, thisnode, ETHERSIZE);
- port.protocol = PROTOCOL;
- if(ioctl(ethernet, NISETA, &port)) {
- perror("NISETA");
- return(-1);
- }
- #ifdef DEBUG
- printf("Port configured as node %s\n", ipaddr(thisnode));
- #endif
- memcpy(mynode, thisnode, ETHERSIZE);
- return(0);
- }
- /*
- * recv: receive a request from the ethernet
- * If it's a request to terminate, propagate a SIGTERM signal.
- * This means that users of this routine can decide on what action to take,
- * and also be sure that no TERMINATE packets will not be detected.
- */
- recv(r)
- register struct request *r;
- {
- if(read(ethernet, r, sizeof (struct request)) == -1) {
- r->r_type = UNDEFINED;
- r->r_size = 0;
- return(-1);
- }
- if(r->r_type == TERMINATE) {
- panicstr = r->r_data;
- skill(getpid(), SIGTERM);
- }
-
- return(0);
- }
- /*
- * send request to specified node
- */
- send(r, size, type, node)
- struct request *r;
- char *node;
- {
- int total, min = sizeof (EI_PORT) + 52;
- memcpy(r->r_port.srcaddr, mynode, ETHERSIZE);
- memcpy(r->r_port.destaddr, node, ETHERSIZE);
- memcpy(r->r_port.ptype, myprotocol, 2);
- r->r_type = type;
- r->r_size = size;
- total = sizeof (struct request) - ((sizeof r->r_data) - size);
- total = total > min ? total : min;
- if(write(ethernet, r, total) == -1) {
- perror("write error");
- printf("Packet: src %s ", ipaddr(r->r_port.srcaddr));
- printf("dest %s\n", ipaddr(r->r_port.destaddr));
- return(-1);
- }
- return(0);
- }
- /*
- * perror
- */
- extern char *sys_errlist[];
- extern int errno;
- extern int sys_nerr;
-
- char *ni_error[] = {
- "Bad network address",
- "Bad port configuration specification",
- "Port not configured",
- "Open failure - out of memory?",
- "HLP circuit failure",
- "HLP fault",
- "Port not available",
- "Network not available",
- "Driver fault",
- "Hardware failure",
- "Network fault",
- "Bad packet",
- "Device has been reset"
- };
-
- perror(msg)
- char *msg;
- {
- char *e;
- if((errno > 200) && (errno < 213)) e = ni_error[errno - 200];
- else e = sys_errlist[errno];
- fprintf(stderr, "%s: %s [%d]\n", msg, e, errno);
- }
- /*
- * used only with 'sdb'
- */
- dump(s)
- char *s;
- {
- printf("%s\n", ipaddr(s));
- }
- hostaddr(host)
- char *host;
- {
- FILE *map;
- char name[32];
- int id;
- if((map = fopen(MAP, "r")) == NULL) return(0);
- while(fscanf(map, "%s%x", name, &id) != EOF)
- if(!strcmp(name, host)) {
- fclose(map);
- return(id);
- }
- fclose(map);
- return(-1);
- }
- /*
- * skill: 'safe' kill. There's a bug somewhere when we kill proc 0 and log
- * everyone out. This is a wrokaround.
- */
- skill(proc, sig){
- if(proc < 1) {
- errno = EINVAL;
- return(-1);
- }
- return(kill(proc, sig));
- }
-
-