Choco OS  V.0.16.9.0
Join to the chocolate world
oc_dhcp.c
Go to the documentation of this file.
1 
27 #include <oc_dhcp.h>
28 #include <oc_netif.h>
29 #include <oc_debug.h>
30 #include <oc_memman.h>
31 #include <oc_math.h>
32 #include <oc_ktime.h>
33 #include <oc_udp.h>
34 
40 #define _________________________________________LOCAL_TYPES_SECTION________________________________________________________________________
41 
42 typedef enum
43 {
44  MessageType_Discover = 1 ,
45  MessageType_Offer = 2 ,
46  MessageType_Request = 3 ,
47  MessageType_Declide = 4 ,
48  MessageType_Acknowledge = 5 ,
49  MessageType_NAK = 6 ,
50  MessageType_Release = 7 ,
51  MessageType_Inform = 8 ,
52 } MessageType_t;
53 
54 #undef _________________________________________LOCAL_TYPES_SECTION________________________________________________________________________
55 
56 
62 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
63 
65 static uint32_t GetHardwareAddressLength ( oC_Dhcp_HardwareType_t HardwareType );
66 static uint8_t* AddOption ( uint8_t * OptionsArray , uint32_t * LeftBytes , oC_Dhcp_Option_t Option , oC_Dhcp_OptionLength_t Length , uint8_t * Data );
67 static bool FindNextOption ( uint8_t * OptionsArray , uint32_t LeftBytes , oC_Dhcp_Option_t * outOption , oC_Dhcp_OptionLength_t * outLength );
68 static uint8_t* ReadOption ( uint8_t * OptionsArray , uint32_t * LeftBytes , uint8_t * outData );
69 static void ConvertToNetworkEndianess ( oC_Dhcp_Message_t * Message );
70 static void ConvertFromNetworkEndianess ( oC_Dhcp_Message_t * Message );
71 
72 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________
73 
74 
80 #define _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
81 
86 //==========================================================================================================================================
111 //==========================================================================================================================================
112 oC_ErrorCode_t oC_Dhcp_SendMessage( oC_Netif_t Netif , oC_Dhcp_Message_t * Message , uint16_t Size, oC_Time_t Timeout )
113 {
114  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
115 
116  if(
117  ErrorCondition( oC_Netif_IsCorrect(Netif) , oC_ErrorCode_ObjectNotCorrect )
118  && ErrorCondition( isaddresscorrect(Message) , oC_ErrorCode_WrongAddress )
119  && ErrorCondition( oC_Netif_IsConfigured(Netif) , oC_ErrorCode_NotConfiguredYet )
120  && ErrorCondition( oC_Udp_IsPortReserved( oC_Udp_Port_BOOTPClient, getcurprocess() ) , oC_ErrorCode_PortNotReserved )
121  )
122  {
123  ConvertToNetworkEndianess(Message);
124 
125  oC_Udp_Packet_t * packet = oC_Udp_Packet_New( getcurallocator() , oC_Net_PacketType_IPv4, Message, Size);
126  oC_Net_Ipv4Info_t info;
127 
129 
130  bzero( &info, sizeof(info) );
131 
132  if(
133  ErrorCondition ( packet != NULL , oC_ErrorCode_AllocationError )
134  && ErrorCode ( oC_Netif_ReadIpv4Info( Netif, &info ) )
135  )
136  {
137  oC_Net_Address_t destination = {
139  .IPv4 = info.DhcpIP,
140  .Protocol = oC_Net_Protocol_UDP ,
142  };
143 
144 
145  if( ErrorCode( oC_Udp_Send( Netif, oC_Udp_Port_BOOTPClient , &destination, packet, Timeout )) )
146  {
147  errorCode = oC_ErrorCode_None;
148  }
149  }
150 
151  oC_SaveIfFalse("DHCP::SendMessage - ", packet == NULL || oC_Udp_Packet_Delete(&packet), oC_ErrorCode_ReleaseError);
152  }
153 
154  return errorCode;
155 }
156 
157 //==========================================================================================================================================
178 //==========================================================================================================================================
179 oC_ErrorCode_t oC_Dhcp_ReceiveMessage( oC_Netif_t Netif , oC_Dhcp_Message_t * outMessage , oC_Time_t Timeout )
180 {
181  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
182 
183  if(
184  ErrorCondition( oC_Netif_IsCorrect(Netif) , oC_ErrorCode_ObjectNotCorrect )
185  && ErrorCondition( isram(outMessage) , oC_ErrorCode_OutputAddressNotInRAM )
186  && ErrorCondition( oC_Netif_IsConfigured(Netif) , oC_ErrorCode_NotConfiguredYet )
187  && ErrorCondition( oC_Udp_IsPortReserved( oC_Udp_Port_BOOTPClient, getcurprocess() ) , oC_ErrorCode_PortNotReserved )
188  )
189  {
190  oC_Udp_Packet_t * packet = malloc( sizeof(oC_Udp_Packet_t), AllocationFlags_Default);
191 
192  if(
193  ErrorCondition ( packet != NULL , oC_ErrorCode_AllocationError )
194  && ErrorCode ( oC_Udp_Receive( Netif, oC_Udp_Port_BOOTPClient, packet, Timeout ) )
195  && ErrorCode ( oC_Udp_Packet_ReadData( packet, outMessage, sizeof(oC_Dhcp_Message_t)) )
196  )
197  {
198  ConvertFromNetworkEndianess(outMessage);
199  errorCode = oC_ErrorCode_None;
200  }
201  oC_SaveIfFalse("DHCP::ReceiveMessage - ", packet == NULL || kfree(packet, 0), oC_ErrorCode_ReleaseError);
202  }
203 
204  return errorCode;
205 }
206 
207 //==========================================================================================================================================
231 //==========================================================================================================================================
232 oC_ErrorCode_t oC_Dhcp_RequestIp( oC_Netif_t Netif , oC_Time_t Timeout )
233 {
234  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
235  oC_Timestamp_t endTimestamp = oC_KTime_GetTimestamp() + Timeout;
237 
238  if(
239  ErrorCondition( oC_Netif_IsCorrect( Netif ) , oC_ErrorCode_NetifNotCorrect )
240  && ErrorCondition( oC_Netif_IsConfigured(Netif) , oC_ErrorCode_NotConfiguredYet )
241  && ErrorCondition( oC_Netif_GetLinkStatus(Netif) == oC_Net_LinkStatus_Up , oC_ErrorCode_LinkNotDetected )
242  && ErrorCondition( Timeout >= 0 , oC_ErrorCode_TimeNotCorrect )
243  && ErrorCondition( iscurroot() , oC_ErrorCode_PermissionDenied )
244  && ErrorCode ( oC_Udp_ReservePort(&udpPort, oC_KTime_CalculateTimeout(endTimestamp)) )
245  )
246  {
247  if(
248  ErrorCode ( oC_Dhcp_SendDiscovery ( Netif, Timeout ) )
249  && ErrorCode ( oC_Dhcp_ReceiveOffer ( Netif, Timeout ) )
250  && ErrorCode ( oC_Dhcp_SendRequest ( Netif, Timeout ) )
251  && ErrorCode ( oC_Dhcp_ReceiveAcknowledge ( Netif, Timeout ) )
252  )
253  {
254  errorCode = oC_ErrorCode_None;
255  }
256  ErrorCode( oC_Udp_ReleasePort( udpPort, oC_KTime_CalculateTimeout(endTimestamp) ));
257  }
258 
259  return errorCode;
260 }
261 
262 //==========================================================================================================================================
285 //==========================================================================================================================================
286 oC_ErrorCode_t oC_Dhcp_SendDiscovery( oC_Netif_t Netif , oC_Time_t Timeout )
287 {
288  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
290 
291  if(
292  ErrorCondition( oC_Netif_IsCorrect( Netif ) , oC_ErrorCode_ObjectNotCorrect )
293  && ErrorCondition( hardwareType != 0 , oC_ErrorCode_UnknownHardwareType )
294  && ErrorCondition( oC_Netif_IsConfigured(Netif) , oC_ErrorCode_NotConfiguredYet )
295  )
296  {
297  oC_Net_Ipv4Info_t info;
298  oC_Dhcp_Message_t* message = kmalloc(sizeof(oC_Dhcp_Message_t), getcurallocator(), AllocationFlags_ZeroFill);
299  oC_Net_HardwareAddress_t hwAddress;
300 
301  bzero( &info, sizeof( info ) );
302  bzero( &hwAddress, sizeof( hwAddress ) );
303 
304  if(
305  ErrorCondition ( message != NULL , oC_ErrorCode_AllocationError )
306  && ErrorCode ( oC_Netif_ReadIpv4Info ( Netif, &info ) )
307  && ErrorCode ( oC_Netif_ReadHardwareAddress( Netif, &hwAddress ) )
308  )
309  {
310  uint8_t* arrayEndPointer = &message->Options[0];
311  uint32_t leftBytes = sizeof(message->Options);
312  oC_Net_Ipv4_t requestedIp = 0;
313  MessageType_t messageType = MessageType_Discover;
314  uint8_t clientId[7] = {0};
315  uint8_t requestedList[] = {
324  };
325 
326  info.DhcpIP = IP(255,255,255,255);
327  info.IP = IP(0,0,0,0);
328  info.BroadcastIP = IP(255,255,255,255);
329  info.NetIP = IP(0,0,0,0);
330  info.Netmask = IP(0,0,0,0);
331 
332  if(ErrorCode( oC_Netif_SetIpv4Info(Netif,&info) ))
333  {
334  //=====================================================================
335  // Preparing default message parameters //
336  //=====================================================================
338  message->HardwareType = hardwareType;
339  message->HardwareAddressLength = GetHardwareAddressLength(hardwareType);
340  message->Hops = 0;
341  message->XID = (uint32_t)Netif;
342  message->Secs = 0;
343  message->Flags = oC_Dhcp_Flags_Broadcast;
345  message->Options[0] = oC_DHCP_END_OPTION;
346 
347  memcpy(&message->CHAddr,&hwAddress,message->HardwareAddressLength);
348  memcpy(&clientId[1], &hwAddress, message->HardwareAddressLength);
349 
350  clientId[0] = hardwareType;
351 
352  //=====================================================================
353  // Adding options to the message //
354  //=====================================================================
355 
356  /* Add information about the message type - it is marking that this *
357  * message stores `Discover` message */
358  arrayEndPointer = AddOption(arrayEndPointer,&leftBytes,oC_Dhcp_Option_MessageType,oC_Dhcp_OptionLength_MessageType, (uint8_t*)&messageType);
359 
360  /* Add MAC address as Client ID */
361  arrayEndPointer = AddOption(arrayEndPointer,&leftBytes,oC_Dhcp_Option_ClientId,sizeof(clientId), (uint8_t*)&clientId);
362 
363  /* Add MAC address as Client ID */
364  arrayEndPointer = AddOption(arrayEndPointer,&leftBytes,oC_Dhcp_Option_Hostname,sizeof("http://ChocoOS.org"), (uint8_t*)"http://ChocoOS.org");
365 
366  /* If we already have an assigned IP, we want to request it again */
367  if(requestedIp != 0)
368  {
369  arrayEndPointer = AddOption(arrayEndPointer,&leftBytes,oC_Dhcp_Option_RequestedIp,oC_Dhcp_OptionLength_RequestedIp,(uint8_t*)&requestedIp);
370  }
371 
372  /* This adds list of parameters that we want to request. */
373  arrayEndPointer = AddOption(arrayEndPointer,&leftBytes,oC_Dhcp_Option_RequestedList,sizeof(requestedList),(uint8_t*)&requestedList);
374 
375  /* counting size of the message */
376  uint16_t size = sizeof(oC_Dhcp_Message_t) - leftBytes + 1;
377 
378  /* Trailer */
379  while((size & 3) && size < sizeof(oC_Dhcp_Message_t))
380  {
381  size++;
382  }
383 
384  //=====================================================================
385  // Sending message via Network Interface //
386  //=====================================================================
387  errorCode = oC_Dhcp_SendMessage(Netif, message, size, Timeout);
388  }
389  }
390 
391  oC_SaveIfFalse( "DHCP::Discovery - cannot release message memory - ", message == NULL || kfree(message,0), oC_ErrorCode_ReleaseError );
392  }
393 
394  return errorCode;
395 }
396 
397 //==========================================================================================================================================
422 //==========================================================================================================================================
423 oC_ErrorCode_t oC_Dhcp_ReceiveOffer( oC_Netif_t Netif , oC_Time_t Timeout )
424 {
425  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
426 
427  if(
428  ErrorCondition( oC_Netif_IsCorrect( Netif ) , oC_ErrorCode_ObjectNotCorrect )
429  && ErrorCondition( oC_Netif_IsConfigured(Netif) , oC_ErrorCode_NotConfiguredYet )
430  )
431  {
432  oC_Net_Ipv4Info_t info ;
433  oC_Dhcp_Message_t * message = malloc(sizeof(oC_Dhcp_Message_t), AllocationFlags_ZeroFill);
434 
435  bzero( &info, sizeof( info ) );
436 
437  if(
438  ErrorCondition ( message != NULL , oC_ErrorCode_AllocationError )
439  && ErrorCode ( oC_Netif_ReadIpv4Info ( Netif, &info ) )
440  )
441  {
442  oC_Timestamp_t startTime = oC_KTime_GetTimestamp();
443  oC_Timestamp_t endTime = startTime + Timeout;
444  oC_Timestamp_t currentTime = oC_KTime_GetTimestamp();
445  MessageType_t messageType = 0;
446  oC_Net_Ipv4Info_t tempInfo;
447 
448  //=====================================================================
449  // Looking offer response message from the network interface //
450  //=====================================================================
451 
452  /* Receive next message from network interface */
453  while(ErrorCode(oC_Dhcp_ReceiveMessage(Netif,message,Timeout)))
454  {
455  uint32_t leftBytes = sizeof(message->Options);
456  uint8_t* options = message->Options;
457  oC_Dhcp_Option_t option = 0;
458  oC_Dhcp_OptionLength_t length = 0;
459  uint8_t data[oC_DHCP_OPTIONS_BUFFER_SIZE];
460 
461  messageType = 0;
462 
463  memcpy(&tempInfo,&info,sizeof(tempInfo));
464 
465  tempInfo.DhcpIP = message->SIAddr;
466  tempInfo.GatewayIP = message->GIAddr;
467  tempInfo.IP = message->YIAddr;
468 
469  memcpy(tempInfo.DhcpServerName, message->SName, sizeof(tempInfo.DhcpServerName));
470 
471  if(
473  && message->XID == ((uint32_t)Netif)
474  )
475  {
476  //=====================================================================
477  // Reading options from the message //
478  //=====================================================================
479 
480  /* Checking if next option is available */
481  while(FindNextOption(options,leftBytes,&option,&length))
482  {
483  memset(data,0,sizeof(data));
484 
485  /* Read option from the message */
486  options = ReadOption(options,&leftBytes,data);
487 
488  //=====================================================================
489  // Parsing option //
490  //=====================================================================
491  if(option == oC_Dhcp_Option_MessageType)
492  {
493  memcpy(&messageType, data, sizeof(messageType));
494  }
495  else if(option == oC_Dhcp_Option_SubnetMask)
496  {
497  memcpy(&tempInfo.Netmask, data, sizeof(tempInfo.Netmask));
499  }
500  else if(option == oC_Dhcp_Option_Router)
501  {
502  memcpy(&tempInfo.NetIP, data, sizeof(tempInfo.NetIP));
504  }
505  else if(option == oC_Dhcp_Option_Broadcast)
506  {
507  memcpy(&tempInfo.BroadcastIP, data, sizeof(tempInfo.BroadcastIP));
509  }
510  else if(option == oC_Dhcp_Option_DnsServer)
511  {
512  memcpy(&tempInfo.DnsIP, data, sizeof(tempInfo.DnsIP));
514  }
515  else if(option == oC_Dhcp_Option_DefaultTTL)
516  {
517  memcpy(&tempInfo.DefaultTTL, data, sizeof(tempInfo.DefaultTTL));
518  }
519  else if(option == oC_Dhcp_Option_MTU)
520  {
521  memcpy(&tempInfo.MTU, data, sizeof(tempInfo.MTU));
522  tempInfo.MTU = oC_Net_ConvertUint32FromNetworkEndianess(tempInfo.MTU);
523  }
524  else if(option == oC_Dhcp_Option_Ntp)
525  {
526  memcpy(&tempInfo.NtpIP, data, sizeof(tempInfo.NtpIP));
528  }
529  else if(option == oC_Dhcp_Option_LeaseTime)
530  {
531  uint32_t leaseTime = 0;
532 
533  memcpy(&leaseTime, data, sizeof(uint32_t));
534 
535  leaseTime = oC_Net_ConvertUint32FromNetworkEndianess(leaseTime);
536 
537  tempInfo.LeaseTime = (oC_Time_t)leaseTime;
538  }
539  }
540  }
541 
542  /* If this is the offer message, we can use it, otherwise we have to *
543  * wait for the next message */
544  if(messageType == MessageType_Offer)
545  {
546  memcpy(&info,&tempInfo,sizeof(info));
547  break;
548  }
549 
550  //=====================================================================
551  // Parsing option //
552  //=====================================================================
553  currentTime = oC_KTime_GetTimestamp();
554 
555  if(currentTime <= endTime)
556  {
557  Timeout = endTime - currentTime;
558  }
559  else
560  {
561  errorCode = oC_ErrorCode_Timeout;
562  break;
563  }
564  }
565 
566 
567  //=====================================================================
568  // If we've received message, we can use data of it //
569  //=====================================================================
570  if(messageType == MessageType_Offer)
571  {
572  errorCode = oC_Netif_SetIpv4Info(Netif,&info);
573  }
574  }
575  oC_SaveIfFalse("DHCP::Offer - cannot release message memory - ", message == NULL || free(message,0) , oC_ErrorCode_ReleaseError);
576  }
577 
578  return errorCode;
579 }
580 
581 //==========================================================================================================================================
603 //==========================================================================================================================================
604 oC_ErrorCode_t oC_Dhcp_SendRequest( oC_Netif_t Netif , oC_Time_t Timeout )
605 {
606  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
608 
609  if(
610  ErrorCondition( oC_Netif_IsCorrect( Netif ) , oC_ErrorCode_ObjectNotCorrect )
611  && ErrorCondition( hardwareType != 0 , oC_ErrorCode_UnknownHardwareType )
612  && ErrorCondition( oC_Netif_IsConfigured(Netif) , oC_ErrorCode_NotConfiguredYet )
613  )
614  {
615  oC_Net_Ipv4Info_t info;
616  oC_Dhcp_Message_t * message = malloc( sizeof(oC_Dhcp_Message_t) , AllocationFlags_ZeroFill );
617  oC_Net_HardwareAddress_t hwAddress;
618 
619  bzero( &info, sizeof( info ) );
620  bzero( &hwAddress, sizeof( hwAddress ) );
621 
622  if(
623  ErrorCondition( message != NULL , oC_ErrorCode_AllocationError )
624  && ErrorCode( oC_Netif_ReadIpv4Info ( Netif, &info ) )
625  && ErrorCode( oC_Netif_ReadHardwareAddress( Netif, &hwAddress ) )
626  )
627  {
628  uint8_t* arrayEndPointer = &message->Options[0];
629  uint32_t leftBytes = sizeof(message->Options);
632  MessageType_t messageType = MessageType_Request;
633 
634  if(ErrorCode( oC_Netif_SetIpv4Info(Netif,&info) ))
635  {
636  //=====================================================================
637  // Preparing default message parameters //
638  //=====================================================================
640  message->HardwareType = hardwareType;
641  message->HardwareAddressLength = GetHardwareAddressLength(hardwareType);
642  message->Hops = 0;
643  message->XID = (uint32_t)Netif;
644  message->Secs = 0;
645  message->Flags = oC_Dhcp_Flags_Broadcast;
647  message->Options[0] = oC_DHCP_END_OPTION;
648  message->SIAddr = info.DhcpIP; // This will be converted before send by the 'SendMessage' function
649  message->CIAddr = info.IP; // This will be converted before send by the 'SendMessage' function
650 
651  memcpy(&message->CHAddr,&hwAddress,message->HardwareAddressLength);
652 
653  //=====================================================================
654  // Adding options to the message //
655  //=====================================================================
656 
657  /* Add information about the message type - it is marking that this *
658  * message stores `Discover` message */
659  arrayEndPointer = AddOption(arrayEndPointer, &leftBytes, oC_Dhcp_Option_MessageType , oC_Dhcp_OptionLength_MessageType , (uint8_t*)&messageType );
660  arrayEndPointer = AddOption(arrayEndPointer, &leftBytes, oC_Dhcp_Option_RequestedIp , oC_Dhcp_OptionLength_RequestedIp , (uint8_t*)&requestedIp );
661  arrayEndPointer = AddOption(arrayEndPointer, &leftBytes, oC_Dhcp_Option_ServerId , oC_Dhcp_OptionLength_ServerId , (uint8_t*)&dhcpIp );
662 
663 
664  /* counting size of the message */
665  uint16_t size = sizeof(oC_Dhcp_Message_t) - leftBytes + 1;
666 
667  /* Trailer */
668  while((size & 3) && size < sizeof(oC_Dhcp_Message_t))
669  {
670  size++;
671  }
672 
673  //=====================================================================
674  // Sending message via Network Interface //
675  //=====================================================================
676  errorCode = oC_Dhcp_SendMessage(Netif,message,size,Timeout);
677  }
678  }
679 
680  oC_SaveIfFalse("DHCP::Request - cannot release message memory - ", message == NULL || free(message,0) , oC_ErrorCode_ReleaseError);
681  }
682 
683  return errorCode;
684 }
685 
686 //==========================================================================================================================================
711 //==========================================================================================================================================
712 oC_ErrorCode_t oC_Dhcp_ReceiveAcknowledge( oC_Netif_t Netif , oC_Time_t Timeout )
713 {
714  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
715 
716  if(
717  ErrorCondition( oC_Netif_IsCorrect( Netif ) , oC_ErrorCode_ObjectNotCorrect )
718  && ErrorCondition( oC_Netif_IsConfigured(Netif) , oC_ErrorCode_NotConfiguredYet )
719  )
720  {
721  oC_Net_Ipv4Info_t info ;
722  oC_Dhcp_Message_t * message = malloc(sizeof(oC_Dhcp_Message_t) , AllocationFlags_ZeroFill);
723 
724  bzero( &info, sizeof( info ) );
725 
726  if(
727  ErrorCondition ( message != NULL , oC_ErrorCode_AllocationError )
728  && ErrorCode ( oC_Netif_ReadIpv4Info ( Netif, &info ) )
729  )
730  {
731  oC_Timestamp_t startTime = oC_KTime_GetTimestamp();
732  oC_Timestamp_t endTime = startTime + Timeout;
733  oC_Timestamp_t currentTime = oC_KTime_GetTimestamp();
734  MessageType_t messageType = 0;
735  oC_Net_Ipv4Info_t tempInfo;
736 
737  //=====================================================================
738  // Looking acknowledge response message from the network interface //
739  //=====================================================================
740 
741  /* Receive next message from network interface */
742  while(ErrorCode(oC_Dhcp_ReceiveMessage(Netif,message,Timeout)))
743  {
744  uint32_t leftBytes = sizeof(message->Options);
745  uint8_t* options = message->Options;
746  oC_Dhcp_Option_t option = 0;
747  oC_Dhcp_OptionLength_t length = 0;
748  uint8_t data[oC_DHCP_OPTIONS_BUFFER_SIZE];
749 
750  messageType = 0;
751 
752  memcpy(&tempInfo,&info,sizeof(tempInfo));
753 
754  if(
756  && message->XID == ((uint32_t)Netif)
757  )
758  {
759  //=====================================================================
760  // Reading options from the message //
761  //=====================================================================
762 
763  /* Checking if next option is available */
764  while(FindNextOption(options,leftBytes,&option,&length))
765  {
766  memset(data,0,sizeof(data));
767 
768  /* Read option from the message */
769  options = ReadOption(options,&leftBytes,data);
770 
771  //=====================================================================
772  // Parsing option //
773  //=====================================================================
774  if(option == oC_Dhcp_Option_MessageType)
775  {
776  memcpy(&messageType, data, sizeof(messageType));
777  }
778  else if(option == oC_Dhcp_Option_SubnetMask)
779  {
780  memcpy(&tempInfo.Netmask, data, sizeof(tempInfo.Netmask));
782  }
783  else if(option == oC_Dhcp_Option_Router)
784  {
785  memcpy(&tempInfo.NetIP, data, sizeof(tempInfo.NetIP));
787  }
788  else if(option == oC_Dhcp_Option_Broadcast)
789  {
790  memcpy(&tempInfo.BroadcastIP, data, sizeof(tempInfo.BroadcastIP));
792  }
793  else if(option == oC_Dhcp_Option_DnsServer)
794  {
795  memcpy(&tempInfo.DnsIP, data, sizeof(tempInfo.DnsIP));
797  }
798  else if(option == oC_Dhcp_Option_DefaultTTL)
799  {
800  memcpy(&tempInfo.DefaultTTL, data, sizeof(tempInfo.DefaultTTL));
801  }
802  else if(option == oC_Dhcp_Option_MTU)
803  {
804  memcpy(&tempInfo.MTU, data, sizeof(tempInfo.MTU));
805  tempInfo.MTU = oC_Net_ConvertUint32FromNetworkEndianess(tempInfo.MTU);
806  }
807  else if(option == oC_Dhcp_Option_Ntp)
808  {
809  memcpy(&tempInfo.NtpIP, data, sizeof(tempInfo.NtpIP));
811  }
812  else if(option == oC_Dhcp_Option_LeaseTime)
813  {
814  uint32_t leaseTime = 0;
815 
816  memcpy(&leaseTime, data, sizeof(uint32_t));
817 
818  leaseTime = oC_Net_ConvertUint32FromNetworkEndianess(leaseTime);
819 
820  tempInfo.LeaseTime = (oC_Time_t)leaseTime;
821  tempInfo.IpExpiredTimestamp = oC_KTime_GetTimestamp() + tempInfo.LeaseTime;
822  }
823  }
824  }
825 
826  /* If this is the offer message, we can use it, otherwise we have to *
827  * wait for the next message */
828  if(messageType == MessageType_Acknowledge || messageType == MessageType_NAK)
829  {
830  memcpy(&info,&tempInfo,sizeof(info));
831  info.IP = message->YIAddr;
832  info.DhcpIP = message->SIAddr;
833  break;
834  }
835 
836  //=====================================================================
837  // Parsing option //
838  //=====================================================================
839  currentTime = oC_KTime_GetTimestamp();
840 
841  if(currentTime <= endTime)
842  {
843  Timeout = endTime - currentTime;
844  }
845  else
846  {
847  errorCode = oC_ErrorCode_Timeout;
848  break;
849  }
850  }
851 
852  //=====================================================================
853  // If we've received message, we can use data of it //
854  //=====================================================================
855  if(messageType == MessageType_Acknowledge || messageType == MessageType_NAK)
856  {
857  oC_Net_Address_t routerAddress = {
859  .IPv4 = info.NetIP
860  };
861  /* We don't check this status to provide work of local network also in case of failure */
862  oC_SaveIfErrorOccur("DHCP::Cannot read HW address of the router!\n",oC_Netif_ReadHardwareAddressOf(Netif,&info.HardwareRouterAddress,&routerAddress,oC_KTime_CalculateTimeout(endTime)));
863 
864  errorCode = oC_Netif_SetIpv4Info(Netif,&info);
865  }
866  }
867 
868  oC_SaveIfFalse("DHCP::Acknowledge - cannot release message memory - ", message == NULL || free(message,0) , oC_ErrorCode_ReleaseError);
869  }
870 
871  return errorCode;
872 }
873 
875 #undef _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
876 
882 #define _________________________________________LOCAL_FUNCTIONS_SECTION___________________________________________________________________
883 
884 //==========================================================================================================================================
888 //==========================================================================================================================================
890 {
891  oC_Dhcp_HardwareType_t result = 0;
892 
893  if(HardwareType == oC_Net_HardwareType_Ethernet)
894  {
896  }
897  else
898  {
899  oC_SaveError("Dhcp::TranslateToDhcpHardwareType: unsupported hardware type - %d\n", HardwareType);
900  }
901 
902  return result;
903 }
904 
905 //==========================================================================================================================================
909 //==========================================================================================================================================
910 static uint32_t GetHardwareAddressLength( oC_Dhcp_HardwareType_t HardwareType )
911 {
912  uint32_t length = 0;
913 
914  if(HardwareType == oC_Dhcp_HardwareType_Ethernet)
915  {
916  length = sizeof(oC_Net_MacAddress_t);
917  }
918  else
919  {
920  kdebuglog(oC_LogType_Error , "Dhcp::GetHardwareAddressLength: unsupported hardware type - %d\n", HardwareType);
921  }
922 
923  return length;
924 }
925 
926 //==========================================================================================================================================
940 //==========================================================================================================================================
941 static uint8_t* AddOption( uint8_t * OptionsArray , uint32_t * LeftBytes , oC_Dhcp_Option_t Option , oC_Dhcp_OptionLength_t Length , uint8_t * Data )
942 {
943  uint32_t realOptionSize = Length + 2;
944 
945  if((*LeftBytes) >= (realOptionSize + 1))
946  {
947  OptionsArray[0] = (uint8_t)Option;
948  OptionsArray[1] = Length;
949 
950  if(Data != NULL)
951  {
952  for(uint32_t i = 2; i < realOptionSize; i++ )
953  {
954  OptionsArray[i] = Data[i-2];
955  }
956  }
957  OptionsArray[realOptionSize] = oC_Dhcp_Option_End;
958  (*LeftBytes) = (*LeftBytes) - realOptionSize;
959  OptionsArray += realOptionSize;
960  }
961  else
962  {
963  kdebuglog(oC_LogType_Error, "Dhcp::AddOption - Cannot add option %d (length %d) - there is no more space in array\n", Option, Length);
964  }
965 
966  return OptionsArray;
967 }
968 
969 //==========================================================================================================================================
973 //==========================================================================================================================================
974 static bool FindNextOption( uint8_t * OptionsArray , uint32_t LeftBytes , oC_Dhcp_Option_t * outOption , oC_Dhcp_OptionLength_t * outLength )
975 {
976  bool nextOptionFound = false;
977 
978  if(LeftBytes >= 3 && OptionsArray[0] != oC_Dhcp_Option_End)
979  {
980  *outOption = (oC_Dhcp_Option_t) OptionsArray[0];
981  *outLength = (oC_Dhcp_OptionLength_t) OptionsArray[1];
982 
983  nextOptionFound = true;
984  }
985 
986  return nextOptionFound;
987 }
988 
989 //==========================================================================================================================================
993 //==========================================================================================================================================
994 static uint8_t* ReadOption( uint8_t * OptionsArray , uint32_t * LeftBytes , uint8_t * outData )
995 {
996  oC_Dhcp_Option_t option = 0;
997  oC_Dhcp_OptionLength_t length = 0;
998  uint32_t realOptionSize = 2;
999 
1000  if(FindNextOption(OptionsArray,*LeftBytes,&option,&length))
1001  {
1002  realOptionSize += length;
1003 
1004  if(outData != NULL)
1005  {
1006  for(uint32_t i = 2;i < realOptionSize; i++)
1007  {
1008  outData[i-2] = OptionsArray[i];
1009  }
1010  }
1011 
1012  OptionsArray = &OptionsArray[realOptionSize];
1013  *LeftBytes -= realOptionSize;
1014  }
1015 
1016  return OptionsArray;
1017 }
1018 
1019 //==========================================================================================================================================
1023 //==========================================================================================================================================
1025 {
1031 }
1032 //==========================================================================================================================================
1036 //==========================================================================================================================================
1038 {
1044 }
1045 
1046 
1047 #undef _________________________________________LOCAL_FUNCTIONS_SECTION___________________________________________________________________
1048 
Packet in type IPv4.
Definition: oc_net.h:177
oC_ErrorCode_t oC_Dhcp_RequestIp(oC_Netif_t Netif, oC_Time_t Timeout)
performs DHCP IP request procedure
Definition: oc_dhcp.c:232
uint32_t GIAddr
Gateway IP Address - a router IP
Definition: oc_dhcp.h:222
oC_Net_Ipv4_t NetIP
IP of the local network (router IP)
Definition: oc_net.h:472
oC_ErrorCode_t oC_Dhcp_ReceiveOffer(oC_Netif_t Netif, oC_Time_t Timeout)
receives offer from the DHCP server
Definition: oc_dhcp.c:423
Basic math operations.
FILE__DESCRIPTION
uint8_t Options[oC_DHCP_OPTIONS_BUFFER_SIZE]
Additional options array.
Definition: oc_dhcp.h:227
Contains definitions of DHCP.
oC_ErrorCode_t oC_Netif_ReadHardwareAddress(oC_Netif_t Netif, oC_Net_HardwareAddress_t *outHardwareAddress)
reads hardware address of the interface
Definition: oc_netif.c:1105
bool oC_Udp_IsPortReserved(oC_Udp_Port_t Port, oC_Process_t Process)
checks if the given UDP port is reserved
Definition: oc_udp.c:235
oC_Udp_Port_t
stores UDP port number
Definition: oc_udp.h:74
static uint32_t GetHardwareAddressLength(oC_Dhcp_HardwareType_t HardwareType)
returns number of bytes required for storing hardware address
Definition: oc_dhcp.c:910
Length in bytes for option oC_Dhcp_Option_MessageType.
Definition: oc_dhcp.h:193
Request to a server.
Definition: oc_dhcp.h:90
User Datagram Protocol.
Definition: oc_net.h:160
uint32_t YIAddr
Your IP Address - the server fills it as the proposed IP address for the client
Definition: oc_dhcp.h:220
oC_Time_t LeaseTime
IP lease time.
Definition: oc_net.h:482
The router option specifies a list of IP addresses on the client subnetwork.
Definition: oc_dhcp.h:148
stores UDP packet
Definition: oc_udp.h:305
uint32_t MagicCookie
Magic cookie - set to oC_DHCP_MAGIC_COOKIE (0x63825363) to identify the information as vendor indepen...
Definition: oc_dhcp.h:226
uint32_t Hops
Set to 0 by a client when transmitting a request and used by relay agents to control the forwarding o...
Definition: oc_dhcp.h:215
stores network address
Definition: oc_net.h:441
Broadcast flag - a client does not know its own IP address so it send the message as broadcast...
Definition: oc_dhcp.h:128
Contains interface for netif object.
Bootstrap Protocol (BOOTP) client; also used by Dynamic Host Configuration Protocol (DHCP) ...
Definition: oc_udp.h:104
struct PACKED oC_Dhcp_Message_t
stores DHCP message
oC_Net_Ipv4_t DnsIP
IP of the local DNS server.
Definition: oc_net.h:477
Used by the DHCP client to request values for specified configuration parameters. ...
Definition: oc_dhcp.h:161
uint32_t Secs
Seconds - In BOOTP this field was vaguely defined and not always used.
Definition: oc_dhcp.h:217
Address to use in client subnetwork for sending broadcast packets.
Definition: oc_dhcp.h:153
static void ConvertFromNetworkEndianess(oC_Dhcp_Message_t *Message)
converts message from network endianess
Definition: oc_dhcp.c:1037
oC_ErrorCode_t oC_Netif_ReadHardwareAddressOf(oC_Netif_t Netif, oC_Net_HardwareAddress_t *outHardwareAddress, const oC_Net_Address_t *Address, oC_Time_t Timeout)
reads hardware address of the given IP address in LAN
Definition: oc_netif.c:1147
uint32_t oC_Net_Ipv4_t
stores IPv4 address
Definition: oc_net.h:132
bool oC_Netif_IsCorrect(oC_Netif_t Netif)
checks if the Netif object is correct
Definition: oc_netif.c:351
Destination IP address of DHCP server.
Definition: oc_dhcp.h:160
uint8_t oC_Net_MacAddress_t[MAC_ADDRESS_LENGTH]
stores MAC address
Definition: oc_net.h:106
uint32_t Operation
Specifies type of the message.
Definition: oc_dhcp.h:212
oC_Net_HardwareType_t
stores hardware type of the network interface
Definition: oc_net.h:202
oC_ErrorCode_t oC_Dhcp_SendDiscovery(oC_Netif_t Netif, oC_Time_t Timeout)
sends DHCP discovery message to DHCP server
Definition: oc_dhcp.c:286
oC_Net_Ipv4_t NtpIP
Main Network Time Protocol Server available in the subnetwork.
Definition: oc_net.h:481
oC_Net_Ipv4_t Netmask
Local network mask.
Definition: oc_net.h:473
uint8_t DefaultTTL
Default TTL value for the IPv4 packets.
Definition: oc_net.h:480
Length in bytes for option oC_Dhcp_Option_RequestedIp.
Definition: oc_dhcp.h:188
oC_ErrorCode_t oC_Dhcp_SendRequest(oC_Netif_t Netif, oC_Time_t Timeout)
sends request message to the DHCP server
Definition: oc_dhcp.c:604
oC_Net_Ipv4_t BroadcastIP
IP that should be used for broadcasting.
Definition: oc_net.h:479
#define oC_DHCP_END_OPTION
Value for marking last entry in the options array.
Definition: oc_dhcp.h:61
bool oC_Udp_Packet_Delete(oC_Udp_Packet_t **Packet)
release memory allocated for a UDP packet
Definition: oc_udp.c:589
oC_ErrorCode_t oC_Udp_ReservePort(oC_Udp_Port_t *Port, oC_Time_t Timeout)
reserves a UDP port
Definition: oc_udp.c:281
uint32_t XID
Transaction ID Generated by the client to allow it to match up the request with replies received from...
Definition: oc_dhcp.h:216
static bool FindNextOption(uint8_t *OptionsArray, uint32_t LeftBytes, oC_Dhcp_Option_t *outOption, oC_Dhcp_OptionLength_t *outLength)
checks if is there any more option in the options array
Definition: oc_dhcp.c:974
oC_MemorySize_t MTU
MTU (Maximum Transmission Unit) for the local network.
Definition: oc_net.h:478
oC_ErrorCode_t oC_Udp_ReleasePort(oC_Udp_Port_t Port, oC_Time_t Timeout)
releases a port
Definition: oc_udp.c:412
uint32_t SIAddr
Server IP Address - the server fills it with its own address, that should be used for the states afte...
Definition: oc_dhcp.h:221
oC_ErrorCode_t oC_Dhcp_ReceiveAcknowledge(oC_Netif_t Netif, oC_Time_t Timeout)
receives ACK message from DHCP server
Definition: oc_dhcp.c:712
static uint32_t oC_Net_ConvertUint32FromNetworkEndianess(uint32_t v)
converts uint32_t from network byte order
Definition: oc_net.h:590
Specifies MTU for the interface.
Definition: oc_dhcp.h:152
oC_Timestamp_t IpExpiredTimestamp
Timestamp of IP expiration.
Definition: oc_net.h:483
The option allows to request the specified static IP.
Definition: oc_dhcp.h:157
static void ConvertToNetworkEndianess(oC_Dhcp_Message_t *Message)
converts message to network endianess
Definition: oc_dhcp.c:1024
Specifies subnetwork mask.
Definition: oc_dhcp.h:146
oC_ErrorCode_t oC_Netif_SetIpv4Info(oC_Netif_t Netif, const oC_Net_Ipv4Info_t *Info)
sets informations about IPv4
Definition: oc_netif.c:1252
stores hardware address
Definition: oc_net.h:114
The end option marks end of the options array.
Definition: oc_dhcp.h:145
uint8_t CHAddr[16]
Client Hardware Address - the hardware address of the client used for identification and communicatio...
Definition: oc_dhcp.h:223
Stores UDP interface.
static uint32_t oC_Net_ConvertUint32ToNetworkEndianess(uint32_t v)
converts uint32_t to network byte order
Definition: oc_net.h:562
oC_ErrorCode_t oC_Udp_Packet_ReadData(const oC_Udp_Packet_t *Packet, void *outData, uint16_t Size)
reads data of the UDP packet
Definition: oc_udp.c:652
oC_ErrorCode_t oC_Dhcp_ReceiveMessage(oC_Netif_t Netif, oC_Dhcp_Message_t *outMessage, oC_Time_t Timeout)
receives DHCP message from DHCP server
Definition: oc_dhcp.c:179
List of Network Time Protocol Servers available in the subnetwork.
Definition: oc_dhcp.h:155
char SName[64]
Server Name - The server can optionally put its name in this field
Definition: oc_dhcp.h:224
IP address in version 4.
Definition: oc_net.h:429
oC_Udp_Packet_t * oC_Udp_Packet_New(Allocator_t PacketAllocator, oC_Net_PacketType_t Type, const void *Data, uint16_t Size)
allocates memory for a UDP packet
Definition: oc_udp.c:547
uint32_t HardwareAddressLength
Length of the hardware address in bytes.
Definition: oc_dhcp.h:214
Length in bytes for option oC_Dhcp_Option_ServerId.
Definition: oc_dhcp.h:191
The file with memory manager interface.
bool oC_Netif_IsConfigured(oC_Netif_t Netif)
checks if the driver is configured
Definition: oc_netif.c:367
Bootstrap Protocol (BOOTP) server; also used by Dynamic Host Configuration Protocol (DHCP) ...
Definition: oc_udp.h:103
Network interface is DOWN (cable is not connected)
Definition: oc_net.h:363
oC_Dhcp_Option_t
Stores DHCP options that can be added into the DHCP message.
Definition: oc_dhcp.h:142
List of DNS servers in the subnetwork.
Definition: oc_dhcp.h:149
uint32_t HardwareType
Hardware Type - specifies type of the hardware used in the local network.
Definition: oc_dhcp.h:213
#define oC_DHCP_OPTIONS_BUFFER_SIZE
stores maximum number of bytes reserved for options in DHCP message
Definition: oc_dhcp.h:69
oC_ErrorCode_t oC_Udp_Send(oC_Netif_t Netif, oC_Udp_Port_t LocalPort, const oC_Net_Address_t *Destination, oC_Udp_Packet_t *Packet, oC_Time_t Timeout)
sends UDP packet
Definition: oc_udp.c:732
oC_Net_Ipv4_t GatewayIP
Default gateway IP.
Definition: oc_net.h:476
uint32_t CIAddr
Client IP Address - If a client has IP address and it is valid (while BOUND, RENEWING or REBINDING st...
Definition: oc_dhcp.h:219
Used by the DHCP clients to specify their unique ID.
Definition: oc_dhcp.h:165
oC_Net_HardwareType_t oC_Netif_GetHardwareType(oC_Netif_t Netif)
returns hardware type of the network interface
Definition: oc_netif.c:1072
oC_Dhcp_HardwareType_t
stores type of hardware for oC_Dhcp_Message_t type
Definition: oc_dhcp.h:102
oC_ErrorCode_t oC_Udp_Receive(oC_Netif_t Netif, oC_Udp_Port_t LocalPort, oC_Udp_Packet_t *Packet, oC_Time_t Timeout)
receives UDP packet
Definition: oc_udp.c:852
oC_ErrorCode_t oC_Netif_ReadIpv4Info(oC_Netif_t Netif, oC_Net_Ipv4Info_t *outInfo)
reads IPv4 informations
Definition: oc_netif.c:1288
Allows the client to request a lease time for the IP address.
Definition: oc_dhcp.h:158
char DhcpServerName[DHCP_SERVER_NAME_LENGTH]
Name of the local DHCP server.
Definition: oc_net.h:475
Used to mark type of the message - 1 for Discover, 2 - Offer, 3 - Request, 4 - Declide, 5 - Pack , 6 - Pnak, 7 - Release, 8 - Inform
Definition: oc_dhcp.h:162
oC_Net_LinkStatus_t oC_Netif_GetLinkStatus(oC_Netif_t Netif)
returns last known link status of the network interface
Definition: oc_netif.c:1026
Ethernet (10Mb)
Definition: oc_dhcp.h:104
oC_Net_Ipv4_t IP
IP of the network interface.
Definition: oc_net.h:471
static uint8_t * AddOption(uint8_t *OptionsArray, uint32_t *LeftBytes, oC_Dhcp_Option_t Option, oC_Dhcp_OptionLength_t Length, uint8_t *Data)
adds option to the options array
Definition: oc_dhcp.c:941
Reply from the server.
Definition: oc_dhcp.h:91
oC_ErrorCode_t oC_Dhcp_SendMessage(oC_Netif_t Netif, oC_Dhcp_Message_t *Message, uint16_t Size, oC_Time_t Timeout)
sends DHCP message to DHCP server
Definition: oc_dhcp.c:112
stores network interface IPv4 informations
Definition: oc_net.h:469
Specifies default TTL value for packets.
Definition: oc_dhcp.h:151
static uint8_t * ReadOption(uint8_t *OptionsArray, uint32_t *LeftBytes, uint8_t *outData)
reads option in the Options array and returns pointer to the next option
Definition: oc_dhcp.c:994
oC_Net_AddressType_t Type
Type of the address stored inside.
Definition: oc_net.h:443
Specifies name of the client.
Definition: oc_dhcp.h:150
static oC_Dhcp_HardwareType_t TranslateToDhcpHardwareType(oC_Net_HardwareType_t HardwareType)
translates oC_Net_HardwareType_t to oC_Dhcp_HardwareType_t
Definition: oc_dhcp.c:889
uint32_t Flags
Flags of the message, look at oC_Dhcp_Flags_t type for more.
Definition: oc_dhcp.h:218
oC_Net_Ipv4_t DhcpIP
IP of the local DHCP server.
Definition: oc_net.h:474
The file with interface of kernel time module.
oC_Net_HardwareAddress_t HardwareRouterAddress
HW address of the local router.
Definition: oc_net.h:484
stores IPv6 address
Definition: oc_net.h:142
#define NULL
pointer to a zero
Definition: oc_null.h:37
#define oC_DHCP_MAGIC_COOKIE
Magic cookie for the DHCP message.
Definition: oc_dhcp.h:53
oC_Dhcp_OptionLength_t
stores length for options from oC_Dhcp_Option_t type
Definition: oc_dhcp.h:175