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