📄 aenet.cpp
字号:
/*
* Created on 1 Nov 2006
* Created by Paul Gardner
* Copyright (C) 2006 Aelitis, All Rights Reserved.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* AELITIS, SAS au capital de 63.529,40 euros
* 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France.
*
*/
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "windows.h"
#include "time.h"
#include "winsock2.h"
#include "WS2TCPIP.H"
#include "aereg.h"
#include "aenet.h"
#include "org_gudy_azureus2_platform_win32_access_impl_AEWin32AccessInterface.h"
// IP ftp://ftp.rfc-editor.org/in-notes/rfc791.txt
// ICMP ftp://ftp.rfc-editor.org/in-notes/rfc792.txt
// UDP ftp://ftp.rfc-editor.org/in-notes/rfc768.txt
bool winsock_started_up = false;
void
initialiseWinsock()
{
if ( !winsock_started_up ){
winsock_started_up = true;
WSADATA wdData;
WSAStartup(MAKEWORD(2, 2), &wdData);
}
}
unsigned short
calculateChecksum(
unsigned short const words[],
int num_words )
{
unsigned long sum = 0;
while (num_words-- > 0){
sum += *(words++);
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += sum >> 16;
unsigned short result = ((unsigned short) ~sum);
if ( result == 0 ){
result = 0xffff;
}
return( result );
}
unsigned short
calculateChecksum2(
unsigned short const words1[],
int num_words1,
unsigned short const words2[],
int num_words2 )
{
unsigned long sum = 0;
while (num_words1-- > 0){
sum += *(words1++);
}
while (num_words2-- > 0){
sum += *(words2++);
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += sum >> 16;
unsigned short result = ((unsigned short) ~sum);
if ( result == 0 ){
result = 0xffff;
}
return( result );
}
int
sendTraceRouteMessage(
JNIEnv* env,
unsigned short trace_id,
int time_to_live,
unsigned int send_sock,
unsigned int recv_sock,
unsigned long source_ip,
unsigned short source_port,
unsigned long target_ip,
unsigned short target_port,
bool use_udp,
bool use_icmp )
{
// Advice is to use UDP rather than ICMP echos. However, reality is that UDP packets can be totally dropped with no ICMP response. So send both...
// UDP
if ( use_udp ){
udp_probe_packet udp_probe;
struct sockaddr_in target;
memset( &target, 0, sizeof( target ));
target.sin_family = AF_INET;
target.sin_addr.s_addr = htonl( target_ip );
target.sin_port = htons( target_port );
// printf( "Sending to %lx from %lx: ip=%d,udp=%d,tot=%d\n", target_ip, source_ip, sizeof( ip_header ), sizeof( udp_header ), sizeof( probe_packet ));
memset( &udp_probe, 0, sizeof( udp_probe ));
udp_probe.ip.ip_version = 4;
udp_probe.ip.ip_header_len = sizeof( ip_header) >> 2;
udp_probe.ip.tos = 0;
udp_probe.ip.total_len = htons( sizeof( udp_probe_packet ));
udp_probe.ip.ident = htons( trace_id );
udp_probe.ip.frag_and_flags = 0;
udp_probe.ip.ttl = time_to_live;
udp_probe.ip.protocol = IPPROTO_UDP;
udp_probe.ip.checksum = 0;
udp_probe.ip.source_ip = htonl( source_ip );
udp_probe.ip.dest_ip = htonl( target_ip );
udp_probe.ip.checksum = calculateChecksum((unsigned short*)&udp_probe.ip, sizeof( ip_header ) / 2 );
udp_probe.udp.source_port = htons( source_port );
udp_probe.udp.dest_port = htons( target_port );
udp_probe.udp.data_len = htons( sizeof( udp_probe_packet ) - sizeof( ip_header ));
udp_probe.udp.checksum = 0;
udp_probe.data = 1234;
pseudo_udp_header puh;
puh.source_ip = htonl( source_ip );
puh.dest_ip = htonl( target_ip );
puh.zero = 0;
puh.protocol = IPPROTO_UDP;
puh.data_len = htons( sizeof( udp_probe_packet ) - sizeof( ip_header ));
udp_probe.udp.checksum = calculateChecksum2( (unsigned short*)&puh, sizeof( pseudo_udp_header ) / 2, (unsigned short *)&udp_probe.udp, (sizeof( udp_probe ) - sizeof( ip_header ))/2);
/*
char* bytes = (char *)&probe;
for (int i=0;i<sizeof( probe );i++ ){
printf( "%x\n", bytes[i] & 0xff );
}
printf( "\n" );
*/
// whereto = to, contains sin_addr and sin_family
int num_sent = sendto(send_sock, (char *)&udp_probe, sizeof( udp_probe ), 0, (struct sockaddr *)&target, sizeof(target));
if ( num_sent == sizeof( udp_probe ) ){
if ( !use_icmp ){
return( 1 );
}
}else if ( num_sent == SOCKET_ERROR ){
throwException( env, "sendto", "UDP operation failed", WSAGetLastError());
return 0;
}else{
throwException( env, "sendto", "UDP incomplete packet sent" );
return 0;
}
}
// ICMP
if ( use_icmp ){
icmp_probe_packet icmp_probe;
struct sockaddr_in target;
memset( &target, 0, sizeof( target ));
target.sin_family = AF_INET;
target.sin_addr.s_addr = htonl( target_ip );
target.sin_port = htons( target_port );
// printf( "Sending to %lx from %lx: ip=%d,udp=%d,tot=%d\n", target_ip, source_ip, sizeof( ip_header ), sizeof( udp_header ), sizeof( probe_packet ));
memset( &icmp_probe, 0, sizeof( icmp_probe ));
icmp_probe.ip.ip_version = 4;
icmp_probe.ip.ip_header_len = sizeof( ip_header) >> 2;
icmp_probe.ip.tos = 0;
icmp_probe.ip.total_len = htons( sizeof( icmp_probe_packet ));
icmp_probe.ip.ident = htons( trace_id );
icmp_probe.ip.frag_and_flags = 0;
icmp_probe.ip.ttl = time_to_live;
icmp_probe.ip.protocol = IPPROTO_ICMP;
icmp_probe.ip.checksum = 0;
icmp_probe.ip.source_ip = htonl( source_ip );
icmp_probe.ip.dest_ip = htonl( target_ip );
icmp_probe.ip.checksum = calculateChecksum((unsigned short*)&icmp_probe.ip, sizeof( ip_header ) / 2 );
icmp_probe.icmp.type = ICMP_TYPE_ECHO;
icmp_probe.icmp.code = 0;
icmp_probe.icmp.checksum = 0;
icmp_probe.icmp.ident = htons( trace_id );
icmp_probe.icmp.sequence = htons( target_port );
icmp_probe.icmp.checksum = calculateChecksum( (unsigned short*)&icmp_probe.icmp, sizeof( icmp_echo_header ) / 2 );
/*
char* bytes = (char *)&probe;
for (int i=0;i<sizeof( probe );i++ ){
printf( "%x\n", bytes[i] & 0xff );
}
printf( "\n" );
*/
// whereto = to, contains sin_addr and sin_family
int num_sent = sendto(send_sock, (char *)&icmp_probe, sizeof( icmp_probe ), 0, (struct sockaddr *)&target, sizeof(target));
if ( num_sent == sizeof( icmp_probe ) ){
return 1;
}else if ( num_sent == SOCKET_ERROR ){
throwException( env, "sendto", "UDP operation failed", WSAGetLastError());
return 0;
}else{
throwException( env, "sendto", "UDP incomplete packet sent" );
return 0;
}
}
throwException( env, "sendto", "no protocol selected" );
return( 0 );
}
int
traceRouteReport(
JNIEnv *env,
jobject callback,
char* msg )
{
jstring j_msg = env->NewStringUTF( msg );
if ( j_msg == NULL ){
throwException( env, "NewStringUTF", "alloc failed" );
return 0;
}
int res = 0;
jclass callback_class = env->GetObjectClass( callback );
if ( callback_class == NULL ){
throwException( env, "GetObjectClass", "failed" );
return 0;
}else{
jmethodID method = env->GetMethodID( callback_class, "generalMessage", "(Ljava/lang/String;)J");
if ( method == NULL ){
throwException( env, "GetMethodID", "method not found" );
}else{
res = (long)env->CallLongMethod( callback, method, j_msg );
}
env->DeleteLocalRef( callback_class );
}
env->ReleaseStringUTFChars( j_msg, msg );
return( res );
}
int
traceRouteReportTimeout(
JNIEnv *env,
jobject callback,
int ttl )
{
char buffer[1024];
sprintf( buffer, "%ld", ttl );
return( traceRouteReport( env, callback, buffer ));
}
int
traceRouteReportResult(
JNIEnv *env,
jobject callback,
int ttl,
unsigned long address,
int time,
bool udp )
{
char buffer[1024];
sprintf( buffer, "%d, %ld, %d, %d", ttl, address, time, udp?1:0 );
return( traceRouteReport( env, callback, buffer ));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -