home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / 3bconnect / eth.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-08  |  3.6 KB  |  166 lines

  1. /*
  2.  * Copyright (C) 1988 Dave Settle. All rights reserved.
  3.  * Permission is granted to use, copy and modify this software, providing
  4.  * that it is not sold for profit, and that this copyright notice is retained
  5.  * in any copies of the source.
  6.  */
  7. /*
  8.  * eth.c: various useful routines to talk to the ethernet.
  9.  */
  10. #include <sys/types.h> 
  11. #include <sys/errno.h>
  12. #include <stdio.h>
  13.  
  14. #include "ni.h"
  15.  
  16. #define MINBUF    64 + 64        /* min 128 bytes data */
  17.  
  18. char *panicstr;            /* cause (if any) of a SIGTERM */
  19.  
  20. /*
  21.  * configure the 'ethernet' fd so that we appear as node 'thisnode'
  22.  * Allocate 'nbufs' to cope with expected data.
  23.  */
  24. configure(thisnode, nbufs, pid)
  25. char *thisnode;
  26. {
  27.     if((ethernet = open("/dev/ni", 2)) == -1) {
  28.         perror("/dev/ni");
  29.         return(-1);
  30.     }
  31.     if(ioctl(ethernet, NIGETA, &port)) {
  32.         perror("NIGETA");
  33.         return(-1);
  34.     }
  35.     thisnode[NODE] = port.srcaddr[LSB];
  36.     thisnode[PIDMSB] = (pid & 0xff00) >> 8;
  37.     thisnode[PIDLSB] = pid & 0xff;
  38. #ifdef DEBUG
  39.     printf("Running on node %s\n", ipaddr(port.srcaddr));
  40. #endif
  41.      port.type = ETHERTYPE;
  42.      if(nbufs) port.rcvq_sz = nbufs;
  43.     port.rcvb_sz = (sizeof (struct request) + 3) & ~3;
  44.      memcpy(port.srcaddr, thisnode, ETHERSIZE);
  45.      port.protocol = PROTOCOL;
  46.      if(ioctl(ethernet, NISETA, &port)) {
  47.          perror("NISETA");
  48.          return(-1);
  49.      }
  50. #ifdef DEBUG
  51.      printf("Port configured as node %s\n", ipaddr(thisnode));
  52. #endif
  53.      memcpy(mynode, thisnode, ETHERSIZE);
  54.      return(0);
  55. }
  56. /*
  57.  * recv: receive a request from the ethernet
  58.  * If it's a request to terminate, propagate a SIGTERM signal.
  59.  * This means that users of this routine can decide on what action to take,
  60.  * and also be sure that no TERMINATE packets will not be detected.
  61.  */
  62. recv(r)
  63. register struct request *r;
  64. {
  65.     if(read(ethernet, r, sizeof (struct request)) == -1) {
  66.         r->r_type = UNDEFINED;
  67.         r->r_size = 0;
  68.         return(-1);
  69.     }
  70.     if(r->r_type == TERMINATE) {
  71.         panicstr = r->r_data;
  72.         skill(getpid(), SIGTERM);
  73.     }
  74.     
  75.     return(0);
  76. }
  77. /*
  78.  * send request to specified node
  79.  */
  80. send(r, size, type, node)
  81. struct request *r;
  82. char *node;
  83. {
  84.     int total, min = sizeof (EI_PORT) + 52;
  85.     memcpy(r->r_port.srcaddr, mynode, ETHERSIZE);
  86.     memcpy(r->r_port.destaddr, node, ETHERSIZE);
  87.     memcpy(r->r_port.ptype, myprotocol, 2);
  88.     r->r_type = type;
  89.     r->r_size = size;
  90.     total = sizeof (struct request) - ((sizeof r->r_data) - size);
  91.     total = total > min ? total : min;
  92.     if(write(ethernet, r, total) == -1) {
  93.         perror("write error");
  94.         printf("Packet: src %s ", ipaddr(r->r_port.srcaddr));
  95.         printf("dest %s\n", ipaddr(r->r_port.destaddr));
  96.         return(-1);
  97.     }
  98.     return(0);
  99. }
  100. /*
  101.  * perror
  102.  */
  103. extern char *sys_errlist[];
  104. extern int errno;
  105. extern int sys_nerr;
  106.  
  107. char *ni_error[] = {
  108.     "Bad network address",
  109.     "Bad port configuration specification",
  110.     "Port not configured",
  111.     "Open failure - out of memory?",
  112.     "HLP circuit failure",
  113.     "HLP fault",
  114.     "Port not available",
  115.     "Network not available",
  116.     "Driver fault",
  117.     "Hardware failure",
  118.     "Network fault",
  119.     "Bad packet",
  120.     "Device has been reset"
  121. };
  122.  
  123. perror(msg)
  124. char *msg;
  125. {
  126.     char *e;
  127.     if((errno > 200) && (errno < 213)) e = ni_error[errno - 200];
  128.     else e = sys_errlist[errno];
  129.     fprintf(stderr, "%s: %s [%d]\n", msg, e, errno);
  130. }
  131. /*
  132.  * used only with 'sdb'
  133.  */
  134. dump(s)
  135. char *s;
  136. {
  137.     printf("%s\n", ipaddr(s));
  138. }
  139. hostaddr(host)
  140. char *host;
  141. {
  142.     FILE *map;
  143.     char name[32];
  144.     int id;
  145.     if((map = fopen(MAP, "r")) == NULL) return(0);
  146.     while(fscanf(map, "%s%x", name, &id) != EOF) 
  147.         if(!strcmp(name, host)) {
  148.             fclose(map);
  149.             return(id);
  150.         }
  151.     fclose(map);
  152.     return(-1);
  153. }
  154. /*
  155.  * skill: 'safe' kill. There's a bug somewhere when we kill proc 0 and log
  156.  * everyone out. This is a wrokaround.
  157.  */
  158. skill(proc, sig){
  159.     if(proc < 1) {
  160.         errno = EINVAL;
  161.         return(-1);
  162.     }
  163.     return(kill(proc, sig));
  164. }
  165.  
  166.