~ubuntu-branches/ubuntu/trusty/netpipe/trusty

« back to all changes in this revision

Viewing changes to src/ipx.c

  • Committer: Bazaar Package Importer
  • Author(s): Camm Maguire
  • Date: 2010-01-06 19:07:32 UTC
  • mfrom: (4.1.1 sid)
  • Revision ID: james.westby@ubuntu.com-20100106190732-fg9urgk31weolrcs
Tags: 3.7.1-1
* New upstream release
* Bug fix: "debian/watch fails to report upstream's version", thanks
  to Raphael Geissert (Closes: #450010).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************/
 
2
/* "NetPIPE" -- Network Protocol Independent Performance Evaluator.          */
 
3
/* Copyright 1997, 1998 Iowa State University Research Foundation, Inc.      */
 
4
/*                                                                           */
 
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.   */
 
10
/*                                                                           */
 
11
/* IPX Extensions Copyright 2006 George V. Neville-Neil and Neville-Neil     */
 
12
/* Consulting                                                                */
 
13
/*                                                                           */
 
14
/*     * ipx.c              ---- IPX calls source                            */
 
15
/*                                                                           */
 
16
/*****************************************************************************/
 
17
#include    "netpipe.h"
 
18
 
 
19
#if defined (MPLITE)
 
20
#include "mplite.h"
 
21
#endif
 
22
 
 
23
 
 
24
int doing_reset = 0;
 
25
 
 
26
void Init(ArgStruct *p, int* pargc, char*** pargv)
 
27
{
 
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. */
 
31
   p->rcv = 1;
 
32
}
 
33
 
 
34
void Setup(ArgStruct *p)
 
35
{
 
36
 
 
37
 int one = 1;
 
38
 int sockfd;
 
39
 struct sockaddr_ipx *lsipx1, *lsipx2;   /* ptr to sockaddr_in in ArgStruct */
 
40
 char *host;
 
41
 int send_size, recv_size, sizeofint = sizeof(int);
 
42
 
 
43
 
 
44
 host = p->host;                           /* copy ptr to hostname */ 
 
45
 
 
46
 lsipx1 = &(p->prot.sipx1);
 
47
 lsipx2 = &(p->prot.sipx2);
 
48
 
 
49
 bzero((char *) lsipx1, sizeof(*lsipx1));
 
50
 bzero((char *) lsipx2, sizeof(*lsipx2));
 
51
 
 
52
 if ( (sockfd = socket(AF_IPX, SOCK_STREAM, 0)) < 0){
 
53
   printf("NetPIPE: can't open IPX DGRAM socket! errno=%d\n", errno);
 
54
   exit(-4);
 
55
 }
 
56
 
 
57
   /* If requested, set the send and receive buffer sizes */
 
58
 
 
59
 if(p->prot.sndbufsz > 0)
 
60
 {
 
61
     if(setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &(p->prot.sndbufsz), 
 
62
                                       sizeof(p->prot.sndbufsz)) < 0)
 
63
     {
 
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");
 
66
          exit(556);
 
67
     }
 
68
     if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 
 
69
                                       sizeof(p->prot.rcvbufsz)) < 0)
 
70
     {
 
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");
 
73
          exit(556);
 
74
     }
 
75
 }
 
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);
 
80
 
 
81
 if(!doing_reset) {
 
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");
 
85
 }
 
86
 
 
87
 if( p->tr ) {                             /* Primary transmitter */
 
88
 
 
89
   lsipx1->sipx_family = AF_IPX;
 
90
   lsipx1->sipx_addr = ipx_addr(host);
 
91
 
 
92
   p->commfd = sockfd;
 
93
 
 
94
 } else if( p->rcv ) {                     /* we are the receiver */
 
95
   
 
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);
 
101
     exit(-6);
 
102
   }
 
103
 
 
104
   p->servicefd = sockfd;
 
105
 }
 
106
 p->upper = send_size + recv_size;
 
107
 
 
108
 establish(p);                               /* Establish connections */
 
109
 
 
110
}   
 
111
 
 
112
static int
 
113
readFully(int fd, void *obuf, int len)
 
114
{
 
115
  int bytesLeft = len;
 
116
  char *buf = (char *) obuf;
 
117
  int bytesRead = 0;
 
118
 
 
119
  while (bytesLeft > 0 &&
 
120
         (bytesRead = read(fd, (void *) buf, bytesLeft)) > 0)
 
121
    {
 
122
      bytesLeft -= bytesRead;
 
123
      buf += bytesRead;
 
124
    }
 
125
  if (bytesRead <= 0) return bytesRead;
 
126
  return len;
 
127
}
 
128
 
 
129
void Sync(ArgStruct *p)
 
130
{
 
131
    char s[] = "SyncMe", response[] = "      ";
 
132
 
 
133
    if (write(p->commfd, s, strlen(s)) < 0 ||           /* Write to nbor */
 
134
        readFully(p->commfd, response, strlen(s)) < 0)  /* Read from nbor */
 
135
      {
 
136
        perror("NetPIPE: error writing or reading synchronization string");
 
137
        exit(3);
 
138
      }
 
139
    if (strncmp(s, response, strlen(s)))
 
140
      {
 
141
        fprintf(stderr, "NetPIPE: Synchronization string incorrect! |%s|\n", response);
 
142
        exit(3);
 
143
      }
 
144
}
 
145
 
 
146
void PrepareToReceive(ArgStruct *p)
 
147
{
 
148
        /*
 
149
            The Berkeley sockets interface doesn't have a method to pre-post
 
150
            a buffer for reception of data.
 
151
        */
 
152
}
 
153
 
 
154
void SendData(ArgStruct *p)
 
155
{
 
156
    int bytesWritten, bytesLeft;
 
157
    char *q;
 
158
 
 
159
    bytesLeft = p->bufflen;
 
160
    bytesWritten = 0;
 
161
    q = p->s_ptr;
 
162
    while (bytesLeft > 0 &&
 
163
           (bytesWritten = write(p->commfd, q, bytesLeft)) > 0)
 
164
      {
 
165
        bytesLeft -= bytesWritten;
 
166
        q += bytesWritten;
 
167
      }
 
168
    if (bytesWritten == -1)
 
169
      {
 
170
        printf("NetPIPE: write: error encountered, errno=%d\n", errno);
 
171
        exit(401);
 
172
      }
 
173
}
 
174
 
 
175
void RecvData(ArgStruct *p)
 
176
{
 
177
    int bytesLeft;
 
178
    int bytesRead;
 
179
    char *q;
 
180
 
 
181
    bytesLeft = p->bufflen;
 
182
    bytesRead = 0;
 
183
    q = p->r_ptr;
 
184
    while (bytesLeft > 0 &&
 
185
           (bytesRead = read(p->commfd, q, bytesLeft)) > 0)
 
186
      {
 
187
        bytesLeft -= bytesRead;
 
188
        q += bytesRead;
 
189
      }
 
190
    if (bytesLeft > 0 && bytesRead == 0)
 
191
      {
 
192
        printf("NetPIPE: \"end of file\" encountered on reading from socket\n");
 
193
      }
 
194
    else if (bytesRead == -1)
 
195
      {
 
196
        printf("NetPIPE: read: error encountered, errno=%d\n", errno);
 
197
        exit(401);
 
198
      }
 
199
}
 
200
 
 
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. */
 
203
 
 
204
void SendTime(ArgStruct *p, double *t)
 
205
{
 
206
    uint32_t ltime, ntime;
 
207
 
 
208
    /*
 
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.
 
211
      */
 
212
    ltime = (uint32_t)(*t * 1.e8);
 
213
 
 
214
    /* Send time in network order */
 
215
    ntime = htonl(ltime);
 
216
    if (write(p->commfd, (char *)&ntime, sizeof(uint32_t)) < 0)
 
217
      {
 
218
        printf("NetPIPE: write failed in SendTime: errno=%d\n", errno);
 
219
        exit(301);
 
220
      }
 
221
}
 
222
 
 
223
void RecvTime(ArgStruct *p, double *t)
 
224
{
 
225
    uint32_t ltime, ntime;
 
226
    int bytesRead;
 
227
 
 
228
    bytesRead = readFully(p->commfd, (void *)&ntime, sizeof(uint32_t));
 
229
    if (bytesRead < 0)
 
230
      {
 
231
        printf("NetPIPE: read failed in RecvTime: errno=%d\n", errno);
 
232
        exit(302);
 
233
      }
 
234
    else if (bytesRead != sizeof(uint32_t))
 
235
      {
 
236
        fprintf(stderr, "NetPIPE: partial read in RecvTime of %d bytes\n",
 
237
                bytesRead);
 
238
        exit(303);
 
239
      }
 
240
    ltime = ntohl(ntime);
 
241
 
 
242
        /* Result is ltime (in microseconds) divided by 1.0e8 to get seconds */
 
243
 
 
244
    *t = (double)ltime / 1.0e8;
 
245
}
 
246
 
 
247
void SendRepeat(ArgStruct *p, int rpt)
 
248
{
 
249
  uint32_t lrpt, nrpt;
 
250
 
 
251
  lrpt = rpt;
 
252
  /* Send repeat count as a long in network order */
 
253
  nrpt = htonl(lrpt);
 
254
  if (write(p->commfd, (void *) &nrpt, sizeof(uint32_t)) < 0)
 
255
    {
 
256
      printf("NetPIPE: write failed in SendRepeat: errno=%d\n", errno);
 
257
      exit(304);
 
258
    }
 
259
}
 
260
 
 
261
void RecvRepeat(ArgStruct *p, int *rpt)
 
262
{
 
263
  uint32_t lrpt, nrpt;
 
264
  int bytesRead;
 
265
 
 
266
  bytesRead = readFully(p->commfd, (void *)&nrpt, sizeof(uint32_t));
 
267
  if (bytesRead < 0)
 
268
    {
 
269
      printf("NetPIPE: read failed in RecvRepeat: errno=%d\n", errno);
 
270
      exit(305);
 
271
    }
 
272
  else if (bytesRead != sizeof(uint32_t))
 
273
    {
 
274
      fprintf(stderr, "NetPIPE: partial read in RecvRepeat of %d bytes\n",
 
275
              bytesRead);
 
276
      exit(306);
 
277
    }
 
278
  lrpt = ntohl(nrpt);
 
279
 
 
280
  *rpt = lrpt;
 
281
}
 
282
 
 
283
void establish(ArgStruct *p)
 
284
{
 
285
  int one = 1;
 
286
  socklen_t clen;
 
287
  struct protoent *proto;
 
288
 
 
289
  clen = (socklen_t) sizeof(p->prot.sipx2);
 
290
 
 
291
  if( p->tr ){
 
292
 
 
293
    while( connect(p->commfd, (struct sockaddr *) &(p->prot.sipx1),
 
294
                   sizeof(p->prot.sipx1)) < 0 ) {
 
295
 
 
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
 
299
       * we have success.
 
300
       */
 
301
      if(!doing_reset || errno != ECONNREFUSED) {
 
302
        printf("Client: Cannot Connect! errno=%d\n",errno);
 
303
        exit(-10);
 
304
      } 
 
305
        
 
306
    }
 
307
 
 
308
  } else if( p->rcv ) {
 
309
 
 
310
    /* SERVER */
 
311
    listen(p->servicefd, 5);
 
312
#if 0
 
313
    p->commfd = accept(p->servicefd, (struct sockaddr *) &(p->prot.sipx2), &clen);
 
314
#else
 
315
    p->commfd = accept(p->servicefd, NULL, NULL);
 
316
#endif
 
317
    if(p->commfd < 0){
 
318
      printf("Server: Accept Failed! errno=%d\n",errno);
 
319
      exit(-12);
 
320
    }
 
321
 
 
322
    /* If requested, set the send and receive buffer sizes */
 
323
    if(p->prot.sndbufsz > 0)
 
324
    {
 
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)
 
329
      {
 
330
        printf("setsockopt: SO_SNDBUF failed! errno=%d\n", errno);
 
331
        exit(556);
 
332
      }
 
333
      if(setsockopt(p->commfd, SOL_SOCKET, SO_RCVBUF, &(p->prot.rcvbufsz), 
 
334
                                       sizeof(p->prot.rcvbufsz)) < 0)
 
335
      {
 
336
        printf("setsockopt: SO_RCVBUF failed! errno=%d\n", errno);
 
337
        exit(556);
 
338
      }
 
339
    }
 
340
  }
 
341
}
 
342
 
 
343
void CleanUp(ArgStruct *p)
 
344
{
 
345
   char *quit="QUIT";
 
346
 
 
347
   if (p->tr) {
 
348
 
 
349
      write(p->commfd,quit, 5);
 
350
      read(p->commfd, quit, 5);
 
351
      close(p->commfd);
 
352
 
 
353
   } else if( p->rcv ) {
 
354
 
 
355
      read(p->commfd,quit, 5);
 
356
      write(p->commfd,quit,5);
 
357
      close(p->commfd);
 
358
      close(p->servicefd);
 
359
 
 
360
   }
 
361
}
 
362
 
 
363
 
 
364
void Reset(ArgStruct *p)
 
365
{
 
366
  
 
367
  /* Reset sockets */
 
368
 
 
369
  if(p->reset_conn) {
 
370
 
 
371
    doing_reset = 1;
 
372
 
 
373
    /* Close the sockets */
 
374
 
 
375
    CleanUp(p);
 
376
 
 
377
    /* Now open and connect new sockets */
 
378
 
 
379
    Setup(p);
 
380
 
 
381
  }
 
382
 
 
383
}
 
384
 
 
385
void AfterAlignmentInit(ArgStruct *p)
 
386
{
 
387
 
 
388
}
 
389