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.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  0, //Type-of-service value
75  IP_DEFAULT_DF, //Do not fragment the IP packet
76  FALSE, //Do not send the packet via a router
77  FALSE, //Do not add an IP Router Alert option
78 #if (ETH_SUPPORT == ENABLED)
79  {{{0}}}, //Source MAC address
80  {{{0}}}, //Destination MAC address
81 #endif
82 #if (ETH_VLAN_SUPPORT == ENABLED)
83  -1, //VLAN priority (802.1Q)
84  -1, //Drop eligible indicator
85 #endif
86 #if (ETH_VMAN_SUPPORT == ENABLED)
87  -1, //VMAN priority (802.1ad)
88  -1, //Drop eligible indicator
89 #endif
90 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
91  0, //Egress port identifier
92  0, //Egress port map
93  FALSE, //Override port state
94 #endif
95 #if (ETH_TIMESTAMP_SUPPORT == ENABLED)
96  -1, //Unique identifier for hardware time stamping
97 #endif
98 };
99 
100 //Default options passed to the stack (RX path)
102 {
103  0, //Time-to-live value
104  0, //Type-of-service 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  {
527  autoIpTick(netInterface[i].autoIpContext);
528  }
529 
530  //Reset tick counter
531  autoIpTickCounter = 0;
532  }
533 #endif
534 
535 #if (IPV4_SUPPORT == ENABLED && DHCP_CLIENT_SUPPORT == ENABLED)
536  //Increment tick counter
538 
539  //Handle DHCP client related timers
541  {
542  //Loop through network interfaces
543  for(i = 0; i < NET_INTERFACE_COUNT; i++)
544  {
545  dhcpClientTick(netInterface[i].dhcpClientContext);
546  }
547 
548  //Reset tick counter
550  }
551 #endif
552 
553 #if (IPV4_SUPPORT == ENABLED && DHCP_SERVER_SUPPORT == ENABLED)
554  //Increment tick counter
556 
557  //Handle DHCP server related timers
559  {
560  //Loop through network interfaces
561  for(i = 0; i < NET_INTERFACE_COUNT; i++)
562  {
563  dhcpServerTick(netInterface[i].dhcpServerContext);
564  }
565 
566  //Reset tick counter
568  }
569 #endif
570 
571 #if (IPV6_SUPPORT == ENABLED && IPV6_FRAG_SUPPORT == ENABLED)
572  //Increment tick counter
574 
575  //Handle IPv6 fragment reassembly timeout
577  {
578  //Loop through network interfaces
579  for(i = 0; i < NET_INTERFACE_COUNT; i++)
580  {
581  //Make sure the interface has been properly configured
582  if(netInterface[i].configured)
584  }
585 
586  //Reset tick counter
588  }
589 #endif
590 
591 #if (IPV6_SUPPORT == ENABLED && MLD_SUPPORT == ENABLED)
592  //Increment tick counter
594 
595  //Handle MLD related timers
597  {
598  //Loop through network interfaces
599  for(i = 0; i < NET_INTERFACE_COUNT; i++)
600  {
601  //Make sure the interface has been properly configured
602  if(netInterface[i].configured)
603  mldTick(&netInterface[i]);
604  }
605 
606  //Reset tick counter
607  mldTickCounter = 0;
608  }
609 #endif
610 
611 #if (IPV6_SUPPORT == ENABLED && NDP_SUPPORT == ENABLED)
612  //Increment tick counter
614 
615  //Handle NDP related timers
617  {
618  //Loop through network interfaces
619  for(i = 0; i < NET_INTERFACE_COUNT; i++)
620  {
621  //Make sure the interface has been properly configured
622  if(netInterface[i].configured)
623  ndpTick(&netInterface[i]);
624  }
625 
626  //Reset tick counter
627  ndpTickCounter = 0;
628  }
629 #endif
630 
631 #if (IPV6_SUPPORT == ENABLED && NDP_ROUTER_ADV_SUPPORT == ENABLED)
632  //Increment tick counter
634 
635  //Handle RA service related timers
637  {
638  //Loop through network interfaces
639  for(i = 0; i < NET_INTERFACE_COUNT; i++)
640  {
641  ndpRouterAdvTick(netInterface[i].ndpRouterAdvContext);
642  }
643 
644  //Reset tick counter
646  }
647 #endif
648 
649 #if (IPV6_SUPPORT == ENABLED && DHCPV6_CLIENT_SUPPORT == ENABLED)
650  //Increment tick counter
652 
653  //Handle DHCPv6 client related timers
655  {
656  //Loop through network interfaces
657  for(i = 0; i < NET_INTERFACE_COUNT; i++)
658  {
659  dhcpv6ClientTick(netInterface[i].dhcpv6ClientContext);
660  }
661 
662  //Reset tick counter
664  }
665 #endif
666 
667 #if (TCP_SUPPORT == ENABLED)
668  //Increment tick counter
670 
671  //Manage TCP related timers
673  {
674  //TCP timer handler
675  tcpTick();
676  //Reset tick counter
677  tcpTickCounter = 0;
678  }
679 #endif
680 
681 #if (DNS_CLIENT_SUPPORT == ENABLED || MDNS_CLIENT_SUPPORT == ENABLED || \
682  NBNS_CLIENT_SUPPORT == ENABLED || LLMNR_CLIENT_SUPPORT == ENABLED)
683  //Increment tick counter
685 
686  //Manage DNS cache
688  {
689  //DNS timer handler
690  dnsTick();
691  //Reset tick counter
692  dnsTickCounter = 0;
693  }
694 #endif
695 
696 #if (MDNS_RESPONDER_SUPPORT == ENABLED)
697  //Increment tick counter
699 
700  //Manage mDNS probing and announcing
702  {
703  //Loop through network interfaces
704  for(i = 0; i < NET_INTERFACE_COUNT; i++)
705  {
706  mdnsResponderTick(netInterface[i].mdnsResponderContext);
707  }
708 
709  //Reset tick counter
711  }
712 #endif
713 
714 #if (DNS_SD_SUPPORT == ENABLED)
715  //Increment tick counter
717 
718  //Manage DNS-SD probing and announcing
720  {
721  //Loop through network interfaces
722  for(i = 0; i < NET_INTERFACE_COUNT; i++)
723  {
724  dnsSdTick(netInterface[i].dnsSdContext);
725  }
726 
727  //Reset tick counter
728  dnsSdTickCounter = 0;
729  }
730 #endif
731 
732  //Loop through the timer callback table
733  for(i = 0; i < NET_MAX_TIMER_CALLBACKS; i++)
734  {
735  //Point to the current entry
736  entry = &netContext.timerCallbacks[i];
737 
738  //Any registered callback?
739  if(entry->callback != NULL)
740  {
741  //Increment timer value
742  entry->timerValue += NET_TICK_INTERVAL;
743 
744  //Timer period elapsed?
745  if(entry->timerValue >= entry->timerPeriod)
746  {
747  //Invoke user callback function
748  entry->callback(entry->param);
749  //Reload timer
750  entry->timerValue = 0;
751  }
752  }
753  }
754 }
755 
756 
757 /**
758  * @brief Start timer
759  * @param[in] timer Pointer to the timer structure
760  * @param[in] interval Time interval
761  **/
762 
763 void netStartTimer(NetTimer *timer, systime_t interval)
764 {
765  //Start timer
766  timer->startTime = osGetSystemTime();
767  timer->interval = interval;
768  timer->running = TRUE;
769 }
770 
771 
772 /**
773  * @brief Stop timer
774  * @param[in] timer Pointer to the timer structure
775  **/
776 
777 void netStopTimer(NetTimer *timer)
778 {
779  //Stop timer
780  timer->running = FALSE;
781 }
782 
783 
784 /**
785  * @brief Check whether the timer is running
786  * @param[in] timer Pointer to the timer structure
787  * @return TRUE if the timer is running, else FALSE
788  **/
789 
791 {
792  //Return TRUE if the timer is running
793  return timer->running;
794 }
795 
796 
797 /**
798  * @brief Check whether the timer has expired
799  * @param[in] timer Pointer to the timer structure
800  * @return TRUE if the timer has expired, else FALSE
801  **/
802 
804 {
805  bool_t expired;
806  systime_t time;
807 
808  //Initialize flag
809  expired = FALSE;
810  //Get current time
811  time = osGetSystemTime();
812 
813  //Check whether the timer is running
814  if(timer->running)
815  {
816  //Check whether the specified time interval has elapsed
817  if(timeCompare(time, timer->startTime + timer->interval) >= 0)
818  {
819  expired = TRUE;
820  }
821  }
822 
823  //Return TRUE if the timer has expired
824  return expired;
825 }
826 
827 
828 /**
829  * @brief Initialize random number generator
830  **/
831 
832 void netInitRand(void)
833 {
834  uint_t i;
835  NetRandState *state;
836  uint8_t iv[10];
837 
838  //Point to the PRNG state
839  state = &netContext.randState;
840 
841  //Increment invocation counter
842  state->counter++;
843 
844  //Copy the EUI-64 identifier of the default interface
845  eui64CopyAddr(iv, &netInterface[0].eui64);
846  //Append the invocation counter
847  STORE16BE(state->counter, iv + sizeof(Eui64));
848 
849  //Clear the 288-bit internal state
850  osMemset(state->s, 0, 36);
851 
852  //Let (s1, s2, ..., s93) = (K1, ..., K80, 0, ..., 0)
853  for(i = 0; i < 10; i++)
854  {
855  state->s[i] = netContext.randSeed[i];
856  }
857 
858  //Load the 80-bit initialization vector
859  for(i = 0; i < 10; i++)
860  {
861  state->s[12 + i] = iv[i];
862  }
863 
864  //Let (s94, s95, ..., s177) = (IV1, ..., IV80, 0, ..., 0)
865  for(i = 11; i < 22; i++)
866  {
867  state->s[i] = (state->s[i + 1] << 5) | (state->s[i] >> 3);
868  }
869 
870  //Let (s178, s279, ..., s288) = (0, ..., 0, 1, 1, 1)
871  NET_RAND_STATE_SET_BIT(state->s, 286, 1);
872  NET_RAND_STATE_SET_BIT(state->s, 287, 1);
873  NET_RAND_STATE_SET_BIT(state->s, 288, 1);
874 
875  //The state is rotated over 4 full cycles, without generating key stream bit
876  for(i = 0; i < (4 * 288); i++)
877  {
878  netGenerateRandBit(state);
879  }
880 }
881 
882 
883 /**
884  * @brief Generate a random 32-bit value
885  * @return Random value
886  **/
887 
888 uint32_t netGenerateRand(void)
889 {
890  uint_t i;
891  uint32_t value;
892 
893  //Initialize value
894  value = 0;
895 
896  //Generate a random 32-bit value
897  for(i = 0; i < 32; i++)
898  {
900  }
901 
902  //Return the random value
903  return value + netContext.entropy;
904 }
905 
906 
907 /**
908  * @brief Generate a random value in the specified range
909  * @param[in] min Lower bound
910  * @param[in] max Upper bound
911  * @return Random value in the specified range
912  **/
913 
914 uint32_t netGenerateRandRange(uint32_t min, uint32_t max)
915 {
916  uint32_t value;
917 
918  //Valid parameters?
919  if(max > min)
920  {
921  //Pick up a random value in the given range
922  value = min + (netGenerateRand() % (max - min + 1));
923  }
924  else
925  {
926  //Use default value
927  value = min;
928  }
929 
930  //Return the random value
931  return value;
932 }
933 
934 
935 /**
936  * @brief Get a string of random data
937  * @param[out] data Buffer where to store random data
938  * @param[in] length Number of random bytes to generate
939  **/
940 
941 void netGenerateRandData(uint8_t *data, size_t length)
942 {
943  size_t i;
944  size_t j;
945 
946  //Generate a string of random data
947  for(i = 0; i < length; i++)
948  {
949  //Initialize value
950  data[i] = 0;
951 
952  //Generate a random 8-bit value
953  for(j = 0; j < 8; j++)
954  {
956  }
957 
958  data[i] += netContext.entropy;
959  }
960 }
961 
962 
963 /**
964  * @brief Generate one random bit
965  * @param[in] state Pointer to the PRNG state
966  * @return Key stream bit
967  **/
968 
970 {
971  uint_t i;
972  uint8_t t1;
973  uint8_t t2;
974  uint8_t t3;
975  uint8_t z;
976 
977  //Let t1 = s66 + s93
978  t1 = NET_RAND_GET_BIT(state->s, 66);
979  t1 ^= NET_RAND_GET_BIT(state->s, 93);
980 
981  //Let t2 = s162 + s177
982  t2 = NET_RAND_GET_BIT(state->s, 162);
983  t2 ^= NET_RAND_GET_BIT(state->s, 177);
984 
985  //Let t3 = s243 + s288
986  t3 = NET_RAND_GET_BIT(state->s, 243);
987  t3 ^= NET_RAND_GET_BIT(state->s, 288);
988 
989  //Generate a key stream bit z
990  z = t1 ^ t2 ^ t3;
991 
992  //Let t1 = t1 + s91.s92 + s171
993  t1 ^= NET_RAND_GET_BIT(state->s, 91) & NET_RAND_GET_BIT(state->s, 92);
994  t1 ^= NET_RAND_GET_BIT(state->s, 171);
995 
996  //Let t2 = t2 + s175.s176 + s264
997  t2 ^= NET_RAND_GET_BIT(state->s, 175) & NET_RAND_GET_BIT(state->s, 176);
998  t2 ^= NET_RAND_GET_BIT(state->s, 264);
999 
1000  //Let t3 = t3 + s286.s287 + s69
1001  t3 ^= NET_RAND_GET_BIT(state->s, 286) & NET_RAND_GET_BIT(state->s, 287);
1002  t3 ^= NET_RAND_GET_BIT(state->s, 69);
1003 
1004  //Rotate the internal state
1005  for(i = 35; i > 0; i--)
1006  {
1007  state->s[i] = (state->s[i] << 1) | (state->s[i - 1] >> 7);
1008  }
1009 
1010  state->s[0] = state->s[0] << 1;
1011 
1012  //Let s1 = t3
1013  NET_RAND_STATE_SET_BIT(state->s, 1, t3);
1014  //Let s94 = t1
1015  NET_RAND_STATE_SET_BIT(state->s, 94, t1);
1016  //Let s178 = t2
1017  NET_RAND_STATE_SET_BIT(state->s, 178, t2);
1018 
1019  //Return one bit of key stream
1020  return z;
1021 }
systime_t arpTickCounter
Definition: arp.c:51
void arpTick(NetInterface *interface)
ARP timer handler.
Definition: arp.c:421
ARP (Address Resolution Protocol)
#define ARP_TICK_INTERVAL
Definition: arp.h:39
#define AUTO_IP_TICK_INTERVAL
Definition: auto_ip.h:53
void autoIpTick(AutoIpContext *context)
Auto-IP timer handler.
Definition: auto_ip_misc.c:59
systime_t autoIpTickCounter
Definition: auto_ip_misc.c:47
Helper functions for Auto-IP.
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
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
#define DHCP_CLIENT_TICK_INTERVAL
Definition: dhcp_client.h:49
void dhcpClientTick(DhcpClientContext *context)
DHCP client timer handler.
systime_t dhcpClientTickCounter
Helper functions for DHCP client.
#define DHCP_SERVER_TICK_INTERVAL
Definition: dhcp_server.h:46
systime_t dhcpServerTickCounter
void dhcpServerTick(DhcpServerContext *context)
DHCP server timer handler.
Helper functions for DHCP server.
#define DHCPV6_CLIENT_TICK_INTERVAL
Definition: dhcpv6_client.h:47
void dhcpv6ClientTick(Dhcpv6ClientContext *context)
DHCPv6 client timer handler.
systime_t dhcpv6ClientTickCounter
Helper functions for DHCPv6 client.
uint32_t t1
uint32_t t2
uint32_t time
void dnsFlushCache(NetInterface *interface)
Flush DNS cache.
Definition: dns_cache.c:75
systime_t dnsTickCounter
Definition: dns_cache.c:50
void dnsTick(void)
DNS timer handler.
Definition: dns_cache.c:229
DNS cache management.
#define DNS_TICK_INTERVAL
Definition: dns_cache.h:40
DNS client (Domain Name System)
uint8_t z
Definition: dns_common.h:191
void dnsSdLinkChangeEvent(DnsSdContext *context)
Callback function for link change event.
Definition: dns_sd.c:680
void dnsSdTick(DnsSdContext *context)
DNS-SD responder timer handler.
Definition: dns_sd.c:514
systime_t dnsSdTickCounter
Definition: dns_sd.c:54
DNS-SD (DNS-Based Service Discovery)
#define DNS_SD_TICK_INTERVAL
Definition: dns_sd.h:48
error_t
Error codes.
Definition: error.h:43
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
@ NO_ERROR
Success.
Definition: error.h:44
Ethernet.
Eui64
Definition: ethernet.h:210
#define eui64CopyAddr(destEui64Addr, srcEui64Addr)
Definition: ethernet.h:136
uint8_t data[]
Definition: ethernet.h:222
Interfaces Group MIB module.
#define IF_MIB_SET_TIME_TICKS(name, value)
Definition: if_mib_module.h:46
systime_t igmpTickCounter
Definition: igmp_common.c:50
void igmpTick(NetInterface *interface)
IGMP timer handler.
Definition: igmp_common.c:91
#define IGMP_TICK_INTERVAL
Definition: igmp_common.h:39
IGMP host.
uint8_t iv[]
Definition: ike.h:1502
#define IP_DEFAULT_DF
Definition: ip.h:40
void ipv4LinkChangeEvent(NetInterface *interface)
Callback function for link change event.
Definition: ipv4.c:551
IPv4 (Internet Protocol Version 4)
void ipv4FragTick(NetInterface *interface)
Fragment reassembly timeout handler.
Definition: ipv4_frag.c:488
systime_t ipv4FragTickCounter
Definition: ipv4_frag.c:57
#define IPV4_FRAG_TICK_INTERVAL
Definition: ipv4_frag.h:54
IPv4 routing.
void ipv6LinkChangeEvent(NetInterface *interface)
Callback function for link change event.
Definition: ipv6.c:876
IPv6 (Internet Protocol Version 6)
void ipv6FragTick(NetInterface *interface)
Fragment reassembly timeout handler.
Definition: ipv6_frag.c:550
systime_t ipv6FragTickCounter
Definition: ipv6_frag.c:47
#define IPV6_FRAG_TICK_INTERVAL
Definition: ipv6_frag.h:54
IPv6 routing.
LLMNR client (Link-Local Multicast Name Resolution)
LLMNR responder (Link-Local Multicast Name Resolution)
mDNS client (Multicast DNS)
Definitions common to mDNS client and mDNS responder.
systime_t mdnsResponderTickCounter
void mdnsResponderTick(MdnsResponderContext *context)
mDNS responder timer handler
void mdnsResponderLinkChangeEvent(MdnsResponderContext *context)
Callback function for link change event.
mDNS responder (Multicast DNS)
#define MDNS_RESPONDER_TICK_INTERVAL
MIB-II module.
#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 mldTickCounter
Definition: mld.c:56
MLD (Multicast Listener Discovery for IPv6)
#define MLD_TICK_INTERVAL
Definition: mld.h:46
NBNS client (NetBIOS Name Service)
Definitions common to NBNS client and NBNS responder.
NBNS responder (NetBIOS Name Service)
systime_t ndpTickCounter
Definition: ndp.c:59
void ndpTick(NetInterface *interface)
NDP timer handler.
Definition: ndp.c:450
NDP (Neighbor Discovery Protocol)
#define NDP_TICK_INTERVAL
Definition: ndp.h:46
#define NDP_ROUTER_ADV_TICK_INTERVAL
systime_t ndpRouterAdvTickCounter
void ndpRouterAdvTick(NdpRouterAdvContext *context)
RA service timer handler.
Helper functions for router advertisement service.
NetContext netContext
Definition: net.c:75
TCP/IP stack core.
#define NET_MAX_TIMER_CALLBACKS
Definition: net.h:134
#define NET_INTERFACE_COUNT
Definition: net.h:113
#define NetInterface
Definition: net.h:36
#define NET_MAX_LINK_CHANGE_CALLBACKS
Definition: net.h:127
#define NET_TICK_INTERVAL
Definition: net.h:174
#define netInterface
Definition: net_legacy.h:199
void netInitRand(void)
Initialize random number generator.
Definition: net_misc.c:832
void netStartTimer(NetTimer *timer, systime_t interval)
Start timer.
Definition: net_misc.c:763
uint32_t netGenerateRandBit(NetRandState *state)
Generate one random bit.
Definition: net_misc.c:969
error_t netDetachTimerCallback(NetTimerCallback callback, void *param)
Unregister timer callback.
Definition: net_misc.c:382
void netProcessLinkChange(NetInterface *interface)
Process link state change event.
Definition: net_misc.c:198
void netGenerateRandData(uint8_t *data, size_t length)
Get a string of random data.
Definition: net_misc.c:941
const NetTxAncillary NET_DEFAULT_TX_ANCILLARY
Definition: net_misc.c:71
uint32_t netGenerateRand(void)
Generate a random 32-bit value.
Definition: net_misc.c:888
uint32_t netGenerateRandRange(uint32_t min, uint32_t max)
Generate a random value in the specified range.
Definition: net_misc.c:914
error_t netDetachLinkChangeCallback(NetInterface *interface, NetLinkChangeCallback callback, void *param)
Unregister link change callback.
Definition: net_misc.c:165
bool_t netTimerExpired(NetTimer *timer)
Check whether the timer has expired.
Definition: net_misc.c:803
bool_t netTimerRunning(NetTimer *timer)
Check whether the timer is running.
Definition: net_misc.c:790
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:101
error_t netAttachTimerCallback(systime_t period, NetTimerCallback callback, void *param)
Register timer callback.
Definition: net_misc.c:344
error_t netAttachLinkChangeCallback(NetInterface *interface, NetLinkChangeCallback callback, void *param)
Register link change callback.
Definition: net_misc.c:127
void netStopTimer(NetTimer *timer)
Stop timer.
Definition: net_misc.c:777
void netTick(void)
Manage TCP/IP timers.
Definition: net_misc.c:413
Helper functions for TCP/IP stack.
#define NetRxAncillary
Definition: net_misc.h:40
#define NetTxAncillary
Definition: net_misc.h:36
#define NET_RAND_GET_BIT(s, n)
Definition: net_misc.h:48
void(* NetLinkChangeCallback)(NetInterface *interface, bool_t linkState, void *param)
Link change callback.
Definition: net_misc.h:64
#define NET_RAND_STATE_SET_BIT(s, n, v)
Definition: net_misc.h:51
void(* NetTimerCallback)(void *param)
Timer callback.
Definition: net_misc.h:84
systime_t nicTickCounter
Definition: nic.c:43
void nicTick(NetInterface *interface)
Network controller timer handler.
Definition: nic.c:250
#define NIC_TICK_INTERVAL
Definition: nic.h:39
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
@ NIC_HALF_DUPLEX_MODE
Definition: nic.h:124
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:111
@ NIC_LINK_SPEED_UNKNOWN
Definition: nic.h:110
@ NIC_LINK_SPEED_1GBPS
Definition: nic.h:113
#define osMemset(p, value, length)
Definition: os_port.h:135
#define timeCompare(t1, t2)
Definition: os_port.h:40
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
systime_t osGetSystemTime(void)
Retrieve system time.
#define osGetSystemTime64()
uint32_t systime_t
System time.
void pppTick(NetInterface *interface)
PPP timer handler.
Definition: ppp.c:864
systime_t pppTickCounter
Definition: ppp.c:53
#define PPP_TICK_INTERVAL
Definition: ppp.h:82
void rawSocketUpdateEvents(Socket *socket)
Update event state for raw sockets.
Definition: raw_socket.c:999
TCP/IP raw sockets.
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
Socket API.
@ SOCKET_TYPE_DGRAM
Definition: socket.h:86
@ SOCKET_TYPE_RAW_IP
Definition: socket.h:87
@ SOCKET_TYPE_RAW_ETH
Definition: socket.h:88
@ SOCKET_TYPE_STREAM
Definition: socket.h:85
#define Socket
Definition: socket.h:36
#define SOCKET_MAX_COUNT
Definition: socket.h:46
NetTimerCallbackEntry timerCallbacks[NET_MAX_TIMER_CALLBACKS]
Definition: net.h:327
uint8_t randSeed[NET_RAND_SEED_SIZE]
Random seed.
Definition: net.h:323
NetLinkChangeCallbackEntry linkChangeCallbacks[NET_MAX_LINK_CHANGE_CALLBACKS]
Definition: net.h:326
uint32_t entropy
Definition: net.h:321
NetRandState randState
Pseudo-random number generator state.
Definition: net.h:324
Link change callback entry.
Definition: net_misc.h:73
void * param
Definition: net_misc.h:76
NetLinkChangeCallback callback
Definition: net_misc.h:75
NetInterface * interface
Definition: net_misc.h:74
Pseudo-random number generator state.
Definition: net_misc.h:184
uint8_t s[36]
Definition: net_misc.h:186
uint16_t counter
Definition: net_misc.h:185
Timer callback entry.
Definition: net_misc.h:92
void * param
Definition: net_misc.h:96
systime_t timerPeriod
Definition: net_misc.h:94
NetTimerCallback callback
Definition: net_misc.h:95
systime_t timerValue
Definition: net_misc.h:93
Timer.
Definition: net_misc.h:172
bool_t running
Definition: net_misc.h:173
systime_t interval
Definition: net_misc.h:175
systime_t startTime
Definition: net_misc.h:174
systime_t tcpTickCounter
Definition: tcp.c:49
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369
#define TCP_TICK_INTERVAL
Definition: tcp.h:47
void tcpUpdateEvents(Socket *socket)
Update TCP related events.
Definition: tcp_misc.c:2052
Helper functions for TCP.
void tcpTick(void)
TCP timer handler.
Definition: tcp_timer.c:56
TCP timer management.
void udpUpdateEvents(Socket *socket)
Update UDP related events.
Definition: udp.c:928