|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 6575 (0x19af) Types: TextFile Names: »atalkrd.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦3b20aab50⟧ »EurOpenD3/network/snmp/kip-snmp.91.tar.Z« └─⟦b503a39fe⟧ └─⟦this⟧ »kip/etc/atalkrd.c«
#ifndef lint static char sccsid[] = "@(#)atalkrd.c 1.1 (Stanford) 10/22/86"; #endif /* * atalkrd - appletalk rebroadcast daemon. * * This daemon retransmits appletalk-in-IP packets received on IP socket * 'rebPort'. It retransmits the packets to one or more IP addresses * supplied as command line arguments. The outgoing IP port is determined * by translating the socket number found in the appletalk destination * socket field. * * This retransmit / rebroadcast service is required for those ether * segments and ether gateways that do not support directed broadcast and * do not have an appletalk gateway (which can also act as a rebroadcast * server). * * The daemon is started at boot time from /etc/rc.local and given as * arguments, one or more IP addresses. Usually just one address is * supplied, the one used for local broadcast. But if desired one can * instead list individual host addresses; this may make sense if only a * few hosts on this ether cable are involved in appletalk traffic. * * Since host name to address lookup is slow in 4.2 BSD, it is best not to * try converting this daemon to run from inetd; but you could * avoid name lookup by only calling it with numeric addresses. * */ /* * (C) 1986, Stanford Univ. CSLI. * May be used but not sold without permission. */ #include <sys/types.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/time.h> #include <netinet/in.h> #define iaddr_t long #include <signal.h> #include <stdio.h> #include <strings.h> #include <errno.h> #include <ctype.h> #include <netdb.h> #include "gwctl.h" #include "ab.h" /* for 4.2 systems */ #ifndef FD_SETSIZE # define FD_SETSIZE sizeof(int)*8 # define NFDBITS sizeof(int)*8 # define howmany(x,y) (1) # define FD_SET(n, p) (p)->fds_bits[0] |= (1<<(n)) # define FD_CLR(n, p) (p)->fds_bits[0] &= ~(1<<(n)) # define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n))) # define FD_ZERO(p) bzero((char *)p, sizeof(*p)) #endif #define NDADDR 16 /* max number of daddr's */ iaddr_t daddr[NDADDR]; /* destination addresses */ int ndaddr; /* number of daddr's supplied on command line */ struct sockaddr_in sin = { AF_INET }; int s; /* socket fd */ struct sockaddr_in fsin; /* foreign sockaddr_in */ int fsinlen; struct timeval tvwait; /* timer for select */ char *atalkrlog = "/usr/adm/atalkrlog"; int debug; extern int errno; struct ap { /* appletalk inside IP/UDP */ u_char ldst; /* lap header */ u_char lsrc; u_char ltype; u_char dd[10]; /* misc ddp header */ u_char dstskt; u_char srcskt; u_char type; u_char data[1024]; } ap; main(argc, argv) char *argv[]; { register struct hostent *host; register int n, i; iaddr_t iaddr; int on = 1; for (argc--, argv++ ; argc > 0 ; argc--, argv++) { if (argv[0][0] == '-') { switch (argv[0][1]) { case 'd': debug++; break; } continue; } else { if (isdigit(**argv)) { if ((iaddr = inet_addr(*argv)) == -1 || iaddr == 0) log("bad ipaddress %s", *argv); } else { if ((host = gethostbyname(*argv)) == 0) log("bad hostname %s", *argv); bcopy(host->h_addr, (caddr_t)&iaddr, sizeof iaddr); } if (ndaddr >= NDADDR) { log("too many addresses"); break; } daddr[ndaddr++] = iaddr; } } if (ndaddr < 1) { log("must supply at least ONE address"); exit(1); } if (debug == 0) { int t, f; if (fork()) exit(0); for (f = 0; f < 10; f++) (void) close(f); (void) open("/", 0); (void) dup2(0, 1); (void) dup2(0, 2); t = open("/dev/tty", 2); if (t >= 0) { ioctl(t, TIOCNOTTY, (char *)0); (void) close(t); } } while ((s = socket(AF_INET, SOCK_DGRAM, 0, 0)) < 0) { log("socket call failed"); sleep(5); } #ifdef SO_BROADCAST if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) { perror("setsockopt"); log("setsockopt broadcast enable failed"); } #endif sin.sin_port = htons(rebPort); if (bind(s, (caddr_t)&sin, sizeof (sin), 0) < 0) { log("bind call failed"); exit(1); } for (;;) { fsinlen = sizeof (fsin); n = recvfrom(s, (caddr_t)&ap, sizeof ap, 0, (caddr_t)&fsin, &fsinlen); if (n < 0) { log("recv failed"); exit(1); } if (ap.ldst != 0xFA || ap.lsrc != 0xCE || ap.ltype != 2) continue; /* not valid lap header */ if (debug) log("recvfrom %s", inet_ntoa(fsin.sin_addr.s_addr)); fsin.sin_port = htons(cap_ddp2ipskt(ap.dstskt)); for (i = 0 ; i < ndaddr ; i++) { fsin.sin_addr.s_addr = daddr[i]; if (debug) log("sendto %s, ddpsoc %d, ipsoc %d", inet_ntoa(daddr[i]), ap.dstskt, ntohs(fsin.sin_port)); if (sendto(s, (caddr_t)&ap, n, 0, &fsin, sizeof fsin) != n){ perror("sendto"); log("sendto failed"); exit(1); } } } } /* * log an error message */ log(fmt, args) char *fmt; { FILE *fp; long time(), tloc; struct tm *tm, *localtime(); if (debug) fp = stderr; else if ((fp = fopen(atalkrlog, "a+")) == NULL) return; time(&tloc); tm = localtime(&tloc); fprintf(fp, "%d/%d %02d:%02d ", tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min); _doprnt(fmt, &args, fp); putc('\n', fp); if (!debug) fclose(fp); } /* * ddp to udp wks translate table: from cap's abkip.c library * */ struct wks { char *name; /* name of wks (as in /etc/services) */ int ddpport; /* ddp port to map from */ int udpport; /* udp port to map to */ int notinited; /* tried /etc/services? */ }; int ddpskt2udpport[ddpMaxWKS+1]; /* ddp "wks" socket to udp port */ /* udpport is set to the old values for compatiblity */ /* insert in order to be nice */ #define WKS_entry(name, ddpsock) {(name), (ddpsock),defddpWKSUnix+(ddpsock), 1} struct wks wks[] = { WKS_entry("at-rtmp",rtmpSkt), WKS_entry("at-nbp",nbpNIS), WKS_entry("at-echo",echoSkt), WKS_entry("at-zis",zipSkt), WKS_entry(NULL, 0) }; /* * Translate ddp socket to UDP port: returns 0 if no mapping * */ cap_ddp2ipskt(ddpskt) int ddpskt; { struct wks *wksp; struct servent *serv; if (ddpskt < 0 || ddpskt > 0xff) /* not defined but is max ddp socket */ return(0); if (ddpskt & ddpWKS) /* 128+x means non-wks */ return(ddpskt + ddpNWKSUnix); if (ddpskt2udpport[ddpskt] == 0) { for (wksp = wks; wksp->name != NULL; wksp++) if (wksp->ddpport == ddpskt) { if ((serv = getservbyname(wksp->name, "udp")) != NULL) wksp->udpport = ntohs(serv->s_port); /* silliness */ endservent(); ddpskt2udpport[ddpskt] = wksp->udpport; return(wksp->udpport); } ddpskt2udpport[ddpskt] = 0; } return(ddpskt2udpport[ddpskt]); }