common_subr.c
上传用户:baixin
上传日期:2008-03-13
资源大小:4795k
文件大小:10k
开发平台:

MultiPlatform

  1. /* common_subr.c - DHCP library common code */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01l,22may02,wap  use tickGet() instead of vxTicks in dhcpTime()
  8. 01k,23apr02,wap  Implement dhcpTime() routine to use instead of time() (SPR
  9.                  #68900)
  10. 01j,12oct01,rae  merge from truestack ver o1k, base o1f (VIRTUAL_STACK)
  11. 01i,04nov00,niq  Changing the MIB2 type names to conform to the RFC2233 names
  12. 01h,24oct00,spm  fixed modification history after tor3_x merge
  13. 01g,23oct00,niq  merged from version 01h of tor3_x branch (base version 01f)
  14. 01f,26aug97,spm  moved routines not shared by client and server
  15. 01e,10jun97,spm  isolated incoming messages in state machine from input hooks
  16. 01d,02jun97,spm  changed DHCP option tags to prevent name conflicts (SPR #8667)
  17.                  and updated man pages
  18. 01c,07apr97,spm  added INCLUDE_FILES to module heading
  19. 01b,29jan97,spm  brought into compliance with Wind River coding standards
  20. 01a,03oct96,spm  created by modifying WIDE Project DHCP Implementation
  21. */
  22. /*
  23. DESCRIPTION
  24. This library contains the code common to the WIDE Project implementations
  25. of the DHCP client (runtime and boot-time versions) and the DHCP server,
  26. modified for VxWorks compatibility, as well as some internal WRS code which
  27. is also shared by those components.
  28. INCLUDE_FILES: None
  29. */
  30. /*
  31.  * WIDE Project DHCP Implementation
  32.  * Copyright (c) 1995 Akihiro Tominaga
  33.  * Copyright (c) 1995 WIDE Project
  34.  * All rights reserved.
  35.  *
  36.  * Permission to use, copy, modify and distribute this software and its
  37.  * documentation is hereby granted, provided only with the following
  38.  * conditions are satisfied:
  39.  *
  40.  * 1. Both the copyright notice and this permission notice appear in
  41.  *    all copies of the software, derivative works or modified versions,
  42.  *    and any portions thereof, and that both notices appear in
  43.  *    supporting documentation.
  44.  * 2. All advertising materials mentioning features or use of this software
  45.  *    must display the following acknowledgement:
  46.  *      This product includes software developed by WIDE Project and
  47.  *      its contributors.
  48.  * 3. Neither the name of WIDE Project nor the names of its contributors
  49.  *    may be used to endorse or promote products derived from this software
  50.  *    without specific prior written permission.
  51.  *
  52.  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
  53.  * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  54.  * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
  55.  * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
  56.  *
  57.  * Feedback of the results generated from any improvements or
  58.  * extensions made to this software would be much appreciated.
  59.  * Any such feedback should be sent to:
  60.  * 
  61.  *  Akihiro Tominaga
  62.  *  WIDE Project
  63.  *  Keio University, Endo 5322, Kanagawa, Japan
  64.  *  (E-mail: dhcp-dist@wide.ad.jp)
  65.  *
  66.  * WIDE project has the rights to redistribute these changes.
  67.  */
  68. /* includes */
  69. #include "vxWorks.h"
  70. #include "m2Lib.h"
  71. #include "sysLib.h"
  72. #include "tickLib.h"
  73. #include "private/timerLibP.h"
  74. #include <stdio.h>
  75. #include <stdlib.h>
  76. #include <string.h>
  77. #include <unistd.h>
  78. #include <sys/socket.h>
  79. #include <net/if.h>
  80. #include <netinet/in_systm.h>
  81. #include <netinet/in.h>
  82. #include <netinet/ip.h>
  83. #include <netinet/udp.h>
  84. #include <netinet/if_ether.h>
  85. #include "dhcp/dhcp.h"
  86. #ifdef VIRTUAL_STACK
  87. #include "netinet/vsLib.h"
  88. #endif /* VIRTUAL_STACK */
  89. /* forward declarations */
  90. u_short get_ipsum (struct ip *);
  91. u_short get_udpsum (struct ip *, struct udphdr *);
  92. u_short udp_cksum (struct ps_udph *, char *, int);
  93. /*******************************************************************************
  94. *
  95. * dhcpConvert - convert the hardware type from the MUX
  96. *
  97. * This routine converts the hardware type value which the MUX interface
  98. * provides into the encoding that DHCP uses. The MUX interface uses the
  99. * RFC 1213 MIB values while DHCP uses the interface encodings from the ARP
  100. * section of the assigned numbers RFC (RFC 1700).
  101. *
  102. * NOMANUAL
  103. *
  104. * RETURNS: RFC 1700 encoding of type value, or ERROR if none.
  105. *
  106. */
  107. int dhcpConvert
  108.     (
  109.     int muxType         /* RFC 1213 interface type value */
  110.     )
  111.     {
  112.     int dhcpType = 0;
  113.     switch (muxType)
  114.         {
  115.         default:
  116.             return (ERROR);
  117.             break;
  118.         case M2_ifType_ethernet_csmacd:
  119.             dhcpType = ETHER;
  120.             break;
  121.         case M2_ifType_ethernet3Mbit:
  122.             dhcpType = EXPETHER;
  123.             break;
  124.         case M2_ifType_proteon10Mbit:     /* fall-through */
  125.         case M2_ifType_proteon80Mbit:
  126.             dhcpType = PRONET;
  127.             break;
  128.         case M2_ifType_iso88023_csmacd:    /* fall-through */
  129.         case M2_ifType_iso88024_tokenBus:  /* fall-through */
  130.         case M2_ifType_iso88025_tokenRing: /* fall-through */
  131.         case M2_ifType_iso88026_man:
  132.             dhcpType = IEEE802;
  133.             break;
  134.         case M2_ifType_hyperchannel:
  135.             dhcpType = HYPERCH;
  136.             break;
  137.         case M2_ifType_starLan:
  138.             dhcpType = LANSTAR;
  139.             break;
  140.         case M2_ifType_ultra:
  141.             dhcpType = ULTRALINK;
  142.             break;
  143.         case M2_ifType_frameRelay:
  144.             dhcpType = FRAMERELAY;
  145.             break;
  146.         case M2_ifType_propPointToPointSerial:    /* fall-through */
  147.         case M2_ifType_ppp:                       /* fall-through */
  148.         case M2_ifType_slip:
  149.             dhcpType = SERIAL;
  150.             break;
  151.         }
  152.     return (dhcpType);
  153.     }
  154. /*******************************************************************************
  155. *
  156. * pickup_opt - extract an option from a DHCP message
  157. *
  158. * This routine searches the fields in a DHCP message for the option specified
  159. * by the <tag> parameter. If the file and sname message fields are overloaded 
  160. * with options, they are searched as well. The search order is:
  161. *
  162. *    options field -> 'file' field -> 'sname' field
  163. *
  164. * RETURNS: Pointer to first occurrence of option, or NULL if not found.
  165. *
  166. * ERRNO:   N/A
  167. *
  168. * SEE ALSO: RFC 1533
  169. *
  170. * NOMANUAL
  171. */
  172. char * pickup_opt
  173.     (
  174.     struct dhcp * msg,      /* Incoming message copied to structure */
  175.     int msglen,   /* Length of message */
  176.     char tag       /* RFC 1533 tag for desired option */
  177.     )
  178.     {
  179.     BOOL  sname_is_opt = FALSE;
  180.     BOOL  file_is_opt = FALSE;
  181.     int  i = 0;
  182.     char * opt = NULL;
  183.     char * found = NULL;
  184.     /*  search option field. */
  185.     opt = &msg->options[MAGIC_LEN];
  186.     for (i = 0; i < msglen - DFLTDHCPLEN + DFLTOPTLEN - MAGIC_LEN; i++) 
  187.         {
  188.         if (*(opt + i) == tag) 
  189.             {
  190.             found = (opt + i);
  191.             break;
  192.             }
  193.         else if (*(opt + i) == _DHCP_END_TAG) 
  194.             break;
  195.         else if (*(opt + i) == _DHCP_OPT_OVERLOAD_TAG) 
  196.             {
  197.             i += 2 ;
  198.             if (*(opt + i) == 1)
  199.                 file_is_opt = TRUE;
  200.             else if (*(opt + i) == 2)
  201.                 sname_is_opt = TRUE;
  202.             else if (*(opt + i) == 3)
  203.                 file_is_opt = sname_is_opt = TRUE;
  204.             continue;
  205.             }
  206.         else if (*(opt + i) == _DHCP_PAD_TAG) 
  207.             continue;
  208.         else 
  209.             i += *(u_char *)(opt + i + 1) + 1;
  210.         }
  211.     if (found != NULL)
  212.         return (found);
  213.     /* If necessary, search file field. */
  214.     if (file_is_opt)
  215.         {
  216.         opt = msg->file;
  217.         for (i = 0; i < sizeof (msg->file); i++) 
  218.              {
  219.              if (*(opt + i) == _DHCP_PAD_TAG) 
  220.                  continue;
  221.              else if (*(opt + i) == _DHCP_END_TAG) 
  222.                  break;
  223.              else if (*(opt + i) == tag) 
  224.                  {
  225.                  found = (opt + i);
  226.                  break;
  227.                  }
  228.              else 
  229.                  i += *(u_char *)(opt + i + 1) + 1;
  230.              }
  231.         if (found != NULL)
  232.             return (found);
  233.         }
  234.     /* If necessary, search sname field. */
  235.     if (sname_is_opt) 
  236.         {
  237.         opt = msg->sname;
  238.         for (i = 0; i < sizeof (msg->sname); i++) 
  239.             {
  240.             if (*(opt + i) == _DHCP_PAD_TAG) 
  241.                 continue;
  242.             else if (*(opt + i) == _DHCP_END_TAG) 
  243.                 break;
  244.             else if (*(opt + i) == tag) 
  245.                 {
  246.                 found = (opt + i);
  247.                 break;
  248.                 }
  249.             else
  250.                 i += *(u_char *)(opt + i + 1) + 1;
  251.             }
  252.         if (found != NULL)
  253.             return(found);
  254.         }
  255.     return(NULL);
  256.     }
  257. /*******************************************************************************
  258. *
  259. * udp_cksum - calculate the UDP header checksum
  260. *
  261. * This routine calculates the checksum for the given UDP pseudo-header and 
  262. * additional bytes of data contained in the provided buffer, interpreted
  263. * as unsigned shorts in network byte order.
  264. *
  265. * RETURNS: Value of calculated checksum, or 0xffff instead of 0.
  266. *
  267. * ERRNO:   N/A
  268. *
  269. * NOMANUAL
  270. */
  271. u_short udp_cksum
  272.     (
  273.     struct ps_udph *pUdpPh, /* UDP pseudo-header */
  274.     char *buf,                  /* Additional data (received UDP header) */
  275.     int n                       /* Length of provided buffer */
  276.     )
  277.     {
  278.     u_long  sum = 0;
  279.     u_short * tmp = NULL;
  280.     u_short result;
  281.     FAST int  i = 0;
  282.     unsigned char  pad[2];
  283.     tmp = (u_short *) pUdpPh;
  284.     for (i = 0; i < 6; i++) 
  285.         {
  286.         sum += *tmp++;
  287.         }      
  288.     tmp = (u_short *)buf;
  289.     while (n > 1) 
  290.         {
  291.         sum += *tmp++;
  292.         n -= sizeof (u_short);
  293.         }
  294.     if (n == 1) /* n % 2 == 1, so padding is needed */
  295.         {
  296.         pad [0] = *(u_char *)tmp;
  297.         pad [1] = 0;
  298.         tmp = (u_short *)pad;
  299.         sum += *tmp;
  300.         }
  301.     sum = (sum >> 16) + (sum & 0xffff);
  302.     sum += (sum >> 16);
  303.     result = (u_short) ~sum;
  304.     if (result == 0)
  305.         result = 0xffff;
  306.     return (result);
  307.     }
  308. /*******************************************************************************
  309. *
  310. * dhcpTime - return system uptime
  311. *
  312. * This routine is similar to the POSIX time() routine, except it returns
  313. * the time in terms of the number of seconds that the system has been
  314. * running and is immune to changes in the system clock made by
  315. * clock_settime(). Note however that it is _not_ immune to someone
  316. * calling tickSet(). This is not the same thing as changing the
  317. * calendar time though and should happen less frequently.
  318. *
  319. * RETURNS: Number of seconds since the system was booted.
  320. *
  321. * ERRNO:   N/A
  322. *
  323. * NOMANUAL
  324. */
  325. time_t dhcpTime
  326.     (
  327.     time_t *timer
  328.     )
  329.     {
  330.     ULONG      sysTicks;
  331.  
  332.     sysTicks = tickGet()/sysClkRateGet();
  333.     if (timer != NULL)
  334.         *timer = (time_t) sysTicks;
  335.     return (time_t) (sysTicks);
  336.     }