This is enitest.c in view mode; [Download] [Up]
/* Sample program which consists of two threads: the original thread, to transmit packets, and a new thread to receive any in-coming packets. - Bill Heelan (wheelan@cs.mcgill.ca) */ #include <stdio.h> #include <stdlib.h> #include <mach.h> #include <sys/types.h> #include <netinet/in.h> #include <servers/netname.h> #include <sys/message.h> #include <net/etherdefs.h> #include <sys/errno.h> #include <strings.h> #include <cthreads.h> #include "eniutils.h" #include "libeni.h" #define DFLT_DST "overbeek" #define ETHER_FILE "etherfile" #define FRAME_TYPE 71 extern u_short htons(u_short s) ; extern u_short ntohs(u_short s) ; extern void rcv_packets(any_t ignore) ; extern void send_packets(void) ; char *prog ; int main(int ac, char *av[]) { cthread_t rthread ; prog = tail(av[0]) ; if(eni_init() == -1) { fprintf(stderr, "%s: eni_init() failed.\n", prog) ; exit(1) ; } ; rthread = cthread_fork((any_t (*)())rcv_packets, (any_t)0) ; cthread_detach(rthread) ; send_packets() ; thread_suspend((thread_t)rthread) ; cthread_abort(rthread) ; exit(0) ; } /* Construct and transmit a packet based on information received from standard input. A newline, in response to a prompt, selects the default value for that item of information. */ void send_packets(void) { char dflt_data[32] ; char dst_host[64] = DFLT_DST ; char in[256] ; int done = 0 ; int pcount = 0 ; int r ; int type = FRAME_TYPE ; unsigned char data[ENI_MTU] ; unsigned char edst[6] ; while( ! done) { printf("Enter destination host [%s]: ", dst_host) ; if(fgets(in, sizeof in, stdin) == (char *)0) { done = 1 ; } else { if(*in != '\n') { nuke_newline(in) ; if( ! get_ether_addr(in, edst, ETHER_FILE)) { fprintf(stderr, "%s: can't find address for %s.\n", prog, in) ; continue ; } strcpy(dst_host, in) ; } printf("Enter packet type [%d]: ", type) ; if(fgets((char *)in, sizeof in, stdin) == (char *)0) { done = 1 ; } else { if(*in != '\n') { if(sscanf(in, "%d", &type) != 1) { fprintf(stderr, "%s: bad number -- using %d.\n", prog, type) ; } } sprintf(dflt_data, "Packet #%d", pcount) ; printf("Enter data [%s]: ", dflt_data) ; if(fgets((char *)data, sizeof data, stdin) == (char *)0) { done = 1 ; } else { u_short t ; t = (u_short)htons(type) ; /* Assume the data is a nul terminated string and copy the nul terminator. */ if(*data == '\n') { bcopy(dflt_data, (char *)data, strlen(dflt_data) + 1) ; } r = eni_send_packet(edst, t, (void *)data, strlen((char *)data) + 1) ; pcount++ ; if(r != 0) { fprintf(stderr, "%s: eni_send_packet() returns %d.\n", prog, r) ; } } } } } } /* Loop, receiving packets and printing their contents, until eni_get_packet returns an error, or we are killed from the initial thread (see the 'main' routine). */ void rcv_packets(any_t ignore) { char dstr[ADDR_STR_LEN] ; int len ; int r ; unsigned char pack[ENI_PACKET_SIZE] ; while((r = eni_get_packet(pack, &len)) != -1) { unsigned short type ; bcopy((char *)(pack + TYPE_OFFSET), (char *)&type, sizeof type) ; type = ntohs(type) ; /* Assume (hope :-) the data is a nul terminated string. */ printf("%s: from %s: type = %d, data length = %d\n\tdata is [%s]\n", prog, addr_to_hex(pack + SADDR_OFFSET, dstr), (int)type, len, pack + DATA_OFFSET) ; } fprintf(stderr, "%s: eni_get_packet() returned %d.\n", prog, r) ; cthread_exit((any_t)0) ; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.