当前位置: 首页 > news >正文

做网站的人月营销案例网站

做网站的人月,营销案例网站,沧州做网站哪家公司好,不能安装wordpress看了tcpcopy的源码,php 和 python 都可以操作raw socket,因此,用php 和 python 实现了tcpcopy,代码比较简单tcpcopy关键点,理认上来说,只要得到tcp请求报文中数据部分,在ip层转发到测试服务器&a…

看了tcpcopy的源码,php 和 python 都可以操作raw socket,因此,用php 和 python 实现了tcpcopy,代码比较简单

tcpcopy关键点,理认上来说,只要得到tcp请求报文中数据部分,在ip层转发到测试服务器,即可实现流量复制。

因此,只需要维护tcp会话即可维护一个假的tcp连接,骗过测试服务器即可。

代码实现,主要以TCP状态机为基础,同时考虑抓包的无序问题,结合tcpdump调试,用php实现tcpcopy,用python实现intercept。

以下代码,经测试,客户机发起5000个http请求(大约50个长连接),流量全部会复制到测试机上。

其实,tcpcopy与lvs、nat、运营商流量劫持工作原理类似,都是通过欺骗tcp协议栈达到目的; 同理,通过在应用层处理原始套接字,也可以实现lvs负载均衡功能(后续可能会尝试)。

Code:

1. tcpcopy.php

两个进程工作,一个进程负责抓包并放入queue中; 另一个进程负责消费抓到的数据包,因此对tcpcopy进程效率要求不高。

s = $s;

return $this->s;

}

// listen local ip

public function create_listen_socket( $local_ip, $remote_ip=null ){

$one = 1;

$raw_socket = socket_create( AF_INET, SOCK_RAW, getprotobyname("tcp") );

// $raw_socket = socket_create( AF_INET, SOCK_RAW, getprotobyname("icmp") );/* no need bind,connect, 不能抓不属于自己的包 */

// $raw_socket = socket_create( AF_INET, SOCK_RAW, 1 );

socket_set_nonblock( $raw_socket );

// trick, 3 is stand for header control

$set_ret = socket_set_option( $raw_socket, getprotobyname("ip"), 3, $one);

$conn_ret = $bind_ret = true;

if( isset( $local_ip) ){

// 设置 dest ip

$bind_ret = socket_bind($raw_socket, $local_ip );

}

if( isset( $remote_ip) ){

// 不限制 source_ip

// $conn_ret = socket_connect( $raw_socket, $remote_ip, 0 );

}

// $bind_ret = socket_connect( $raw_socket, $remote_ip, 0 );

// $bind_ret = socket_bind($raw_socket, $local_ip );

if( $raw_socket === false

|| $set_ret === false

|| $conn_ret === false

|| $bind_ret === false ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

return false;

}

$this->s = $raw_socket;

return $this->s;

}

// send raw socket to ip

public function create_send_socket( $remote_ip ){

$this->dest_ip = $remote_ip;

$dest_ip_fake = "127.0.0.1";

$dest_ip_fake = "192.168.56.101";

$dest_port_fake = 8080;

$one = 1;

$raw_socket = socket_create( AF_INET, SOCK_RAW, getprotobyname("tcp") );

// $raw_socket = socket_create( AF_INET, SOCK_RAW, getprotobyname("ip") );

socket_set_nonblock( $raw_socket );

// trick, 3 is stand for header control

$set_ret = socket_set_option( $raw_socket, getprotobyname("ip"), 3, $one);

// trick, connect is needed anyway.$dest_ip must by right.

$conn_ret = socket_connect( $raw_socket, $remote_ip, 0 );

// $conn_ret = socket_connect( $raw_socket, $dest_ip_fake, $dest_port );

// trick, for read

// socket_bind($raw_socket, $src_ip );

if( $raw_socket === false

|| $set_ret === false

|| $conn_ret === false ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

return false;

}

$this->s = $raw_socket;

return $this->s;

}

public function create_socket( $src_ip, $src_port, $dest_ip=null, $dest_port=null ){

$this->dest_ip = $dest_ip;

$this->dest_port = $dest_port;

$dest_ip_fake = "127.0.0.1";

$dest_ip_fake = "192.168.56.101";

$dest_port_fake = 8080;

$one = 1;

$raw_socket = socket_create( AF_INET, SOCK_RAW, getprotobyname("tcp") );

socket_set_nonblock( $raw_socket );

// trick, 3 is stand for header control

$set_ret = socket_set_option( $raw_socket, getprotobyname("ip"), 3, $one);

// trick, connect is needed anyway.$dest_ip must by right.

// $conn_ret = socket_connect( $raw_socket, $dest_ip, $dest_port );

// $conn_ret = socket_connect( $raw_socket, $dest_ip_fake, $dest_port );

// trick, for read

socket_bind($raw_socket, $src_ip );

if( $raw_socket === false

|| $set_ret === false

|| $conn_ret === false ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

return false;

}

$this->s = $raw_socket;

return $this->s;

}

public function socket_read_raw( ){

$read_ret = socket_read( $this->s, 65535 );

if( $read_ret === false ){

$error = socket_last_error();

if( 11 !== $error ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

return null;

}

return false;

}

if( strlen($read_ret) > 20 ){

// echo "read_data...\n";

return self::IPUnpack( $read_ret );

}

return null;

}

public function socket_read_udp( ){

$read_ret = socket_recvfrom( $this->s, $buf, 65535, 0, $from='', $port=0 );

//echo $read_ret . "\n";

if( $read_ret === false ){

$error = socket_last_error();

if( 11 !== $error ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

return null;

}

return false;

}

if( $read_ret > 20 ){

// echo "udp_read_data...\n";

return self::IPUnpack( $buf );

}

return null;

}

/*

public function socket_recv_raw( ){

$buf = '';

$read_ret = socket_recvfrom( $this->s, $buf, 65535 );

if( $read_ret === false ){

$error = socket_last_error();

if( 11 !== $error ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

return null;

}

return false;

}

if( strlen($buf) > 20 ){

echo "read_data...\n";

return $this->IPUnpack( $buf );

}

return null;

}

*/

public function socket_send(

$src_ip, $src_port, $dest_ip, $dest_port,

$seq_num, $ack_num, $tcp_flag,

$tcp_data,$timestamp, $ts_echo ){

$ip_data = self::TCPPacket( ip2long($src_ip), ip2long($dest_ip), $src_port, $dest_port,

$seq_num, $ack_num, $tcp_flag,

$tcp_data, $timestamp, $ts_echo );

// echo "tcp_data_md5:" . md5( $ip_data ) . "\n";

$ip_data = self::IPPacket("tcp", ip2long($src_ip), ip2long($dest_ip), $ip_data );

$write_ret = socket_write( $this->s, $ip_data );

if( $write_ret === false || $write_ret !== strlen($ip_data)){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

return false;

}

// echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

// echo "write_ret:" . json_encode( $write_ret ) . "\n";

return $write_ret;

}

/* IP header */

/*

versionAndHeaderlen: 1Byte

service: 1Byte

totalLen: 2Bytes

PacketID: 2Bytes

SliceInfo: 2Bytes

TTL: 1Byte

type: 1Byte

checksum: 2Bytes==> just ip header, 16bits fan ma sum

srcIP: 4Bytes

destIP: 4Bytes

*/

public static function IPUnpack( $packet ){

$arr = unpack("Cverlen/x/ntotal_len/x4/Cttl/Ctype/ncheck_sum/Nsrc_ip/Ndest_ip/x*", $packet);

$arr['version'] = $arr['verlen'] >> 4;

$arr['header_len'] = ($arr['verlen'] & 0x0f) << 2;

unset( $arr['verlen'] );

$arr['type'] = getprotobynumber( $arr['type'] );

$arr['src_ip'] = long2ip( $arr['src_ip'] );

$arr['dest_ip'] = long2ip( $arr['dest_ip'] );

if( $arr['type'] == 'tcp' ){

$arr['tcp'] = self::TCPUnPack( substr($packet, $arr['header_len'] ) );

$tcp_data_len = $arr['total_len'] - $arr['header_len'] - $arr['tcp']['header_len'];

$arr['tcp']['data_len'] = $tcp_data_len;

}

if( strlen($packet) < 20 ) return false;

return $arr;

}

public static function IPPacket( $proto, $src_ip, $dest_ip, $data ){

$ver_len = 4<<4 | 5;

$service = 0;

$total_len = 20+strlen($data);

$id_flag_offset = 0;

$ttl = 65;

$type = getprotobyname( $proto);

$chk_sum = 0;

$i = 2;

while( $i-- ){

$header = pack("CCn"."N"."CCn"."N"."N",

$ver_len, $service, $total_len,

$id_flag_offset,

$ttl, $type, str2int($chk_sum,2),

$src_ip, $dest_ip

);

$chk_sum= self::check_sum( $header, false );

}

//echo "check_sum_verify:";

//get_asc($this->check_sum( $header ));

return $header . $data;

}

/* TCP header */

/*

srcPort: 2Bytes

destPort: 2Bytes

seqNum: 4Bytes

ackNum: 4Bytes

headerLenAndFlag: 2Byte==> 4Bits(Len)+6Bits(reserved)+(U,ACK,PSH,RST,SYN,FIN)

windowSize: 2Bytes

checkSum: 2Bytes ==> tcp header + tcp data

urgentPoint: 2Bytes

*/

/*

* opt: kind(8bit)+len(8bit)+content

*/

public static function TCPUnpack( $packet ){

$arr = unpack("nsrc_port/ndest_port/Nseq_num/Nack_num/nhdrlen_flag/nwindow_size/ncheck_sum/nurgent/xtcp_data", $packet."*" );

$arr['header_len'] = ($arr['hdrlen_flag'] >> 12 ) << 2;

$flag = $arr['hdrlen_flag'] & 0x3f;

unset( $arr['hdrlen_falg'] );

$arr['FIN'] = ($flag & 0x01) ? true : false;

$arr['SYN'] = (($flag>>1) & 0x01) ? true : false;

$arr['RST'] = (($flag>>2) & 0x01) ? true : false;

$arr['ACK'] = (($flag>>4) & 0x01) ? true : false;

$arr['tcp_data'] = strlen($packet) == $arr['header_len'] ? '': substr( $packet, $arr['header_len'] );

return $arr;

}

public static function TCPPacket( $src_ip, $dest_ip, $src_port, $dest_port, $seq_num, $ack_num, $flag,

$tcp_data, $timestamp=null, $ts_echo=null ){

$window_size = 6000;

$chk_sum = 0;

$header_len = 20 >> 2;

$header_option = "";

if( $timestamp !== null ){

$header_option = pack("CCNNn", 8, 10, $timestamp, $ts_echo, 0);

$header_len = (20+12) >> 2;

}

$i = 2;

while( $i -- ){

$tcp_header = pack("nn"."N"."N"."nn"."nn",

$src_port, $dest_port,

$seq_num,

$ack_num,

($header_len << 12) + $flag, $window_size,

str2int($chk_sum,2), 0

//$chk_sum, 0

)

. $header_option;

$ps_header = pack("NNCCn",

$src_ip, $dest_ip,

0, getprotobyname("tcp"),

strlen($tcp_header)+strlen($tcp_data)

);

$chk_sum = self::check_sum( $ps_header . $tcp_header . $tcp_data );

}

$packet = $tcp_header . $tcp_data;

return $packet;

}

private static function check_sum( $data, $need_pack=false ){

if( strlen($data)%2 ){

$data .= "\x00";

}

$bits = unpack("n*", $data );

$chk_sum = array_sum( $bits );

while( $chk_sum >> 16 ){

$chk_sum = ($chk_sum >> 16) + ($chk_sum & 0xffff);

}

$chk_sum = 0xffff & ~$chk_sum;

if( true || $need_pack ){

$chk_sum = pack("n*", $chk_sum );

return $chk_sum;

}

return $chk_sum;

}

}

$TCP_SYN = 1<<1;

$TCP_ACK = 1<<4;

$TCP_FIN = 1;

$tcp_data = "";

$tcp_flag = 0 | $TCP_SYN;

$timestamp = 100000000;

//$timestamp = null;

$ts_echo = 0;

/*

$raw_socket = socket_create( AF_INET, SOCK_RAW, getprotobyname("tcp") );

socket_set_nonblock( $raw_socket );

$one = 1;

$set_ret = socket_set_option( $raw_socket, getprotobyname("ip"), 3, $one);

$conn_ret = socket_connect( $raw_socket, $dest_ip_fake, $dest_port );

while( true ){

break;

$read_ret = socket_read( $raw_socket, 65535 );

if( $read_ret !== false ){

echo json_encode( IPUnpack( $read_ret ) ) . "\n";

}

}

*/

$g_send_socket = $raw_socket_1 = new RawSocket();

$s1 = $raw_socket_1->create_send_socket($dest_ip);

/*

$raw_socket_1->socket_send( $src_ip, $src_port, $dest_ip, $dest_port,

$seq_num, $ack_num, $tcp_flag,

$tcp_data, $timestamp, $ts_echo );

*/

