mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-29 16:31:05 +02:00
Conflicts:
src/gui/moviebrowser.cpp
src/gui/nfs.cpp
Origin commit data
------------------
Branch: ni/coolstream
Commit: 706ea95092
Author: martii <m4rtii@gmx.de>
Date: 2013-06-29 (Sat, 29 Jun 2013)
------------------
This commit was generated by Migit
285 lines
6.0 KiB
C++
285 lines
6.0 KiB
C++
/**
|
|
* PING module
|
|
*
|
|
* Copyright (C) 2001 Jeffrey Fulmer <jdfulmer@armstrong.com>
|
|
* This file is part of LIBPING
|
|
*
|
|
* This program 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 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
*/
|
|
|
|
|
|
#include "ping.h"
|
|
|
|
|
|
#ifndef EXIT_SUCCESS
|
|
# define EXIT_SUCCESS 0
|
|
#endif /*EXIT_SUCCESS*/
|
|
#ifndef EXIT_FAILURE
|
|
# define EXIT_FAILURE 1
|
|
#endif /*EXIT_FAILURE*/
|
|
|
|
#define MAXPACKET 65535
|
|
#define PKTSIZE 64
|
|
#define HDRLEN ICMP_MINLEN
|
|
#define DATALEN (PKTSIZE-HDRLEN)
|
|
#define MAXDATA (MAXPKT-HDRLEN-TIMLEN)
|
|
#define DEF_TIMEOUT 5
|
|
|
|
static int ident = 0;
|
|
static int timo = 2;
|
|
static int rrt;
|
|
static int sock = -1;
|
|
|
|
static int
|
|
in_checksum( u_short *buf, int len )
|
|
{
|
|
register long sum = 0;
|
|
u_short answer = 0;
|
|
|
|
while( len > 1 ){
|
|
sum += *buf++;
|
|
len -= 2;
|
|
}
|
|
|
|
if( len == 1 ){
|
|
*( u_char* )( &answer ) = *( u_char* )buf;
|
|
sum += answer;
|
|
}
|
|
sum = ( sum >> 16 ) + ( sum & 0xffff );
|
|
sum += ( sum >> 16 );
|
|
answer = ~sum;
|
|
|
|
return ( answer );
|
|
|
|
}
|
|
|
|
int
|
|
send_ping( const char *host, struct sockaddr_in *taddr )
|
|
{
|
|
int len;
|
|
int ss;
|
|
unsigned char buf[ HDRLEN + DATALEN ];
|
|
struct protoent *proto;
|
|
struct hostent *hp;
|
|
struct icmp *icp;
|
|
unsigned short last;
|
|
|
|
len = HDRLEN + DATALEN;
|
|
|
|
if(( proto = getprotobyname( "icmp" )) == NULL ){
|
|
return -1;
|
|
}
|
|
|
|
if(( hp = gethostbyname( host )) != NULL ){
|
|
memmove( &taddr->sin_addr, hp->h_addr_list[0], sizeof( taddr->sin_addr ));
|
|
taddr->sin_port = 0;
|
|
taddr->sin_family = AF_INET;
|
|
}
|
|
else if( inet_aton( host, &taddr->sin_addr ) == 0 ){
|
|
return -1;
|
|
}
|
|
|
|
last = ntohl( taddr->sin_addr.s_addr ) & 0xFF;
|
|
if(( last == 0x00 ) || ( last == 0xFF )){
|
|
return -1;
|
|
}
|
|
|
|
if((sock < 0) && ( sock = socket( AF_INET, SOCK_RAW, proto->p_proto )) < 0 ){
|
|
#ifdef DEBUG
|
|
perror( "sock" );
|
|
#endif/*DEBUG*/
|
|
return -2;
|
|
}
|
|
|
|
icp = (struct icmp *)buf;
|
|
icp->icmp_type = ICMP_ECHO;
|
|
icp->icmp_code = 0;
|
|
icp->icmp_cksum = 0;
|
|
icp->icmp_id = getpid() & 0xFFFF;
|
|
icp->icmp_cksum = in_checksum((u_short *)icp, len );
|
|
|
|
if(( ss = sendto( sock, buf, sizeof( buf ), 0,
|
|
(struct sockaddr*)taddr, sizeof( *taddr ))) < 0 ){
|
|
#ifdef DEBUG
|
|
perror( "sock" );
|
|
#endif/*DEBUG*/
|
|
close( sock );
|
|
sock = -1;
|
|
return -2;
|
|
}
|
|
if( ss != len ){
|
|
#ifdef DEBUG
|
|
perror( "malformed packet" );
|
|
#endif/*DEBUG*/
|
|
close( sock );
|
|
sock = -1;
|
|
return -2;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
recv_ping( struct sockaddr_in *taddr )
|
|
{
|
|
int len;
|
|
socklen_t from;
|
|
int nf, cc;
|
|
unsigned char buf[ HDRLEN + DATALEN ];
|
|
//struct icmp *icp;
|
|
struct sockaddr_in faddr;
|
|
struct timeval to;
|
|
fd_set readset, writeset;
|
|
|
|
to.tv_sec = timo / 100000;
|
|
to.tv_usec = ( timo - ( to.tv_sec * 100000 ) ) * 10;
|
|
|
|
FD_ZERO( &readset );
|
|
FD_ZERO( &writeset );
|
|
FD_SET( sock, &readset );
|
|
/* we use select to see if there is any activity
|
|
on the socket. If not, then we've requested an
|
|
unreachable network and we'll time out here. */
|
|
if(( nf = select( sock + 1, &readset, &writeset, NULL, &to )) < 0 ){
|
|
#ifdef DEBUG
|
|
perror( "select" );
|
|
#endif/*DEBUG*/
|
|
exit( EXIT_FAILURE );
|
|
}
|
|
if( nf == 0 ){
|
|
return -1;
|
|
}
|
|
|
|
len = HDRLEN + DATALEN;
|
|
from = sizeof( faddr );
|
|
|
|
cc = recvfrom( sock, buf, len, 0, (struct sockaddr*)&faddr, &from );
|
|
if( cc < 0 ){
|
|
exit( EXIT_FAILURE );
|
|
}
|
|
|
|
//icp = (struct icmp *)(buf + HDRLEN + DATALEN );
|
|
if( faddr.sin_addr.s_addr != taddr->sin_addr.s_addr ){
|
|
return 1;
|
|
}
|
|
/*****
|
|
if( icp->icmp_id != ( getpid() & 0xFFFF )){
|
|
printf( "id: %d\n", icp->icmp_id );
|
|
return 1;
|
|
}
|
|
*****/
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* elapsed_time
|
|
* returns an int value for the difference
|
|
* between now and starttime in milliseconds.
|
|
*/
|
|
static int
|
|
elapsed_time( struct timeval *starttime ){
|
|
struct timeval *newtime;
|
|
int elapsed;
|
|
newtime = (struct timeval*)malloc( sizeof(struct timeval));
|
|
gettimeofday(newtime,NULL);
|
|
elapsed = 0;
|
|
if(( newtime->tv_usec - starttime->tv_usec) > 0 ){
|
|
elapsed += (newtime->tv_usec - starttime->tv_usec)/1000 ;
|
|
}
|
|
else{
|
|
elapsed += ( 1000000 + newtime->tv_usec - starttime->tv_usec ) /1000;
|
|
newtime->tv_sec--;
|
|
}
|
|
if(( newtime->tv_sec - starttime->tv_sec ) > 0 ){
|
|
elapsed += 1000 * ( newtime->tv_sec - starttime->tv_sec );
|
|
}
|
|
free(newtime);
|
|
return( elapsed );
|
|
}
|
|
|
|
static int
|
|
myping(const std::string &hostname, int t, struct sockaddr_in *sa = NULL)
|
|
{
|
|
int err;
|
|
struct sockaddr_in _sa;
|
|
struct timeval mytime;
|
|
|
|
if (!sa)
|
|
sa = &_sa;
|
|
|
|
ident = getpid() & 0xFFFF;
|
|
|
|
if( t == 0 ) timo = 2;
|
|
else timo = t;
|
|
|
|
(void) gettimeofday( &mytime, (struct timezone *)NULL);
|
|
if(( err = send_ping( hostname.c_str(), sa )) < 0 ){
|
|
return err;
|
|
}
|
|
do{
|
|
if(( rrt = elapsed_time( &mytime )) > timo * 1000 ){
|
|
close( sock );
|
|
sock = -1;
|
|
return 0;
|
|
}
|
|
} while( recv_ping(sa));
|
|
close( sock );
|
|
sock = -1;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
pinghost(const std::string &hostname, std::string *ip)
|
|
{
|
|
struct sockaddr_in sa;
|
|
int res = myping( hostname, 0, &sa);
|
|
if (ip) {
|
|
char *p = inet_ntoa(sa.sin_addr);
|
|
*ip = p ? std::string(p) : "";
|
|
}
|
|
return res;
|
|
}
|
|
|
|
int
|
|
pingthost(const std::string &hostname, int t)
|
|
{
|
|
return myping( hostname, t );
|
|
}
|
|
|
|
int
|
|
tpinghost(const std::string &hostname)
|
|
{
|
|
int ret;
|
|
|
|
if(( ret = myping( hostname, 0 )) > 0 )
|
|
return rrt;
|
|
else
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
tpingthost(const std::string &hostname, int t )
|
|
{
|
|
int ret;
|
|
|
|
if(( ret = myping( hostname, t )) > 0 )
|
|
return rrt;
|
|
else
|
|
return ret;
|
|
}
|