?? ospf_vx_ip_adaptation.c
字號(hào):
/* ospf_vx_ip_adaptation.c *//* Copyright 2000-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02h,28may03,agi Changed type of variable mutex_acquired to STATUS02g,12may03,asr Changes to make OSPF virtual stack compatible02f,26may03,htm Replacing the magic number 1000 with OSPF_MAX_PKT_SIZE.02e,14may03,agi Changed RWOS semaphores to vxWorks semaphores02d,10feb03,hme Fixed the solution to SPR#81451 to work on Pentium02c,15jan03,hme Fixed SPR#69807 and SPR#7216702b,15jan03,hme Fixed SPR#8145102c,26oct02,hme Fix TSR#29522802b,21oct02,htm Apply fix for SPR#83274 OSPF is not updating properly the PPP Interface routes to neighboring routers 02a,08oct02,agi Fixed compiler warnings11,24jun02,kc Removed reference to low-level interface handler in ospf_indicate_lower_level_interface_state_change().10,13apr02,kc Changed ospf_indicate_lower_level_interface_state_change() to step interface state machine to bring down the interface so that the mib api can also updates the interface operational status and stats.09,15feb02,kc Changed printf statement to OSPF_PRINTF_DEBUG.08,16feb02,kc Added ospf_if_status import statement to remove compiler warning.07,06feb02,bt look for changes in comment __UNNUMBERED_LINK__ver1.006,22sep01,kc Removed references to port number.05,22sep01,kc Fixed raw socket transmit and receive routines.04,19jan01,jkw Added raw_sockets to replace direct call to IP. The purpose of this is for protection domains. There will be no more direct calls to IP03,23aug01,jkw Fixed compiler warnings.02,15may01,aos Added memset to ospf_receive_message_buffer01,3may01,jkw change to ospf_indicate_lower_level_interface_state_change to use ospf_reset_interface_variables_and_timers_and_destroy_all_ _associated_neighbor_connections*//*DESCRIPTIONospf_vx_ip_adaptation.c is used for sending and receiving packets. This file contains the functions to interact with Vxworks input and output functions. This file contains the functions for using raw sockets or direct calls to IP.This file is used whenever an OSPF packet is sent or received.*/#include <vxWorks.h>#include <net/mbuf.h>#include <sys/socket.h>#include <net/socketvar.h>#include <net/protosw.h>#include <errno.h>#include <sys/stat.h>#include <netinet/in.h>#include <net/if.h>#include <net/route.h>#include <netinet/in_var.h>#include <netinet/in_pcb.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/ip_var.h>#include <netLib.h>#include "ospf.h"#if defined (__OSPF_VIRTUAL_STACK__)#include "ospf_vs_lib.h"#endif /* __OSPF_VIRTUAL_STACK__ *//*raw socket - Added socket library files to resolve undefined externs jkw*/#include <sockLib.h>#include <inetLib.h>#include <stdioLib.h>#include <strLib.h>#include <hostLib.h>#include <ioLib.h>#include <selectLib.h>/*raw socket - End of changes*/ULONG ospf_sendspace = 8192;ULONG ospf_recvspace = 8192;BYTE ospf_receive_message_buffer[8192];struct mbuf m_block;/* HME Fix SPR#81451 Begin */#define ENABLE_IP_HDRINCL TRUE /* if ENABLE_IP_HDRINCL is defined, ospf will construct and send an entire IP packet to the IP layer */#if defined(ENABLE_IP_HDRINCL)#define IPHL sizeof (struct ip) /* IP header length */void ipHeaderCreate( int , /* protocol number */ struct in_addr * , /* source ip address */ struct in_addr * , /* dest ip address */ struct ip * , /* internet header */ int /* datagram size */ );#endif/* HME Fix SPR#81451 End *//* HME Fix SPR#69807 & SPR#72167 Begin*/#if defined(ENABLE_IP_HDRINCL)#define TOS_BYTE_VALUE 0xC0 /* The TOS Byte * * 0 1 2 3 4 5 6 7 * | | | | | | | * | PRECEDENCE | D | T | R | 0 | 0 | * | | | | | | | * +-----+-----+-----+-----+-----+-----+-----+-----+ * * Bits 0-2: Precedence. * Bit 3: 0 = Normal Delay, 1 = Low Delay. * Bits 4: 0 = Normal Throughput, 1 = High Throughput. * Bits 5: 0 = Normal Relibility, 1 = High Relibility. * Bit 6-7: Reserved for Future Use. * * Precedence * * 111 - Network Control * 110 - Internetwork Control * 101 - CRITIC/ECP * 100 - Flash Override * 011 - Flash * 010 - Immediate * 001 - Priority * 000 - Routine */#endif/* HME Fix SPR#69807 & SPR#72167 End */IMPORT int ospf_if_status (unsigned long intf, int interface_index, unsigned long ip_address);/* globals */static struct sockaddr_in ospf_src = { sizeof(ospf_src), AF_INET };/*raw socket - Created socket interface function to be called by a task *that reads from the socket. jkw*//************************************************************************//* Added change as per TMS PR # 1652 *//* for tOspfRecv: added local prototype for received packet processing routine */int ospf_vx_ip_receive_packet (OSPF_PACKET *ospf_packet, ULONG rcvif_handle);/**************************************************************************************** ospf_vx_ip_receive_socket_input - OSPF packet received routine** This is the entry point for "tOspfInput" task that is created in ospf_intialize_router()* (see ospf_initialization.c file). It waits for packet on the raw socket using the* select() call. Once select() returns, it calls recvfrom() to read the data from* the socket and the ospf_router_rx_packet() to process the received packet.* Unlike the tranditional receive routine that processes mbuf, it is not necssary to* enqueue the received packet to a linked list and have a separate task to do the actual* packet processing functionality. This is because the "tOspfInput" task always pend on a* set of sockets waiting for data and this task is receiving data independent of the* "tNetTask".*/int ospf_vx_ip_receive_socket_input (void) { struct ip *ip_header; struct fd_set readFd; struct sockaddr from_sockaddr; struct sockaddr_in *pFrom_sockaddr; struct in_ifaddr *recvif; OSPF_INTERFACE *sptr_interface = NULL; OSPF_INTERFACE *sptr_next_interface = NULL;#if defined (__UNNUMBERED_LINK__) /* __UNNUMBERED_LINK__ver1.0 */ OSPF_INTERFACE * sptr_saved_interface; ULONG source_address = 0x00000000L;#endif /* __UNNUMBERED_LINK__ver1.0 */ STATUS mutex_acquired; int recvLen; int recv_bufsize; int sockaddr_len; int maxFd; ULONG intf_addr; ULONG destination_address = 0x00000000; int spl; u_short original_if_index; /* introduced for fixing TSR #295228 */ maxFd = ipSock; /* asr: set virtual stack context. Need to set the stack context only once since call to virtualStackNumTaskIdSet() will add myStackNum as a task variable to the input task. Therefore, all functions called within the context of the input task will use the correct value for myStackNum. */ #if defined (VIRTUAL_STACK) virtualStackNumTaskIdSet (ospf.ospf_vsid); #endif /* VIRTUAL_STACK */ for (;;) { /* zero out the file descriptor structure */ FD_ZERO (&readFd); /* tell 'em which file descriptor that we wanna to listen */ FD_SET (ipSock, &readFd); /* wait for select to fire, wait indefinitely for input on sockets */ if (select(maxFd+1, &readFd, NULL, NULL, NULL) == ERROR) continue; /* got it. Figure out if it is the file descriptor that we want to listen */ if (FD_ISSET (ipSock, &readFd)) { /* read data into the flat buffer. Unlike mbuf, it is a valid to assume * that the data read from the socket is contiguous, i.e. a complete * OSPF packet */ recv_bufsize = sizeof(ospf_receive_message_buffer); memset( (char *)&from_sockaddr, 0, sizeof(from_sockaddr)); memset(ospf_receive_message_buffer, 0, recv_bufsize); sockaddr_len = sizeof(from_sockaddr); recvLen = recvfrom(ipSock, (char *)ospf_receive_message_buffer, recv_bufsize, 0, (struct sockaddr *)&from_sockaddr, &sockaddr_len); if (sockaddr_len) { from_sockaddr.sa_family = AF_INET; from_sockaddr.sa_len = sockaddr_len; } /* recvfrom returns number of bytes read (between 1 to recv_buffsize) or * ERROR if file descriptor is not valid */ if ( recvLen < 1 ) { continue; } /* we are reading from raw socket. Data received contains ip header * follows by the ospf packet. First get the pointer to the ip header */ ip_header = (struct ip *)ospf_receive_message_buffer; /* associate the received packet with the correct ospf interface as descirbed * in section 8.2 of the ospf specification. */ destination_address = ip_header->ip_dst.s_addr; destination_address = net_to_host_long(destination_address); if (IN_MULTICAST (destination_address)) { /* first try to locate the point-to-point interface using the given * destination address from the recvfrom() * NOTE: ifa_ifwithdstaddr() and ifa_ifwithnet() returns pointer to * the ifaddr structure. Can't figure out how to get the handler to * in_ifaddr structure from ifaddr. Typecasting the returned type * for both functions to pointer to in_ifaddr structure may seems * to be inappropriate, but this is also done in ip_output() and * ip_dooptions() stack code. Thus, I think it is ok to do so... */ /* sin_port and sin_zero needs to be zero'd before calling ifa_ifwithnet Otherwise, binary compare of structures may fail. */ /* hme - TSR #295228 fix for swapping two Rx interfaces Begin */ /* retrive if_index from socketaddr_in. First 4 bytes of sin_zero contains if_index */ original_if_index = *((unsigned int *)&(((struct sockaddr_in *)&from_sockaddr)->sin_zero[0])); /* hme - TSR #295228 fix for swapping two Rx interfaces End*/ recvif = (struct in_ifaddr *)NULL; pFrom_sockaddr = (struct sockaddr_in *)&from_sockaddr; pFrom_sockaddr->sin_port = 0; /* htm - SPR #83274 fix Begin */ memset(&(pFrom_sockaddr->sin_zero), 0, 8*sizeof(char)); /* htm - SPR #83274 fix End */ spl = splnet(); recvif = (struct in_ifaddr *)ifa_ifwithdstaddr(&from_sockaddr); splx(spl); if ( recvif == NULL) { /* recvif not point-to-point. Try to find the recvif on a specific * network. If many choices, the most specific one should be * returned by ifa_ifwithnet() */ /* htm - SPR #83274 fix Begin */ spl = splnet(); recvif = (struct in_ifaddr *)ifa_ifwithnet(&from_sockaddr); splx(spl); /* htm - SPR #83274 fix End */ if ( recvif == NULL) { OSPF_PRINTF_DEBUG(OSPF_ALARM_PRINTF, "dropped recvpkt - recvif not found!\n"); continue; } } /* hme - TSR #295228 fix for swapping two Rx interfaces Begin */ if (recvif->ia_ifa.ifa_ifp->if_index != original_if_index){ /*Interface did not match*/ OSPF_PRINTF_DEBUG(OSPF_ALARM_PRINTF, "dropped recvpkt - packet did not match receive interface!\n"); continue; } /* hme - TSR #295228 fix for swapping two Rx interfaces End */ /* lock mutex for mutual exclusion to the ospf data structure */ mutex_acquired = semTake (ospf_global_mutex, WAIT_FOREVER); if (mutex_acquired == ERROR) { continue; } for (sptr_interface = ospf.sptr_interface_list; sptr_interface != NULL; sptr_interface = sptr_next_interface) { sptr_next_interface = sptr_interface->sptr_forward_link; intf_addr = sptr_interface->address; /* find interface matches the subnet of the sender. If there * are many possible interfaces, choose the most specific one, * i.e. the one with the longest netmask */ if (intf_addr == net_to_host_long(recvif->ia_addr.sin_addr.s_addr)) { break; } } } else /* (IN_MULTICAST (destination_address)) */ { /* lock mutex for mutual exclusion to the ospf data structure */ mutex_acquired = semTake (ospf_global_mutex, WAIT_FOREVER); if (mutex_acquired == ERROR) { continue; }#if defined (__UNNUMBERED_LINK__) /* __UNNUMBERED_LINK__ver1.0 */ sptr_saved_interface = NULL; /* it is unicast - got destination address in the ip header */ for (sptr_interface = ospf.sptr_interface_list; sptr_interface != NULL; sptr_interface = sptr_interface->sptr_forward_link) { destination_address = ip_header->ip_dst.s_addr; destination_address = net_to_host_long(destination_address); source_address = ip_header->ip_src.s_addr; source_address = net_to_host_long(source_address); if (sptr_interface->address == 0) /* unnumbered link*/ { intf_addr = sptr_interface->unnumbered_router_id; } else { intf_addr = sptr_interface->address; }
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -