Kernel/IPStack - (minor) TODO retransmit timer
[tpg/acess2.git] / Tools / NetTest_Runner / net.c
1 /*
2  */
3 #include <sys/socket.h>
4 #include <sys/un.h>
5 #include <string.h>
6 #include <stdbool.h>
7 #include <stdio.h>
8 #include <assert.h>
9 #include <sys/select.h>
10 #include "net.h"
11 #include <stdint.h>
12 #include <unistd.h>     // unlink/...
13 #include <sys/time.h>   // gettimeofday
14
15 #define CONNECT_TIMEOUT 10*1000
16 #define MAX_IFS 4
17
18 typedef struct {
19          int    FD;
20         socklen_t       addrlen;
21         struct sockaddr_un      addr;
22         FILE    *CapFP;
23 } tIf;
24
25 // === PROTOTYPES ===
26  int    Net_int_Open(const char *Path);
27
28 // === GLOBALS ===
29 tIf     gaInterfaces[MAX_IFS];
30
31 // === CODE ===
32 int Net_Open(int IfNum, const char *Path)
33 {
34         if( IfNum >= MAX_IFS )
35                 return 1;
36         
37         if(gaInterfaces[IfNum].FD != 0) return 1;
38         gaInterfaces[IfNum].addrlen = sizeof(gaInterfaces[IfNum].addr);
39         gaInterfaces[IfNum].FD = Net_int_Open(Path);
40         
41         char cappath[] = "testif00.pcap";
42         sprintf(cappath, "testif%i.pcap", IfNum);
43         gaInterfaces[IfNum].CapFP = fopen(cappath, "w");
44         {
45                 struct {
46                         uint32_t magic_number;   /* magic number */
47                         uint16_t version_major;  /* major version number */
48                         uint16_t version_minor;  /* minor version number */
49                          int32_t  thiszone;       /* GMT to local correction */
50                         uint32_t sigfigs;        /* accuracy of timestamps */
51                         uint32_t snaplen;        /* max length of captured packets, in octets */
52                         uint32_t network;        /* data link type */
53                 } __attribute__((packed)) hdr = {
54                         0xa1b2c3d4,
55                         2,4,
56                         0,
57                         0,
58                         65535,
59                         1
60                 };
61                 fwrite(&hdr, sizeof(hdr), 1, gaInterfaces[IfNum].CapFP);
62         }
63         return 0;
64 }
65
66 int Net_int_Open(const char *Path)
67 {
68         int fd = socket(AF_UNIX, SOCK_DGRAM, 0);
69         struct sockaddr_un      sa = {AF_UNIX, ""};
70         strcpy(sa.sun_path, Path);
71         unlink(Path);
72         if( bind(fd, (struct sockaddr*)&sa, sizeof(sa)) ) {
73                 perror("NetTest_OpenUnix - bind");
74                 close(fd);
75                 return -1;
76         }
77         
78         return fd;
79 }
80
81 void Net_Close(int IfNum)
82 {
83         assert(IfNum < MAX_IFS);
84         close(gaInterfaces[IfNum].FD);
85         gaInterfaces[IfNum].FD = 0;
86         fclose(gaInterfaces[IfNum].CapFP);
87 }
88
89 bool WaitOnFD(int FD, bool Write, unsigned int Timeout)
90 {
91         fd_set  fds;
92         FD_ZERO(&fds);
93         FD_SET(FD, &fds);
94         struct timeval  timeout;
95         timeout.tv_sec = Timeout/1000;
96         timeout.tv_usec = (Timeout%1000) * 1000;
97         
98         if( Write )
99                 select(FD+1, NULL, &fds, NULL, &timeout);
100         else
101                 select(FD+1, &fds, NULL, NULL, &timeout);
102         return FD_ISSET(FD, &fds);
103 }
104
105 bool Net_int_EnsureConnected(int IfNum)
106 {
107         assert(IfNum < MAX_IFS);
108         #if 0
109         if( gaInterface_Clients[IfNum] == 0 )
110         {
111                 //if( !WaitOnFD(gaInterface_Servers[IfNum], CONNECT_TIMEOUT) )
112                 //{
113                 //      fprintf(stderr, "ERROR: Client has not connected");
114                 //      return false;
115                 //}
116                 gaInterface_Clients[IfNum] = accept(gaInterface_Servers[IfNum], NULL, NULL);
117                 if( gaInterface_Clients[IfNum] < 0 ) {
118                         perror("Net_int_EnsureConnected - accept");
119                         return false;
120                 }
121         }
122         #endif
123         return true;
124 }
125
126 void Net_int_SavePacket(tIf *If, size_t size, const void *data)
127 {
128         struct timeval  curtime;
129         gettimeofday(&curtime, NULL);
130         struct {
131                 uint32_t ts_sec;
132                 uint32_t ts_usec;
133                 uint32_t incl_len;
134                 uint32_t orig_len;
135         } __attribute__((packed)) hdr = {
136                 curtime.tv_sec, curtime.tv_usec,
137                 size, size
138         };
139         fwrite(&hdr, sizeof(hdr), 1, If->CapFP);
140         fwrite(data, size, 1, If->CapFP);
141 }
142
143 size_t Net_Receive(int IfNum, size_t MaxLen, void *DestBuf, unsigned int Timeout)
144 {
145         assert(IfNum < MAX_IFS);
146         tIf     *If = &gaInterfaces[IfNum];
147         
148         if( Net_int_EnsureConnected(IfNum) && WaitOnFD(If->FD, false, Timeout) )
149         {
150                 size_t rv = recvfrom(If->FD, DestBuf, MaxLen, 0, (struct sockaddr*)&If->addr, &If->addrlen);
151                 Net_int_SavePacket(If, rv, DestBuf);
152                 return rv;
153         }
154         return 0;
155 }
156
157 void Net_Send(int IfNum, size_t Length, const void *Buf)
158 {
159         assert(IfNum < MAX_IFS);
160         tIf     *If = &gaInterfaces[IfNum];
161         
162         if( !WaitOnFD(If->FD, true, CONNECT_TIMEOUT) )
163                 return ;
164         Net_int_SavePacket(If, Length, Buf);
165         int rv = sendto(If->FD, Buf, Length, 0, (struct sockaddr*)&If->addr, If->addrlen);
166         if( rv < 0 )
167                 perror("Net_Send - send");
168 }
169
170

UCC git Repository :: git.ucc.asn.au