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-2025 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.5.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 "dhcp/dhcp_client_misc.h"
48 #include "dhcp/dhcp_server_misc.h"
49 #include "nat/nat_misc.h"
50 #include "ipv6/ipv6.h"
51 #include "ipv6/ipv6_routing.h"
52 #include "ipv6/ndp.h"
54 #include "mld/mld_node.h"
56 #include "dns/dns_cache.h"
57 #include "dns/dns_client.h"
58 #include "mdns/mdns_client.h"
59 #include "mdns/mdns_responder.h"
60 #include "mdns/mdns_common.h"
62 #include "netbios/nbns_client.h"
63 #include "netbios/nbns_responder.h"
64 #include "netbios/nbns_common.h"
65 #include "llmnr/llmnr_client.h"
66 #include "llmnr/llmnr_responder.h"
67 #include "mibs/mib2_module.h"
68 #include "mibs/if_mib_module.h"
69 #include "debug.h"
70 
71 //Default options passed to the stack (TX path)
73 {
74 #if (UDP_SUPPORT == ENABLED)
75  FALSE, //Disable UDP checksum generation
76 #endif
77  0, //Time-to-live value
78  0, //Type-of-service value
79  IP_DEFAULT_DF, //Do not fragment the IP packet
80  FALSE, //Do not send the packet via a router
81  FALSE, //Do not add an IP Router Alert option
82 #if (ETH_SUPPORT == ENABLED)
83  {{{0}}}, //Source MAC address
84  {{{0}}}, //Destination MAC address
85 #endif
86 #if (ETH_VLAN_SUPPORT == ENABLED)
87  -1, //VLAN priority (802.1Q)
88  -1, //Drop eligible indicator
89 #endif
90 #if (ETH_VMAN_SUPPORT == ENABLED)
91  -1, //VMAN priority (802.1ad)
92  -1, //Drop eligible indicator
93 #endif
94 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
95  0, //Egress port identifier
96  0, //Egress port map
97  FALSE, //Override port state
98 #endif
99 #if (ETH_TIMESTAMP_SUPPORT == ENABLED)
100  -1, //Unique identifier for hardware time stamping
101 #endif
102 };
103 
104 //Default options passed to the stack (RX path)
106 {
107  0, //Time-to-live value
108  0, //Type-of-service value
109 #if (ETH_SUPPORT == ENABLED)
110  {{{0}}}, //Source MAC address
111  {{{0}}}, //Destination MAC address
112  0, //Ethernet type field
113 #endif
114 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
115  0, //Ingress port identifier
116 #endif
117 #if (ETH_TIMESTAMP_SUPPORT == ENABLED)
118  {0}, //Captured time stamp
119 #endif
120 };
121 
122 
123 /**
124  * @brief Register link change callback
125  * @param[in] interface Underlying network interface
126  * @param[in] callback Callback function to be called when the link state changed
127  * @param[in] param Callback function parameter
128  * @return Error code
129  **/
130 
132  NetLinkChangeCallback callback, void *param)
133 {
134  uint_t i;
136 
137  //Loop through the table
138  for(i = 0; i < NET_MAX_LINK_CHANGE_CALLBACKS; i++)
139  {
140  //Point to the current entry
141  entry = &netContext.linkChangeCallbacks[i];
142 
143  //Check whether the entry is available
144  if(entry->callback == NULL)
145  {
146  //Create a new entry
147  entry->interface = interface;
148  entry->callback = callback;
149  entry->param = param;
150 
151  //Successful processing
152  return NO_ERROR;
153  }
154  }
155 
156  //The table runs out of space
157  return ERROR_OUT_OF_RESOURCES;
158 }
159 
160 
161 /**
162  * @brief Unregister link change callback
163  * @param[in] interface Underlying network interface
164  * @param[in] callback Callback function to be unregistered
165  * @param[in] param Callback function parameter
166  * @return Error code
167  **/
168 
170  NetLinkChangeCallback callback, void *param)
171 {
172  uint_t i;
174 
175  //Loop through the table
176  for(i = 0; i < NET_MAX_LINK_CHANGE_CALLBACKS; i++)
177  {
178  //Point to the current entry
179  entry = &netContext.linkChangeCallbacks[i];
180 
181  //Check whether the current entry matches the specified callback function
182  if(entry->interface == interface && entry->callback == callback &&
183  entry->param == param)
184  {
185  //Unregister callback function
186  entry->interface = NULL;
187  entry->callback = NULL;
188  entry->param = NULL;
189  }
190  }
191 
192  //Successful processing
193  return NO_ERROR;
194 }
195 
196 
197 /**
198  * @brief Process link state change event
199  * @param[in] interface Underlying network interface
200  **/
201 
203 {
204  uint_t i;
205  Socket *socket;
206 
207  //Check link state
208  if(interface->linkState)
209  {
210  //Display link state
211  TRACE_INFO("Link is up (%s)...\r\n", interface->name);
212 
213  //Display link speed
214  if(interface->linkSpeed == NIC_LINK_SPEED_1GBPS)
215  {
216  //1000BASE-T
217  TRACE_INFO(" Link speed = 1000 Mbps\r\n");
218  }
219  else if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
220  {
221  //100BASE-TX
222  TRACE_INFO(" Link speed = 100 Mbps\r\n");
223  }
224  else if(interface->linkSpeed == NIC_LINK_SPEED_10MBPS)
225  {
226  //10BASE-T
227  TRACE_INFO(" Link speed = 10 Mbps\r\n");
228  }
229  else if(interface->linkSpeed != NIC_LINK_SPEED_UNKNOWN)
230  {
231  //10BASE-T
232  TRACE_INFO(" Link speed = %" PRIu32 " bps\r\n",
233  interface->linkSpeed);
234  }
235 
236  //Display duplex mode
237  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
238  {
239  //1000BASE-T
240  TRACE_INFO(" Duplex mode = Full-Duplex\r\n");
241  }
242  else if(interface->duplexMode == NIC_HALF_DUPLEX_MODE)
243  {
244  //100BASE-TX
245  TRACE_INFO(" Duplex mode = Half-Duplex\r\n");
246  }
247  }
248  else
249  {
250  //Display link state
251  TRACE_INFO("Link is down (%s)...\r\n", interface->name);
252  }
253 
254  //The time at which the interface entered its current operational state
255  MIB2_IF_SET_TIME_TICKS(ifTable[interface->index].ifLastChange,
256  osGetSystemTime64() / 10);
257  IF_MIB_SET_TIME_TICKS(ifTable[interface->index].ifLastChange,
258  osGetSystemTime64() / 10);
259 
260 #if (IPV4_SUPPORT == ENABLED)
261  //Notify IPv4 of link state changes
262  ipv4LinkChangeEvent(interface);
263 #endif
264 
265 #if (IPV6_SUPPORT == ENABLED)
266  //Notify IPv6 of link state changes
267  ipv6LinkChangeEvent(interface);
268 #endif
269 
270 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \
271  NBNS_CLIENT_SUPPORT == ENABLED)
272  //Flush DNS cache
273  dnsFlushCache(interface);
274 #endif
275 
276 #if (MDNS_RESPONDER_SUPPORT == ENABLED)
277  //Perform probing and announcing
278  mdnsResponderLinkChangeEvent(interface->mdnsResponderContext);
279 #endif
280 
281 #if (DNS_SD_RESPONDER_SUPPORT == ENABLED)
282  //Perform probing and announcing
283  dnsSdResponderLinkChangeEvent(interface->dnsSdResponderContext);
284 #endif
285 
286  //Loop through the link change callback table
287  for(i = 0; i < NET_MAX_LINK_CHANGE_CALLBACKS; i++)
288  {
290 
291  //Point to the current entry
292  entry = &netContext.linkChangeCallbacks[i];
293 
294  //Any registered callback?
295  if(entry->callback != NULL)
296  {
297  //Check whether the network interface matches the current entry
298  if(entry->interface == NULL || entry->interface == interface)
299  {
300  //Invoke user callback function
301  entry->callback(interface, interface->linkState, entry->param);
302  }
303  }
304  }
305 
306  //Loop through opened sockets
307  for(i = 0; i < SOCKET_MAX_COUNT; i++)
308  {
309  //Point to the current socket
310  socket = &socketTable[i];
311 
312 #if (TCP_SUPPORT == ENABLED)
313  //Connection-oriented socket?
314  if(socket->type == SOCKET_TYPE_STREAM)
315  {
317  }
318 #endif
319 
320 #if (UDP_SUPPORT == ENABLED)
321  //Connectionless socket?
322  if(socket->type == SOCKET_TYPE_DGRAM)
323  {
325  }
326 #endif
327 
328 #if (RAW_SOCKET_SUPPORT == ENABLED)
329  //Raw socket?
330  if(socket->type == SOCKET_TYPE_RAW_IP ||
331  socket->type == SOCKET_TYPE_RAW_ETH)
332  {
334  }
335 #endif
336  }
337 }
338 
339 
340 /**
341  * @brief Register timer callback
342  * @param[in] period Timer reload value, in milliseconds
343  * @param[in] callback Callback function to be called when the timer expires
344  * @param[in] param Callback function parameter
345  * @return Error code
346  **/
347 
349  void *param)
350 {
351  uint_t i;
352  NetTimerCallbackEntry *entry;
353 
354  //Loop through the table
355  for(i = 0; i < NET_MAX_TIMER_CALLBACKS; i++)
356  {
357  //Point to the current entry
358  entry = &netContext.timerCallbacks[i];
359 
360  //Check whether the entry is available
361  if(entry->callback == NULL)
362  {
363  //Create a new entry
364  entry->timerValue = 0;
365  entry->timerPeriod = period;
366  entry->callback = callback;
367  entry->param = param;
368 
369  //Successful processing
370  return NO_ERROR;
371  }
372  }
373 
374  //The table runs out of space
375  return ERROR_OUT_OF_RESOURCES;
376 }
377 
378 
379 /**
380  * @brief Unregister timer callback
381  * @param[in] callback Callback function to be unregistered
382  * @param[in] param Callback function parameter
383  * @return Error code
384  **/
385 
387 {
388  uint_t i;
389  NetTimerCallbackEntry *entry;
390 
391  //Loop through the table
392  for(i = 0; i < NET_MAX_TIMER_CALLBACKS; i++)
393  {
394  //Point to the current entry
395  entry = &netContext.timerCallbacks[i];
396 
397  //Check whether the current entry matches the specified callback function
398  if(entry->callback == callback && entry->param == param)
399  {
400  //Unregister callback function
401  entry->timerValue = 0;
402  entry->timerPeriod = 0;
403  entry->callback = NULL;
404  entry->param = NULL;
405  }
406  }
407 
408  //Successful processing
409  return NO_ERROR;
410 }
411 
412 
413 /**
414  * @brief Manage TCP/IP timers
415  **/
416 
417 void netTick(void)
418 {
419  uint_t i;
420  NetTimerCallbackEntry *entry;
421 
422  //Increment tick counter
424 
425  //Handle periodic operations such as polling the link state
427  {
428  //Loop through network interfaces
429  for(i = 0; i < NET_INTERFACE_COUNT; i++)
430  {
431  //Make sure the interface has been properly configured
432  if(netInterface[i].configured)
433  nicTick(&netInterface[i]);
434  }
435 
436  //Reset tick counter
437  nicTickCounter = 0;
438  }
439 
440 #if (PPP_SUPPORT == ENABLED)
441  //Increment tick counter
443 
444  //Manage PPP related timers
446  {
447  //Loop through network interfaces
448  for(i = 0; i < NET_INTERFACE_COUNT; i++)
449  {
450  //Make sure the interface has been properly configured
451  if(netInterface[i].configured)
452  pppTick(&netInterface[i]);
453  }
454 
455  //Reset tick counter
456  pppTickCounter = 0;
457  }
458 #endif
459 
460 #if (IPV4_SUPPORT == ENABLED && ETH_SUPPORT == ENABLED)
461  //Increment tick counter
463 
464  //Manage ARP cache
466  {
467  //Loop through network interfaces
468  for(i = 0; i < NET_INTERFACE_COUNT; i++)
469  {
470  //Make sure the interface has been properly configured
471  if(netInterface[i].configured)
472  arpTick(&netInterface[i]);
473  }
474 
475  //Reset tick counter
476  arpTickCounter = 0;
477  }
478 #endif
479 
480 #if (IPV4_SUPPORT == ENABLED && IPV4_FRAG_SUPPORT == ENABLED)
481  //Increment tick counter
483 
484  //Handle IPv4 fragment reassembly timeout
486  {
487  //Loop through network interfaces
488  for(i = 0; i < NET_INTERFACE_COUNT; i++)
489  {
490  //Make sure the interface has been properly configured
491  if(netInterface[i].configured)
493  }
494 
495  //Reset tick counter
497  }
498 #endif
499 
500 #if (IPV4_SUPPORT == ENABLED && (IGMP_HOST_SUPPORT == ENABLED || \
501  IGMP_ROUTER_SUPPORT == ENABLED || IGMP_SNOOPING_SUPPORT == ENABLED))
502  //Increment tick counter
504 
505  //Handle IGMP related timers
507  {
508  //Loop through network interfaces
509  for(i = 0; i < NET_INTERFACE_COUNT; i++)
510  {
511  //Make sure the interface has been properly configured
512  if(netInterface[i].configured)
513  igmpTick(&netInterface[i]);
514  }
515 
516  //Reset tick counter
517  igmpTickCounter = 0;
518  }
519 #endif
520 
521 #if (IPV4_SUPPORT == ENABLED && AUTO_IP_SUPPORT == ENABLED)
522  //Increment tick counter
524 
525  //Handle Auto-IP related timers
527  {
528  //Loop through network interfaces
529  for(i = 0; i < NET_INTERFACE_COUNT; i++)
530  {
531  autoIpTick(netInterface[i].autoIpContext);
532  }
533 
534  //Reset tick counter
535  autoIpTickCounter = 0;
536  }
537 #endif
538 
539 #if (IPV4_SUPPORT == ENABLED && DHCP_CLIENT_SUPPORT == ENABLED)
540  //Increment tick counter
542 
543  //Handle DHCP client related timers
545  {
546  //Loop through network interfaces
547  for(i = 0; i < NET_INTERFACE_COUNT; i++)
548  {
549  dhcpClientTick(netInterface[i].dhcpClientContext);
550  }
551 
552  //Reset tick counter
554  }
555 #endif
556 
557 #if (IPV4_SUPPORT == ENABLED && DHCP_SERVER_SUPPORT == ENABLED)
558  //Increment tick counter
560 
561  //Handle DHCP server related timers
563  {
564  //Loop through network interfaces
565  for(i = 0; i < NET_INTERFACE_COUNT; i++)
566  {
567  dhcpServerTick(netInterface[i].dhcpServerContext);
568  }
569 
570  //Reset tick counter
572  }
573 #endif
574 
575 #if (IPV4_SUPPORT == ENABLED && NAT_SUPPORT == ENABLED)
576  //Increment tick counter
578 
579  //Manage NAT related timers
581  {
582  //NAT timer handler
584  //Reset tick counter
585  natTickCounter = 0;
586  }
587 #endif
588 
589 #if (IPV6_SUPPORT == ENABLED && IPV6_FRAG_SUPPORT == ENABLED)
590  //Increment tick counter
592 
593  //Handle IPv6 fragment reassembly timeout
595  {
596  //Loop through network interfaces
597  for(i = 0; i < NET_INTERFACE_COUNT; i++)
598  {
599  //Make sure the interface has been properly configured
600  if(netInterface[i].configured)
602  }
603 
604  //Reset tick counter
606  }
607 #endif
608 
609 #if (IPV6_SUPPORT == ENABLED && MLD_NODE_SUPPORT == ENABLED)
610  //Increment tick counter
612 
613  //Handle MLD related timers
615  {
616  //Loop through network interfaces
617  for(i = 0; i < NET_INTERFACE_COUNT; i++)
618  {
619  //Make sure the interface has been properly configured
620  if(netInterface[i].configured)
621  mldTick(&netInterface[i]);
622  }
623 
624  //Reset tick counter
625  mldTickCounter = 0;
626  }
627 #endif
628 
629 #if (IPV6_SUPPORT == ENABLED && NDP_SUPPORT == ENABLED)
630  //Increment tick counter
632 
633  //Handle NDP related timers
635  {
636  //Loop through network interfaces
637  for(i = 0; i < NET_INTERFACE_COUNT; i++)
638  {
639  //Make sure the interface has been properly configured
640  if(netInterface[i].configured)
641  ndpTick(&netInterface[i]);
642  }
643 
644  //Reset tick counter
645  ndpTickCounter = 0;
646  }
647 #endif
648 
649 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED)
650  //Increment tick counter
652 
653  //Handle RA service related timers
655  {
656  //Loop through network interfaces
657  for(i = 0; i < NET_INTERFACE_COUNT; i++)
658  {
659  ndpRouterAdvTick(netInterface[i].ndpRouterAdvContext);
660  }
661 
662  //Reset tick counter
664  }
665 #endif
666 
667 #if (IPV6_SUPPORT == ENABLED && DHCPV6_CLIENT_SUPPORT == ENABLED)
668  //Increment tick counter
670 
671  //Handle DHCPv6 client related timers
673  {
674  //Loop through network interfaces
675  for(i = 0; i < NET_INTERFACE_COUNT; i++)
676  {
677  dhcpv6ClientTick(netInterface[i].dhcpv6ClientContext);
678  }
679 
680  //Reset tick counter
682  }
683 #endif
684 
685 #if (TCP_SUPPORT == ENABLED)
686  //Increment tick counter
688 
689  //Manage TCP related timers
691  {
692  //TCP timer handler
693  tcpTick();
694  //Reset tick counter
695  tcpTickCounter = 0;
696  }
697 #endif
698 
699 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \
700  NBNS_CLIENT_SUPPORT == ENABLED || LLMNR_CLIENT_SUPPORT == ENABLED)
701  //Increment tick counter
703 
704  //Manage DNS cache
706  {
707  //DNS timer handler
708  dnsTick();
709  //Reset tick counter
710  dnsTickCounter = 0;
711  }
712 #endif
713 
714 #if (MDNS_RESPONDER_SUPPORT == ENABLED)
715  //Increment tick counter
717 
718  //Manage mDNS probing and announcing
720  {
721  //Loop through network interfaces
722  for(i = 0; i < NET_INTERFACE_COUNT; i++)
723  {
724  mdnsResponderTick(netInterface[i].mdnsResponderContext);
725  }
726 
727  //Reset tick counter
729  }
730 #endif
731 
732 #if (DNS_SD_RESPONDER_SUPPORT == ENABLED)
733  //Increment tick counter
735 
736  //Manage DNS-SD probing and announcing
738  {
739  //Loop through network interfaces
740  for(i = 0; i < NET_INTERFACE_COUNT; i++)
741  {
742  dnsSdResponderTick(netInterface[i].dnsSdResponderContext);
743  }
744 
745  //Reset tick counter
747  }
748 #endif
749 
750  //Loop through the timer callback table
751  for(i = 0; i < NET_MAX_TIMER_CALLBACKS; i++)
752  {
753  //Point to the current entry
754  entry = &netContext.timerCallbacks[i];
755 
756  //Any registered callback?
757  if(entry->callback != NULL)
758  {
759  //Increment timer value
760  entry->timerValue += NET_TICK_INTERVAL;
761 
762  //Timer period elapsed?
763  if(entry->timerValue >= entry->timerPeriod)
764  {
765  //Invoke user callback function
766  entry->callback(entry->param);
767  //Reload timer
768  entry->timerValue = 0;
769  }
770  }
771  }
772 }
773 
774 
775 /**
776  * @brief Start timer
777  * @param[in] timer Pointer to the timer structure
778  * @param[in] interval Time interval
779  **/
780 
781 void netStartTimer(NetTimer *timer, systime_t interval)
782 {
783  //Start timer
784  timer->startTime = osGetSystemTime();
785  timer->interval = interval;
786  timer->running = TRUE;
787 }
788 
789 
790 /**
791  * @brief Stop timer
792  * @param[in] timer Pointer to the timer structure
793  **/
794 
795 void netStopTimer(NetTimer *timer)
796 {
797  //Stop timer
798  timer->running = FALSE;
799 }
800 
801 
802 /**
803  * @brief Check whether the timer is running
804  * @param[in] timer Pointer to the timer structure
805  * @return TRUE if the timer is running, else FALSE
806  **/
807 
809 {
810  //Return TRUE if the timer is running
811  return timer->running;
812 }
813 
814 
815 /**
816  * @brief Check whether the timer has expired
817  * @param[in] timer Pointer to the timer structure
818  * @return TRUE if the timer has expired, else FALSE
819  **/
820 
822 {
823  bool_t expired;
824  systime_t time;
825 
826  //Initialize flag
827  expired = FALSE;
828  //Get current time
829  time = osGetSystemTime();
830 
831  //Check whether the timer is running
832  if(timer->running)
833  {
834  //Check whether the specified time interval has elapsed
835  if((time - timer->startTime) >= timer->interval)
836  {
837  expired = TRUE;
838  }
839  }
840 
841  //Return TRUE if the timer has expired
842  return expired;
843 }
844 
845 
846 /**
847  * @brief Get the remaining value of the running timer
848  * @param[in] timer Pointer to the timer structure
849  * @return Remaining time
850  **/
851 
853 {
854  systime_t time;
855  systime_t remaining;
856 
857  //Initialize variable
858  remaining = 0;
859  //Get current time
860  time = osGetSystemTime();
861 
862  //Check whether the timer is running
863  if(timer->running)
864  {
865  //Calculate remaining time
866  if((time - timer->startTime) < timer->interval)
867  {
868  remaining = timer->startTime + timer->interval - time;
869  }
870  }
871 
872  //Return remaining time
873  return remaining;
874 }
875 
876 
877 /**
878  * @brief Initialize random number generator
879  **/
880 
881 void netInitRand(void)
882 {
883  uint_t i;
884  NetRandState *state;
885  uint8_t iv[10];
886 
887  //Point to the PRNG state
888  state = &netContext.randState;
889 
890  //Increment invocation counter
891  state->counter++;
892 
893  //Copy the EUI-64 identifier of the default interface
894  eui64CopyAddr(iv, &netInterface[0].eui64);
895  //Append the invocation counter
896  STORE16BE(state->counter, iv + sizeof(Eui64));
897 
898  //Clear the 288-bit internal state
899  osMemset(state->s, 0, 36);
900 
901  //Let (s1, s2, ..., s93) = (K1, ..., K80, 0, ..., 0)
902  for(i = 0; i < 10; i++)
903  {
904  state->s[i] = netContext.randSeed[i];
905  }
906 
907  //Load the 80-bit initialization vector
908  for(i = 0; i < 10; i++)
909  {
910  state->s[12 + i] = iv[i];
911  }
912 
913  //Let (s94, s95, ..., s177) = (IV1, ..., IV80, 0, ..., 0)
914  for(i = 11; i < 22; i++)
915  {
916  state->s[i] = (state->s[i + 1] << 5) | (state->s[i] >> 3);
917  }
918 
919  //Let (s178, s279, ..., s288) = (0, ..., 0, 1, 1, 1)
920  NET_RAND_STATE_SET_BIT(state->s, 286, 1);
921  NET_RAND_STATE_SET_BIT(state->s, 287, 1);
922  NET_RAND_STATE_SET_BIT(state->s, 288, 1);
923 
924  //The state is rotated over 4 full cycles, without generating key stream bit
925  for(i = 0; i < (4 * 288); i++)
926  {
927  netGenerateRandBit(state);
928  }
929 }
930 
931 
932 /**
933  * @brief Generate a random 32-bit value
934  * @return Random value
935  **/
936 
937 uint32_t netGenerateRand(void)
938 {
939  uint_t i;
940  uint32_t value;
941 
942  //Initialize value
943  value = 0;
944 
945  //Generate a random 32-bit value
946  for(i = 0; i < 32; i++)
947  {
949  }
950 
951  //Return the random value
952  return value + netContext.entropy;
953 }
954 
955 
956 /**
957  * @brief Generate a random value in the specified range
958  * @param[in] min Lower bound
959  * @param[in] max Upper bound
960  * @return Random value in the specified range
961  **/
962 
963 uint32_t netGenerateRandRange(uint32_t min, uint32_t max)
964 {
965  uint32_t value;
966 
967  //Valid parameters?
968  if(max > min)
969  {
970  //Pick up a random value in the given range
971  value = min + (netGenerateRand() % (max - min + 1));
972  }
973  else
974  {
975  //Use default value
976  value = min;
977  }
978 
979  //Return the random value
980  return value;
981 }
982 
983 
984 /**
985  * @brief Get a string of random data
986  * @param[out] data Buffer where to store random data
987  * @param[in] length Number of random bytes to generate
988  **/
989 
990 void netGenerateRandData(uint8_t *data, size_t length)
991 {
992  size_t i;
993  size_t j;
994 
995  //Generate a string of random data
996  for(i = 0; i < length; i++)
997  {
998  //Initialize value
999  data[i] = 0;
1000 
1001  //Generate a random 8-bit value
1002  for(j = 0; j < 8; j++)
1003  {
1005  }
1006 
1007  data[i] += netContext.entropy;
1008  }
1009 }
1010 
1011 
1012 /**
1013  * @brief Generate one random bit
1014  * @param[in] state Pointer to the PRNG state
1015  * @return Key stream bit
1016  **/
1017 
1019 {
1020  uint_t i;
1021  uint8_t t1;
1022  uint8_t t2;
1023  uint8_t t3;
1024  uint8_t z;
1025 
1026  //Let t1 = s66 + s93
1027  t1 = NET_RAND_GET_BIT(state->s, 66);
1028  t1 ^= NET_RAND_GET_BIT(state->s, 93);
1029 
1030  //Let t2 = s162 + s177
1031  t2 = NET_RAND_GET_BIT(state->s, 162);
1032  t2 ^= NET_RAND_GET_BIT(state->s, 177);
1033 
1034  //Let t3 = s243 + s288
1035  t3 = NET_RAND_GET_BIT(state->s, 243);
1036  t3 ^= NET_RAND_GET_BIT(state->s, 288);
1037 
1038  //Generate a key stream bit z
1039  z = t1 ^ t2 ^ t3;
1040 
1041  //Let t1 = t1 + s91.s92 + s171
1042  t1 ^= NET_RAND_GET_BIT(state->s, 91) & NET_RAND_GET_BIT(state->s, 92);
1043  t1 ^= NET_RAND_GET_BIT(state->s, 171);
1044 
1045  //Let t2 = t2 + s175.s176 + s264
1046  t2 ^= NET_RAND_GET_BIT(state->s, 175) & NET_RAND_GET_BIT(state->s, 176);
1047  t2 ^= NET_RAND_GET_BIT(state->s, 264);
1048 
1049  //Let t3 = t3 + s286.s287 + s69
1050  t3 ^= NET_RAND_GET_BIT(state->s, 286) & NET_RAND_GET_BIT(state->s, 287);
1051  t3 ^= NET_RAND_GET_BIT(state->s, 69);
1052 
1053  //Rotate the internal state
1054  for(i = 35; i > 0; i--)
1055  {
1056  state->s[i] = (state->s[i] << 1) | (state->s[i - 1] >> 7);
1057  }
1058 
1059  state->s[0] = state->s[0] << 1;
1060 
1061  //Let s1 = t3
1062  NET_RAND_STATE_SET_BIT(state->s, 1, t3);
1063  //Let s94 = t1
1064  NET_RAND_STATE_SET_BIT(state->s, 94, t1);
1065  //Let s178 = t2
1066  NET_RAND_STATE_SET_BIT(state->s, 178, t2);
1067 
1068  //Return one bit of key stream
1069  return z;
1070 }
IPv6 (Internet Protocol Version 6)
@ NIC_LINK_SPEED_1GBPS
Definition: nic.h:113
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:781
void ipv6FragTick(NetInterface *interface)
Fragment reassembly timeout handler.
Definition: ipv6_frag.c:550
#define IF_MIB_SET_TIME_TICKS(name, value)
Definition: if_mib_module.h:46
int bool_t
Definition: compiler_port.h:61
void ipv4FragTick(NetInterface *interface)
Fragment reassembly timeout handler.
Definition: ipv4_frag.c:488
@ NIC_LINK_SPEED_UNKNOWN
Definition: nic.h:110
bool_t running
Definition: net_misc.h:176
const NetTxAncillary NET_DEFAULT_TX_ANCILLARY
Definition: net_misc.c:72
systime_t timerPeriod
Definition: net_misc.h:94
bool_t netTimerRunning(NetTimer *timer)
Check whether the timer is running.
Definition: net_misc.c:808
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
systime_t netGetRemainingTime(NetTimer *timer)
Get the remaining value of the running timer.
Definition: net_misc.c:852
#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:971
Eui64
Definition: ethernet.h:210
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:547
error_t netAttachLinkChangeCallback(NetInterface *interface, NetLinkChangeCallback callback, void *param)
Register link change callback.
Definition: net_misc.c:131
#define TRUE
Definition: os_port.h:50
uint16_t counter
Definition: net_misc.h:188
uint8_t data[]
Definition: ethernet.h:222
#define DNS_TICK_INTERVAL
Definition: dns_cache.h:40
uint32_t entropy
Definition: net.h:328
#define IPV4_FRAG_TICK_INTERVAL
Definition: ipv4_frag.h:54
@ 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:348
@ SOCKET_TYPE_DGRAM
Definition: socket.h:93
NetTimerCallbackEntry timerCallbacks[NET_MAX_TIMER_CALLBACKS]
Definition: net.h:334
void ipv4LinkChangeEvent(NetInterface *interface)
Callback function for link change event.
Definition: ipv4.c:556
void ndpRouterAdvTick(NdpRouterAdvContext *context)
RA service timer handler.
systime_t mldTickCounter
Definition: mld_common.c:63
systime_t dnsSdResponderTickCounter
#define ARP_TICK_INTERVAL
Definition: arp.h:39
#define NET_INTERFACE_COUNT
Definition: net.h:115
systime_t nicTickCounter
Definition: nic.c:44
IPv6 routing.
void * param
Definition: net_misc.h:96
NetContext netContext
Definition: net.c:75
#define NET_TICK_INTERVAL
Definition: net.h:176
void mldTick(NetInterface *interface)
MLD node timer handler.
Definition: mld_common.c:104
void pppTick(NetInterface *interface)
PPP timer handler.
Definition: ppp.c:864
#define IP_DEFAULT_DF
Definition: ip.h:40
void * param
Definition: net_misc.h:76
Helper functions for DHCPv6 client.
void dnsFlushCache(NetInterface *interface)
Flush DNS cache.
Definition: dns_cache.c:74
@ SOCKET_TYPE_STREAM
Definition: socket.h:92
Helper functions for DHCP client.
void arpTick(NetInterface *interface)
ARP timer handler.
Definition: arp.c:521
Pseudo-random number generator state.
Definition: net_misc.h:187
systime_t ipv6FragTickCounter
Definition: ipv6_frag.c:47
Helper functions for DHCP server.
Ethernet.
#define NET_MAX_LINK_CHANGE_CALLBACKS
Definition: net.h:129
error_t netDetachTimerCallback(NetTimerCallback callback, void *param)
Unregister timer callback.
Definition: net_misc.c:386
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:937
void dnsSdResponderTick(DnsSdResponderContext *context)
DNS-SD responder timer handler.
systime_t igmpTickCounter
Definition: igmp_common.c:63
uint8_t s[36]
Definition: net_misc.h:189
#define MIB2_IF_SET_TIME_TICKS(name, value)
Definition: mib2_module.h:155
systime_t ndpTickCounter
Definition: ndp.c:59
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:1018
#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:963
#define IPV6_FRAG_TICK_INTERVAL
Definition: ipv6_frag.h:54
error_t
Error codes.
Definition: error.h:43
#define netInterface
Definition: net_legacy.h:199
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:795
Definitions common to NBNS client and NBNS responder.
DNS-SD responder (DNS-Based Service Discovery)
Timer callback entry.
Definition: net_misc.h:92
NetLinkChangeCallbackEntry linkChangeCallbacks[NET_MAX_LINK_CHANGE_CALLBACKS]
Definition: net.h:333
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:65
NBNS client (NetBIOS Name Service)
#define IGMP_TICK_INTERVAL
Definition: igmp_common.h:39
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:105
Timer.
Definition: net_misc.h:175
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
systime_t dhcpv6ClientTickCounter
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:36
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:111
#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:990
#define NET_RAND_GET_BIT(s, n)
Definition: net_misc.h:48
#define NetTxAncillary
Definition: net_misc.h:36
#define NAT_TICK_INTERVAL
Definition: nat.h:53
mDNS client (Multicast DNS)
systime_t startTime
Definition: net_misc.h:177
uint8_t iv[]
Definition: ike.h:1626
@ SOCKET_TYPE_RAW_IP
Definition: socket.h:94
void tcpUpdateEvents(Socket *socket)
Update TCP related events.
Definition: tcp_misc.c:2175
#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:169
uint32_t t2
#define TRACE_INFO(...)
Definition: debug.h:105
IGMP host.
uint8_t length
Definition: tcp.h:375
void natTick(NatContext *context)
NAT timer handler.
Definition: nat_misc.c:54
Interfaces Group MIB module.
void netProcessLinkChange(NetInterface *interface)
Process link state change event.
Definition: net_misc.c:202
#define TCP_TICK_INTERVAL
Definition: tcp.h:47
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
Helper functions for NAT.
NatContext * natContext
NAT context.
Definition: net.h:336
void rawSocketUpdateEvents(Socket *socket)
Update event state for raw sockets.
Definition: raw_socket.c:1025
void mdnsResponderTick(MdnsResponderContext *context)
mDNS responder timer handler
void dnsTick(void)
DNS timer handler.
Definition: dns_cache.c:228
systime_t natTickCounter
Definition: nat_misc.c:46
NDP (Neighbor Discovery Protocol)
DNS client (Domain Name System)
TCP/IP raw sockets.
uint8_t z
Definition: dns_common.h:191
systime_t tcpTickCounter
Definition: tcp.c:49
uint32_t systime_t
System time.
#define NET_MAX_TIMER_CALLBACKS
Definition: net.h:136
MLD node (Multicast Listener Discovery for IPv6)
LLMNR client (Link-Local Multicast Name Resolution)
#define MDNS_RESPONDER_TICK_INTERVAL
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:881
#define AUTO_IP_TICK_INTERVAL
Definition: auto_ip.h:53
void netTick(void)
Manage TCP/IP timers.
Definition: net_misc.c:417
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:124
#define DHCP_CLIENT_TICK_INTERVAL
Definition: dhcp_client.h:49
systime_t dhcpClientTickCounter
#define MLD_TICK_INTERVAL
Definition: mld_common.h:39
uint8_t value[]
Definition: tcp.h:376
#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:95
void autoIpTick(AutoIpContext *context)
Auto-IP timer handler.
Definition: auto_ip_misc.c:59
NetRandState randState
Pseudo-random number generator state.
Definition: net.h:331
void tcpTick(void)
TCP timer handler.
Definition: tcp_timer.c:56
Helper functions for Auto-IP.
LLMNR responder (Link-Local Multicast Name Resolution)
void dhcpClientTick(DhcpClientContext *context)
DHCP client timer handler.
IPv4 (Internet Protocol Version 4)
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
TCP timer management.
void ipv6LinkChangeEvent(NetInterface *interface)
Callback function for link change event.
Definition: ipv6.c:884
unsigned int uint_t
Definition: compiler_port.h:57
void nicTick(NetInterface *interface)
Network controller timer handler.
Definition: nic.c:251
void igmpTick(NetInterface *interface)
IGMP timer handler.
Definition: igmp_common.c:107
Helper functions for router advertisement service.
uint8_t randSeed[NET_RAND_SEED_SIZE]
Random seed.
Definition: net.h:330
#define osMemset(p, value, length)
Definition: os_port.h:138
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:821
systime_t mdnsResponderTickCounter
ARP (Address Resolution Protocol)
#define DNS_SD_RESPONDER_TICK_INTERVAL
Helper functions for TCP/IP stack.
systime_t ndpRouterAdvTickCounter
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
void dnsSdResponderLinkChangeEvent(DnsSdResponderContext *context)
Callback function for link change event.
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.
systime_t interval
Definition: net_misc.h:178
systime_t osGetSystemTime(void)
Retrieve system time.
systime_t dnsTickCounter
Definition: dns_cache.c:49