|
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 - downloadIndex: ┃ T s ┃
Length: 6731 (0x1a4b) Types: TextFile Names: »server.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/inet/server.c«
set noglob echo Extracting client.c cat > client.c <<'##EOF##' #include <stdio.h> #include <netdb.h> #include <sys/types.h> #include <sys/time.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <netinet/in.h> #include <net/if.h> extern void request_service(); /* * These variables may be accessed externally in order to verify that * further messages received on the socket are actually being sent by * the same server. This may easily be done using the command: * * bcmp( (char *) &server_addr, (char *) &addr, server_addr_size ) */ struct sockaddr_in server_addr; int server_addr_size = sizeof(server_addr); /* * int obtain_service( char *name, int port, int timeout_sec, * char *request, int request_size ) * * Sends a broadcast message over the net asking for the existence * of a server socket on the given port associated with the named * service. The port argument is a default port number if the service * is not found in the local net DB. If there is no response after * timeout_sec seconds, then we return with -1. If a response is * received, then the socket is connected to that address and the socket * number is returned. The socket type used is SOCK_DGRAM. */ int obtain_service( serv_name, serv_port, timeout_sec, request, request_size ) char *serv_name; int serv_port; int timeout_sec; char *request; int request_size; { int sock; fd_set mask; struct timeval timeout; struct servent *serv, *getservbyname(); struct protoent *proto, *getprotobyname(); int serv_proto = 0; static char tbuf[64]; /* Initialize the timeout structure */ timeout.tv_sec = timeout_sec; timeout.tv_usec = 0; /* Get service information */ serv_port = htons(serv_port); if ( (serv = getservbyname( serv_name, (char *) 0 )) != NULL ) { serv_port = serv->s_port; #ifdef PROTO_SUPPORTED if ( (proto = getprotobyname(serv->s_proto)) != NULL ) serv_proto = proto->p_proto; #endif PROTO_SUPPORTED } #ifdef DEBUG printf( "Access port %d and proto %d\n", ntohs(serv_port), serv_proto ); fflush(stdout); #endif DEBUG /* Initialize the socket */ if ( (sock = socket( AF_INET, SOCK_DGRAM, serv_proto )) < 0 ) { perror( "creating socket to server" ); exit(1); } /* Make the request */ printf( "[Request service ..." ); fflush(stdout); request_service( sock, serv_port, request, request_size ); /* Now, wait for some response */ FD_ZERO(&mask); FD_SET(sock,&mask); if ( select(FD_SETSIZE,&mask,(fd_set *)0,(fd_set *)0,&timeout) <= 0 || !FD_ISSET( sock, &mask ) ) { printf( " timed out]\n" ); fflush(stdout); return -1; } /* We got a response (YAY!) */ printf( " answered..." ); fflush(stdout); /* So, peek at the response (to get address) */ if ( recvfrom( sock, tbuf, sizeof(tbuf), MSG_PEEK, &server_addr, &server_addr_size ) < 0 ) { perror( "receive initial response" ); exit(1); } #ifdef DEBUG printf( "[by %s %d]...", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port) ); fflush(stdout); #endif DEBUG /* Connect socket to the address */ if ( connect( sock, &server_addr, server_addr_size ) < 0 ) { perror( "connect to server" ); exit(1); } /* Return with a happy (:-) response */ printf( " connected]\n" ); fflush(stdout); return sock; } \f /* * int get_ifc( int sock ) * * Put the IFCONF data structure into the ifc structure and return * the number of ifreq structures it contains. */ static struct ifconf ifc; int get_ifc( sock ) int sock; { static char ifc_buffer[BUFSIZ]; ifc.ifc_len = sizeof(ifc_buffer); ifc.ifc_buf = ifc_buffer; if ( (ioctl( sock, SIOCGIFCONF, (char *) &ifc )) < 0 ) { perror( "get ifconf" ); exit(1); } return ifc.ifc_len / sizeof(struct ifreq); } \f /* * request_service( int sock, int port, char *data, int data_len ) * * This function broadcasts a request for the given service using * the socket sock. The request is directed at servers on the named * port on all machines in the local INET network. */ void request_service( sock, port, data, data_len ) int sock; int port; char *data; int data_len; { struct sockaddr_in sin; struct sockaddr dst; int off = 0, on = 1; int n; struct ifreq *ifr; /* Set socket for broadcast mode */ if ( (setsockopt( sock,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on) )) < 0 ) { perror( "set socket option for broadcast" ); exit(1); } /* Initialize broadcast address and bind socket to it */ sin.sin_family = AF_INET; sin.sin_port = port; sin.sin_addr.s_addr = htonl(INADDR_ANY); bind( sock, (struct sockaddr *) &sin, sizeof(sin) ); for ( n = get_ifc(sock), ifr = ifc.ifc_req; n > 0; --n, ++ifr ) { /* Only deal with AF_INET networks */ if ( ifr->ifr_addr.sa_family != AF_INET ) continue; /* Use the current address by default */ bzero( (char *) &dst, sizeof(dst) ); bcopy( (char *)&ifr->ifr_addr, (char *)&dst, sizeof(ifr->ifr_addr) ); /* Get the flags */ if ( ioctl( sock, SIOCGIFFLAGS, (char *) ifr ) < 0 ) { perror( "get ifr flags" ); exit(1); } /* Skip unusable cases */ if ( !(ifr->ifr_flags & IFF_UP) || /* If not up, OR */ (ifr->ifr_flags & IFF_LOOPBACK ) || /* if loopback, OR */ !(ifr->ifr_flags & (IFF_BROADCAST | IFF_POINTOPOINT)) ) continue; /* Now, determine the address to send to */ if ( ifr->ifr_flags & IFF_POINTOPOINT ) { if ( ioctl( sock, SIOCGIFDSTADDR, (char *) ifr ) < 0 ) { perror( "get ifr destination address" ); exit(1); } bcopy( (char *) &ifr->ifr_dstaddr, (char *) &dst, sizeof(ifr->ifr_dstaddr) ); } if ( ifr->ifr_flags & IFF_BROADCAST ) { if ( ioctl( sock, SIOCGIFBRDADDR, (char *) ifr ) < 0 ) { perror( "get ifr broadcast address" ); exit(1); } bcopy( (char *) &ifr->ifr_broadaddr, (char *) &dst, sizeof(ifr->ifr_broadaddr) ); } /* ... make sure that the port number is OK */ if ( dst.sa_family == AF_INET ) { struct sockaddr_in *sa_in = (struct sockaddr_in *) &dst; sa_in->sin_port = port; #ifdef DEBUG printf( "Request address = %s (%d)\n", inet_ntoa(sa_in->sin_addr), ntohs(port) ); fflush(stdout); #endif DEBUG } /* ... and send the request */ if ( sendto( sock, data, data_len, 0, (struct sockaddr *) &dst, sizeof(dst) ) < 0 ) { perror( "sendto" ); exit(1); } } /* Reset socket option to normal operation */ if ( (setsockopt( sock,SOL_SOCKET,SO_BROADCAST,&off,sizeof(off) )) < 0 ) { perror( "reset socket option for no broadcast" ); exit(1); } } ##EOF## echo Extracting service.h cat > service.h <<'##EOF##'