From db3494b6d548703e3ccdf5f6511d10790b2730ff Mon Sep 17 00:00:00 2001 From: "Janet B. Anderson" Date: Thu, 14 Apr 1994 08:25:32 +0000 Subject: [PATCH] Initial revision --- src/ca/caRepeater.c | 29 +++++ src/ca/if_depen.c | 289 +++++++++++++++++++++++++++++++++++++++++++ src/ca/netdb_depen.c | 83 +++++++++++++ 3 files changed, 401 insertions(+) create mode 100644 src/ca/caRepeater.c create mode 100644 src/ca/if_depen.c create mode 100644 src/ca/netdb_depen.c diff --git a/src/ca/caRepeater.c b/src/ca/caRepeater.c new file mode 100644 index 000000000..16d4476ad --- /dev/null +++ b/src/ca/caRepeater.c @@ -0,0 +1,29 @@ +/* + * caRepeater.c + * share/src/ca/caRepeater.c + * + * CA broadcast repeater executable + * + * Author: Jeff Hill + * Date: 3-27-90 + * + * PURPOSE: + * Broadcasts fan out over the LAN, but UDP does not allow + * two processes on the same machine to get the same broadcast. + * This code takes extends the broadcast model from the net to within + * the OS. + * + * NOTES: + * + * see repeater.c + * + */ + +#include +#include + +main() +{ + ca_repeater(); + assert(0); +} diff --git a/src/ca/if_depen.c b/src/ca/if_depen.c new file mode 100644 index 000000000..526fba8e2 --- /dev/null +++ b/src/ca/if_depen.c @@ -0,0 +1,289 @@ +/* if_depen.c */ +/* share/src/ca/$Id$ */ + +/* + * Author: Jeff Hill + * Date: 04-05-94 + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * 8/87 Jeff Hill Init Release + * 072792 Jeff Hill better messages + * 09-DEC-1992 Gerhard Grygiel (GeG) support VMS/UCX + * 050593 Jeff Hill now checks all N interfaces + * (and not N-1 interfaces) + */ + + +static char *sccsId = "$Id$"; + + +#include "iocinf.h" + + + +/* + * local_addr() + * + * Perhaps it is sufficient for this to return 127.0.0.1 + * (the loop back address) + */ +#ifdef __STDC__ +int local_addr(int s, struct sockaddr_in *plcladdr) +#else +int local_addr(s, plcladdr) +int s; +struct sockaddr_in *plcladdr; +#endif +{ + int status; + struct ifconf ifconf; + struct ifreq ifreq[25]; + struct ifreq *pifreq; + static struct sockaddr_in addr; + static char init = FALSE; + struct sockaddr_in *tmpaddr; + + if (init){ + *plcladdr = addr; + return OK; + } + + /* + * get the addr of the first interface found + * (report inconsistent interfaces however) + */ + ifconf.ifc_len = sizeof ifreq; + ifconf.ifc_req = ifreq; + status = socket_ioctl(s, SIOCGIFCONF, (int)&ifconf); + if (status < 0 || ifconf.ifc_len == 0) { + ca_printf("CAC: ioctl failed %d\n", MYERRNO); + ifconf.ifc_len = 0; + } + + for ( pifreq = ifconf.ifc_req; + ifconf.ifc_len >= sizeof(*pifreq); + pifreq++, ifconf.ifc_len -= sizeof(*pifreq)) { + + status = socket_ioctl(s, SIOCGIFFLAGS, (int)pifreq); + if (status == ERROR){ + ca_printf("CAC: could not obtain if flags\n"); + continue; + } + + if (!(pifreq->ifr_flags & IFF_UP)) { + continue; + } + + if (pifreq->ifr_flags & IFF_LOOPBACK) { + continue; + } + + if (!(pifreq->ifr_flags & IFF_BROADCAST)) { + continue; + } + +#ifdef DEBUG + ca_printf("CAC: if fnd %s\n", pifreq->ifr_name); +#endif + + status = socket_ioctl(s, SIOCGIFADDR, (int)pifreq); + if (status == ERROR){ +#ifdef DEBUG + ca_printf("CAC: could not obtain addr\n"); +#endif + continue; + } + + if (pifreq->ifr_addr.sa_family != AF_INET){ +#ifdef DEBUG + ca_printf("CAC: interface was not AF_INET\n"); +#endif + continue; + } + + tmpaddr = (struct sockaddr_in *) &pifreq->ifr_addr; + + if (!init){ + init = TRUE; + addr = *tmpaddr; + } + else { + if (tmpaddr->sin_addr.s_addr + != addr.sin_addr.s_addr) + ca_printf("CAC: %s: interface=%s inet addr does not match first interface found %x\n", + __FILE__, + pifreq->ifr_name, + tmpaddr->sin_addr.s_addr); + if (tmpaddr->sin_port != addr.sin_port) + ca_printf("CAC: local_addr(): inconsistent port found- first used\n"); + } + } + + if(!init){ + return ERROR; + } + + *plcladdr = addr; + return OK; +} + + + +/* + * caDiscoverInterfaces() + * + * Load the list with the broadcast address for all + * interfaces found that support broadcast. + */ +#ifdef __STDC__ +void caDiscoverInterfaces(ELLLIST *pList, int socket, int port) +#else /*__STDC__*/ +void caDiscoverInterfaces(pList, socket, port) +ELLLIST *pList; +int socket; +int port; +#endif /*__STDC__*/ +{ + struct sockaddr_in localAddr; + struct sockaddr_in *pInetAddr; + caAddrNode *pNode; + int status; + struct ifconf ifconf; + struct ifreq *pIfreqList; + struct ifreq *pifreq; + unsigned nelem; + + /* + * use pool so that we avoid using to much stack space + * under vxWorks + * + * nelem is set to the maximum interfaces + * on one machine here + */ + nelem = 100; + pIfreqList = (struct ifreq *)calloc(nelem, sizeof(*pifreq)); + if(!pIfreqList){ + return; + } + + ifconf.ifc_len = nelem*sizeof(*pifreq); + ifconf.ifc_req = pIfreqList; + status = socket_ioctl(socket, SIOCGIFCONF, (int)&ifconf); + if (status < 0 || ifconf.ifc_len == 0) { + free(pIfreqList); + return; + } + + nelem = ifconf.ifc_len/sizeof(struct ifreq); + for (pifreq = pIfreqList; pifreq<(pIfreqList+nelem); pifreq++){ + status = socket_ioctl(socket, SIOCGIFFLAGS, (int) pifreq); + if (status){ + continue; + } + + /* + * dont bother with interfaces that have been disabled + */ + if (!(pifreq->ifr_flags & IFF_UP)) { + continue; + } + + /* + * dont use the loop back interface + */ + if (pifreq->ifr_flags & IFF_LOOPBACK) { + continue; + } + + /* + * Fetch the local address for this interface + */ + status = socket_ioctl(socket, SIOCGIFADDR, (int)pifreq); + if (status){ + continue; + } + /* + * If its not an internet inteface + * then dont use it. + */ + if (pifreq->ifr_addr.sa_family != AF_INET) { + continue; + } + pInetAddr = (struct sockaddr_in *)&pifreq->ifr_addr; + localAddr = *pInetAddr; + + /* + * If this is an interface that supports + * broadcast fetch the broadcast address. + * + * Otherwise if this is a point to point + * interface then use the destination address. + * + * Otherwise CA will not query through the + * interface. + */ + if (pifreq->ifr_flags & IFF_BROADCAST) { + status = socket_ioctl( + socket, + SIOCGIFBRDADDR, + (int) pifreq); + if (status){ + continue; + } + } + else if(pifreq->ifr_flags & IFF_POINTOPOINT){ + status = socket_ioctl( + socket, + SIOCGIFDSTADDR, + (int) pifreq); + if (status){ + continue; + } + } + else{ + continue; + } + + + + + pNode = (caAddrNode *) calloc(1,sizeof(*pNode)); + if(!pNode){ + continue; + } + + pNode->destAddr.inetAddr = *pInetAddr; + pNode->destAddr.inetAddr.sin_port = htons(port); + pNode->srcAddr.inetAddr = localAddr; + + LOCK; + ellAdd(pList, &pNode->node); + UNLOCK; + + } + + free(pIfreqList); +} + + diff --git a/src/ca/netdb_depen.c b/src/ca/netdb_depen.c new file mode 100644 index 000000000..9f5af9a71 --- /dev/null +++ b/src/ca/netdb_depen.c @@ -0,0 +1,83 @@ +/* netdb_depen.c */ +/* share/src/ca/$Id$ */ +/* + * Author: Jeff Hill + * Date: 04-05-94 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * Modification Log: + * ----------------- + * .00 mm-dd-yy iii Comment + */ + + +static char *sccsId = "$Id$"; + + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +/* + * caHostFromInetAddr() + */ +#ifdef __STDC__ +void caHostFromInetAddr(struct in_addr *pnet_addr, char *pBuf, unsigned size) +#else +void caHostFromInetAddr(pnet_addr, pBuf, size) +struct in_addr *pnet_addr; +char *pBuf; +unsigned size; +#endif +{ + char *pString; + struct hostent *ent; + + ent = gethostbyaddr( + pnet_addr, + sizeof(*pnet_addr), + AF_INET); + if(ent){ + pString = ent->h_name; + } + else{ + pString = inet_ntoa(*pnet_addr); + } + + /* + * force null termination + */ + strncpy(pBuf, pString, size-1); + pBuf[size-1] = '\0'; + + return; +} +