interface.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:9k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* interface.c - DHCP server and relay agent network interface library */
  2. /* Copyright 1984 - 2001 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01f,10oct01,rae  fixed modhist line
  8. 01e,06oct97,spm  split interface name into device name and unit number
  9. 01d,26aug97,spm  moved routines from common_subr.c not used by DHCP client
  10. 01c,06may97,spm  changed memory access to align IP header on four byte
  11.                  boundary; removed unused timeout variable
  12. 01b,18apr97,spm  added conditional include DHCPS_DEBUG for displayed output
  13. 01a,07apr97,spm  created by modifying WIDE project DHCP implementation
  14. */
  15. /*
  16. DESCRIPTION
  17. This library contains the code used by the DHCP server and relay agents to
  18. monitor one or more network interfaces for incoming DHCP messages. The monitor
  19. routine is triggered on a semaphore given by an Ethernet input hook. The
  20. corresponding message, read from a pre-allocated ring buffer, identifies the
  21. originating network interface and the amount of received data. The data itself
  22. is then copied from another ring buffer into a temporary interface-specific
  23. buffer.
  24. INCLUDE_FILES: None
  25. */
  26. /*
  27.  * WIDE Project DHCP Implementation
  28.  * Copyright (c) 1995 Akihiro Tominaga
  29.  * Copyright (c) 1995 WIDE Project
  30.  * All rights reserved.
  31.  *
  32.  * Permission to use, copy, modify and distribute this software and its
  33.  * documentation is hereby granted, provided only with the following
  34.  * conditions are satisfied:
  35.  *
  36.  * 1. Both the copyright notice and this permission notice appear in
  37.  *    all copies of the software, derivative works or modified versions,
  38.  *    and any portions thereof, and that both notices appear in
  39.  *    supporting documentation.
  40.  * 2. All advertising materials mentioning features or use of this software
  41.  *    must display the following acknowledgement:
  42.  *      This product includes software developed by WIDE Project and
  43.  *      its contributors.
  44.  * 3. Neither the name of WIDE Project nor the names of its contributors
  45.  *    may be used to endorse or promote products derived from this software
  46.  *    without specific prior written permission.
  47.  *
  48.  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE
  49.  * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  50.  * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE
  51.  * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED.
  52.  *
  53.  * Feedback of the results generated from any improvements or
  54.  * extensions made to this software would be much appreciated.
  55.  * Any such feedback should be sent to:
  56.  * 
  57.  *  Akihiro Tominaga
  58.  *  WIDE Project
  59.  *  Keio University, Endo 5322, Kanagawa, Japan
  60.  *  (E-mail: dhcp-dist@wide.ad.jp)
  61.  *
  62.  * WIDE project has the rights to redistribute these changes.
  63.  */
  64. #include "vxWorks.h"
  65. #include "ioLib.h"  /* ioctl() declaration */
  66. #include "vxLib.h"  /* checksum() declaration */
  67. #include "sockLib.h"
  68. #include "logLib.h"
  69. #include "rngLib.h"
  70. #include <stdio.h>
  71. #include <stdlib.h>
  72. #include <fcntl.h>
  73. #include <string.h>
  74. #include <unistd.h>
  75. #include <sys/ioctl.h>
  76. #include <sys/socket.h>
  77. #include <net/if.h>
  78. #include <netinet/in_systm.h>
  79. #include <netinet/in.h>
  80. #include "dhcp/dhcp.h"
  81. #include "dhcp/common.h"
  82. #include "dhcp/common_subr.h"
  83. /*******************************************************************************
  84. *
  85. * open_if - initialize per-interface data structure
  86. *
  87. * This routine sets the IP address and subnet mask entries for each
  88. * interface monitored by the DHCP server or relay agent.
  89. *
  90. * RETURNS: 0 if successful, or -1 on error.
  91. *
  92. * ERRNO: N/A
  93. *
  94. * NOMANUAL
  95. */
  96. int open_if
  97.     (
  98.     struct if_info *ifinfo  /* pointer to interface descriptor */
  99.     )
  100.     {
  101.     int n;
  102.     struct ifreq ifreq;
  103.     bzero ( (char *)&ifreq, sizeof(ifreq));
  104.     sprintf (ifreq.ifr_name, "%s%d", ifinfo->name, ifinfo->unit);
  105.     /*
  106.      * Initialize the interface information (subnet and IP address).
  107.      */
  108.     n = socket (AF_INET, SOCK_DGRAM, 0);
  109.     if (n < 0) 
  110.         return (-1);
  111.     if (ioctl (n, SIOCGIFNETMASK, (int)&ifreq) < 0) 
  112.         {
  113. #ifdef DHCPS_DEBUG
  114.         logMsg("Error: Can't retrieve netmask in open_if().n", 
  115.                 0, 0, 0, 0, 0, 0);
  116. #endif
  117.         close (n);
  118.         return (-1);
  119.         }
  120.     ifinfo->subnetmask.s_addr =
  121.                     ( (struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
  122.     if (ioctl(n, SIOCGIFADDR, (int)&ifreq) < 0) 
  123.         {
  124. #ifdef DHCPS_DEBUG
  125.         logMsg("Error: can't retrieve address in open_if().n", 
  126.                 0, 0, 0, 0, 0, 0);
  127. #endif
  128.         close (n);
  129.         return (-1);
  130.         }
  131.     ifinfo->ipaddr.s_addr = 
  132.                     ( (struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
  133.     close(n);
  134.     /*
  135.      * Store size of preallocated buffer. Offset used to align IP header on 
  136.      * 4-byte boundary for Sun BSP's. 
  137.      */
  138.     ifinfo->buf_size = DHCP_MSG_SIZE + DHCPS_OFF;
  139.     return (0);
  140.     }
  141. /*******************************************************************************
  142. *
  143. * read_interfaces - extract arriving messages from shared buffers
  144. *
  145. * This function waits for the arrival of a DHCP message (extracted by
  146. * a BPF device) and copies the message into the private buffer
  147. * associated with the receiving interface.
  148. *
  149. * RETURNS: Pointer to data structure of receiving interface, or NULL on error.
  150. *
  151. * ERRNO: N/A
  152. *
  153. * NOMANUAL
  154. */
  155. struct if_info * read_interfaces
  156.     (
  157.     struct if_info *iflist,  /* pointer to interface descriptors */
  158.     int *n,  /* buffer for actual length of message */
  159.     int maxSize  /* length of (internal) buffer for message */
  160.     )
  161.     {
  162.     struct if_info *ifp = NULL;  /* descriptor of receiver's interface */
  163.     int status;  /* message extraction results */
  164.     fd_set readFds;
  165.     int fileNum = 0;
  166.     int maxFileNum = 0;
  167.     /* Wait for an arriving DHCP message. */
  168.     FD_ZERO (&readFds);
  169.     ifp = iflist;
  170.     while (ifp != NULL)
  171.         {
  172.         fileNum = ifp->bpfDev;
  173.         FD_SET (fileNum, &readFds);
  174.         if (fileNum > maxFileNum)
  175.             maxFileNum = fileNum;
  176.         ifp = ifp->next;
  177.         }
  178.     maxFileNum++;    /* Adjust maximum for select() routine. */
  179. #ifdef DHCPS_DEBUG
  180.     logMsg ("DHCP server: waiting for data.n", 0, 0, 0, 0, 0, 0);
  181. #endif
  182.     status = select (maxFileNum, &readFds, NULL, NULL, NULL);
  183.     if (status <= 0)
  184.         return (NULL);
  185. #ifdef DHCPS_DEBUG
  186.    logMsg ("DHCP server: read_interfaces() received new message.n", 
  187.            0, 0, 0, 0, 0, 0);
  188. #endif
  189.     /* Find the interface descriptor for the first available DHCP message. */
  190.     ifp = iflist;
  191.     while (ifp != NULL)
  192.         {
  193.         fileNum = ifp->bpfDev;
  194.         if (FD_ISSET (fileNum, &readFds))
  195.             break;
  196.         ifp = ifp->next;
  197.         }
  198.    if (ifp == NULL) 
  199.        {
  200. #ifdef DHCPS_DEBUG
  201.        logMsg ("Warning: invalid network device in read_interfaces()n", 
  202.                0, 0, 0, 0, 0, 0);
  203. #endif
  204.        return (NULL);
  205.        }
  206.    status = read (fileNum, ifp->buf, maxSize);
  207.    if (status <= 0)
  208.        {
  209. #ifdef DHCPS_DEBUG
  210.        logMsg ("Warning: error reading DHCP message.n", 0, 0, 0, 0, 0, 0);
  211. #endif
  212.        return (NULL);
  213.        }
  214.    *n = status;
  215.    return (ifp);
  216.    }
  217. /*******************************************************************************
  218. *
  219. * get_ipsum - retrieve the IP header checksum
  220. *
  221. * This routine fetches the checksum for the given IP header.
  222. *
  223. * RETURNS: Value of checksum in network byte order.
  224. *
  225. * ERRNO:   N/A
  226. *
  227. * NOMANUAL
  228. */
  229. u_short get_ipsum
  230.     (
  231.     struct ip *  pIph  /* IP header */
  232.     )
  233.     {
  234.     pIph->ip_sum = 0;
  235. #if BSD<44
  236.     return (checksum ( (u_short *)pIph, (pIph->ip_v_hl & 0xf) << 2));
  237. #else
  238.     return (checksum ( (u_short *)pIph, pIph->ip_hl << 2));
  239. #endif
  240.     }
  241. /*******************************************************************************
  242. *
  243. * check_ipsum - verify the IP header checksum
  244. *
  245. * This routine retrieves the checksum for the given IP header and compares
  246. * it to the received checksum.
  247. *
  248. * RETURNS: TRUE if checksums match, or FALSE otherwise.
  249. *
  250. * ERRNO:   N/A
  251. *
  252. * NOMANUAL
  253. */
  254. BOOL check_ipsum
  255.     (
  256.     struct ip *  pIph  /* Received IP header */
  257.     )
  258.     {
  259.     u_short ripcksum;   /* received IP checksum */
  260.     ripcksum = pIph->ip_sum;
  261.     return (ripcksum == get_ipsum (pIph));
  262.     }
  263. /*******************************************************************************
  264. *
  265. * get_udpsum - retrieve the UDP header checksum
  266. *
  267. * This routine fetches the checksum for a UDP header.
  268. *
  269. * RETURNS: Value of checksum in network byte order.
  270. *
  271. * ERRNO:   N/A
  272. *
  273. * NOMANUAL
  274. */
  275. u_short get_udpsum
  276.     (
  277.     struct ip *  pIph,  /* IP header */
  278.     struct udphdr *  pUdph  /* UDP header */
  279.     )
  280.     {
  281.     struct ps_udph UdpPh;       /* UDP pseudo-header */
  282.     bzero ( (char *)&UdpPh, sizeof (UdpPh));
  283.     UdpPh.srcip.s_addr = pIph->ip_src.s_addr;
  284.     UdpPh.dstip.s_addr = pIph->ip_dst.s_addr;
  285.     UdpPh.zero = 0;
  286.     UdpPh.prto = IPPROTO_UDP;
  287.     UdpPh.ulen = pUdph->uh_ulen;
  288.     pUdph->uh_sum = 0;
  289.     return (udp_cksum (&UdpPh, (char *)pUdph, ntohs (UdpPh.ulen)));
  290.     }
  291. /*******************************************************************************
  292. *
  293. * check_udpsum - verify the IP header checksum
  294. *
  295. * This routine retrieves the checksum for a UDP header and compares it
  296. * to the received checksum.
  297. *
  298. * RETURNS: TRUE if checksums match, or FALSE otherwise.
  299. *
  300. * ERRNO:   N/A
  301. *
  302. * NOMANUAL
  303. */
  304. int check_udpsum
  305.     (
  306.     struct ip *  pIph,  /* Received IP header */
  307.     struct udphdr *  pUdph  /* Received UDP header */
  308.     )
  309.     {
  310.     u_short rudpcksum;  /* received UDP checksum */
  311.     if (pUdph->uh_sum == 0)
  312.         return(TRUE);
  313.     rudpcksum = pUdph->uh_sum;
  314.     return (rudpcksum == get_udpsum (pIph, pUdph));
  315.     }