/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: iplite_ppp.c,v $ $Revision: 1.24 $ * $Source: /home/interpeak/CVSRoot/iplite2/src/iplite_ppp.c,v $ * $Author: lob $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Lennart Bang ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #ifndef IPCOM_KERNEL #define IPCOM_KERNEL #endif #include "iplite_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #ifdef IPPPP #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include "iplite_h.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ /* Number of bits in the host part (EUI-64) when using the * PPP to create a IPv6 address (RFC 2464?) */ #define IPPPP_IP6_ID_BITS 64 /* **************************************************************************** * 5 TYPES **************************************************************************** */ /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ IP_STATIC void iplite_ppp_input(struct Iplite_netif_struct *netif, Ipcom_pkt *pkt); IP_STATIC int iplite_ppp_ioctl(struct Iplite_netif_struct *netif, Ip_u32 command, void *data); IP_STATIC int iplite_ppp_ioevent(Ipcom_netif *netif, int command, void *data, int fcflags); #ifdef IPCOM_USE_INET IP_STATIC int iplite_ppp_ip4_output(struct Iplite_netif_struct *netif, struct Ip_in_addr *next_hop, Ipcom_pkt *pkt); #endif #ifdef IPCOM_USE_INET6 IP_STATIC int iplite_ppp_ip6_output(struct Iplite_netif_struct *netif, struct Iplite_ip6_nc_entry_struct *nc, Ipcom_pkt *pkt); #endif IP_PUBLIC int ipppp_if_init2(void *voidif); /* **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * iplite_ppp_input *=========================================================================== * Description: Input handler for ethernet frames. pkt->start is the offset * to the ethernet header. * Parameters: pkt - The ethernet frame. * Returns: * */ IP_STATIC void iplite_ppp_input(struct Iplite_netif_struct *netif, Ipcom_pkt *pkt) { IPLITE_CODE_ISLOCKED_ASSERT(); (void)ipppp_input(&netif->ipcom, pkt); } /* *=========================================================================== * iplite_ppp_ioctl *=========================================================================== * Description: PPP IO control. * Parameters: netif - The interface on which the multicast address will * be used. * command - ioctl command. * data - Depends on command. * Returns: 0 = success, < 0 = error code * */ IP_STATIC int iplite_ppp_ioctl(struct Iplite_netif_struct *netif, Ip_u32 command, void *data) { IPLITE_CODE_ISLOCKED_ASSERT(); return ipppp_ioctl(&netif->ipcom, command, data); } /* *=========================================================================== * iplite_ppp_ip4_output *=========================================================================== * Description: Outputs a IPv4 packet. * Parameters: * Returns: 0 = success, <0 = error code. * */ #ifdef IPCOM_USE_INET IP_STATIC int iplite_ppp_ip4_output(struct Iplite_netif_struct *netif, struct Ip_in_addr *next_hop, Ipcom_pkt *pkt) { (void)next_hop; IPLITE_CODE_ISLOCKED_ASSERT(); return ipppp_ip4_output(&netif->ipcom, pkt); } #endif /* *=========================================================================== * iplite_ppp_ip6_output *=========================================================================== * Description: * Parameters: * Returns: * */ #ifdef IPCOM_USE_INET6 IP_STATIC int iplite_ppp_ip6_output(struct Iplite_netif_struct *netif, struct Iplite_ip6_nc_entry_struct *nc, Ipcom_pkt *pkt) { (void)nc; IPLITE_CODE_ISLOCKED_ASSERT(); return ipppp_ip6_output(&netif->ipcom, pkt); } #endif /* *=========================================================================== * iplite_ppp_ioevent *=========================================================================== * Description: * Parameters: * Returns: * */ IP_STATIC int iplite_ppp_ioevent(Ipcom_netif *netif, int command, void *data, int fcflags) { int retval; if(!IP_BIT_ISSET(fcflags, IP_FLAG_FC_ISRCONTEXT | IP_FLAG_FC_STACKCONTEXT)) IPLITE_CODE_LOCK(); retval = ipppp_ioevent(netif, command, data); if(!IP_BIT_ISSET(fcflags, IP_FLAG_FC_ISRCONTEXT | IP_FLAG_FC_STACKCONTEXT)) IPLITE_CODE_UNLOCK(); return retval; } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* *=========================================================================== * iplite_ppp_if_init *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC int ipppp_if_init2(void *voidif) { Iplite_netif *netif = voidif; IPLITE_CODE_ISLOCKED_ASSERT(); /* Setup link functions for PPP use. */ netif->link_input = iplite_ppp_input; netif->link_ioctl = iplite_ppp_ioctl; netif->ipcom.link_ioevent = iplite_ppp_ioevent; #ifdef IPCOM_USE_INET netif->link_ip4_output = iplite_ppp_ip4_output; #endif #ifdef IPCOM_USE_INET6 netif->inet6_if_id_bits = IPPPP_IP6_ID_BITS; netif->link_ip6_output = iplite_ppp_ip6_output; #endif return ipppp_if_init(&netif->ipcom); } /* *=========================================================================== * ipcom_ppp_ioevent *=========================================================================== * Description: * Parameters: * Returns: * */ IP_PUBLIC int ipcom_ppp_ioevent(Ipcom_netif *netif, int command, void *data) { #ifdef NOTYET struct Iplite_route_add_param param; struct Iplite_rt_metrics metrics; #endif Ip_u32 netmask_n; Iplite_netif *iplite_netif = (Iplite_netif *)netif; int ret = 0; #ifdef IPCOM_USE_INET6 Iplite_ip6_nc_entry *nc; #endif switch(command) { case IPPPP_EIOXBLOCKOK: IPLITE_CODE_ISLOCKED_ASSERT(); if (iplite_is_stack_task() == IP_FALSE) ret = 1; /* user process -> block is ok. */ break; case IPPPP_EIOXDRVIOCTL: { Ipppp_eio_ioctl *eio_ioctl = data; ip_assert(netif); IPLITE_CODE_ISLOCKED_ASSERT(); IPLITE_CODE_UNLOCK(); ret = netif->drv_ioctl(netif, eio_ioctl->command, eio_ioctl->data); IPLITE_CODE_LOCK(); break; } case IPPPP_EIOXOUTPUT_IF: ip_assert(iplite_netif); IPLITE_CODE_ISLOCKED_ASSERT(); ret = iplite_if_output(iplite_netif, data); break; case IPPPP_EIOXINDEXTONETIF: { Iplite_netif *ptr; IPLITE_CODE_ISLOCKED_ASSERT(); ptr = iplite_if_indextonetif((Ip_u32)data); return (int)ptr; } case IPPPP_EIOXCODE_LOCK: IPLITE_CODE_LOCK(); break; case IPPPP_EIOXCODE_UNLOCK: IPLITE_CODE_ISLOCKED_ASSERT(); IPLITE_CODE_UNLOCK(); break; case IPPPP_EIOXIF_LOCK: ip_assert(netif); IPLITE_CODE_ISLOCKED_ASSERT(); iplite_if_lock(iplite_netif); break; case IPPPP_EIOXIF_UNLOCK: ip_assert(netif); IPLITE_CODE_ISLOCKED_ASSERT(); (void)iplite_if_unlock(iplite_netif); break; #ifdef IPCOM_USE_INET case IPPPP_EIOXINPUT_IN: ip_assert(iplite_netif); IPLITE_CODE_ISLOCKED_ASSERT(); iplite_ip4_input(iplite_netif, data); break; case IPPPP_EIOXUP_IN: { Ipppp_eio_in *eio_in = data; ip_assert(netif); IPLITE_CODE_ISLOCKED_ASSERT(); /* Add local IPv4 address to this interface. */ netmask_n = IP_NETMASK(eio_in->local_addr_n); if(iplite_ip4_add_addr(iplite_netif, eio_in->local_addr_n, netmask_n) < 0) { IP_PANIC2(); return -1; } /* Save peer address for "route" lookup. */ iplite_netif->inet4_peeraddr_n = eio_in->peer_addr_n; if (ipppp_sysvar_get_conf_string(netif, IP_NULL, "ipppp.flags", "defaultroute")) { /* Add default IPv4 gateway to peer. */ iplite.ip4.default_gateway_n = eio_in->peer_addr_n; } } break; case IPPPP_EIOXDOWN_IN: ip_assert(iplite_netif); IPLITE_CODE_ISLOCKED_ASSERT(); iplite_if_clean(iplite_netif, IP_TRUE, IP_FALSE); break; case IPPPP_EIOXDSTADDR_IN: { struct Ip_ifreq ifreq; struct Ip_sockaddr_in *inaddr = (struct Ip_sockaddr_in *)&ifreq.ip_ifr_addr; Ip_u32 dstaddr = ((struct Ip_in_addr *)data)->s_addr; Iplite_netif *tmpif; int i; IPLITE_CODE_ISLOCKED_ASSERT(); dstaddr = ip_htonl(dstaddr); for (i = 1; i < IPLITE_CONF_MAX_NETIF; i++) { tmpif = iplite.netifs[i]; if (tmpif == IP_NULL) continue; if (IP_BIT_ISFALSE(tmpif->ipcom.flags, IP_IFF_POINTOPOINT)) continue; (void)tmpif->link_ioctl(tmpif, IP_SIOCGIFDSTADDR, &ifreq); if (inaddr->sin_addr.s_addr == dstaddr) return 1; } } return 0; #endif /* ifdef IPCOM_USE_INET */ #ifdef IPCOM_USE_INET6 case IPPPP_EIOXINPUT_IN6: ip_assert(iplite_netif); IPLITE_CODE_ISLOCKED_ASSERT(); iplite_ip6_input(iplite_netif, data); break; case IPPPP_EIOXUP_IN6: { Ipppp_eio_in6 *eio_in6 = data; ip_assert(netif); IPLITE_CODE_ISLOCKED_ASSERT(); /* Add IPv6 address. */ if(iplite_ip6_add_addr(iplite_netif, &eio_in6->local_addr, 64, 0, IPCOM_ADDR_INFINITE, IPCOM_ADDR_INFINITE) != 0) { IP_PANIC2(); return -1; } /* Create neighbor cache entry for peer. */ nc = iplite_ip6_neighbor_cache_find(iplite_netif, (IP_CONST struct Ip_in6_addr *)&eio_in6->peer_addr); nc->status = IPLITE_IP6_ND_REACHABLE; nc->next_timeout = IPCOM_ADDR_INFINITE; /* Save peer address for "route" lookup. */ ipcom_memcpy(&iplite_netif->inet6_peeraddr, &eio_in6->peer_addr, sizeof(struct Ip_in6_addr)); } break; case IPPPP_EIOXDOWN_IN6: ip_assert(iplite_netif); IPLITE_CODE_ISLOCKED_ASSERT(); iplite_if_clean(iplite_netif, IP_FALSE, IP_TRUE); nc = iplite_ip6_neighbor_cache_find(iplite_netif, (IP_CONST struct Ip_in6_addr *)&iplite_netif->inet6_peeraddr); nc->status = IPLITE_IP6_ND_INCOMPLETE; nc->next_timeout = iplite.seconds + 1; break; #endif /* ifdef IPCOM_USE_INET6 */ default: ip_assert(iplite_netif); IPLITE_CODE_ISLOCKED_ASSERT(); iplite_kioevent(iplite_netif, command, data); break; } return ret; } #endif /* IPPPP */ /* **************************************************************************** * END OF FILE **************************************************************************** */