📄 sys-ecos.c
字号:
for (ifr = ifc.ifc_req; ifr < ifend;
ifr = (struct ifreq *) ((char *)&ifr->ifr_addr
+ MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)))) {
if (ifr->ifr_addr.sa_family == AF_INET) {
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
/*
* Check that the interface is up, and not point-to-point
* or loopback.
*/
if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
continue;
if ((ifreq.ifr_flags &
(IFF_UP|IFF_BROADCAST|IFF_POINTOPOINT|IFF_LOOPBACK|IFF_NOARP))
!= (IFF_UP|IFF_BROADCAST))
continue;
/*
* Get its netmask and check that it's on the right subnet.
*/
if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
continue;
mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
if ((ipaddr & mask) != (ina & mask))
continue;
break;
}
}
if (ifr >= ifend)
return 0;
syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name);
/*
* Now scan through again looking for a link-level address
* for this interface.
*/
ifp = ifr;
for (ifr = ifc.ifc_req; ifr < ifend; ) {
if (strcmp(ifp->ifr_name, ifr->ifr_name) == 0
&& ifr->ifr_addr.sa_family == AF_LINK) {
/*
* Found the link-level address - copy it out
*/
dla = (struct sockaddr_dl *) &ifr->ifr_addr;
BCOPY(dla, hwaddr, dla->sdl_len);
return 1;
}
ifr = (struct ifreq *) ((char *)&ifr->ifr_addr
+ MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)));
}
return 0;
}
//==========================================================================
/*
* Return user specified netmask, modified by any mask we might determine
* for address `addr' (in network byte order).
* Here we scan through the system's list of interfaces, looking for
* any non-point-to-point interfaces which might appear to be on the same
* network as `addr'. If we find any, we OR in their netmask to the
* user-specified netmask.
*/
u_int32_t
GetMask(addr)
u_int32_t addr;
{
u_int32_t mask, nmask, ina;
struct ifreq *ifr, *ifend, ifreq;
struct ifconf ifc;
struct ifreq ifs[MAX_IFS];
addr = ntohl(addr);
if (IN_CLASSA(addr)) /* determine network mask for address class */
nmask = IN_CLASSA_NET;
else if (IN_CLASSB(addr))
nmask = IN_CLASSB_NET;
else
nmask = IN_CLASSC_NET;
/* class D nets are disallowed by bad_ip_adrs */
mask = netmask | htonl(nmask);
/*
* Scan through the system's network interfaces.
*/
ifc.ifc_len = sizeof(ifs);
ifc.ifc_req = ifs;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) < 0) {
syslog(LOG_WARNING, "ioctl(SIOCGIFCONF): %m");
return mask;
}
ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
for (ifr = ifc.ifc_req; ifr < ifend;
ifr = (struct ifreq *) ((char *)&ifr->ifr_addr
+ MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr)))) {
/*
* Check the interface's internet address.
*/
if (ifr->ifr_addr.sa_family != AF_INET)
continue;
ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
if ((ntohl(ina) & nmask) != (addr & nmask))
continue;
/*
* Check that the interface is up, and not point-to-point or loopback.
*/
strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0)
continue;
if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))
!= IFF_UP)
continue;
/*
* Get its netmask and OR it into our mask.
*/
if (ioctl(sockfd, SIOCGIFNETMASK, &ifreq) < 0)
continue;
mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr;
}
return mask;
}
//==========================================================================
/*
* Use the hostid as part of the random number seed.
*/
int
get_host_seed()
{
//db_printf("%s called\n", __PRETTY_FUNCTION__);
#ifndef __ECOS
return gethostid();
#endif
return 0;
}
//=====================================================================
// PAP stubs
//
// When omitting PAP, these fill in the dangling references from auth.c
//
#ifndef CYGPKG_PPP_PAP
void
upap_authwithpeer(unit, user, password)
int unit;
char *user, *password;
{
unit=unit;
user=user;
password=password;
}
void
upap_authpeer(unit)
int unit;
{
unit=unit;
}
#endif
//=====================================================================
// CHAP stubs
//
// When omitting CHAP, these fill in the dangling references from auth.c
//
#ifndef CYGPKG_PPP_CHAP
void
ChapAuthWithPeer(unit, our_name, digest)
int unit;
char *our_name;
int digest;
{
unit=unit;
our_name=our_name;
digest=digest;
}
void
ChapAuthPeer(unit, our_name, digest)
int unit;
char *our_name;
int digest;
{
unit=unit;
our_name=our_name;
digest=digest;
}
#endif
//=====================================================================
// eCos API
externC cyg_int32 cyg_ppp_options_init( cyg_ppp_options_t *options )
{
if( options == NULL )
return -1;
options->debug = 0;
options->kdebugflag = 0;
options->default_route = 1;
options->modem = 0;
options->flowctl = CYG_PPP_FLOWCTL_HARDWARE;
options->refuse_pap = 0;
options->refuse_chap = 0;
options->baud = CYGNUM_SERIAL_BAUD_115200;
options->idle_time_limit = 1*60;
options->maxconnect = 0;
options->our_address = 0;
options->his_address = 0;
options->script = NULL;
strncpy( options->user, CYGPKG_PPP_AUTH_DEFAULT_USER, MAXNAMELEN );
strncpy( options->passwd, CYGPKG_PPP_AUTH_DEFAULT_PASSWD, MAXSECRETLEN );
return 0;
}
// -------------------------------------------------------------------------
#define CYGNUM_PPP_PPPD_THREAD_STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL+0x1000)
static char cyg_pppd_stack[CYGNUM_PPP_PPPD_THREAD_STACK_SIZE];
static cyg_thread cyg_pppd_thread_obj;
static char cyg_ppp_tx_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
static cyg_thread cyg_ppp_tx_thread_obj;
externC void cyg_pppd_main(CYG_ADDRWORD arg);
externC cyg_ppp_handle_t cyg_ppp_up( const char *devnam_arg,
const cyg_ppp_options_t *options )
{
if( options == NULL || phase != PHASE_DEAD )
return 0;
strncpy( devnam, devnam_arg, PATH_MAX );
ppp_tty.options = options;
// Start the PPPD thread
cyg_thread_create(CYGNUM_PPP_PPPD_THREAD_PRIORITY,
cyg_pppd_main,
(CYG_ADDRWORD)&ppp_tty,
"PPPD",
&cyg_pppd_stack[0],
CYGNUM_PPP_PPPD_THREAD_STACK_SIZE,
&ppp_tty.pppd_thread,
&cyg_pppd_thread_obj
);
cyg_thread_resume(ppp_tty.pppd_thread);
// Start the TX thread
cyg_semaphore_init( &ppp_tty.tx_sem, 0 );
cyg_thread_create(CYGNUM_PPP_PPPD_THREAD_PRIORITY+1,
cyg_ppp_tx_thread,
(CYG_ADDRWORD)&ppp_tty,
"PPP Tx Thread",
&cyg_ppp_tx_thread_stack[0],
sizeof(cyg_ppp_tx_thread_stack),
&ppp_tty.tx_thread,
&cyg_ppp_tx_thread_obj
);
cyg_thread_resume(ppp_tty.tx_thread);
// Wait for the PPPD thread to get going and start the PPP
// initialization phase.
while(phase == PHASE_DEAD )
cyg_thread_delay(100);
return (cyg_ppp_handle_t)&ppp_tty;
}
// -------------------------------------------------------------------------
externC char **script;
externC void cyg_ppp_options_install( const cyg_ppp_options_t *options )
{
debug = options->debug;
kdebugflag = options->kdebugflag;
modem = options->modem;
flowctl = options->flowctl;
refuse_pap = options->refuse_pap;
refuse_chap = options->refuse_chap;
inspeed = options->baud;
idle_time_limit = options->idle_time_limit;
maxconnect = options->maxconnect;
{
ipcp_options *wo = &ipcp_wantoptions[0];
wo->ouraddr = options->our_address;
wo->hisaddr = options->his_address;
wo->default_route = options->default_route;
}
script = options->script;
strncpy( user, &options->user[0], MAXNAMELEN );
strncpy( passwd, &options->passwd[0], MAXSECRETLEN );
}
// -------------------------------------------------------------------------
externC cyg_int32 cyg_ppp_down( const cyg_ppp_handle_t handle )
{
if( phase != PHASE_DEAD )
{
externC int kill_link;
kill_link = 1;
cyg_thread_release( ppp_tty.pppd_thread );
ppp_tty.pppd_wakeup = 1;
return 0;
}
else
return -1;
}
// -------------------------------------------------------------------------
externC cyg_int32 cyg_ppp_wait_up( cyg_ppp_handle_t handle )
{
while(!( (phase == PHASE_NETWORK && ifaddrs[0] != 0) ||
phase == PHASE_DEAD ) )
cyg_thread_delay(100);
return phase == PHASE_NETWORK ? 0 : -1;
}
// -------------------------------------------------------------------------
externC void cyg_ppp_wait_down( cyg_ppp_handle_t handle )
{
while( ppp_tty.tx_thread_running || ppp_tty.pppd_thread_running )
cyg_thread_delay(100);
cyg_thread_delete( ppp_tty.tx_thread );
cyg_thread_delete( ppp_tty.pppd_thread );
}
//=====================================================================
// eCos extras
void syslog( int level, char *fmt, ... )
{
va_list ap;
int ret;
#ifdef CYGPKG_PPP_DEBUG_WARN_ONLY
if(!( level == LOG_ERR ||
level == LOG_WARNING ))
return;
#endif
va_start(ap, fmt);
diag_printf("SYSLOG %02x: ",level);
ret = diag_vprintf(fmt, ap);
diag_printf("\n");
va_end(ap);
}
//=====================================================================
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
cyg_tick_count_t time = cyg_current_time();
tv->tv_sec = time/CYGNUM_HAL_RTC_DENOMINATOR;
tv->tv_usec = (time%CYGNUM_HAL_RTC_DENOMINATOR)*10000;
// db_printf("%s: %d %d\n", __PRETTY_FUNCTION__, tv->tv_sec, tv->tv_usec);
return 0;
}
//=====================================================================
char *crypt (const char *key, const char *salt)
{
static char res[13];
db_printf("%s called\n", __PRETTY_FUNCTION__);
return res;
}
//=====================================================================
/*
* Substitute procedures for those systems which don't have
* drand48 et al.
*/
double
drand48(void)
{
return (double)rand() / (double)0x7fffffffL; /* 2**31-1 */
}
long
mrand48(void)
{
return rand();
}
void
srand48(long seedval)
{
srand(seedval);
}
//=====================================================================
#if 0
#undef MD5Init
#undef MD5Update
#undef MD5Final
#include <sys/types.h>
#include <sys/md5.h>
void cyg_MD5Init( MD5_CTX *ctx );
void cyg_MD5Update (MD5_CTX *ctx, const unsigned char *buf, unsigned int size);
void cyg_MD5Final (unsigned char hash[16], MD5_CTX *ctx);
void cyg_ppp_MD5Init( MD5_CTX *ctx )
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
cyg_MD5Init( ctx );
return;
}
void cyg_ppp_MD5Update (MD5_CTX *ctx, const unsigned char *buf, unsigned int size)
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
cyg_MD5Update( ctx, buf, size );
return;
}
void cyg_ppp_MD5Final (unsigned char hash[16], MD5_CTX *ctx)
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
cyg_MD5Final( hash, ctx );
return;
}
#endif
//=====================================================================
// End of sys-ecos.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -