470 lines
13 KiB
C
470 lines
13 KiB
C
/*
|
|
******************************************************************************
|
|
* 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 <lob@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 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 <ipcom_type.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_clib.h>
|
|
|
|
#include <ipppp.h>
|
|
#include <ipppp_ipstack.h>
|
|
|
|
#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
|
|
****************************************************************************
|
|
*/
|
|
|