I have questions related to socket programming.
I don't have computer education background and all of what i got are from informal education, that's why sometimes i think i am able to answer these questions but sometimes i am still a bit doubt it, i am just not sure about my own answer (so that your answer is needed to strengthen my confidence).
What's the difference between SOCK_RAW and SOCK_STREAM ?
well, from mixter, they said something like this :
"The basic concept of low level sockets is to send a single packet at one a time, with all protocol headers filled in by the program (instead of the kernel)".
Is that the definition of socket raw ? I am not sure, i am afraid i misinterpreted that statement, so what's socket raw ? here's my own definition of sock raw, its like :
1. Well, with sock raw we can send single packet to destination, it isnt like SOCK_STREAM, with SOCK_STREAM we must follow the rule of 3 ways handshakes. that's mean we must send packet with tcp flags set to SYN at the first time we want to connect to the destination, and then we'll received ACK (and SYN) from destination, then we send another (packet) SYN+ACK to destination and then the connection is established.
2. With Socket Raw, we can build header of the packet whatever we want packet header looks like, i mean we can send packet and set tcp flag to FIN to destination at the first time we want to connect, or we can set it to ACK (3 way handshakes said 'we must set it to SYN at the first time)
3. From point #2, we can say that SOCK RAW give us more control to build the packet header.
What do you think ?
How about ICMP, ICMP using Socket Raw ?
I was keep my thinking that ICMP is using port (like someone else said in sans forum), and that's wrong, ICMP isn't using PORT to communicate, but how about this code :
my $ip = inet_aton('192.168.0.1'); my $saddr = sockaddr_in(0,$ip);
ICMP using Port 0 ? i don't think so, maybe 0 in that code means "there's no port", right ?
ICMP using Socket Raw ? yes, why ? we can see 'SOCK_RAW' in the following code :
Too bad i dont have better answer for this question, how about you ?socket(SOCK,PF_INET,SOCK_RAW,getprotobyname('icmp');
Where's the position of ICMP in TCP/IP layer ?
When IP is in OSI layer 3, TCP is in OSI layer 3 where's ICMP at ?
When IP is using UDP/TCP to send packet, how about ICMP ? (ICMP's not using port)
By the way i built this code below, And you can see my questions inside the code. I know there's Net::Ping and Net::RawIP and sure i'll use these modules after my understanding about TCP/IP is better. I build this code without these modules is because i can understand better about TCP/IP than i use modules in my code (it's like i can understand better how the packet is constructed, etc).
use strict; use Socket; #use FileHandle; my $ICMP_PORT = 0; #ICMP, no port ! my $ICMP_FLAGS = 0; #No special flag my $ICMP_SUBCODE = 0; my $SEQ = 1; #cuz we're going to send single packet my $pid = $$ & 0xffff; #get the PID my $checksum = 0; #starter if(!defined $ARGV[0] || !defined $ARGV[1] || !defined $ARGV[2]) { usag +e(); } my $ip = inet_aton($ARGV[0]); length($ip) or die "$ARGV[0] is not valid or $ARGV[0] is Unreachable\n +"; my $time_out = 10; if(defined $ARGV[3] && defined $ARGV[4]) { die "Unknown options $ARGV[3] - You should try with -t \n" if ($ARGV +[3] ne "-t") ; $time_out = $ARGV[4]; } socket(SOCK,PF_INET,SOCK_RAW,getprotobyname('icmp')) || die "Can not c +reate socket $! \n"; my $saddr = sockaddr_in($ICMP_PORT,$ip); if(defined $ARGV[1]) { if($ARGV[2] eq 'ec') { print "send icmp echo request \n"; ping_icmp_echo_req(); } elsif($ARGV[2] eq 'ts') { print "send timestamp request \n"; ping_icmp_timestamp_req(); } elsif($ARGV[2] eq 'in') { print "send information request \n"; ping_icmp_information_req(); } elsif($ARGV[2] eq 'am') { print "send address mask request \n"; ping_icmp_addressmask_req(); } else { print "unknown request type \n"; kill_sock(); exit(1); } } else { usage(); kill_sock(); } sub ping_icmp_echo_req { my $msg = pack("C2 n3",8,0,$checksum,$pid,$SEQ); #someone said i must pack the minimum of icmp packet #with this -> "C2 S3", but it's work with "C2" n3", #what do you think ? $checksum = checksum($msg); $msg = pack("C2 n3",8,0,$checksum,$pid,$SEQ); send(SOCK,$msg,$ICMP_FLAGS,$saddr) || die "error sending : $! \n"; #$socket->autoflush(1); #im not sure to add this line to this code, any advices ? my $buff = timing(); my($icmp_type, $icmp_subcode,$icmp_cksum,$icmp_pid,$icmp_seq) = unpa +ck("C2 n3",substr($buff,20,8)); alive($icmp_type); kill_sock(); } sub ping_icmp_timestamp_req { my $msg = pack("C2 n3 N3",13,$ICMP_SUBCODE,$checksum,$pid,$SEQ,0,0,0 +); $checksum = checksum($msg); $msg = pack("C2 n3 N3",13,$ICMP_SUBCODE,$checksum,$pid,$SEQ,0,0,0); send(SOCK,$msg,$ICMP_FLAGS,$saddr); #SOCK->autoflush(1); #hmmm ? my $buff = timing(); my($icmp_type,$icmp_subcode) = unpack("C2",substr($buff,20,2)) ; alive($icmp_type); kill_sock(); } sub ping_icmp_information_req { my $ICMP_STRUCT_INFORM = "C2 n3 N"; my $ICMP_INFORM_REQ = 15; my $ICMP_INFORM_REPLY = 16; #echo req code my $msg = pack("C2 n3 N",15,$ICMP_SUBCODE,$checksum,$pid,$SEQ,0); $checksum = checksum($msg); $msg = pack("C2 n3 N",15,$ICMP_SUBCODE,$checksum,$pid,$SEQ,0); send(SOCK,$msg,$ICMP_FLAGS,$saddr) || die "error sending : $! \n"; #$socket->autoflush(1); #im not sure to add this line to this code, +any advices ? my $buff= timing(); my($icmp_type, $icmp_subcode) = unpack("C2",substr($buff,20,2)); kill_sock(); } sub ping_icmp_addressmask_req { my $msg = pack("C2 n3 N",17,$ICMP_SUBCODE,$checksum,$pid,$SEQ,0); $checksum = checksum($msg); $msg = pack("C2 n3 N",17,$ICMP_SUBCODE,$checksum,$pid,$SEQ,0); send(SOCK,$msg,$ICMP_FLAGS,$saddr) || die "error sending : $! \n"; #$socket->autoflush(1); my $buff = timing(); my($icmp_type, $icmp_subcode) = unpack("C2 n3 N",substr($buff,20,2)) +; alive($icmp_type); kill_sock(); } sub alive { my ($type) = @_; # 0 = icmp echo reply, # 14 = icmp timestamp reply # 16 = icmp infoemation reply # 18 = icmp address mask reply if($type == 0) { print "Received ICMP echo reply from $ARGV[0], aliv +e ! \n" } elsif($type == 14) { print "Received ICMP timestamp reply from $ARGV +[0], alive ! \n" } elsif($type == 16) { print "Received ICMP information reply from $AR +GV[0], alive ! \n"} elsif($type == 18) { print "Received ICMP address mask reply from $A +RGV[0], alive ! \n"} else { print "I never expect to received this kind of ICMP reply, Uk +nown type ! \n" } } sub kill_sock { close(SOCK) || warn "Can not close socket $! \n"; } sub timing { my $buff=""; print "time out set to $time_out\n"; $SIG{ALRM} = sub { die "TIMED OUT \n" }; eval { alarm($time_out); recv(SOCK,$buff,1500,$ICMP_FLAGS); alarm(0); }; kill_sock() if (length($buff) == 0); die "timed out \n" if (length($buff) == 0); return $buff; } sub checksum { my ($msg) = @_; my ($len_msg, $num_short, $short, $chk); $len_msg = length($msg); $num_short = int($len_msg / 2); $chk = 0; foreach $short (unpack("n$num_short", $msg)){ $chk += $short; } $chk += (unpack("C", substr($msg, $len_msg - 1, 1)) << 8) if $len_ms +g % 2; $chk = ($chk >> 16) + ($chk & 0xffff); # Fold high into low return(~(($chk >> 16) + $chk) & 0xffff); # Again and complement } sub usage { print "Usage $0 : <host ip> -c <request type[ec/ts/in/am]> -t <timeo +ut>\n"; exit(1); }
and one thing, my question is :
1. When we need to use setsockopt function, actually what is it ? setsockopt's used only in server side ?
Thanks for your answer, and i hope you'll understand my 'limited' english.
i have a lots questions about socket programming and Perl, too bad i just cant translate it to proper english..
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |