1
/*****************************************************************************/
2
/* "NetPIPE" -- Network Protocol Independent Performance Evaluator. */
3
/* Copyright 1997, 1998 Iowa State University Research Foundation, Inc. */
5
/* This program is free software; you can redistribute it and/or modify */
6
/* it under the terms of the GNU General Public License as published by */
7
/* the Free Software Foundation. You should have received a copy of the */
8
/* GNU General Public License along with this program; if not, write to the */
9
/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
11
/* IPX Extensions Copyright 2006 George V. Neville-Neil and Neville-Neil */
14
/* * ipx.c ---- IPX calls source */
16
/*****************************************************************************/
26
void Init(ArgStruct *p, int* pargc, char*** pargv)
28
p->reset_conn = 0; /* Default to not resetting connection */
29
p->prot.sndbufsz = p->prot.rcvbufsz = 0;
30
p->tr = 0; /* The transmitter will be set using the -h host flag. */
34
void Setup(ArgStruct *p)
39
struct sockaddr_ipx *lsipx1, *lsipx2; /* ptr to sockaddr_in in ArgStruct */
41
int send_size, recv_size, sizeofint = sizeof(int);
44
host = p->host; /* copy ptr to hostname */
46
lsipx1 = &(p->prot.sipx1);
47
lsipx2 = &(p->prot.sipx2);
49
bzero((char *) lsipx1, sizeof(*lsipx1));
50
bzero((char *) lsipx2, sizeof(*lsipx2));
52
if ( (sockfd = socket(AF_IPX, SOCK_STREAM, 0)) < 0){
53
printf("NetPIPE: can't open IPX DGRAM socket! errno=%d\n", errno);
57
/* If requested, set the send and receive buffer sizes */
59
if(p->prot.sndbufsz > 0)
61
if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz),
62
sizeof(p->prot.sndbufsz)) < 0)
64
printf("NetPIPE: setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
65
printf("You may have asked for a buffer larger than the system can handle\n");
68
if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz),
69
sizeof(p->prot.rcvbufsz)) < 0)
71
printf("NetPIPE: setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
72
printf("You may have asked for a buffer larger than the system can handle\n");
76
getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF,
77
(char *) &send_size, (void *) &sizeofint);
78
getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF,
79
(char *) &recv_size, (void *) &sizeofint);
82
fprintf(stderr,"Send and receive buffers are %d and %d bytes\n",
83
send_size, recv_size);
84
fprintf(stderr, "(A bug in Linux doubles the requested buffer sizes)\n");
87
if( p->tr ) { /* Primary transmitter */
89
lsipx1->sipx_family = AF_IPX;
90
lsipx1->sipx_addr = ipx_addr(host);
94
} else if( p->rcv ) { /* we are the receiver */
96
bzero((char *) lsipx1, sizeof(*lsipx1));
97
lsipx1->sipx_family = AF_IPX;
98
lsipx1->sipx_addr.x_port = DEFPORT;
99
if (bind(sockfd, (struct sockaddr *) lsipx1, sizeof(*lsipx1)) < 0){
100
printf("NetPIPE: server: bind on local address failed! errno=%d", errno);
104
p->servicefd = sockfd;
106
p->upper = send_size + recv_size;
108
establish(p); /* Establish connections */
113
readFully(int fd, void *obuf, int len)
116
char *buf = (char *) obuf;
119
while (bytesLeft > 0 &&
120
(bytesRead = read(fd, (void *) buf, bytesLeft)) > 0)
122
bytesLeft -= bytesRead;
125
if (bytesRead <= 0) return bytesRead;
129
void Sync(ArgStruct *p)
131
char s[] = "SyncMe", response[] = " ";
133
if (write(p->commfd, s, strlen(s)) < 0 || /* Write to nbor */
134
readFully(p->commfd, response, strlen(s)) < 0) /* Read from nbor */
136
perror("NetPIPE: error writing or reading synchronization string");
139
if (strncmp(s, response, strlen(s)))
141
fprintf(stderr, "NetPIPE: Synchronization string incorrect! |%s|\n", response);
146
void PrepareToReceive(ArgStruct *p)
149
The Berkeley sockets interface doesn't have a method to pre-post
150
a buffer for reception of data.
154
void SendData(ArgStruct *p)
156
int bytesWritten, bytesLeft;
159
bytesLeft = p->bufflen;
162
while (bytesLeft > 0 &&
163
(bytesWritten = write(p->commfd, q, bytesLeft)) > 0)
165
bytesLeft -= bytesWritten;
168
if (bytesWritten == -1)
170
printf("NetPIPE: write: error encountered, errno=%d\n", errno);
175
void RecvData(ArgStruct *p)
181
bytesLeft = p->bufflen;
184
while (bytesLeft > 0 &&
185
(bytesRead = read(p->commfd, q, bytesLeft)) > 0)
187
bytesLeft -= bytesRead;
190
if (bytesLeft > 0 && bytesRead == 0)
192
printf("NetPIPE: \"end of file\" encountered on reading from socket\n");
194
else if (bytesRead == -1)
196
printf("NetPIPE: read: error encountered, errno=%d\n", errno);
201
/* uint32_t is used to insure that the integer size is the same even in tests
202
* between 64-bit and 32-bit architectures. */
204
void SendTime(ArgStruct *p, double *t)
206
uint32_t ltime, ntime;
209
Multiply the number of seconds by 1e8 to get time in 0.01 microseconds
210
and convert value to an unsigned 32-bit integer.
212
ltime = (uint32_t)(*t * 1.e8);
214
/* Send time in network order */
215
ntime = htonl(ltime);
216
if (write(p->commfd, (char *)&ntime, sizeof(uint32_t)) < 0)
218
printf("NetPIPE: write failed in SendTime: errno=%d\n", errno);
223
void RecvTime(ArgStruct *p, double *t)
225
uint32_t ltime, ntime;
228
bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(uint32_t));
231
printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno);
234
else if (bytesRead != sizeof(uint32_t))
236
fprintf(stderr, "NetPIPE: partial read in RecvTime of %d bytes\n",
240
ltime = ntohl(ntime);
242
/* Result is ltime (in microseconds) divided by 1.0e8 to get seconds */
244
*t = (double)ltime / 1.0e8;
247
void SendRepeat(ArgStruct *p, int rpt)
252
/* Send repeat count as a long in network order */
254
if (write(p->commfd, (void *) &nrpt, sizeof(uint32_t)) < 0)
256
printf("NetPIPE: write failed in SendRepeat: errno=%d\n", errno);
261
void RecvRepeat(ArgStruct *p, int *rpt)
266
bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(uint32_t));
269
printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno);
272
else if (bytesRead != sizeof(uint32_t))
274
fprintf(stderr, "NetPIPE: partial read in RecvRepeat of %d bytes\n",
283
void establish(ArgStruct *p)
287
struct protoent *proto;
289
clen = (socklen_t) sizeof(p->prot.sipx2);
293
while( connect(p->commfd, (struct sockaddr *) &(p->prot.sipx1),
294
sizeof(p->prot.sipx1)) < 0 ) {
296
/* If we are doing a reset and we get a connection refused from
297
* the connect() call, assume that the other node has not yet
298
* gotten to its corresponding accept() call and keep trying until
301
if(!doing_reset || errno != ECONNREFUSED) {
302
printf("Client: Cannot Connect! errno=%d\n",errno);
308
} else if( p->rcv ) {
311
listen(p->servicefd, 5);
313
p->commfd = accept(p->servicefd, (struct sockaddr *) &(p->prot.sipx2), &clen);
315
p->commfd = accept(p->servicefd, NULL, NULL);
318
printf("Server: Accept Failed! errno=%d\n",errno);
322
/* If requested, set the send and receive buffer sizes */
323
if(p->prot.sndbufsz > 0)
325
/* printf("Send and Receive Buffers on accepted socket set to %d bytes\n",*/
326
/* p->prot.sndbufsz);*/
327
if(setsockopt(p->commfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz),
328
sizeof(p->prot.sndbufsz)) < 0)
330
printf("setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
333
if(setsockopt(p->commfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz),
334
sizeof(p->prot.rcvbufsz)) < 0)
336
printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
343
void CleanUp(ArgStruct *p)
349
write(p->commfd,quit, 5);
350
read(p->commfd, quit, 5);
353
} else if( p->rcv ) {
355
read(p->commfd,quit, 5);
356
write(p->commfd,quit,5);
364
void Reset(ArgStruct *p)
373
/* Close the sockets */
377
/* Now open and connect new sockets */
385
void AfterAlignmentInit(ArgStruct *p)