embkernel
 All Classes Functions Variables Typedefs Groups Pages
NetIp.cpp
1 //------------------------------------------------------------------------------
2 //This file is part of embKernel.
3 //See license.txt for the full license governing this code.
4 //------------------------------------------------------------------------------
5 
6 #include "NetIp.hpp"
7 #include "Net.hpp"
8 #include "NetIcmp.hpp"
9 #include "NetUdp.hpp"
10 #include "NetTcp.hpp"
11 #include "LibEndian.hpp"
12 #include "NetMac.hpp"
13 #include "NetChecksum.hpp"
14 
15 void NetIp::processFrame(NetDefs::FRAME& frame, NetDefs::IP_HEADER& header) {
16  swapHeader(header);
17 
18  if (checkDstAddress(header.dstAddr)) {
19 
20  //Calculate the sizes
21  int headerLen = (int) ((header.headerLen) << 2);
22  int optionLen = headerLen - sizeof(NetDefs::IP_HEADER);
23  int len = header.totalLen - headerLen;
24 
25  switch (header.protocol) {
26  case NetDefs::IP_PROTOCOL_ICMP:
27  NetIcmp::processFrame(frame, *((NetDefs::ICMP_HEADER*) (((uint8_t*) &header) + headerLen + optionLen)), len);
28  break;
29  case NetDefs::IP_PROTOCOL_UDP:
30  NetUdp::processFrame(frame, *((NetDefs::UDP_HEADER*) (((uint8_t*) &header) + headerLen + optionLen)), len);
31  break;
32  case NetDefs::IP_PROTOCOL_TCP:
33  NetTcp::processFrame(frame, *((NetDefs::TCP_HEADER*) (((uint8_t*) &header) + headerLen + optionLen)), len);
34  break;
35  default:
36  Net::freeFrame(frame);
37  break;
38  }
39  }
40  else {
41  Net::freeFrame(frame);
42  }
43 
44 }
45 
46 bool NetIp::checkDstAddress(NetDefs::IP_ADDR& address) {
47  //Broadcast
48  if (address == NetDefs::IP_BROADCAST) {
49  return true;
50  }
51  //Multicast
52  if ((address.val ^ (~Net::sConfig.mask.val)) == (Net::sConfig.ipAddr.val & Net::sConfig.mask.val)) {
53  return true;
54  }
55  //Unicast
56  if (address == Net::sConfig.ipAddr) {
57  return true;
58  }
59 
60  return false;
61 }
62 
63 void NetIp::putHeader(NetDefs::FRAME& frame, const NetDefs::MAC_ADDR& macDst, const NetDefs::IP_ADDR& ipDst, int dataLen, uint8_t protocol) {
64  static int identification = 0x0000;
65 
66  frame.types.ip.ipHeader.version = 4;
67  frame.types.ip.ipHeader.headerLen = 5;
68  frame.types.ip.ipHeader.typeOfService = 0x00;
69  frame.types.ip.ipHeader.totalLen = sizeof(NetDefs::IP_HEADER) + dataLen;
70  frame.types.ip.ipHeader.identification = ++identification;
71  frame.types.ip.ipHeader.fragmentInfo = 0;
72  frame.types.ip.ipHeader.timeToLive = 0x80;
73  frame.types.ip.ipHeader.protocol = (NetDefs::IP_PROTOCOL) protocol;
74  frame.types.ip.ipHeader.headerChecksum = 0;
75  frame.types.ip.ipHeader.dstAddr = ipDst;
76  frame.types.ip.ipHeader.srcAddr = Net::sConfig.ipAddr;
77 
78  swapHeader(frame.types.ip.ipHeader);
79 
80  frame.types.ip.ipHeader.headerChecksum = NetChecksum::finalizeCheckSum(NetChecksum::calcPartialChecksum((uint8_t*) &frame.types.ip.ipHeader, sizeof(NetDefs::IP_HEADER)));
81 
82  Net::putHeader(frame, macDst, NetDefs::MAC_TYPE_IP);
83 }
84 
85 void NetIp::flush(NetDefs::FRAME& frame, int dataLen, bool discardable) {
86  Net::flush(frame, sizeof(NetDefs::IP_HEADER) + dataLen, discardable);
87 }
88 
89 void NetIp::swapHeader(NetDefs::IP_HEADER& header) {
90  header.totalLen = LibEndian::hwToBe(header.totalLen);
91  header.identification = LibEndian::hwToBe(header.identification);
92  header.headerChecksum = LibEndian::hwToBe(header.headerChecksum);
93 }
94