📄 dhcprelay.c
字号:
/* dhcpRelay.c - DHCP server and relay agent shared code library *//* Copyright 1984 - 1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history____________________01f,04dec97,spm added code review modifications01e,06oct97,spm split interface name into device name and unit number; fixed errors in debugging output01d,02jun97,spm changed DHCP option tags to prevent name conflicts (SPR #8667) and updated man pages01c,28apr97,spm limited maximum number of hops to 16 for RFC compliance01b,18apr97,spm added conditional include DHCPR_DEBUG for displayed output01a,07apr97,spm created by modifying WIDE project DHCP implementation*//*DESCRIPTIONThis library contains the code used by the DHCP relay agent to transfer packets between DHCP or BOOTP clients and DHCP servers. The DHCP serverwill also use this code if configured to act as a relay agent.INCLUDE_FILES: dhcprLib.h*//* * WIDE Project DHCP Implementation * Copyright (c) 1995 Akihiro Tominaga * Copyright (c) 1995 WIDE Project * All rights reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided only with the following * conditions are satisfied: * * 1. Both the copyright notice and this permission notice appear in * all copies of the software, derivative works or modified versions, * and any portions thereof, and that both notices appear in * supporting documentation. * 2. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by WIDE Project and * its contributors. * 3. Neither the name of WIDE Project nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND WIDE * PROJECT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ALSO, THERE * IS NO WARRANTY IMPLIED OR OTHERWISE, NOR IS SUPPORT PROVIDED. * * Feedback of the results generated from any improvements or * extensions made to this software would be much appreciated. * Any such feedback should be sent to: * * Akihiro Tominaga * WIDE Project * Keio University, Endo 5322, Kanagawa, Japan * (E-mail: dhcp-dist@wide.ad.jp) * * WIDE project has the rights to redistribute these changes. *//* includes */#include "vxWorks.h"#include "vxLib.h" /* checksum() declaration. */#include <stdio.h>#include <stdlib.h>#include <sys/ioctl.h>#include <netinet/in.h>#include <arpa/inet.h>#include "etherLib.h"#include "logLib.h"#include "sockLib.h"#include "ioLib.h"#ifdef DHCPR_DEBUG#include "inetLib.h"#endif#include "dhcprLib.h"#include "dhcp/dhcp.h"#include "dhcp/common.h"#include "dhcp/common_subr.h"/* globals */DHCP_TARGET_DESC * pDhcpRelayTargetTbl;struct server * pDhcpTargetList = NULL;int dhcpNumTargets = 0;struct msg dhcpMsgIn;struct msg dhcprMsgOut;/* forward declarations */void dhcpServerRelay (struct if_info *);void dhcpClientRelay (struct if_info *, int);LOCAL STATUS forwarding();/********************************************************************************* dhcpServerRelay - send incoming DHCP/BOOTP message to client port** This routine relays a DHCP or BOOTP message to the client port of * every DHCP server or relay agent whose IP address is contained in the * circular linked list of targets. That list is constructed during startup of * the relay agent (or server, if configured to relay messages). The routine* accesses global pointers already set to indicate the outgoing message. * All messages are discarded after the hops field exceeds 16 to comply with* the relay agent behavior specified in RFC 1542. The relay agent normally* discards such messages before this routine is called. They will only* be received by this routine if the user ignores the instructions in the* manual and sets the value of DHCP_MAX_HOPS higher than 16.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void dhcpServerRelay ( struct if_info *ifp ) { unsigned int hash; int i; struct server *srvp; dhcpMsgIn.dhcp->hops++; if (dhcpMsgIn.dhcp->hops >= 17) /* RFC limits to 16 hops - ignore. */ return; if (dhcpMsgIn.dhcp->giaddr.s_addr == 0) dhcpMsgIn.dhcp->giaddr.s_addr = ifp->ipaddr.s_addr; /* Quick and dirty load balancing - pick starting point in circular list. */ hash = (unsigned)checksum( (u_short *)dhcpMsgIn.dhcp->chaddr, (MAX_HLEN / 2)); hash %= dhcpNumTargets; srvp = pDhcpTargetList; for (i = 0; i < hash; i++) srvp = srvp->next; forwarding (srvp); return; }/********************************************************************************* forwarding - send DHCP/BOOTP message to target address** This routine relays a DHCP or BOOTP message to the specified target address.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/static STATUS forwarding ( struct server *srvp ) { int i, n; int sockfd = -1; int msgsize = DHCPLEN (dhcpMsgIn.udp); struct sockaddr_in my_addr, serv_addr; int result;#ifdef DHCPR_DEBUG char output [INET_ADDR_LEN];#endif if ( (sockfd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {#ifdef DHCPR_DEBUG logMsg ("socket() error in forwarding()\n", 0, 0, 0, 0, 0, 0);#endif return (ERROR); } bzero ((char *)&my_addr, sizeof (my_addr)); my_addr.sin_family = AF_INET; my_addr.sin_addr.s_addr = htonl (INADDR_ANY); my_addr.sin_port = dhcpc_port; /* Servers expect client port. */ if (bind (sockfd, (struct sockaddr *) &my_addr, sizeof (my_addr)) < 0) {#ifdef DHCPR_DEBUG logMsg("bind() error in forwarding()\n", 0, 0, 0, 0, 0, 0);#endif close (sockfd); return (ERROR); } dhcprMsgOut.dhcp = dhcpMsgIn.dhcp; result = setsockopt (sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&msgsize, sizeof (msgsize)); if (result < 0) {#ifdef DHCPR_DEBUG logMsg ("Warning: can't set send buffer in forwarding().\n", 0, 0, 0, 0, 0, 0);#endif close (sockfd); return (ERROR); } n = sizeof(serv_addr); for (i = 0; i < dhcpNumTargets; i++) { bzero ((char *)&serv_addr, n); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = srvp->ip.s_addr; serv_addr.sin_port = dhcps_port;#ifdef DHCPR_DEBUG inet_ntoa_b (srvp->ip, output); printf ("Server relay: sending %d bytes to %s.\n", msgsize, output);#endif sendto (sockfd, (char *)dhcprMsgOut.dhcp, msgsize, 0, (struct sockaddr *)&serv_addr, n); srvp = srvp->next; } close (sockfd); return (OK); }/********************************************************************************* dhcpClientRelay - send DHCP/BOOTP replies to client** This routine relays a DHCP or BOOTP reply to the client which generated* the initial request. The routine accesses global pointers already set to * indicate the reply. All messages are discarded after the hops field exceeds * 16 to comply with the relay agent behavior specified in RFC 1542. The relay * agent normally discards such messages before this routine is called. They * will only be received by this routine if the user ignores the instructions * in the manual and sets the value of DHCP_MAX_HOPS higher than 16.** RETURNS: N/A** ERRNO: N/A** NOMANUAL*/void dhcpClientRelay
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -