embkernel
 All Classes Functions Variables Typedefs Groups Pages
NetNbns.cpp
1 //------------------------------------------------------------------------------
2 //This file is part of embKernel.
3 //See license.txt for the full license governing this code.
4 //------------------------------------------------------------------------------
5 
6 #include "Net.hpp"
7 #include "NetUdp.hpp"
8 #include "NetNbns.hpp"
9 #include "LibEndian.hpp"
10 #include <string.h>
11 #include <ctype.h>
12 
13 void NetNbns::processFrame(NetDefs::FRAME& frame, NetDefs::NBNS_HEADER& header, int len) {
14  uint8_t* questionEntry = ((uint8_t*) &header) + sizeof(NetDefs::NBNS_HEADER);
15 
16  for (int i = LibEndian::hwToBe(header.questions); i > 0; i--) {
17  unsigned int labelLen = *questionEntry;
18 
19  uint16_t nbType = LibEndian::hwToBe(((uint16_t*) (&questionEntry[labelLen + 2]))[0]);
20  uint16_t nbClass = LibEndian::hwToBe(((uint16_t*) (&questionEntry[labelLen + 2]))[1]);
21 
22  //Check the type and class
23  if ((nbType == NetDefs::NBNS_TYPE_NB) && (nbClass == NetDefs::NBNS_CLASS_IN)) {
24  bool result = true;
25  uint8_t* data = &questionEntry[1];
26 
27  for (unsigned int j = 0; j < (labelLen >> 1); j++) {
28  char c;
29 
30  c = (((*data++) - 'A') << 4);
31  c |= ((*data++) - 'A');
32  if (c == 0x20) {
33  c = 0;
34  }
35  c = toupper(c);
36  if (c != toupper(Net::sConfig.deviceName[j]) || (j >= sizeof(Net::sConfig.deviceName))) {
37  result = false;
38  break;
39  }
40  }
41 
42  if (!result) {
43  questionEntry += labelLen + 6;
44  continue;
45  }
46 
47  NetDefs::FRAME * sendFrame = Net::allocFrame(sizeof(NetDefs::MAC_HEADER) + sizeof(NetDefs::IP_HEADER) + sizeof(NetDefs::UDP_HEADER) + 128);
48 
49  if (!sendFrame) {
50  questionEntry += labelLen + 6;
51  continue;
52  }
53 
54  sendFrame->types.nbns.nbnsHeader.id = header.id;
55  sendFrame->types.nbns.nbnsHeader.flags = LibEndian::hwToBe((uint16_t) 0x8400);
56  sendFrame->types.nbns.nbnsHeader.questions = 0;
57  sendFrame->types.nbns.nbnsHeader.answers = LibEndian::hwToBe((uint16_t) 0x0001);
58  sendFrame->types.nbns.nbnsHeader.authorities = 0;
59  sendFrame->types.nbns.nbnsHeader.additionals = 0;
60 
61  memcpy(&sendFrame->types.nbns.data[0], questionEntry, labelLen + 2);
62  const uint8_t trailer[] = {
63  0x00, 0x20, 0x00, 0x01, 0x00, 0x03, 0xF4, 0x80, 0x00, 0x06, 0x60, 0x00 };
64  memcpy(&sendFrame->types.nbns.data[labelLen + 2], trailer, sizeof(trailer));
65  memcpy(&sendFrame->types.nbns.data[labelLen + 2 + sizeof(trailer)], &Net::sConfig.ipAddr, sizeof(NetDefs::IP_ADDR));
66 
67  NetUdp::putHeader(*sendFrame, frame.types.mac.macHeader.srcAddr, frame.types.ip.ipHeader.srcAddr, frame.types.udp.udpHeader.srcPort,
68  NetDefs::UDP_PORT_NBNS, sizeof(NetDefs::NBNS_HEADER) + labelLen + 2 + sizeof(trailer) + sizeof(NetDefs::IP_ADDR));
69 
70  NetUdp::flush(*sendFrame, sizeof(NetDefs::NBNS_HEADER) + labelLen + 2 + sizeof(trailer) + sizeof(NetDefs::IP_ADDR), true);
71  questionEntry += labelLen + 6;
72  }
73  }
74  Net::freeFrame(frame);
75 }
76