net_misc.c
Go to the documentation of this file.
1 /**
2  * @file net_misc.c
3  * @brief Helper functions for TCP/IP stack
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2022 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.2.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "core/net_misc.h"
37 #include "core/socket.h"
38 #include "core/raw_socket.h"
39 #include "core/tcp_timer.h"
40 #include "core/tcp_misc.h"
41 #include "core/ethernet.h"
42 #include "ipv4/arp.h"
43 #include "ipv4/ipv4.h"
44 #include "ipv4/ipv4_routing.h"
45 #include "ipv4/auto_ip_misc.h"
46 #include "igmp/igmp_host.h"
47 #include "ipv6/ipv6.h"
48 #include "ipv6/ipv6_routing.h"
49 #include "ipv6/mld.h"
50 #include "ipv6/ndp.h"
52 #include "dhcp/dhcp_client_misc.h"
53 #include "dhcp/dhcp_server_misc.h"
55 #include "dns/dns_cache.h"
56 #include "dns/dns_client.h"
57 #include "mdns/mdns_client.h"
58 #include "mdns/mdns_responder.h"
59 #include "mdns/mdns_common.h"
60 #include "dns_sd/dns_sd.h"
61 #include "netbios/nbns_client.h"
62 #include "netbios/nbns_responder.h"
63 #include "netbios/nbns_common.h"
64 #include "llmnr/llmnr_client.h"
65 #include "llmnr/llmnr_responder.h"
66 #include "mibs/mib2_module.h"
67 #include "mibs/if_mib_module.h"
68 #include "debug.h"
69 
70 //Default options passed to the stack (TX path)
72 {
73  0, //Time-to-live value
74  FALSE, //Do not send the packet via a router
75  FALSE, //Do not add an IP Router Alert option
76 #if (IP_DIFF_SERV_SUPPORT == ENABLED)
77  0, //Differentiated services codepoint
78 #endif
79 #if (ETH_SUPPORT == ENABLED)
80  {{{0}}}, //Source MAC address
81  {{{0}}}, //Destination MAC address
82 #endif
83 #if (ETH_VLAN_SUPPORT == ENABLED)
84  -1, //VLAN priority (802.1Q)
85  -1, //Drop eligible indicator
86 #endif
87 #if (ETH_VMAN_SUPPORT == ENABLED)
88  -1, //VMAN priority (802.1ad)
89  -1, //Drop eligible indicator
90 #endif
91 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
92  0, //Egress port identifier
93  0, //Egress port map
94  FALSE, //Override port state
95 #endif
96 #if (ETH_TIMESTAMP_SUPPORT == ENABLED)
97  -1, //Unique identifier for hardware time stamping
98 #endif
99 };
100 
101 //Default options passed to the stack (RX path)
103 {
104  0, //Time-to-live value
105 #if (ETH_SUPPORT == ENABLED)
106  {{{0}}}, //Source MAC address
107  {{{0}}}, //Destination MAC address
108  0, //Ethernet type field
109 #endif
110 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
111  0, //Ingress port identifier
112 #endif
113 #if (ETH_TIMESTAMP_SUPPORT == ENABLED)
114  {0}, //Captured time stamp
115 #endif
116 };
117 
118 
119 /**
120  * @brief Register link change callback
121  * @param[in] interface Underlying network interface
122  * @param[in] callback Callback function to be called when the link state changed
123  * @param[in] param Callback function parameter
124  * @return Error code
125  **/
126 
128  NetLinkChangeCallback callback, void *param)
129 {
130  uint_t i;
132 
133  //Loop through the table
134  for(i = 0; i < NET_MAX_LINK_CHANGE_CALLBACKS; i++)
135  {
136  //Point to the current entry
137  entry = &netContext.linkChangeCallbacks[i];
138 
139  //Check whether the entry is available
140  if(entry->callback == NULL)
141  {
142  //Create a new entry
143  entry->interface = interface;
144  entry->callback = callback;
145  entry->param = param;
146 
147  //Successful processing
148  return NO_ERROR;
149  }
150  }
151 
152  //The table runs out of space
153  return ERROR_OUT_OF_RESOURCES;
154 }
155 
156 
157 /**
158  * @brief Unregister link change callback
159  * @param[in] interface Underlying network interface
160  * @param[in] callback Callback function to be unregistered
161  * @param[in] param Callback function parameter
162  * @return Error code
163  **/
164 
166  NetLinkChangeCallback callback, void *param)
167 {
168  uint_t i;
170 
171  //Loop through the table
172  for(i = 0; i < NET_MAX_LINK_CHANGE_CALLBACKS; i++)
173  {
174  //Point to the current entry
175  entry = &netContext.linkChangeCallbacks[i];
176 
177  //Check whether the current entry matches the specified callback function
178  if(entry->interface == interface && entry->callback == callback &&
179  entry->param == param)
180  {
181  //Unregister callback function
182  entry->interface = NULL;
183  entry->callback = NULL;
184  entry->param = NULL;
185  }
186  }
187 
188  //Successful processing
189  return NO_ERROR;
190 }
191 
192 
193 /**
194  * @brief Process link state change event
195  * @param[in] interface Underlying network interface
196  **/
197 
199 {
200  uint_t i;
201  Socket *socket;
202 
203  //Check link state
204  if(interface->linkState)
205  {
206  //Display link state
207  TRACE_INFO("Link is up (%s)...\r\n", interface->name);
208 
209  //Display link speed
210  if(interface->linkSpeed == NIC_LINK_SPEED_1GBPS)
211  {
212  //1000BASE-T
213  TRACE_INFO(" Link speed = 1000 Mbps\r\n");
214  }
215  else if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
216  {
217  //100BASE-TX
218  TRACE_INFO(" Link speed = 100 Mbps\r\n");
219  }
220  else if(interface->linkSpeed == NIC_LINK_SPEED_10MBPS)
221  {
222  //10BASE-T
223  TRACE_INFO(" Link speed = 10 Mbps\r\n");
224  }
225  else if(interface->linkSpeed != NIC_LINK_SPEED_UNKNOWN)
226  {
227  //10BASE-T
228  TRACE_INFO(" Link speed = %" PRIu32 " bps\r\n",
229  interface->linkSpeed);
230  }
231 
232  //Display duplex mode
233  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
234  {
235  //1000BASE-T
236  TRACE_INFO(" Duplex mode = Full-Duplex\r\n");
237  }
238  else if(interface->duplexMode == NIC_HALF_DUPLEX_MODE)
239  {
240  //100BASE-TX
241  TRACE_INFO(" Duplex mode = Half-Duplex\r\n");
242  }
243  }
244  else
245  {
246  //Display link state
247  TRACE_INFO("Link is down (%s)...\r\n", interface->name);
248  }
249 
250  //The time at which the interface entered its current operational state
251  MIB2_IF_SET_TIME_TICKS(ifTable[interface->index].ifLastChange,
252  osGetSystemTime64() / 10);
253  IF_MIB_SET_TIME_TICKS(ifTable[interface->index].ifLastChange,
254  osGetSystemTime64() / 10);
255 
256 #if (IPV4_SUPPORT == ENABLED)
257  //Notify IPv4 of link state changes
258  ipv4LinkChangeEvent(interface);
259 #endif
260 
261 #if (IPV6_SUPPORT == ENABLED)
262  //Notify IPv6 of link state changes
263  ipv6LinkChangeEvent(interface);
264 #endif
265 
266 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \
267  NBNS_CLIENT_SUPPORT == ENABLED)
268  //Flush DNS cache
269  dnsFlushCache(interface);
270 #endif
271 
272 #if (MDNS_RESPONDER_SUPPORT == ENABLED)
273  //Perform probing and announcing
274  mdnsResponderLinkChangeEvent(interface->mdnsResponderContext);
275 #endif
276 
277 #if (DNS_SD_SUPPORT == ENABLED)
278  //Perform probing and announcing
279  dnsSdLinkChangeEvent(interface->dnsSdContext);
280 #endif
281 
282  //Loop through the link change callback table
283  for(i = 0; i < NET_MAX_LINK_CHANGE_CALLBACKS; i++)
284  {
286 
287  //Point to the current entry
288  entry = &netContext.linkChangeCallbacks[i];
289 
290  //Any registered callback?
291  if(entry->callback != NULL)
292  {
293  //Check whether the network interface matches the current entry
294  if(entry->interface == NULL || entry->interface == interface)
295  {
296  //Invoke user callback function
297  entry->callback(interface, interface->linkState, entry->param);
298  }
299  }
300  }
301 
302  //Loop through opened sockets
303  for(i = 0; i < SOCKET_MAX_COUNT; i++)
304  {
305  //Point to the current socket
306  socket = socketTable + i;
307 
308 #if (TCP_SUPPORT == ENABLED)
309  //Connection-oriented socket?
310  if(socket->type == SOCKET_TYPE_STREAM)
311  {
313  }
314 #endif
315 
316 #if (UDP_SUPPORT == ENABLED)
317  //Connectionless socket?
318  if(socket->type == SOCKET_TYPE_DGRAM)
319  {
321  }
322 #endif
323 
324 #if (RAW_SOCKET_SUPPORT == ENABLED)
325  //Raw socket?
326  if(socket->type == SOCKET_TYPE_RAW_IP ||
327  socket->type == SOCKET_TYPE_RAW_ETH)
328  {
330  }
331 #endif
332  }
333 }
334 
335 
336 /**
337  * @brief Register timer callback
338  * @param[in] period Timer reload value, in milliseconds
339  * @param[in] callback Callback function to be called when the timer expires
340  * @param[in] param Callback function parameter
341  * @return Error code
342  **/
343 
345  void *param)
346 {
347  uint_t i;
348  NetTimerCallbackEntry *entry;
349 
350  //Loop through the table
351  for(i = 0; i < NET_MAX_TIMER_CALLBACKS; i++)
352  {
353  //Point to the current entry
354  entry = &netContext.timerCallbacks[i];
355 
356  //Check whether the entry is available
357  if(entry->callback == NULL)
358  {
359  //Create a new entry
360  entry->timerValue = 0;
361  entry->timerPeriod = period;
362  entry->callback = callback;
363  entry->param = param;
364 
365  //Successful processing
366  return NO_ERROR;
367  }
368  }
369 
370  //The table runs out of space
371  return ERROR_OUT_OF_RESOURCES;
372 }
373 
374 
375 /**
376  * @brief Unregister timer callback
377  * @param[in] callback Callback function to be unregistered
378  * @param[in] param Callback function parameter
379  * @return Error code
380  **/
381 
383 {
384  uint_t i;
385  NetTimerCallbackEntry *entry;
386 
387  //Loop through the table
388  for(i = 0; i < NET_MAX_TIMER_CALLBACKS; i++)
389  {
390  //Point to the current entry
391  entry = &netContext.timerCallbacks[i];
392 
393  //Check whether the current entry matches the specified callback function
394  if(entry->callback == callback && entry->param == param)
395  {
396  //Unregister callback function
397  entry->timerValue = 0;
398  entry->timerPeriod = 0;
399  entry->callback = NULL;
400  entry->param = NULL;
401  }
402  }
403 
404  //Successful processing
405  return NO_ERROR;
406 }
407 
408 
409 /**
410  * @brief Manage TCP/IP timers
411  **/
412 
413 void netTick(void)
414 {
415  uint_t i;
416  NetTimerCallbackEntry *entry;
417 
418  //Increment tick counter
420 
421  //Handle periodic operations such as polling the link state
423  {
424  //Loop through network interfaces
425  for(i = 0; i < NET_INTERFACE_COUNT; i++)
426  {
427  //Make sure the interface has been properly configured
428  if(netInterface[i].configured)
429  nicTick(&netInterface[i]);
430  }
431 
432  //Reset tick counter
433  nicTickCounter = 0;
434  }
435 
436 #if (PPP_SUPPORT == ENABLED)
437  //Increment tick counter
439 
440  //Manage PPP related timers
442  {
443  //Loop through network interfaces
444  for(i = 0; i < NET_INTERFACE_COUNT; i++)
445  {
446  //Make sure the interface has been properly configured
447  if(netInterface[i].configured)
448  pppTick(&netInterface[i]);
449  }
450 
451  //Reset tick counter
452  pppTickCounter = 0;
453  }
454 #endif
455 
456 #if (IPV4_SUPPORT == ENABLED && ETH_SUPPORT == ENABLED)
457  //Increment tick counter
459 
460  //Manage ARP cache
462  {
463  //Loop through network interfaces
464  for(i = 0; i < NET_INTERFACE_COUNT; i++)
465  {
466  //Make sure the interface has been properly configured
467  if(netInterface[i].configured)
468  arpTick(&netInterface[i]);
469  }
470 
471  //Reset tick counter
472  arpTickCounter = 0;
473  }
474 #endif
475 
476 #if (IPV4_SUPPORT == ENABLED && IPV4_FRAG_SUPPORT == ENABLED)
477  //Increment tick counter
479 
480  //Handle IPv4 fragment reassembly timeout
482  {
483  //Loop through network interfaces
484  for(i = 0; i < NET_INTERFACE_COUNT; i++)
485  {
486  //Make sure the interface has been properly configured
487  if(netInterface[i].configured)
489  }
490 
491  //Reset tick counter
493  }
494 #endif
495 
496 #if (IPV4_SUPPORT == ENABLED && (IGMP_HOST_SUPPORT == ENABLED || \
497  IGMP_ROUTER_SUPPORT == ENABLED || IGMP_SNOOPING_SUPPORT == ENABLED))
498  //Increment tick counter
500 
501  //Handle IGMP related timers
503  {
504  //Loop through network interfaces
505  for(i = 0; i < NET_INTERFACE_COUNT; i++)
506  {
507  //Make sure the interface has been properly configured
508  if(netInterface[i].configured)
509  igmpTick(&netInterface[i]);
510  }
511 
512  //Reset tick counter
513  igmpTickCounter = 0;
514  }
515 #endif
516 
517 #if (IPV4_SUPPORT == ENABLED && AUTO_IP_SUPPORT == ENABLED)
518  //Increment tick counter
520 
521  //Handle Auto-IP related timers
523  {
524  //Loop through network interfaces
525  for(i = 0; i < NET_INTERFACE_COUNT; i++)
526  autoIpTick(netInterface[i].autoIpContext);
527 
528  //Reset tick counter
529  autoIpTickCounter = 0;
530  }
531 #endif
532 
533 #if (IPV4_SUPPORT == ENABLED && DHCP_CLIENT_SUPPORT == ENABLED)
534  //Increment tick counter
536 
537  //Handle DHCP client related timers
539  {
540  //Loop through network interfaces
541  for(i = 0; i < NET_INTERFACE_COUNT; i++)
542  dhcpClientTick(netInterface[i].dhcpClientContext);
543 
544  //Reset tick counter
546  }
547 #endif
548 
549 #if (IPV4_SUPPORT == ENABLED && DHCP_SERVER_SUPPORT == ENABLED)
550  //Increment tick counter
552 
553  //Handle DHCP server related timers
555  {
556  //Loop through network interfaces
557  for(i = 0; i < NET_INTERFACE_COUNT; i++)
558  dhcpServerTick(netInterface[i].dhcpServerContext);
559 
560  //Reset tick counter
562  }
563 #endif
564 
565 #if (IPV6_SUPPORT == ENABLED && IPV6_FRAG_SUPPORT == ENABLED)
566  //Increment tick counter
568 
569  //Handle IPv6 fragment reassembly timeout
571  {
572  //Loop through network interfaces
573  for(i = 0; i < NET_INTERFACE_COUNT; i++)
574  {
575  //Make sure the interface has been properly configured
576  if(netInterface[i].configured)
578  }
579 
580  //Reset tick counter
582  }
583 #endif
584 
585 #if (IPV6_SUPPORT == ENABLED && MLD_SUPPORT == ENABLED)
586  //Increment tick counter
588 
589  //Handle MLD related timers
591  {
592  //Loop through network interfaces
593  for(i = 0; i < NET_INTERFACE_COUNT; i++)
594  {
595  //Make sure the interface has been properly configured
596  if(netInterface[i].configured)
597  mldTick(&netInterface[i]);
598  }
599 
600  //Reset tick counter
601  mldTickCounter = 0;
602  }
603 #endif
604 
605 #if (IPV6_SUPPORT == ENABLED && NDP_SUPPORT == ENABLED)
606  //Increment tick counter
608 
609  //Handle NDP related timers
611  {
612  //Loop through network interfaces
613  for(i = 0; i < NET_INTERFACE_COUNT; i++)
614  {
615  //Make sure the interface has been properly configured
616  if(netInterface[i].configured)
617  ndpTick(&netInterface[i]);
618  }
619 
620  //Reset tick counter
621  ndpTickCounter = 0;
622  }
623 #endif
624 
625 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED)
626  //Increment tick counter
628 
629  //Handle RA service related timers
631  {
632  //Loop through network interfaces
633  for(i = 0; i < NET_INTERFACE_COUNT; i++)
634  ndpRouterAdvTick(netInterface[i].ndpRouterAdvContext);
635 
636  //Reset tick counter
638  }
639 #endif
640 
641 #if (IPV6_SUPPORT == ENABLED && DHCPV6_CLIENT_SUPPORT == ENABLED)
642  //Increment tick counter
644 
645  //Handle DHCPv6 client related timers
647  {
648  //Loop through network interfaces
649  for(i = 0; i < NET_INTERFACE_COUNT; i++)
650  dhcpv6ClientTick(netInterface[i].dhcpv6ClientContext);
651 
652  //Reset tick counter
654  }
655 #endif
656 
657 #if (TCP_SUPPORT == ENABLED)
658  //Increment tick counter
660 
661  //Manage TCP related timers
663  {
664  //TCP timer handler
665  tcpTick();
666  //Reset tick counter
667  tcpTickCounter = 0;
668  }
669 #endif
670 
671 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \
672  NBNS_CLIENT_SUPPORT == ENABLED || LLMNR_CLIENT_SUPPORT == ENABLED)
673  //Increment tick counter
675 
676  //Manage DNS cache
678  {
679  //DNS timer handler
680  dnsTick();
681  //Reset tick counter
682  dnsTickCounter = 0;
683  }
684 #endif
685 
686 #if (MDNS_RESPONDER_SUPPORT == ENABLED)
687  //Increment tick counter
689 
690  //Manage mDNS probing and announcing
692  {
693  //Loop through network interfaces
694  for(i = 0; i < NET_INTERFACE_COUNT; i++)
695  mdnsResponderTick(netInterface[i].mdnsResponderContext);
696 
697  //Reset tick counter
699  }
700 #endif
701 
702 #if (DNS_SD_SUPPORT == ENABLED)
703  //Increment tick counter
705 
706  //Manage DNS-SD probing and announcing
708  {
709  //Loop through network interfaces
710  for(i = 0; i < NET_INTERFACE_COUNT; i++)
711  dnsSdTick(netInterface[i].dnsSdContext);
712 
713  //Reset tick counter
714  dnsSdTickCounter = 0;
715  }
716 #endif
717 
718  //Loop through the timer callback table
719  for(i = 0; i < NET_MAX_TIMER_CALLBACKS; i++)
720  {
721  //Point to the current entry
722  entry = &netContext.timerCallbacks[i];
723 
724  //Any registered callback?
725  if(entry->callback != NULL)
726  {
727  //Increment timer value
728  entry->timerValue += NET_TICK_INTERVAL;
729 
730  //Timer period elapsed?
731  if(entry->timerValue >= entry->timerPeriod)
732  {
733  //Invoke user callback function
734  entry->callback(entry->param);
735  //Reload timer
736  entry->timerValue = 0;
737  }
738  }
739  }
740 }
741 
742 
743 /**
744  * @brief Start timer
745  * @param[in] timer Pointer to the timer structure
746  * @param[in] interval Time interval
747  **/
748 
749 void netStartTimer(NetTimer *timer, systime_t interval)
750 {
751  //Start timer
752  timer->startTime = osGetSystemTime();
753  timer->interval = interval;
754  timer->running = TRUE;
755 }
756 
757 
758 /**
759  * @brief Stop timer
760  * @param[in] timer Pointer to the timer structure
761  **/
762 
763 void netStopTimer(NetTimer *timer)
764 {
765  //Stop timer
766  timer->running = FALSE;
767 }
768 
769 
770 /**
771  * @brief Check whether the timer is running
772  * @param[in] timer Pointer to the timer structure
773  * @return TRUE if the timer is running, else FALSE
774  **/
775 
777 {
778  //Return TRUE if the timer is running
779  return timer->running;
780 }
781 
782 
783 /**
784  * @brief Check whether the timer has expired
785  * @param[in] timer Pointer to the timer structure
786  * @return TRUE if the timer has expired, else FALSE
787  **/
788 
790 {
791  bool_t expired;
792  systime_t time;
793 
794  //Initialize flag
795  expired = FALSE;
796  //Get current time
797  time = osGetSystemTime();
798 
799  //Check whether the timer is running
800  if(timer->running)
801  {
802  //Check whether the specified time interval has elapsed
803  if(timeCompare(time, timer->startTime + timer->interval) >= 0)
804  {
805  expired = TRUE;
806  }
807  }
808 
809  //Return TRUE if the timer has expired
810  return expired;
811 }
812 
813 
814 /**
815  * @brief Initialize random number generator
816  **/
817 
818 void netInitRand(void)
819 {
820  uint_t i;
821  NetRandState *state;
822  uint8_t iv[10];
823 
824  //Point to the PRNG state
825  state = &netContext.randState;
826 
827  //Increment invocation counter
828  state->counter++;
829 
830  //Copy the EUI-64 identifier of the default interface
831  eui64CopyAddr(iv, &netInterface[0].eui64);
832  //Append the invocation counter
833  STORE16BE(state->counter, iv + sizeof(Eui64));
834 
835  //Clear the 288-bit internal state
836  osMemset(state->s, 0, 36);
837 
838  //Let (s1, s2, ..., s93) = (K1, ..., K80, 0, ..., 0)
839  for(i = 0; i < 10; i++)
840  {
841  state->s[i] = netContext.randSeed[i];
842  }
843 
844  //Load the 80-bit initialization vector
845  for(i = 0; i < 10; i++)
846  {
847  state->s[12 + i] = iv[i];
848  }
849 
850  //Let (s94, s95, ..., s177) = (IV1, ..., IV80, 0, ..., 0)
851  for(i = 11; i < 22; i++)
852  {
853  state->s[i] = (state->s[i + 1] << 5) | (state->s[i] >> 3);
854  }
855 
856  //Let (s178, s279, ..., s288) = (0, ..., 0, 1, 1, 1)
857  NET_RAND_STATE_SET_BIT(state->s, 286, 1);
858  NET_RAND_STATE_SET_BIT(state->s, 287, 1);
859  NET_RAND_STATE_SET_BIT(state->s, 288, 1);
860 
861  //The state is rotated over 4 full cycles, without generating key stream bit
862  for(i = 0; i < (4 * 288); i++)
863  {
864  netGenerateRandBit(state);
865  }
866 }
867 
868 
869 /**
870  * @brief Generate a random 32-bit value
871  * @return Random value
872  **/
873 
874 uint32_t netGenerateRand(void)
875 {
876  uint_t i;
877  uint32_t value;
878 
879  //Initialize value
880  value = 0;
881 
882  //Generate a random 32-bit value
883  for(i = 0; i < 32; i++)
884  {
886  }
887 
888  //Return the random value
889  return value + netContext.entropy;
890 }
891 
892 
893 /**
894  * @brief Generate a random value in the specified range
895  * @param[in] min Lower bound
896  * @param[in] max Upper bound
897  * @return Random value in the specified range
898  **/
899 
900 uint32_t netGenerateRandRange(uint32_t min, uint32_t max)
901 {
902  uint32_t value;
903 
904  //Valid parameters?
905  if(max > min)
906  {
907  //Pick up a random value in the given range
908  value = min + (netGenerateRand() % (max - min + 1));
909  }
910  else
911  {
912  //Use default value
913  value = min;
914  }
915 
916  //Return the random value
917  return value;
918 }
919 
920 
921 /**
922  * @brief Get a string of random data
923  * @param[out] data Buffer where to store random data
924  * @param[in] length Number of random bytes to generate
925  **/
926 
927 void netGenerateRandData(uint8_t *data, size_t length)
928 {
929  size_t i;
930  size_t j;
931 
932  //Generate a string of random data
933  for(i = 0; i < length; i++)
934  {
935  //Initialize value
936  data[i] = 0;
937 
938  //Generate a random 8-bit value
939  for(j = 0; j < 8; j++)
940  {
942  }
943 
944  data[i] += netContext.entropy;
945  }
946 }
947 
948 
949 /**
950  * @brief Generate one random bit
951  * @param[in] state Pointer to the PRNG state
952  * @return Key stream bit
953  **/
954 
956 {
957  uint_t i;
958  uint8_t t1;
959  uint8_t t2;
960  uint8_t t3;
961  uint8_t z;
962 
963  //Let t1 = s66 + s93
964  t1 = NET_RAND_GET_BIT(state->s, 66);
965  t1 ^= NET_RAND_GET_BIT(state->s, 93);
966 
967  //Let t2 = s162 + s177
968  t2 = NET_RAND_GET_BIT(state->s, 162);
969  t2 ^= NET_RAND_GET_BIT(state->s, 177);
970 
971  //Let t3 = s243 + s288
972  t3 = NET_RAND_GET_BIT(state->s, 243);
973  t3 ^= NET_RAND_GET_BIT(state->s, 288);
974 
975  //Generate a key stream bit z
976  z = t1 ^ t2 ^ t3;
977 
978  //Let t1 = t1 + s91.s92 + s171
979  t1 ^= NET_RAND_GET_BIT(state->s, 91) & NET_RAND_GET_BIT(state->s, 92);
980  t1 ^= NET_RAND_GET_BIT(state->s, 171);
981 
982  //Let t2 = t2 + s175.s176 + s264
983  t2 ^= NET_RAND_GET_BIT(state->s, 175) & NET_RAND_GET_BIT(state->s, 176);
984  t2 ^= NET_RAND_GET_BIT(state->s, 264);
985 
986  //Let t3 = t3 + s286.s287 + s69
987  t3 ^= NET_RAND_GET_BIT(state->s, 286) & NET_RAND_GET_BIT(state->s, 287);
988  t3 ^= NET_RAND_GET_BIT(state->s, 69);
989 
990  //Rotate the internal state
991  for(i = 35; i > 0; i--)
992  {
993  state->s[i] = (state->s[i] << 1) | (state->s[i - 1] >> 7);
994  }
995 
996  state->s[0] = state->s[0] << 1;
997 
998  //Let s1 = t3
999  NET_RAND_STATE_SET_BIT(state->s, 1, t3);
1000  //Let s94 = t1
1001  NET_RAND_STATE_SET_BIT(state->s, 94, t1);
1002  //Let s178 = t2
1003  NET_RAND_STATE_SET_BIT(state->s, 178, t2);
1004 
1005  //Return one bit of key stream
1006  return z;
1007 }
__start_packed struct @1 Eui64
EUI-64 identifier.
uint8_t length
Definition: coap_common.h:193
IPv6 (Internet Protocol Version 6)
@ NIC_LINK_SPEED_1GBPS
Definition: nic.h:111
NetTimerCallback callback
Definition: net_misc.h:95
MIB-II module.
systime_t ipv4FragTickCounter
Definition: ipv4_frag.c:57
void netStartTimer(NetTimer *timer, systime_t interval)
Start timer.
Definition: net_misc.c:749
void ipv6FragTick(NetInterface *interface)
Fragment reassembly timeout handler.
Definition: ipv6_frag.c:547
#define IF_MIB_SET_TIME_TICKS(name, value)
Definition: if_mib_module.h:46
int bool_t
Definition: compiler_port.h:48
void ipv4FragTick(NetInterface *interface)
Fragment reassembly timeout handler.
Definition: ipv4_frag.c:472
@ NIC_LINK_SPEED_UNKNOWN
Definition: nic.h:108
bool_t running
Definition: net_misc.h:173
const NetTxAncillary NET_DEFAULT_TX_ANCILLARY
Definition: net_misc.c:71
systime_t timerPeriod
Definition: net_misc.h:94
bool_t netTimerRunning(NetTimer *timer)
Check whether the timer is running.
Definition: net_misc.c:776
uint8_t data[]
Definition: ethernet.h:220
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:123
#define NET_RAND_STATE_SET_BIT(s, n, v)
Definition: net_misc.h:51
void udpUpdateEvents(Socket *socket)
Update UDP related events.
Definition: udp.c:831
systime_t arpTickCounter
Definition: arp.c:51
systime_t timerValue
Definition: net_misc.h:93
void ndpTick(NetInterface *interface)
NDP timer handler.
Definition: ndp.c:285
error_t netAttachLinkChangeCallback(NetInterface *interface, NetLinkChangeCallback callback, void *param)
Register link change callback.
Definition: net_misc.c:127
#define TRUE
Definition: os_port.h:50
uint16_t counter
Definition: net_misc.h:185
#define DNS_TICK_INTERVAL
Definition: dns_cache.h:40
uint32_t entropy
Definition: net.h:312
#define IPV4_FRAG_TICK_INTERVAL
Definition: ipv4_frag.h:47
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
error_t netAttachTimerCallback(systime_t period, NetTimerCallback callback, void *param)
Register timer callback.
Definition: net_misc.c:344
@ SOCKET_TYPE_DGRAM
Definition: socket.h:79
NetTimerCallbackEntry timerCallbacks[NET_MAX_TIMER_CALLBACKS]
Definition: net.h:318
void ipv4LinkChangeEvent(NetInterface *interface)
Callback function for link change event.
Definition: ipv4.c:516
void ndpRouterAdvTick(NdpRouterAdvContext *context)
RA service timer handler.
#define ARP_TICK_INTERVAL
Definition: arp.h:39
#define NET_INTERFACE_COUNT
Definition: net.h:113
systime_t nicTickCounter
Definition: nic.c:43
IPv6 routing.
void * param
Definition: net_misc.h:96
NetContext netContext
Definition: net.c:75
#define NET_TICK_INTERVAL
Definition: net.h:174
void pppTick(NetInterface *interface)
PPP timer handler.
Definition: ppp.c:851
void * param
Definition: net_misc.h:76
Helper functions for DHCPv6 client.
void dnsFlushCache(NetInterface *interface)
Flush DNS cache.
Definition: dns_cache.c:75
@ SOCKET_TYPE_STREAM
Definition: socket.h:78
#define timeCompare(t1, t2)
Definition: os_port.h:42
Helper functions for DHCP client.
void arpTick(NetInterface *interface)
ARP timer handler.
Definition: arp.c:432
Pseudo-random number generator state.
Definition: net_misc.h:184
systime_t ipv6FragTickCounter
Definition: ipv6_frag.c:47
Helper functions for DHCP server.
Ethernet.
#define NET_MAX_LINK_CHANGE_CALLBACKS
Definition: net.h:127
error_t netDetachTimerCallback(NetTimerCallback callback, void *param)
Unregister timer callback.
Definition: net_misc.c:382
systime_t pppTickCounter
Definition: ppp.c:53
Definitions common to mDNS client and mDNS responder.
uint32_t netGenerateRand(void)
Generate a random 32-bit value.
Definition: net_misc.c:874
DNS-SD (DNS-Based Service Discovery)
systime_t igmpTickCounter
Definition: igmp_common.c:50
uint8_t s[36]
Definition: net_misc.h:186
#define MIB2_IF_SET_TIME_TICKS(name, value)
Definition: mib2_module.h:155
void mldTick(NetInterface *interface)
MLD timer handler.
Definition: mld.c:155
systime_t ndpTickCounter
Definition: ndp.c:60
void(* NetLinkChangeCallback)(NetInterface *interface, bool_t linkState, void *param)
Link change callback.
Definition: net_misc.h:64
uint32_t netGenerateRandBit(NetRandState *state)
Generate one random bit.
Definition: net_misc.c:955
#define FALSE
Definition: os_port.h:46
systime_t dhcpServerTickCounter
Helper functions for TCP.
uint32_t netGenerateRandRange(uint32_t min, uint32_t max)
Generate a random value in the specified range.
Definition: net_misc.c:900
#define IPV6_FRAG_TICK_INTERVAL
Definition: ipv6_frag.h:54
error_t
Error codes.
Definition: error.h:43
#define netInterface
Definition: net_legacy.h:270
void dhcpv6ClientTick(Dhcpv6ClientContext *context)
DHCPv6 client timer handler.
#define eui64CopyAddr(destEui64Addr, srcEui64Addr)
Definition: ethernet.h:136
void netStopTimer(NetTimer *timer)
Stop timer.
Definition: net_misc.c:763
Definitions common to NBNS client and NBNS responder.
Timer callback entry.
Definition: net_misc.h:92
NetLinkChangeCallbackEntry linkChangeCallbacks[NET_MAX_LINK_CHANGE_CALLBACKS]
Definition: net.h:317
int_t socket(int_t family, int_t type, int_t protocol)
Create a socket that is bound to a specific transport service provider.
Definition: bsd_socket.c:63
NBNS client (NetBIOS Name Service)
#define IGMP_TICK_INTERVAL
Definition: igmp_common.h:39
uint8_t value[]
Definition: tcp.h:367
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:102
Timer.
Definition: net_misc.h:172
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
systime_t dhcpv6ClientTickCounter
void dnsSdTick(DnsSdContext *context)
DNS-SD responder timer handler.
Definition: dns_sd.c:514
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:36
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:109
#define DHCP_SERVER_TICK_INTERVAL
Definition: dhcp_server.h:46
NetInterface * interface
Definition: net_misc.h:74
void netGenerateRandData(uint8_t *data, size_t length)
Get a string of random data.
Definition: net_misc.c:927
#define NET_RAND_GET_BIT(s, n)
Definition: net_misc.h:48
#define NetTxAncillary
Definition: net_misc.h:36
mDNS client (Multicast DNS)
systime_t startTime
Definition: net_misc.h:174
@ SOCKET_TYPE_RAW_IP
Definition: socket.h:80
void tcpUpdateEvents(Socket *socket)
Update TCP related events.
Definition: tcp_misc.c:2009
#define NDP_TICK_INTERVAL
Definition: ndp.h:46
error_t netDetachLinkChangeCallback(NetInterface *interface, NetLinkChangeCallback callback, void *param)
Unregister link change callback.
Definition: net_misc.c:165
uint32_t t2
#define TRACE_INFO(...)
Definition: debug.h:95
IGMP host.
Interfaces Group MIB module.
void netProcessLinkChange(NetInterface *interface)
Process link state change event.
Definition: net_misc.c:198
#define TCP_TICK_INTERVAL
Definition: tcp.h:47
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:50
void rawSocketUpdateEvents(Socket *socket)
Update event state for raw sockets.
Definition: raw_socket.c:925
void mdnsResponderTick(MdnsResponderContext *context)
mDNS responder timer handler
void dnsTick(void)
DNS timer handler.
Definition: dns_cache.c:229
NDP (Neighbor Discovery Protocol)
DNS client (Domain Name System)
TCP/IP raw sockets.
uint8_t z
Definition: dns_common.h:175
systime_t tcpTickCounter
Definition: tcp.c:50
uint32_t systime_t
System time.
#define NET_MAX_TIMER_CALLBACKS
Definition: net.h:134
systime_t mldTickCounter
Definition: mld.c:56
LLMNR client (Link-Local Multicast Name Resolution)
#define MDNS_RESPONDER_TICK_INTERVAL
#define DNS_SD_TICK_INTERVAL
Definition: dns_sd.h:48
systime_t dnsSdTickCounter
Definition: dns_sd.c:54
NetLinkChangeCallback callback
Definition: net_misc.h:75
DNS cache management.
#define NIC_TICK_INTERVAL
Definition: nic.h:39
uint32_t time
void mdnsResponderLinkChangeEvent(MdnsResponderContext *context)
Callback function for link change event.
uint32_t t1
#define NDP_ROUTER_ADV_TICK_INTERVAL
void netInitRand(void)
Initialize random number generator.
Definition: net_misc.c:818
#define AUTO_IP_TICK_INTERVAL
Definition: auto_ip.h:53
void netTick(void)
Manage TCP/IP timers.
Definition: net_misc.c:413
Link change callback entry.
Definition: net_misc.h:73
#define Socket
Definition: socket.h:36
systime_t autoIpTickCounter
Definition: auto_ip_misc.c:47
@ NIC_HALF_DUPLEX_MODE
Definition: nic.h:122
#define DHCP_CLIENT_TICK_INTERVAL
Definition: dhcp_client.h:49
systime_t dhcpClientTickCounter
#define DHCPV6_CLIENT_TICK_INTERVAL
Definition: dhcpv6_client.h:47
IPv4 routing.
#define PPP_TICK_INTERVAL
Definition: ppp.h:82
#define osGetSystemTime64()
Socket API.
@ SOCKET_TYPE_RAW_ETH
Definition: socket.h:81
void autoIpTick(AutoIpContext *context)
Auto-IP timer handler.
Definition: auto_ip_misc.c:59
NetRandState randState
Pseudo-random number generator state.
Definition: net.h:315
void tcpTick(void)
TCP timer handler.
Definition: tcp_timer.c:56
Helper functions for Auto-IP.
LLMNR responder (Link-Local Multicast Name Resolution)
void dnsSdLinkChangeEvent(DnsSdContext *context)
Callback function for link change event.
Definition: dns_sd.c:680
void dhcpClientTick(DhcpClientContext *context)
DHCP client timer handler.
#define MLD_TICK_INTERVAL
Definition: mld.h:46
IPv4 (Internet Protocol Version 4)
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:110
TCP timer management.
void ipv6LinkChangeEvent(NetInterface *interface)
Callback function for link change event.
Definition: ipv6.c:847
unsigned int uint_t
Definition: compiler_port.h:45
void nicTick(NetInterface *interface)
Network controller timer handler.
Definition: nic.c:250
void igmpTick(NetInterface *interface)
IGMP timer handler.
Definition: igmp_common.c:91
Helper functions for router advertisement service.
uint8_t randSeed[NET_RAND_SEED_SIZE]
Random seed.
Definition: net.h:314
#define osMemset(p, value, length)
Definition: os_port.h:131
TCP/IP stack core.
#define SOCKET_MAX_COUNT
Definition: socket.h:46
bool_t netTimerExpired(NetTimer *timer)
Check whether the timer has expired.
Definition: net_misc.c:789
systime_t mdnsResponderTickCounter
ARP (Address Resolution Protocol)
Helper functions for TCP/IP stack.
systime_t ndpRouterAdvTickCounter
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
void(* NetTimerCallback)(void *param)
Timer callback.
Definition: net_misc.h:84
NBNS responder (NetBIOS Name Service)
mDNS responder (Multicast DNS)
void dhcpServerTick(DhcpServerContext *context)
DHCP server timer handler.
MLD (Multicast Listener Discovery for IPv6)
systime_t interval
Definition: net_misc.h:175
systime_t osGetSystemTime(void)
Retrieve system time.
systime_t dnsTickCounter
Definition: dns_cache.c:50