$raw_socket_2 = new RawSocket( );

$s2 = $raw_socket_2->create_listen_socket( /*local_ip*/ $local_ip, /*$dest_ip*/ null );

/*

while( true ){

$read_ret = $raw_socket_2->socket_read_raw( );

if( $read_ret !== false && null !== $read_ret ){

echo json_encode( $read_ret ) . "\n";

}

}

*/

$raw_socket_3= new RawSocket( );

$s3 = $raw_socket_3->create_listen_udp( /*local_ip*/ $local_ip, /*$dest_ip*/ $local_udp_port );

/*

while( true ){

$read_ret = $raw_socket_3->socket_read_udp( );

if( $read_ret !== false && null !== $read_ret ){

echo json_encode( $read_ret ) . "\n";

}

}

*/

$socket_map = array(

(string)($s1) => array('type'=>'send_raw', 'obj'=>$raw_socket_1),

(string)($s2) => array('type'=>'read_raw', 'obj'=>$raw_socket_2),

(string)($s3) => array('type'=>'read_udp', 'obj'=>$raw_socket_3),

);

// var_dump( $socket_map );

/*

$raw_socket_4 = new RawSocket();

$raw_socket_4->create_listen_socket($local_ip);

while( true ){

$read_ret = $raw_socket_4->socket_recv_raw( );

if( $read_ret !== false && null !== $read_ret ){

echo json_encode( $read_ret ) . "\n";

}

}

*/

$g_real_map = array();

$g_fake_map = array();

$g_fake_request_info = array(

'real_ip'=>'',

'real_port'=>'',

'fake_ip'=>'',

'fake_port'=>'',

'send_data_len'=>0,

'receive_data_len'=>0,

'send_data_count'=>0,

'init_seq'=>0,

'next_seq'=>0,

'next_ack'=>0,

'need_deal'=>array(),

'need_deal_seq_min'=>0,

'need_deal_seq_next'=>0,

'update_time'=>0,

'state'=>'INIT',

'update_time'=>0,

'real_next_seq'=>0,// 与 next_seq 同步更新

'real_init_seq'=>0,

'test_init_seq'=>0,// 测试服务器开始序号

'latest_ack'=>0,// 测试服务器最后的确认

);

function add_need_deal_packet( & $fake_info, & $ip_packet, $real_time_request=true ){

global $g_cur_version;

$ip_packet['cur_version'] = $g_cur_version;

$ip_packet['enqueue_state'] = true;

isset( $ip_packet['enqueue_count'] )? $ip_packet['enqueue_count']++ : $ip_packet['enqueue_count'] = 1;

$fake_info['need_deal'][] = $ip_packet;

if( count($fake_info['need_deal']) == 1 ){

$fake_info['need_deal_seq_min'] = $fake_info['need_deal_seq_max'] = $ip_packet['tcp']['seq_num'];

$fake_info['need_deal_seq_next'] = $ip_packet['tcp']['seq_num'];

}else if( $real_time_request && $fake_info['need_deal_seq_next'] != $ip_packet['tcp']['seq_num'] ){

echo "ip_packet:" . json_encode( $ip_packet ) . "\n";

$tmp_fake_info = $fake_info;

$tmp_fake_info['need_deal_count'] = count( $tmp_fake_info['need_deal'] );

unset( $tmp_fake_info['need_deal'] );

echo "fake_info: " . json_encode( $tmp_fake_info ) . "\n";

echo ( "FATAL, may be lost packet\n" );

}

if( $real_time_request ){

$fake_info['need_deal_seq_next'] = get_next_seq( $fake_info['need_deal_seq_next'], $ip_packet['tcp']['data_len'] ) ;

}

}

$g_cur_version = 1;

function get_offset( $cur, $old ){

$offset = $cur - $old;

if( $offset < 0 && abs($offset) > (0xffffffff>>1) ){

$offset += (0xffffffff+1);

}

return $offset;

}

function get_next_seq( $cur, $inc ){

$next = $cur + $inc;

if( $next > 0xffffffff ){

$next %= (0xffffffff+1);

}

return $next;

}

function is_before( $cur, $old ){

$diff = $cur - $old;

if( $diff > 0 ) return true;

if( $diff < -(0xffffffff>>1) ) return true;

return false;

}

function is_after_or_equal( $cur, $old ){

$diff = $cur - $old;

if( $diff >= 0 ) return true;

if( $diff < -(0xffffffff>>1) ) return true;

return false;

}

function is_before_or_equal( $cur, $old ){

return is_after_or_equal( $old, $cur );

}

function is_after( $cur, $old ){

return is_before( $old, $cur );

}

function is_real_after( $fake_info, $cur ){

$old = $fake_info['real_next_seq'];

$diff = $cur - $old;

if( $diff > 0 ) return true;

//if( $diff < 0 && abs($diff) > (0xffffffff>>1) ) return true;

if( $diff < -(0xffffffff>>1) ) return true;

return false;

}

function is_real_before( $fake_info, $cur ){

return ! is_real_after($fake_info, $cur );

}

function is_real_equal( $fake_info, $cur ){

return $fake_info['real_next_seq'] == $cur;

}

function update_next_seq( & $fake_info, $inc ){

$fake_info['next_seq'] = get_next_seq( $fake_info['next_seq'] , $inc );

$fake_info['real_next_seq'] = get_next_seq( $fake_info['real_next_seq'] , $inc );

}

function update_next_ack( & $fake_info, $inc ){

$fake_info['next_ack'] = get_next_seq( $fake_info['next_ack'] , $inc );

}

/*

function get_fake_offset( $fake_info, $cur ){

return get_offset( $cur , $fake_info['next_seq'] );

}

function get_real_offset( $fake_info, $cur ){

return get_offset( $cur , $fake_info['real_next_seq'] );

}

*/

function set_update_time( & $fake_info ){

$cur = intval( microtime( true ) * 1000 );

$fake_info['update_time'] = $cur;

}

function deal_delay_data( & $fake_info, $not_crontab = true ){

global $g_cur_version;

if( $not_crontab ) {

set_update_time( $fake_info );

}

if( count($fake_info['need_deal']) < 1 ) return;

if( $fake_info['state'] !== 'ESTABLISHED' ) return;

// return;

echo "count_need_deal: " . count($fake_info['need_deal']) . "\n";

$tmp_fake_info = $fake_info;

unset( $tmp_fake_info['need_deal'] );

echo "fake_info: " . json_encode( $tmp_fake_info ) . "\n";

echo "need_deal_BEGIN\n";

$g_cur_version ++;

$latest_undeal_version = $g_cur_version;

$count = 0;

while( true ){

$count ++;

echo "deal_delay_data, packet count in buffer:" . count($fake_info['need_deal']) . "\n";

// echo "deal_delay_data: $count\n";

$ip_packet = array_shift($fake_info['need_deal']);

$ip_packet['enqueue_state'] = false;

echo "fake_info: " . json_encode( $tmp_fake_info ) . "\n";

echo sprintf("real_seq:[%d], real_data_len:[%d]\n" ,$ip_packet['tcp']['seq_num'], $ip_packet['tcp']['data_len']);

receive_real_request( $ip_packet, "need_deal" );

echo "ip_packet: " . json_encode( $ip_packet ) . "\n";

echo "ip_packet_enqueue_state:" . $ip_packet['enqueue_state'] . "\n";

echo "enqueue_count:" . $ip_packet['enqueue_count'] . "\n";

if( $ip_packet['cur_version'] >= $latest_undeal_version ){

break;

}

break;

if( 0 == count($fake_info['need_deal']) ){

break;

}

}

echo "need_deal_END\n";

}

function crontab_task( ){

global $g_fake_map, $g_real_map;

// echo "crontab_task..............\n";

$now = intval( microtime(true)*1000 );

if( count( $g_real_map ) == 0 ){

// echo "g_real_map is emtpy\n";

}else{

// echo "g_real_map count:" . count( $g_real_map ) . "\n";

}

foreach( $g_real_map as & $fake_info ){

/*

echo "crontab_task................................\n";

$update_time = $fake_info['update_time'];

echo "now[ $now ], update_time[ $update_time ]\n";

echo sprintf("now_update_time_diff:%d\n", $now - $update_time);

*/

$diff = $now - $fake_info['update_time'];

// echo "diff: " . $diff . "\n";

if( count($fake_info['need_deal']) > 0 ){

//&& ($now - $fake_info['update_time'] > -1) ){

deal_delay_data( $fake_info, false );

}

// echo $fake_info['state'] . "\n";

if( $fake_info['state'] == 'TIME_WAIT' && $diff > 1000*3 ){

$real_ip_port_key = $fake_info['real_ip'] .":" . $fake_info['real_port'];

$fake_ip_port_key = $fake_info['fake_ip'] .":" . $fake_info['fake_port'];

unset( $g_real_map[ $real_ip_port_key ] );

unset( $g_fake_map[ $fake_ip_port_key ] );

return;

}else if( $diff > 1000*3 ){

// var_dump( $fake_info );

// die( 0 );

}

}

}

function receive_test_server_request( $ip_packet ){

global $g_real_map, $g_fake_map, $g_real_request_info, $g_fake_request_info;

global $g_send_socket;

global $g_remote_test_ip;

global $g_cur_version;

$cur_time = microtime( true );

// echo "receive_test_server_response.....................test_server\n";

$TCP_SYN = 1<<1;

$TCP_ACK = 1<<4;

$TCP_FIN = 1;

$src_ip = $ip_packet['src_ip'];$src_port = $ip_packet['tcp']['src_port'];

$dest_ip = $ip_packet['dest_ip'];$dest_port = $ip_packet['tcp']['dest_port'];

$tcp_hdr = $ip_packet['tcp'];

$flag_syn = $tcp_hdr['SYN'];$flag_ack = $tcp_hdr['ACK'];

$flag_fin = $tcp_hdr['FIN'];$flag_rst = $tcp_hdr['RST'];

$seq_num = $tcp_hdr['seq_num'];$ack_num = $tcp_hdr['ack_num'];

$tcp_data = $tcp_hdr['tcp_data'];

$tcp_data_len = $tcp_hdr['data_len'];

if( $src_ip != $g_remote_test_ip ){

return;

}

$fake_ip_port_key = $dest_ip . ":" . $dest_port;

if( !isset( $g_fake_map[ $fake_ip_port_key ] ) ){

echo "NOTICE: not set g_fake_map[ fake_ip_port_key ]\n";

return;

}

$fake_info = & $g_fake_map[ $fake_ip_port_key ];

$status = $fake_info['state'];

// 建立连接

if( $flag_syn === true ){

if( $status == 'SYN_SEND' ){

$fake_info['next_ack'] = $seq_num;

$fake_info['latest_ack'] = $ack_num;

$fake_info['test_init_seq'] = $seq_num;

update_next_ack( $fake_info, 1 );

$fake_info['state'] = 'ESTABLISHED';

echo "--- receive test syn ----------------- SEND SYN ACK\n";

echo sprintf("seq:%d, ack:%d\n", $fake_info['next_seq'], $fake_info['next_ack'] );

$g_send_socket->socket_send($fake_info['fake_ip'], $fake_info['fake_port'], $src_ip, $src_port,

$fake_info['next_seq'], $fake_info['next_ack'], $TCP_ACK,

'', null, null);

deal_delay_data( $fake_info );

return;

}else if( $status == 'ESTABLISHED' ){

echo "WARNING: receive dumplicated syn from test server.\n";

deal_delay_data( $fake_info );

return;

}

/*

log2( sprintf("line[%d],%s", __LINE__ , "WARNING: syn from test server, status not match:\nfake_info:" . json_encode( $fake_info )

. ";\nip_packet:" . json_encode($ip_packet)) );

packet_debug( $ip_packet );

*/

return;

}

if( is_after_or_equal( $ack_num, $fake_info['latest_ack'] ) ){

$fake_info['latest_ack'] = $ack_num;

}

// $fake_info['latest_ack'] = $ack_num;

//服务端返回数据.

if( $flag_ack

&& ! $flag_fin

&& ! $flag_rst

&& $tcp_data_len > 0 ){

// && is_before_or_equal( $ack_num, $fake_info['next_seq'] )// 过时的ack

// && is_before_or_equal( $seq_num, $fake_info['next_ack'] ) ){// 过时的seq

if( $seq_num == $fake_info['next_ack'] ){

update_next_ack( $fake_info, $tcp_data_len );

}

$g_send_socket->socket_send( $fake_info['fake_ip'], $fake_info['fake_port'], $src_ip, $src_port,

$fake_info['next_seq'], $fake_info['next_ack'], $TCP_ACK,

'', null, null);

deal_delay_data( $fake_info );

return;

}

// 测试服务器返回数据包无序, 返回数据包的ack_num可以比fake_info的seq小,因为fake_client 可以在没有收到ack的情况下继续发数据包.

if( $seq_num != $fake_info['next_ack'] ){

// echo ( sprintf("line[%d],%s", __LINE__ , "WARNING: receive unsorted packet from test server :\nfake_info:" . json_encode( $fake_info )

// . ";\nip_packet:" . json_encode($ip_packet)) );

deal_delay_data( $fake_info );

return;

}

// 收到FIN

if( $flag_fin ){

// fake client 被动关闭

if( $fake_info['state'] == 'ESTABLISHED' ){

$fake_info['state'] = 'CLOSE_WAIT';

//$fake_info['next_ack'] += (1 + $tcp_data_len);

update_next_ack( $fake_info, 1+$tcp_data_len );

$fake_info['state'] = 'LAST_ACK';

$g_send_socket->socket_send( $fake_info['fake_ip'], $fake_info['fake_port'], $src_ip, $src_port,

$fake_info['next_seq'], $fake_info['next_ack'], $TCP_FIN | $TCP_ACK,

'', null, null);

//$fake_info['next_seq']++;

update_next_seq( $fake_info, 1 );

return;

// fake client 主动关闭

} else if( $fake_info['state'] == 'TIME_WAIT' ) {

echo ("WARNING: receive FIN from test server, fake_info state is TIME_WAIT, " . json_encode( $fake_info )

. ";\nip_packet:" . json_encode($ip_packet) );

return;

// 同时关闭

}else if( $fake_info['state'] == 'FIN_WAIT_1'){

// $fake_info['next_ack'] += 1 + $tcp_data_len;

update_next_ack( $fake_info, 1+$tcp_data_len );

$g_send_socket->socket_send( $fake_info['fake_ip'], $fake_info['fake_port'], $src_ip, $src_port,

$fake_info['next_seq'], $fake_info['next_ack'], $TCP_ACK,

'', null, null);

$fake_info['state'] = 'CLOSING';

return;

// 主动关闭对方ACK 先于FIN到达

}else if( $fake_info['state'] == 'FIN_WAIT_2'){

//$fake_info['next_ack'] += 1 + $tcp_data_len;

update_next_ack( $fake_info, 1+$tcp_data_len );

$g_send_socket->socket_send( $fake_info['fake_ip'], $fake_info['fake_port'], $src_ip, $src_port,

$fake_info['next_seq'], $fake_info['next_ack'], $TCP_ACK,

'', null, null);

$fake_info['state'] = 'TIME_WAIT';

return;

}

log2( "WARNING: fin from test server, status not match, fake_info:" . json_encode( $fake_info ) );

packet_debug( $ip_packet );

return;

}

if( $flag_rst ){

$msg = "recv RST from test server";

log2( $msg );

return;

}

if( $flag_ack

&& ! $flag_fin

&& ! $flag_rst

&& in_array($status, array('FIN_WAIT_1', 'LAST_ACK', 'CLOSING'))

&& $tcp_data_len == 0 ){

// 主动关闭,收到FIN的ack.

if( $status == 'FIN_WAIT_1' ){

// echo "receive FIN_WAIT_1 ACK !!!!!!!!!!!!!!!!!!!!!!!!\n";

$fake_info['state'] = 'FIN_WAIT_2';

return;

}

// 被动关闭,收到FIN的ack.

if( $status == 'LAST_ACK' ){

$fake_info['state'] = 'CLOSED';

return;

}

// 同时关闭.

if( $status == 'CLOSING' ){

$fake_info['state'] = 'TIME_WAIT';

return;

}

}

if( $flag_ack

&& ! $flag_fin

&& ! $flag_rst

&& in_array($status , array( 'ESTABLISHED', 'TIME_WAIT', 'FIN_WAIT_2') )

&& $tcp_data_len == 0 ){

if( $ack_num <= $fake_info['next_seq'] ){

}else{

echo "Notice, receive test server ack num bigger than next_seq:\n" . "fake_info:" . json_encode( $fake_info )

. ";\nip_packet:" . json_encode($ip_packet) . "\n";

}

deal_delay_data( $fake_info );

return;

}

if( is_before( $seq_num, $fake_info['next_ack'] )

&& $tcp_data_len == 0

&& ! $flag_fin

&& ! $flag_rst ){

deal_delay_data( $fake_info );

return;

}

log2( sprintf("line[%d],%s", __LINE__ , "WARNING: can't deal packet from test server, status not match:\nfake_info:" . json_encode( $fake_info )

. ";\nip_packet:" . json_encode($ip_packet)) );

return;

}

function receive_real_request( & $ip_packet, $type = "" ){

global $g_real_map, $g_fake_map, $g_real_request_info, $g_fake_request_info;

global $g_remote_test_ip;

global $g_send_socket;

global $g_cur_version;

global $g_fake_port_indx;

$deal_real_time_request = true;

$deal_retry = false;

$TCP_SYN = 1<<1;

$TCP_ACK = 1<<4;

$TCP_PSH = 1<<3;

$TCP_FIN = 1;

if( strlen($type) > 0 ){

echo "Notice: " . $type . "\n";

$deal_real_time_request = false;

$deal_retry = true;

}

echo sprintf("DEBUG: %d : %d\n",

$deal_real_time_request, isset($ip_packet['cur_version']) ? $ip_packet['cur_version'] : -1);

$src_ip = $ip_packet['src_ip'];$src_port = $ip_packet['tcp']['src_port'];

$dest_ip = $ip_packet['dest_ip'];$dest_port = $ip_packet['tcp']['dest_port'];

$tcp_hdr = $ip_packet['tcp'];

$flag_syn = $tcp_hdr['SYN'];$flag_ack = $tcp_hdr['ACK'];

$flag_fin = $tcp_hdr['FIN'];$flag_rst = $tcp_hdr['RST'];

$seq_num = $tcp_hdr['seq_num'];$ack_num = $tcp_hdr['ack_num'];

$tcp_data = $tcp_hdr['tcp_data'];

$tcp_data_len = strlen( $tcp_data );

$flag_str = '';

if( $flag_ack ){ $flag_str .= "ACK"; }

if( $flag_syn ){ $flag_str .= "SYN"; }

if( $flag_fin ){ $flag_str .= "FIN"; }

if( $flag_rst ){ $flag_str .= "RST"; }

$ip_port_key = $src_ip . ":" . $src_port;

$cur = intval( microtime(true)*1000 );

// 建立连接

if( $flag_syn === true && $flag_ack === false ){

if( isset($g_real_map[ $ip_port_key ]) ){

$fake_info = & $g_real_map[ $ip_port_key ];

if( $fake_info['real_init_seq'] != $seq_num ){

$fake_ip_port_key = $fake_info['fake_ip'] .":" . $fake_info['fake_port'];

unset( $g_real_map[ $ip_port_key ] );

unset( $g_fake_map[ $fake_ip_port_key ] );

}else{

return;

}

}

echo "receive REAL_SYN ,ip_packet:" . json_encode($ip_packet) . "\n";

//$fake_ip = $src_ip;$fake_port = $src_port;

//$fake_ip = "11.11.11.11";

$fake_ip = "193.168.56.121";

$g_fake_port_indx ++;

if( $g_fake_port_indx > 60000 ){

$g_fake_port_indx = 20000;

}

$fake_port = $g_fake_port_indx;

$real_ip_port_key = $src_ip .":" . $src_port;

$fake_ip_port_key = $fake_ip .":" . $fake_port;

$g_fake_map[ $fake_ip_port_key ] = $g_fake_request_info;

$g_real_map[ $real_ip_port_key ] = & $g_fake_map[ $fake_ip_port_key ];

$fake_info = & $g_fake_map[ $fake_ip_port_key ];

$fake_info['real_ip'] = $src_ip;

$fake_info['real_port'] = $src_port;

$fake_info['fake_ip'] = $fake_ip;

$fake_info['fake_port'] = $fake_port;

$fake_info['real_next_seq'] = $seq_num + 1;

$fake_info['relative_seq'] = $fake_info['next_seq'] = $fake_info['init_seq'] = 0xffffffff;

$fake_info['relative_seq'] = $fake_info['next_seq'] = $fake_info['init_seq'] = $seq_num;

$fake_info['real_relative_seq'] = $fake_info['real_next_seq'] = $fake_info['real_init_seq'] = $seq_num;

$fake_info['state'] = 'INIT';

$fake_info['update_time'] = $cur;

// 发送syn数据包,建立连接.

/*

RawSocket::socket_send( $src_ip, $src_port, $dest_ip, $dest_port,

$seq_num, $ack_num, $tcp_flag,

$tcp_data,$timestamp, $ts_echo );

*/

$g_send_socket->socket_send( $fake_ip, $fake_port, $g_remote_test_ip, $dest_port,

$fake_info['next_seq'], 0, $TCP_SYN,

'', null, null);

$fake_info['state'] = 'SYN_SEND';

/*

$fake_info['next_seq'] += 1;

$fake_info['real_next_seq'] += 1;

*/

update_next_seq( $fake_info, 1 );

echo "### receive real syn ################## SEND SYN\n";

/*

var_dump( $fake_info );

var_dump( $g_remote_test_ip );

die( 0 );

*/

return;

}

$real_ip_port_key = $src_ip .":" . $src_port;

if( ! isset( $g_real_map[ $real_ip_port_key ] ) ){

echo "WARNING: real_ip_port_key, no fake_info, " . ", ip_packet:" . json_encode($ip_packet);

return;

}

$fake_info = & $g_real_map[ $real_ip_port_key ];

$fake_ip = $fake_info['fake_ip'];

$fake_port = $fake_info['fake_port'];

$real_offset =get_offset( $seq_num, $fake_info['real_next_seq'] );

if( $tcp_data_len > 0 || true ){

echo sprintf("DEBUG: type[$type], real_offset, data_len, flags, [ %d ][ %d ][ %s ]\n",

$real_offset, $tcp_data_len, $flag_str);

}

// fake client 处理较慢

//if( is_real_after($fake_info, $seq_num) && $tcp_data_len > 0 ){

if( $real_offset > 0 && $tcp_data_len > 0 ){

echo sprintf("NOTICE: test is slow, real_offset[%d], tcp_data_len[%d]\n", $real_offset, $tcp_data_len);

echo sprintf("line[%d], %s", __LINE__ , "ADD NEED DEAL DATA\n");

/*

$ip_packet['cur_version'] = $g_cur_version;

$fake_info['need_deal'][] = $ip_packet;

*/

add_need_deal_packet( $fake_info, $ip_packet, $deal_real_time_request );

if( $deal_real_time_request ){

echo "will deal_delay_data\n";

deal_delay_data( $fake_info );

}

return;

}

if( $real_offset < 0 ){

echo "REAL_OFFSET: real_offset: $real_offset\n";

echo sprintf("WARNING: real_offset < 0, ignore, tcp_data_len[%d]\n", $tcp_data_len);

echo "FAKE_INFO:" . json_encode( $fake_info ) . "\n";

echo "IP_PACKET:" . json_encode( $ip_packet ) . "\n";

// $fake_info['need_deal'][] = $ip_packet;

return;

}

if( $flag_fin ){

// return;

if( $tcp_data_len > 0 ){

echo "FATAL: fin packet with tcp_data_len > 0, ip_packet: " . json_encode( $ip_packet ) . "\n";

die( 255 );

}

if( $fake_info['state'] == 'ESTABLISHED'

&& $real_offset == 0 && is_after_or_equal($fake_info['latest_ack'], $fake_info['next_seq'])

&& $cur - $fake_info['update_time'] > 30 * 1000// 30s

){

$g_send_socket->socket_send( $fake_ip, $fake_port, $g_remote_test_ip, $dest_port,

$fake_info['next_seq'], $fake_info['next_ack'], $TCP_FIN | $TCP_ACK,

'', null, null);

$fake_info['state'] = 'FIN_WAIT_1';

// 更新next_seq, real_next_seq

update_next_seq( $fake_info, 1 );

echo "### receive real fin ################## SEND FIN\n";

return;

}else{

// return;

/*

$tmp = $fake_info;

$tmp['need_deal'] = count( $tmp['need_deal'] );

echo sprintf( "line[%d],%s", __LINE__ , "WARNING: receive FIN from real client, fake info state is not ESTABLISHED, fake_info:"

. json_encode( $tmp )

. ", ip_packet:" . json_encode($ip_packet) );

*/

add_need_deal_packet( $fake_info, $ip_packet, $deal_real_time_request );

if( $deal_real_time_request ){

echo "will deal_delay_data\n";

deal_delay_data( $fake_info );

}

return;

}

return;

}

if( $flag_rst ){

$msg = "WARNING, recv RST from real client";

log2( $msg );

return;

}

if( $flag_ack && $tcp_data_len > 0 ){

//if( $fake_info['state'] == 'ESTABLISHED' && is_after_or_equal($fake_info['latest_ack'], $fake_info['next_seq']) ){

if( $fake_info['state'] == 'ESTABLISHED' ){

echo "### receive real data ################## SEND DATA\n";

$g_send_socket->socket_send( $fake_ip, $fake_port, $g_remote_test_ip, $dest_port,

$fake_info['next_seq'], $fake_info['next_ack'], $TCP_ACK | $TCP_PSH,

$tcp_data, null, null);

$fake_info['send_data_len'] += $tcp_data_len;

$fake_info['send_data_count'] ++;

// 更新next_seq, real_next_seq

update_next_seq( $fake_info, $tcp_data_len );

if( isset($ip_packet['cur_version']) ){

echo "NOTICE: deal backup data success\n";

}

}else{

echo sprintf("line[%d], %s", __LINE__ , "ADD NEED DEAL DATA\n");

add_need_deal_packet( $fake_info, $ip_packet, $deal_real_time_request );

}

if( $deal_real_time_request ){

echo "will deal_delay_data 2\n";

deal_delay_data( $fake_info );

}

return;

}

if( $flag_ack

&& ! $flag_fin

&& ! $flag_rst

&& 0 == $tcp_data_len ){

echo "### receive real ack #################### IGNORE ACK\n";

return;

}

/*

log2( sprintf("line[%d],%s", __LINE__ , "WARNING: no default, receive packet from client, status not match, fake_info:"

. json_encode( $fake_info ) )

. ", ip_packet:" . json_encode($ip_packet) );

packet_debug( $ip_packet );

echo "\n";

*/

$tmp = $fake_info;

$tmp['need_deal'] = count( $tmp['need_deal'] );

echo sprintf( "WARNING, need die, line[%d],%s", __LINE__ , ", fake_info:"

. json_encode( $tmp )

. ", ip_packet:" . json_encode($ip_packet) . "\n" );

return;

return;

}

function log2( $msg ){

echo $msg . "\n";

echo "back_trace: " . json_encode( debug_backtrace() ) . "\n";

}

function packet_debug( $ip_packet ){

$src_ip = $ip_packet['src_ip'];$src_port = $ip_packet['tcp']['src_port'];

$dest_ip = $ip_packet['dest_ip'];$dest_port = $ip_packet['tcp']['dest_port'];

$tcp_hdr = $ip_packet['tcp'];

$flag_syn = $tcp_hdr['SYN'];$flag_ack = $tcp_hdr['ACK'];

$flag_fin = $tcp_hdr['FIN'];$flag_rst = $tcp_hdr['RST'];

$seq_num = $tcp_hdr['seq_num'];$ack_num = $tcp_hdr['ack_num'];

$tcp_data = $tcp_hdr['tcp_data'];

$ip_port_key = $src_ip . ":" . $src_port;$cur = time();

echo sprintf("read_raw_tcp: %s:%s --> %s:%s\n", $src_ip, $src_port, $dest_ip, $dest_port );

echo sprintf("\t: seq_num[%d], ack_num[%d], SYN:%d, ACK:%d, FIN:%d, RST:%d\n",

$tcp_hdr['seq_num'], $tcp_hdr['ack_num'],

$tcp_hdr['SYN'], $tcp_hdr['ACK'], $tcp_hdr['FIN'], $tcp_hdr['RST']);

}

$select_read = array( $s2, $s3 );

// $select_read = array( $s3 );

$mq_key = ftok( dirname(__FILE__), 'a');

$mq = msg_get_queue($mq_key, 0666);

msg_remove_queue( $mq );

$mq = msg_get_queue($mq_key, 0666);

$pid = pcntl_fork();

if( $pid == 0 ){

// tcpcopy进程,从mq里拿数据包,发送伪造请求报文 或 回复test server报文。

while( true ){

$ret = msg_receive($mq, 0, $message_type=1, 10240, $m, true, MSG_IPC_NOWAIT);

if( $ret == false ){

crontab_task( );

continue;

}

$ip_packet = json_decode( $m, true );

switch( $ip_packet['from'] ){

case 'read_raw':

receive_real_request( $ip_packet );

break;

case 'send_raw':

// echo "need send_raw\n";

break;

case 'read_udp':

// receive_test_server_packet

receive_test_server_request( $ip_packet );

break;

default:

echo "NOTICE:error\n";

break;

}

}

}else{

// 抓包进程,单纯从socket接收IP报文,防止进程过慢而丢包.

$need_send = array();

while( true ){

$need_read = $select_read;

$select_ret = socket_select( $need_read, $need_write = null, $expect, 1, 0 );

if( false === $select_ret ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

continue;

}

if( $select_ret < 1 ){

// echo "no need read\n";

continue;

}

// echo "after select\n";

// echo "need_read:\n";

if( is_array($need_read) && count($need_read) > 0 ){

foreach( $need_read as $s ){

$type = $socket_map[ (string)$s ]['type'];

$obj = $socket_map[ (string)$s ]['obj'];

switch( $type ){

case 'read_raw':

// echo "need_read_raw\n";

$read_ret = $obj->socket_read_raw( );

if( $read_ret === false || null === $read_ret ){

continue;

// echo json_encode( $read_ret ) . "\n\n";

}else{

// echo json_encode( $read_ret ) . "\n\n";

}

// receive_real_packet

// receive_real_request( $read_ret );

$ip_packet = & $read_ret;

$ip_packet['from'] = 'read_raw';

// $ret = msg_send($mq, 1, json_encode( $ip_packet), true, false, $msg_err );

$need_send[] = $ip_packet;

break;

case 'send_raw':

// echo "need send_raw\n";

break;

case 'read_udp':

// echo "need read udp --------------------- read udp packet\n";

$read_ret = $obj->socket_read_udp( );

if( $read_ret === false || null === $read_ret ){

continue;

}else{

// echo json_encode( $read_ret ) . "\n\n";

}

// receive_test_server_packet

// receive_test_server_request( $read_ret );

$ip_packet = & $read_ret;

$ip_packet['from'] = 'read_udp';

// $ret = msg_send($mq, 1, json_encode( $ip_packet), true, false, $msg_err );

$need_send[] = $ip_packet;

break;

default:

echo "NOTICE:error\n";

break;

}

if( false && $ret == false ){

$mq_stat = msg_stat_queue( $mq );

echo "NOTICE:" . $mq_stat['msg_qnum'] . "\n";

echo "FATAL: msg_send_ret false\n";

var_dump( $msg_err );

//die( "FATAL: msg_send_error" );

$need_send[] = $ip_packet;

}

}//foreach

}//if

$mq_stat = msg_stat_queue( $mq );

if( $mq_stat['msg_qnum'] > 100 ){

continue;

}

if( count($need_send) > 0 ){

foreach( $need_send as $k => $ip_packet ){

$ret = msg_send($mq, 1, json_encode( $ip_packet), true, false, $msg_err );

if( $ret ==true ){

unset( $need_send[$k] );

$mq_stat = msg_stat_queue( $mq );

if( $mq_stat['msg_qnum'] > 100 ){

break;

}

}else{

break;

}

}

}

}//while

die( 0 );

}

while( true ){

$need_read = $select_read;

$select_ret = socket_select( $need_read, $need_write = null, $expect, 1, 0 );

if( false === $select_ret ){

echo "socket_last_error_str:" . socket_strerror(socket_last_error()) . "\n";

continue;

}

if( $select_ret < 1 ){

// echo "no need read\n";

continue;

}

// echo "after select\n";

// echo "need_read:\n";

if( is_array($need_read) && count($need_read) > 0 ){

foreach( $need_read as $s ){

$type = $socket_map[ (string)$s ]['type'];

$obj = $socket_map[ (string)$s ]['obj'];

switch( $type ){

case 'read_raw':

// echo "need_read_raw\n";

$read_ret = $obj->socket_read_raw( );

if( $read_ret === false || null === $read_ret ){

continue;

// echo json_encode( $read_ret ) . "\n\n";

}else{

// echo json_encode( $read_ret ) . "\n\n";

}

// receive_real_packet

receive_real_request( $read_ret );

break;

case 'send_raw':

// echo "need send_raw\n";

break;

case 'read_udp':

// echo "need read udp --------------------- read udp packet\n";

$read_ret = $obj->socket_read_udp( );

if( $read_ret === false || null === $read_ret ){

continue;

}else{

// echo json_encode( $read_ret ) . "\n\n";

}

// receive_test_server_packet

receive_test_server_request( $read_ret );

break;

default:

echo "NOTICE:error\n";

break;

}

}

}

}

die( 0 );

function get_asc( $str ){

echo "get_asc:\n";

$arr = str_split( $str,1 );

foreach( $arr as $v ){

echo ord( $v ) . "," . bin2hex($v) . "\n";

}

echo "\n";

}

function str2int( $str, $size=4 ){

$ret = 0;

for( $i=0; $i

2. intercept.py

抓到测试服务器返回的数据,将其发送到tcpcopy进程。

#!/usr/bin/python

import socket

import struct

import binascii

remote_addr = ("192.168.56.101", 20000)

address=('localhost',20000)

udp_s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

#udp_s.bind( address )

#print udp_s.getsockname()

s=socket.socket(socket.PF_PACKET,socket.SOCK_RAW,socket.htons(0x0800))

while True:

pkt = s.recvfrom(65532)

#print pkt[1]

ethernetHeader=pkt[0][0:14]

eth_hdr = struct.unpack("!6s6s2s",ethernetHeader)

#print eth_hdr

eth_hdr2 = struct.unpack("!6s6sH",ethernetHeader)

if( eth_hdr2[2] != 0x0800 ):

continue

print 'IP:'

print len(pkt[0])

ipHeader = pkt[0][14:34]

ip_hdr = struct.unpack("!12s4s4s",ipHeader)

#ip_header_len = 4* (ord(ip_hdr[0][0]) & 0xf)

ip_header_len = (struct.unpack("!1B11x", ip_hdr[0])[0] & 0x0f) << 2;

print ip_header_len

ip_packet_len = (struct.unpack("!2xH8x", ip_hdr[0])[0] & 0xffff);

print ip_packet_len;

proto = struct.unpack("!9x1B2x", ip_hdr[0])[0]

if proto != 0x06:

continue;

print proto

proto_map={1:"ICMP", 2:"IGMP", 6:"TCP", 17:"UDP", 89:"OSPF" }

print proto_map[proto]

print ip_header_len

print ip_packet_len

tcp_packet = pkt[0][14+ip_header_len:14+ip_packet_len]

print len(tcp_packet)

tcp_header = tcp_packet[0:20]

tcp_hdr_len = 4*(struct.unpack("!12x1H6x", tcp_header)[0] >> 12)

print tcp_hdr_len

ip_tcp_header = pkt[0][14:14+ip_header_len+tcp_hdr_len]

print len(ip_tcp_header)

print "real_len:%d, ip:%d, tcp:%d" % ((ip_header_len + tcp_hdr_len), ip_header_len, tcp_hdr_len )

print remote_addr

ret = udp_s.sendto( ip_tcp_header, remote_addr )

print ret

print "Source IP address:"+socket.inet_ntoa(ip_hdr[1])

print "Destination IP address:"+socket.inet_ntoa(ip_hdr[2])

# tcpHeader = pkt[0][34:54]

# tcp_hdr = struct.unpack("!HH16s",tcpHeader)

3. 环境设置:

1). 环境介绍:

101: centos4, online server.

104: centos5, fake router.

102: centos4-1, test server.

103: centos4-2, real client.

2). 102设置路由:

route add -host 193.168.56.121 gw 192.168.56.104

4. 注意:

104 上禁用 ICMP redirects。

原本想用PHP写raw socket玩玩的,原来看过tcpcopy代码,用php写了个试试,没想还跑通了...

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

http://www.wooajung.com/news/34329.html

相关文章:

  • 高端网网站建设个人开发app可以上架吗
  • 手机怎做网站磁力bt种子搜索
  • 成都seo网站开发免费seo排名网站
  • 做邀请函的网站江苏seo外包
  • 自己怎么做外贸网站空间百度移动权重
  • 企业建设网站公司有哪些免费的行情网站app
  • 猎头公司电话南宁正规的seo费用
  • 北京建设规划委员会网站seo营销推广多少钱
  • 南通装饰网站建设网页设计与制作代码成品
  • 做网站哪家公司好苏州全国防疫大数据平台
  • 北京网站建设公司资讯自己做网站
  • 怎么做国际网站949公社招聘信息
  • 苏州汇聚人电子科技有限公司如何优化搜索引擎的搜索功能
  • 扬州做机床公司网站百度的特点和优势
  • 免费虚拟主机vps陕西seo推广
  • 网站日记在哪里看产品宣传方案
  • 供应链金融网站开发seo快速优化文章排名
  • 天津如何做百度的网站互联网销售
  • 建设银行网站logo郑州怎么优化网站排名靠前
  • 企业的网站一般做哪些维护最经典最常用的网站推广方式
  • 专业科技网站建设网络营销的营销策略
  • 做受免费网站天津seo霸屏
  • 公司网站如何上传视频优化手机性能的软件
  • 外国做动漫图片的网站叫什么网站排名优化推广
  • 企业内部管理网站建设计划网站优化推广外包
  • 那家财经网站做的好网站域名解析
  • ipv6改造网站怎么做站长平台官网
  • 做外贸 网站没有邮箱怎么找怎样推广自己的商城
  • 男女做性哪个的小视频网站国内推广平台
  • 做ppt一般在什么网站bing搜索