helloBye3.cpp
Go to the documentation of this file.
1 #ifndef HELLOBYE3PROTO_CPP
2 #define HELLOBYE3PROTO_CPP
3 
4 #include <cstdlib>
5 #include <sstream>
6 
7 #include "IPv4_5TupleL2Ident.hpp"
8 #include "headers.hpp"
9 #include "helloBye3.hpp"
10 #include "mbuf.hpp"
11 #include "samplePacket.hpp"
12 
13 // using namespace Headers;
14 // using namespace std;
15 
16 namespace HelloBye3 {
17 
18 namespace Server {
19 
21  (void)id;
22  struct server *s = new server();
23  s->serverCookie = rand() % 256;
24  s->clientCookie = 0;
25  return s;
26 };
27 
28 void runHello(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
29  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
30 
31  server *s = reinterpret_cast<struct server *>(state.stateData);
32 
33  // Get info from packet
34  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
35  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
36  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
37 
38  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
39 
40  D(std::cout << "HelloBye3::Server::runHello() pkt: " << (void *)pkt->getData()
41  << ", ident: " << msg->ident << std::endl;)
42 
43  if (msg->role != 0) {
44  // std::abort();
45  std::cout << "HelloBye3::Server::runHello() client hello wrong - role not client"
46  << std::endl;
47  funIface.transition(States::Terminate);
48  delete (s);
49  funIface.freePkt();
50  return;
51  }
52 
53  if (msg->msg != 0) {
54  // std::abort();
55  std::cout << "HelloBye3::Server::runHello() client hello wrong - msg not hello"
56  << std::endl;
57  funIface.transition(States::Terminate);
58  delete (s);
59  funIface.freePkt();
60  return;
61  }
62 
63  // Get client cookie
64  s->clientCookie = msg->cookie;
65  D(std::cout << "HelloBye3::Server::runHello() clientCookie: "
66  << static_cast<int>(s->clientCookie) << std::endl;)
67 
70  msg->cookie = s->serverCookie;
71 
72  // Set the IP header stuff
73  // Leave the payload length alone for now...
74 
75  ipv4->ttl = 64;
76  uint32_t tmp = ipv4->dstIP;
77  ipv4->dstIP = ipv4->srcIP;
78  ipv4->srcIP = tmp;
79  ipv4->checksum = 0;
80 
81  // Set UDP checksum to 0 and hope for the best
82 
83  udp->checksum = 0;
84  uint16_t tmp16 = udp->dstPort;
85  udp->dstPort = udp->srcPort;
86  udp->srcPort = tmp16;
87 
88  funIface.transition(States::Bye);
89 };
90 
91 void runBye(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
92  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
93 
94  server *s = reinterpret_cast<struct server *>(state.stateData);
95 
96  // Get info from packet
97  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
98  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
99  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
100 
101  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
102 
103  if ((msg->role != msg::ROLE_CLIENT) || (msg->msg != msg::MSG_BYE)) {
104  std::cout << "HelloBye3::Server::runBye() msg fields wrong" << std::endl;
105  funIface.transition(States::Terminate);
106  delete (s);
107  funIface.freePkt();
108  return;
109  }
110 
111  if (msg->cookie != s->serverCookie) {
112  std::cout << "HelloBye3::Server::runBye() Client sent over wrong cookie" << std::endl;
113  funIface.transition(States::Terminate);
114  delete (s);
115  funIface.freePkt();
116  return;
117  }
118 
119  // Prepare new packet
120  msg->cookie = s->clientCookie;
122  msg->msg = msg::MSG_BYE;
123 
124  // Set the IP header stuff
125  // Leave the payload length alone for now...
126  ipv4->ttl = 64;
127  uint32_t tmp = ipv4->dstIP;
128  ipv4->dstIP = ipv4->srcIP;
129  ipv4->srcIP = tmp;
130  ipv4->checksum = 0;
131 
132  // Set UDP checksum to 0 and hope for the best
133  udp->checksum = 0;
134  uint16_t tmp16 = udp->dstPort;
135  udp->dstPort = udp->srcPort;
136  udp->srcPort = tmp16;
137 
138  // We are done after this -> transition to Terminate
139  funIface.transition(States::Terminate);
140  delete (s);
141 };
142 }; // namespace Server
143 
144 namespace Client {
146  uint32_t srcIp, uint32_t dstIp, uint16_t srcPort, uint16_t dstPort, uint64_t ident) {
147 
148  struct client *c = new client();
149  c->srcIp = srcIp;
150  c->dstIp = dstIp;
151  c->srcPort = srcPort;
152  c->dstPort = dstPort;
153  c->ident = ident;
154  c->clientCookie = rand() % 256;
155  c->serverCookie = 0;
156 
157  StateMachine<Identifier<mbuf>, mbuf>::State state(
158  States::Hello, reinterpret_cast<void *>(c));
159  return state;
160 };
161 
162 void runHello(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
163  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
164 
165  client *c = reinterpret_cast<struct client *>(state.stateData);
166 
167  memset(pkt->getData(), 0, pkt->getDataLen());
168 
169  // Get info from packet
170  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
171  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
172 
173  // Set the IP header stuff
174  // Leave the payload length alone for now...
175  ipv4->setVersion();
176  ipv4->setIHL(5);
177  ipv4->ttl = 64;
178  ipv4->setLength(100 - 14);
179  ipv4->setDstIP(c->dstIp);
180  ipv4->setSrcIP(c->srcIp);
181  ipv4->setProtoUDP();
182  ipv4->checksum = 0;
183 
184  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
185  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
186 
187  // Prepare msg
188  msg->ident = c->ident;
190  msg->cookie = c->clientCookie;
192 
193  ether->ethertype = htons(0x0800);
194 
195  // Set UDP checksum to 0 and hope for the best
196  udp->checksum = 0;
197  udp->setDstPort(c->dstPort);
198  udp->setSrcPort(c->srcPort);
199  udp->setPayloadLength(50);
200 
201  funIface.transition(States::Bye);
202 };
203 
204 void runBye(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
205  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
206 
207  client *c = reinterpret_cast<struct client *>(state.stateData);
208 
209  // Get info from packet
210  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
211  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
212  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
213 
214  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
215 
216  D(std::cout << "HelloBye3::Client::runBye() function called, ident:" << msg->ident
217  << std::endl;)
218 
219  if ((msg->role != msg::ROLE_SERVER) || (msg->msg != msg::MSG_HELLO)) {
220  std::cout << "HelloBye3::Client::runBye() msg fields wrong" << std::endl;
221  funIface.transition(States::Terminate);
222  delete (c);
223  funIface.freePkt();
224  return;
225  }
226 
227  // Get server cookie
228  c->serverCookie = msg->cookie;
229 
230  msg->cookie = c->serverCookie;
232  msg->msg = msg::MSG_BYE;
233 
234  // Set the IP header stuff
235  // Leave the payload length alone for now...
236  ipv4->ttl = 64;
237  uint32_t tmp = ipv4->dstIP;
238  ipv4->dstIP = ipv4->srcIP;
239  ipv4->srcIP = tmp;
240  ipv4->checksum = 0;
241 
242  // Set UDP checksum to 0 and hope for the best
243  udp->checksum = 0;
244  uint16_t tmp16 = udp->dstPort;
245  udp->dstPort = udp->srcPort;
246  udp->srcPort = tmp16;
247 
248  D(std::cout << "HelloBye3::Client::runBye() Dump of outgoing packet" << std::endl;)
249  D(hexdump(pkt->getData(), 64);)
250 
251  // We need to wait for the server reply
252  funIface.transition(States::RecvBye);
253 };
254 
255 void runRecvBye(StateMachine<Identifier<mbuf>, mbuf>::State &state, mbuf *pkt,
256  StateMachine<Identifier<mbuf>, mbuf>::FunIface &funIface) {
257 
258  client *c = reinterpret_cast<struct client *>(state.stateData);
259 
260  // Get info from packet
261  Headers::Ethernet *ether = reinterpret_cast<Headers::Ethernet *>(pkt->getData());
262  Headers::IPv4 *ipv4 = reinterpret_cast<Headers::IPv4 *>(ether->getPayload());
263  Headers::Udp *udp = reinterpret_cast<Headers::Udp *>(ipv4->getPayload());
264 
265  struct msg *msg = reinterpret_cast<struct msg *>(udp->getPayload());
266 
267  if ((msg->role != msg::ROLE_SERVER) || (msg->msg != msg::MSG_BYE)) {
268  std::cout << "HelloBye3::Client::runRecvBye() msg fields wrong" << std::endl;
269  funIface.transition(States::Terminate);
270  delete (c);
271  funIface.freePkt();
272  return;
273  }
274 
275  if (msg->cookie != c->clientCookie) {
276  std::cout << "HelloBye3::Client::runRecvBye() Server sent over wrong cookie"
277  << std::endl;
278  std::cout << "Expected: " << static_cast<int>(c->clientCookie);
279  std::cout << ", Got: " << static_cast<int>(msg->cookie) << std::endl;
280  funIface.transition(States::Terminate);
281  delete (c);
282  funIface.freePkt();
283  return;
284  }
285 
286  funIface.freePkt();
287 
288  // We are done after this -> transition to Terminate
289  funIface.transition(States::Terminate);
290  delete (c);
291 };
292 }; // namespace Client
293 }; // namespace HelloBye3
294 
295 extern "C" {
296 
297 /*
298  * Server
299  */
300 
302 
303  srand(time(NULL));
304 
306 
307  obj->registerEndStateID(HelloBye3::Server::States::Terminate);
309 
312 
313  return obj;
314 };
315 
316 void *HelloBye3_Server_process(void *obj, struct rte_mbuf **inPkts, unsigned int inCount,
317  unsigned int *sendCount, unsigned int *freeCount) {
318 
319  BufArray<mbuf> *inPktsBA =
320  new BufArray<mbuf>(reinterpret_cast<mbuf **>(inPkts), inCount, true);
321 
322  auto *sm = reinterpret_cast<StateMachine<HelloBye3::Identifier<mbuf>, mbuf> *>(obj);
323  sm->runPktBatch(*inPktsBA);
324  *sendCount = inPktsBA->getSendCount();
325  *freeCount = inPktsBA->getFreeCount();
326 
327  return inPktsBA;
328 };
329 
331  void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts) {
332  BufArray<mbuf> *inPktsBA = reinterpret_cast<BufArray<mbuf> *>(obj);
333 
334  inPktsBA->getSendBufs(reinterpret_cast<mbuf **>(sendPkts));
335  inPktsBA->getFreeBufs(reinterpret_cast<mbuf **>(freePkts));
336 
337  delete (inPktsBA);
338 };
339 
340 void HelloBye3_Server_free(void *obj) {
341  delete (reinterpret_cast<StateMachine<HelloBye3::Identifier<mbuf>, mbuf> *>(obj));
342 };
343 
344 /*
345  * Client
346  */
347 
349 
350  srand(time(NULL));
351 
353 
354  obj->registerEndStateID(HelloBye3::Client::States::Terminate);
355 
359 
360  return obj;
361 };
362 
363 void *HelloBye3_Client_connect(void *obj, struct rte_mbuf **inPkts, unsigned int inCount,
364  unsigned int *sendCount, unsigned int *freeCount, uint32_t srcIP, uint32_t dstIP,
365  uint16_t srcPort, uint16_t dstPort, uint64_t ident) {
366 
367  auto *sm = reinterpret_cast<StateMachine<HelloBye3::Identifier<mbuf>, mbuf> *>(obj);
368 
369  BufArray<mbuf> *inPktsBA =
370  new BufArray<mbuf>(reinterpret_cast<mbuf **>(inPkts), inCount, true);
371 
373  cID.ident = ident;
374 
375  auto state = HelloBye3::Client::createHello(srcIP, dstIP, srcPort, dstPort, ident);
376 
377  sm->addState(cID, state, *inPktsBA);
378 
379  *sendCount = inPktsBA->getSendCount();
380  *freeCount = inPktsBA->getFreeCount();
381 
382  return inPktsBA;
383 };
384 
386  void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts) {
387  BufArray<mbuf> *inPktsBA = reinterpret_cast<BufArray<mbuf> *>(obj);
388 
389  inPktsBA->getSendBufs(reinterpret_cast<mbuf **>(sendPkts));
390  inPktsBA->getFreeBufs(reinterpret_cast<mbuf **>(freePkts));
391 
392  delete (inPktsBA);
393 };
394 
395 void *HelloBye3_Client_process(void *obj, struct rte_mbuf **inPkts, unsigned int inCount,
396  unsigned int *sendCount, unsigned int *freeCount) {
397  BufArray<mbuf> *inPktsBA =
398  new BufArray<mbuf>(reinterpret_cast<mbuf **>(inPkts), inCount, true);
399 
400  auto *sm = reinterpret_cast<StateMachine<HelloBye3::Identifier<mbuf>, mbuf> *>(obj);
401  sm->runPktBatch(*inPktsBA);
402  *sendCount = inPktsBA->getSendCount();
403  *freeCount = inPktsBA->getFreeCount();
404 
405  return inPktsBA;
406 };
407 
408 void HelloBye3_Client_free(void *obj) {
409  delete (reinterpret_cast<StateMachine<HelloBye3::Identifier<mbuf>, mbuf> *>(obj));
410 };
411 };
412 #endif /* HELLOBYE3PROTO_CPP */
uint16_t checksum
header checksum
Definition: headers.hpp:122
void setSrcIP(uint32_t ip)
Set the source ip.
Definition: headers.hpp:129
void HelloBye3_Client_free(void *obj)
Free recources used by the state machine.
Definition: helloBye3.cpp:408
uint8_t role
Definition: helloBye3.hpp:17
void setProtoUDP()
Set the protocol to UDP.
Definition: headers.hpp:120
static constexpr uint8_t ROLE_SERVER
Definition: helloBye3.hpp:22
uint16_t getDataLen()
Definition: mbuf.hpp:11
Representation of the IPv4 header.
Definition: headers.hpp:65
State machine framework.
uint32_t dstIP
destination IPv4 address
Definition: headers.hpp:124
void * getPayload()
Get the SDU.
Definition: headers.hpp:149
uint8_t ttl
Time to live.
Definition: headers.hpp:106
void setSrcPort(uint16_t p)
Set the source port.
Definition: headers.hpp:218
void setDstIP(uint32_t ip)
Set the destination ip.
Definition: headers.hpp:134
uint32_t getFreeCount() const
Get the number of packets currently marked as free.
Definition: bufArray.hpp:166
Representation of the etherner header.
Definition: headers.hpp:15
uint32_t srcIP
source IPv4 address
Definition: headers.hpp:123
void HelloBye3_Client_getPkts(void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts)
Get the packets to send and free.
Definition: helloBye3.cpp:385
void setIHL(uint8_t len)
Sets the IP header length.
Definition: headers.hpp:81
static constexpr StateID Bye
Definition: helloBye3.hpp:129
void setDstPort(uint16_t p)
Set the destination port.
Definition: headers.hpp:223
void * HelloBye3_Client_process(void *obj, struct rte_mbuf **inPkts, unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount)
Process a batch of packets.
Definition: helloBye3.cpp:395
void hexdump(const void *data, int dataLen)
Dump hex data.
Definition: hexdump.cpp:12
Representation of the UDP header.
Definition: headers.hpp:209
void * getPayload()
Get the SDU.
Definition: headers.hpp:248
static constexpr uint8_t MSG_BYE
Definition: helloBye3.hpp:25
void * HelloBye3_Server_init()
Init a HelloBye server.
Definition: helloBye3.cpp:301
uint8_t cookie
Definition: helloBye3.hpp:19
void runHello(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
Definition: helloBye3.cpp:28
uint64_t ident
Definition: helloBye3.hpp:16
#define D(x)
Definition: common.hpp:10
void HelloBye3_Server_free(void *obj)
Free recources used by the state machine.
Definition: helloBye3.cpp:340
StateMachine< Identifier< mbuf >, mbuf >::State createHello(uint32_t srcIp, uint32_t dstIp, uint16_t srcPort, uint16_t dstPort, uint64_t ident)
Definition: helloBye3.cpp:145
void runHello(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
Definition: helloBye3.cpp:162
uint16_t srcPort
Source port.
Definition: headers.hpp:210
static constexpr uint8_t ROLE_CLIENT
Definition: helloBye3.hpp:21
void runBye(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
Definition: helloBye3.cpp:91
static constexpr StateID RecvBye
Definition: helloBye3.hpp:130
static constexpr StateID Terminate
Definition: helloBye3.hpp:131
uint32_t getSendCount() const
Get the number of packets currently marked as send.
Definition: bufArray.hpp:151
void setPayloadLength(uint16_t length)
Set the length of the L4-SDU (UDP payload)
Definition: headers.hpp:243
uint16_t dstPort
Destination port.
Definition: headers.hpp:211
void * HelloBye3_Client_connect(void *obj, struct rte_mbuf **inPkts, unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount, uint32_t srcIP, uint32_t dstIP, uint16_t srcPort, uint16_t dstPort, uint64_t ident)
Open a connection to a server.
Definition: helloBye3.cpp:363
Wrapper aroung DPDK rte_mbuf.
Definition: mbuf.hpp:9
static constexpr StateID Bye
Definition: helloBye3.hpp:95
void getSendBufs(Packet **sendBufs) const
Get all the packets which are to be sent.
Definition: bufArray.hpp:175
void * HelloBye3_Server_process(void *obj, struct rte_mbuf **inPkts, unsigned int inCount, unsigned int *sendCount, unsigned int *freeCount)
Process a batch of packets.
Definition: helloBye3.cpp:316
void runBye(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
Definition: helloBye3.cpp:204
void * HelloBye3_Client_init()
Init a HelloBye client.
Definition: helloBye3.cpp:348
static constexpr StateID Hello
Definition: helloBye3.hpp:94
void runRecvBye(StateMachine< Identifier< mbuf >, mbuf >::State &state, mbuf *pkt, StateMachine< Identifier< mbuf >, mbuf >::FunIface &funIface)
Definition: helloBye3.cpp:255
void getFreeBufs(Packet **freeBufs) const
Get all the packets which are to be freed.
Definition: bufArray.hpp:193
void setLength(uint16_t len)
Definition: headers.hpp:164
uint16_t checksum
Checksum.
Definition: headers.hpp:213
void HelloBye3_Server_getPkts(void *obj, struct rte_mbuf **sendPkts, struct rte_mbuf **freePkts)
Get the packets to send and free.
Definition: helloBye3.cpp:330
static constexpr StateID Terminate
Definition: helloBye3.hpp:96
static constexpr StateID Hello
Definition: helloBye3.hpp:128
void * getData()
Definition: mbuf.hpp:10
static constexpr uint8_t MSG_HELLO
Definition: helloBye3.hpp:24
Wrapper around MoonGen bufarrays.
Definition: bufArray.hpp:42
void * factory(Identifier< mbuf >::ConnectionID id)
Definition: helloBye3.cpp:20
void setVersion()
Set the version field to 4.
Definition: headers.hpp:73
void * getPayload()
Get the SDU.
Definition: headers.hpp:23