📄 sys-ecos.c
字号:
//==========================================================================
//
// src/sys-ecos.c
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Portions created by Nick Garnett are
// Copyright (C) 2003, 2004 eCosCentric Ltd.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD,
// FreeBSD or other sources, and are covered by the appropriate
// copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
/*
* sys-bsd.c - System-dependent procedures for setting up
* PPP interfaces on bsd-4.4-ish systems (including 386BSD, NetBSD, etc.)
*
* Copyright (c) 1989 Carnegie Mellon University.
* Copyright (c) 1995 The Australian National University.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by Carnegie Mellon University and The Australian National University.
* The names of the Universities may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
//static char rcsid[] = "$FreeBSD: src/usr.sbin/pppd/sys-bsd.c,v 1.17 1999/08/28 01:19:08 peter Exp $";
#endif
/* $NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $ */
/*
* TODO:
*/
//==========================================================================
#include <pkgconf/system.h>
#include <pkgconf/net.h>
#include <pkgconf/ppp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <signal.h>
#define _KERNEL 1
#include <sys/param.h>
#undef _KERNEL
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
#ifdef NetBSD1_2
#include <util.h>
#endif
#ifdef PPP_FILTER
#include <net/bpf.h>
#endif
#include <cyg/ppp/syslog.h>
#include <net/if.h>
#include <cyg/ppp/net/ppp_defs.h>
#include <cyg/ppp/net/if_ppp.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#ifdef IPX_CHANGE
#include <netipx/ipx.h>
#endif
#if RTM_VERSION >= 3
#include <sys/param.h>
#if defined(NetBSD) && (NetBSD >= 199703)
#include <netinet/if_inarp.h>
#else /* NetBSD 1.2D or later */
#include <netinet/if_ether.h>
#endif
#endif
#include "cyg/ppp/pppd.h"
#include "cyg/ppp/fsm.h"
#include "cyg/ppp/ipcp.h"
#include "cyg/ppp/ppp_io.h"
#include <cyg/ppp/ppp.h>
//==========================================================================
static int rtm_seq;
static cyg_io_handle_t ppp_handle; /* IO subsystem handle to PPP stream */
struct tty ppp_tty; /* dummy TTY structure */
static cyg_handle_t ppp_rtc;
static cyg_resolution_t ppp_rtc_resolution;
static int loop_slave = -1;
static int loop_master;
static unsigned char inbuf[PPP_MTU + PPP_HDRLEN + 100]; /* buffer for chars read from input */
static int sockfd = -1; /* socket for doing interface ioctls */
static int if_is_up; /* the interface is currently up */
static u_int32_t ifaddrs[2]; /* local and remote addresses we set */
static u_int32_t default_route_gateway; /* gateway addr for default route */
static u_int32_t proxy_arp_addr; /* remote addr for proxy arp */
/* Prototypes for procedures local to this file. */
static int dodefaultroute __P((u_int32_t, int));
static int get_ether_addr __P((u_int32_t, struct sockaddr_dl *));
static void wait_input_alarm(cyg_handle_t alarm, cyg_addrword_t data);
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
void cyg_ppp_serial_callback( cyg_serial_line_status_t *s,
CYG_ADDRWORD priv );
#endif
extern u_int32_t netmask; /* IP netmask to set on interface */
//==========================================================================
/*
* sys_init - System-dependent initialization.
*/
void
sys_init()
{
if( sockfd == -1 )
{
/* Get an internet socket for doing socket ioctl's on. */
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
syslog(LOG_ERR, "Couldn't create IP socket: %d",errno);
die(1);
}
}
ppp_tty.pppd_wakeup = 0;
ppp_tty.pppd_thread_running = true;
ppp_rtc = cyg_real_time_clock();
ppp_rtc_resolution = cyg_clock_get_resolution( ppp_rtc );
cyg_alarm_create( ppp_rtc,
wait_input_alarm,
(cyg_addrword_t)&ppp_tty,
&ppp_tty.alarm,
&ppp_tty.alarm_obj);
}
//==========================================================================
/*
* sys_cleanup - restore any system state we modified before exiting:
* mark the interface down, delete default route and/or proxy arp entry.
* This should call die() because it's called from die().
*/
void
sys_cleanup()
{
struct ifreq ifr;
db_printf("%s called\n", __PRETTY_FUNCTION__);
if (if_is_up) {
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0
&& ((ifr.ifr_flags & IFF_UP) != 0)) {
ifr.ifr_flags &= ~IFF_UP;
ioctl(sockfd, SIOCSIFFLAGS, &ifr);
}
}
if (ifaddrs[0] != 0)
cifaddr(0, ifaddrs[0], ifaddrs[1]);
if (default_route_gateway)
cifdefaultroute(0, 0, default_route_gateway);
if (proxy_arp_addr)
cifproxyarp(0, proxy_arp_addr);
if( sockfd != -1 )
{
close(sockfd);
sockfd = -1;
}
}
//==========================================================================
#ifdef __ECOS
void
sys_exit(void)
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
phase = PHASE_DEAD;
while( ppp_tty.tx_thread_running )
{
db_printf("kick tx thread\n");
cyg_semaphore_post( &ppp_tty.tx_sem );
cyg_thread_delay(100);
}
ppp_tty.pppd_thread_running = false;
cyg_thread_exit();
}
#endif
//==========================================================================
/*
* sys_close - Clean up in a child process before execing.
*/
void
sys_close()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
if (loop_slave >= 0) {
close(loop_slave);
close(loop_master);
}
}
//==========================================================================
/*
* sys_check_options - check the options that the user specified
*/
void
sys_check_options()
{
//db_printf("%s called\n", __PRETTY_FUNCTION__);
}
//==========================================================================
/*
* ppp_available - check whether the system has any ppp interfaces
* (in fact we check whether we can do an ioctl on ppp0).
*/
int
ppp_available()
{
int s, ok;
struct ifreq ifr;
extern char *no_ppp_msg;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
return 1; /* can't tell */
strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
close(s);
no_ppp_msg = "\This system lacks kernel support for PPP. To include PPP support\n\in the kernel, please follow the steps detailed in the README.bsd\n\file in the ppp-2.2 distribution.\n";
return ok;
}
//==========================================================================
/*
* establish_ppp - Turn the serial port into a ppp interface.
*/
void
establish_ppp(cyg_io_handle_t handle)
{
int s;
int x;
int err;
//db_printf("%s called\n", __PRETTY_FUNCTION__);
ppp_handle = ppp_tty.t_handle = handle;
ppp_tty.t_sc = NULL;
s = splsoftnet();
err = cyg_ppp_pppopen( &ppp_tty );
if( err != 0 )
syslog( LOG_ERR, "Couldn't establish PPP interface: %d", err );
/*
* Enable debug in the driver if requested.
*/
if (kdebugflag) {
if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCGFLAGS, (caddr_t) &x, 0)) < 0) {
syslog(LOG_WARNING, "ioctl (PPPIOCGFLAGS): %d",err);
} else {
x |= (kdebugflag & 0xFF) * SC_DEBUG;
if ((err = cyg_ppp_ppptioctl(&ppp_tty, PPPIOCSFLAGS, (caddr_t) &x, 0)) < 0)
syslog(LOG_WARNING, "ioctl(PPPIOCSFLAGS): %d",err);
}
}
splx(s);
}
//==========================================================================
/*
* restore_loop - reattach the ppp unit to the loopback.
*/
void
restore_loop()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}
//==========================================================================
/*
* disestablish_ppp - Restore the serial port to normal operation.
* This shouldn't call die() because it's called from die().
*/
void
disestablish_ppp(cyg_io_handle_t handle)
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}
//==========================================================================
/*
* Check whether the link seems not to be 8-bit clean.
*/
void
clean_check()
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}
//==========================================================================
/*
* set_up_tty: Set up the serial port on `fd' for 8 bits, no parity,
* at the requested speed, etc. If `local' is true, set CLOCAL
* regardless of whether the modem option was specified.
*
* For *BSD, we assume that speed_t values numerically equal bits/second.
*/
void
set_up_tty(cyg_io_handle_t handle, int local)
{
cyg_serial_info_t cfg;
int err;
int len = sizeof(cfg);
err = cyg_io_get_config( handle,
CYG_IO_GET_CONFIG_SERIAL_INFO,
&cfg,
&len);
if( err != 0 ) {
syslog(LOG_ERR, "cyg_io_get_config: %d",err);
die(1);
}
switch ( flowctl )
{
case CYG_PPP_FLOWCTL_DEFAULT:
break;
case CYG_PPP_FLOWCTL_NONE:
cfg.flags &= ~(CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX|
CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX);
break;
case CYG_PPP_FLOWCTL_HARDWARE:
cfg.flags &= ~(CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX);
cfg.flags |= CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX;
break;
case CYG_PPP_FLOWCTL_SOFTWARE:
cfg.flags &= ~(CYGNUM_SERIAL_FLOW_RTSCTS_RX|CYGNUM_SERIAL_FLOW_RTSCTS_TX);
cfg.flags |= CYGNUM_SERIAL_FLOW_XONXOFF_RX|CYGNUM_SERIAL_FLOW_XONXOFF_TX;
break;
}
if( inspeed != 0 )
cfg.baud = inspeed;
err = cyg_io_set_config( handle,
CYG_IO_SET_CONFIG_SERIAL_INFO,
&cfg,
&len);
if( err != 0 ) {
syslog(LOG_ERR, "cyg_io_set_config: %d",err);
die(1);
}
}
//==========================================================================
/*
* restore_tty - restore the terminal to the saved settings.
*/
void
restore_tty(cyg_io_handle_t handle)
{
#ifdef CYGOPT_IO_SERIAL_SUPPORT_LINE_STATUS
if( modem )
{
// Restore callback handler if it was set.
Cyg_ErrNo err;
cyg_uint32 len = sizeof(ppp_tty.serial_callbacks);
db_printf("%s called\n", __PRETTY_FUNCTION__);
err = cyg_io_set_config( handle,
CYG_IO_SET_CONFIG_SERIAL_STATUS_CALLBACK,
&ppp_tty.serial_callbacks,
&len);
if( err != 0 ) {
syslog(LOG_ERR, "cyg_io_set_config(restore serial callbacks): %d",err);
die(1);
}
}
#endif
}
//==========================================================================
/*
* setdtr - control the DTR line on the serial port.
* This is called from die(), so it shouldn't call die().
*/
void
setdtr(fd, on)
int fd, on;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}
//==========================================================================
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -