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.