Why is the ACK flag in a tcpdump represented as a period "." instead of an "A"? - tcpdump

This is the output of the three way handshake of a TCP connection:
23:40:36.011400 IP 10.1.1.11.44733 > 73.5.9.44.80: Flags [S], seq 106492654, win 64240, optio0
23:40:36.013994 IP 73.5.9.44.80 > 10.1.1.11.44733: Flags [S.], seq 712839050, ack 106492655, 0
23:40:36.014026 IP 10.1.1.11.44733 > 73.5.9.44.80: Flags [.], ack 1, win 502, options [nop,no0
Inside the brackets are the flags for each packet: [S] [S.] [.]
The man page for tcpdump describes these values:
The general format of a TCP protocol line is:
src > dst: Flags [tcpflags], seq data-seqno, ack ackno, win window,
urg urgent, options [opts], length len
Src and dst are the source and destination IP addresses and ports.
Tcpflags are some combination of S (SYN), F (FIN), P (PUSH), R (RST),
U (URG), W (ECN CWR), E (ECN-Echo) or '.' (ACK), or 'none' if no flags
are set
Why is the ACK flag represented by a period (.) instead of an A?
Some googling lead me to this:
https://github.com/the-tcpdump-group/tcpdump/issues/319
Which implies the reason for not using an A is described here:
http://article.gmane.org/gmane.network.tcpdump.devel/6383
But this link has been giving me a 522 error =/

Related

using expect to send a single byte

Have a tcl expect connection to a telnetd and want to send the telnet BREAK.
There for the telnetd must be informend to go into command mode. So the IAC (255) hast to be sende.
After this BRK(243) has to be send.
I verifyed this with a putty->telnetd connection. Putty can send "BREAK". The network traffic shows what is expected 255/243
When I send ICA(255)/BRK(243) with tcl expect I see in the network traffic, that three bytes (255/255/243) were send.
I found out when I send i.e. 254 I see one byte
When I send 255. It is two bytes.
I expect 255, which is -1 or ff has someting special in expect.
How can I achive to get just 255 onto the wire?
fconfigure $channel -translation
exp_send -i $channel -- [binary format H4 FFF3]
This sends "ff ff f3" to the telnetd
As mention in the responce, yes, the language has to be taken into account. So I add fconfigure to have none
Here is my code:
package require Expect
spawn telnet localhost
fconfigure $spawn_id -translation binary
exp_send "[binary format H4 FFf3]"
after 2000
When I look on the wire with tcpdump -X -i localhost port 23 I see FFFFF3.
11:26:10.358187 IP localhost.44802 > localhost.telnet: Flags [P.], seq 129:132, ack 148, win 342, options [nop,nop,TS val 1826173122 ecr 1826168178], length 3
0x0000: 4510 0037 835b 4000 4006 b953 7f00 0001 E..7.[#.#..S....
0x0010: 7f00 0001 af02 0017 b004 9eec f815 49e3 ..............I.
0x0020: 8018 0156 fe2b 0000 0101 080a 6cd9 30c2 ...V.+......l.0.
0x0030: 6cd9 1d72 ffff f3
I look into telnet with strace and see:
203 27482 12:37:28 read(0, "\377\363", 8192) = 2
204 27482 12:37:28 select(4, [0 3], [3], [3], {0, 0}) = 1 (out [3], left {0, 0})
205 27482 12:37:28 sendto(3, "\377\377\363", 3, 0, NULL, 0) = 3
fff3 is received by expect, ff ff f3 is send to the telnetd.
I was totally wrong with my toughts.
Because I use "telnet" spawned within expect, I have to send "CTRL]" "send brk\r".
And everything is fine.

Understand tcpdump output for RTCP RR and SR

Can somebody explain the SR/RR parts of this tcpdump output?
Example: tcpdump -n udp -x port 5091 and less 129 -T rtcp
16:58:15.034159 IP 1.2.3.4.5091 > 10.2.3.4.45041: sr #3665059093.56 3025985984 1003p 160480b 3l 1012s 12j #23811.54+1.80 sdes 12
16:58:23.753766 IP 1.2.3.4.5091 > 10.2.3.4.45041: rr 5l 1446s 24j #23820.57+1.49 bye 8
Thanks!
I found the information here
I believe the values (e.g. packet loss) will be seen as "missing" if 0.
Adding -vvv for further verbose and you get something along the lines of:
sr 608743728 #3665062971.29 3057007839 124p 19840b 458089647 2l 135s 7j #0.00+0.00 sdes 12 608743728
Which will be
rtcp_type;ssrc_sender;ntp_timestamp_reference;media_timestamp_reference;num_packets_sent;num_bytes_sent;ssrc_source;packet_loss;ext_last_seq_recieved;jitter;some_ts;no_bytes_of_source_desc;ssrc_sender

When trying to change http header using nf_hook .Unable to send ack to a response instead sending tcp retransmission packets

Aim:- Writing a kernel module,when inserted does the following things.
1.if a user wants to open a website named "abcde.in" in any browser ,he should get "google.co.in" webpage, in place of "abcde.in" web page.
Normally accessing google.in i get:-
Observation..(in http header)
302 Moved
The document has moved
HREF=http://www.google.co.in
:-) next i send an ack And i got the google homepage:-
With Modification:-
Steps i have taken
a. edited /etc/hosts
(google.in IP ) abcde.in
So that it gets ip of "google.in"'s for "abcde.in"
b.Next inserting the following piece of module in nf_hook POST_ROUTING implementation
Observation..
i am able to correctly modify and wireshark shows that in reply i am able to get 302 Moved
But i am sending Tcp retransmissions GET / HTTP/1.1. again and again.
I feel i am missing the ack which i need to send as in original case.
why am i unable to send an ack instead of that why i am retransmitting tcp packets to "GET / HTTP/1.1"
if(skb){
liph=(struct iphdr *)skb_network_header(skb);
if(liph->protocol == 6) {
ltcph = (struct tcphdr *)skb_transport_header(skb);
data=skb->data+(liph->ihl*4) + (ltcph->doff*4);
datalen=skb->len - ((liph->ihl*4)+(ltcph->doff*4));
replace_n=strstr(data,"abcde.in");
if(replace_n) {
temp = kmalloc(512 * sizeof(char), GFP_KERNEL);
memcpy(temp, data, datalen);
replace_n=strstr(temp,"abcde.in");
replace_size=strlen("google.in");
site_diff=replace_size - strlen("abcde.in");
memmove(replace_n+strlen("abcde.in")+site_diff,replace_n+strlen("abcde.in"),strlen(replace_n)-strlen("abcde.in"));
memcpy(replace_n,"google.in",strlen("google.in"));
skb_put(skb,site_diff);
memcpy(data,temp,datalen+site_diff);
liph->tot_len=htons(datalen+site_diff+20+(ltcph->doff*4)); /*modifing necessary fields*/
liph->check=0;
liph->check=ip_fast_csum((unsigned char *)liph,liph->ihl);
int ipl=liph->ihl * 4;
int ihl=ntohs(liph->tot_len);
ltcph->check = 0;
skb->csum = csum_partial(ltcph, ihl - ipl, 0);
ltcph->check = tcp_v4_check(ihl - ipl,liph->saddr, liph->daddr, skb->csum);
skb->ip_summed = CHECKSUM_NONE;
Retransmission tck packet wireshark capture

IP database from ip2location and convert IPV4 to IPV6 in Perl

I am trying to use IP to country database from ip2location.
My question is, does the IPV6 database files already contains the IPV4 address embedded
or do I have to use both IPV4 and IPV6 databases to cover all the IP Ranges for the internet
for all versions.
What I mean if I want to support both IPV4 and IPV6 I should load both database files
into the same mysql table or should I just use IPV6.
I am talking about the file IP2LOCATION-LITE-DB11.CSV.ZIP and IP2LOCATION-LITE-DB11.IPV6.CSV.ZIP
I am answering my own question after two days of search and testing. The IPV4 can be embedded in IPV6 and this file IP2LOCATION-LITE-DB11.IPV6.CSV.ZIP contains the IPV4 embedded as IPV6 and all IPs are stored as decimal(39, 0).
The trick I used here to use the IPV6 database file for both versions of IP's IPV4 and IPV6 is to convert the IPV4 address when searching the database to IPV6 then to Integer and do the search normal. This way your application supports both IPV4 and IPV6.
To convert IPV4 to IPV6, this wiki article is the answer:
http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses
IPv4-mapped IPv6 addresses
Hybrid dual-stack IPv6/IPv4 implementations recognize a special class of addresses,
the IPv4-mapped IPv6 addresses. In these addresses, the first 80 bits are zero, the
next 16 bits are one, and the remaining 32 bits are the IPv4 address. One may see these
addresses with the first 96 bits written in the standard IPv6 format, and the
remaining 32 bits written in the customary dot-decimal notation of IPv4. For example,
::ffff:192.0.2.128 represents the IPv4 address 192.0.2.128. A deprecated format for
IPv4-compatible IPv6 addresses was ::192.0.2.128
and this article also good on this issue:
IPv6/IPv4 Address Embedding
All you need to do is prepend the IP with ::ffff: so the IP address 192.0.2.128 will be ::ffff:192.0.2.128 as valid IPV6.
The next step is to convert your IP either IPV4 or IPV6 to Decimail (39,0) and you can now search the database normal.
Since I use Perl, here are some helping code for testing and clearing.
use Net::IP ':PROC';
# IPV4 address
my $ipaddress = '197.36.107.146';
my $ip = new Net::IP ($ipaddress) or die (Net::IP::Error());
print ("IPV4 : ".$ip->ip()."\n");
print ("IPV4 Integer : ".$ip->intip()."\n");
print ("Version : ".$ip->version()."\n");
print ("Size: ".$ip->size()."\n");
print ("Len : ".$ip->prefixlen()."\n");
print ("Type: ".$ip->iptype()."\n");
print "\n";
# Convert IPV4 to IPV6. Just prepend ipv4 with '::ffff:'
my $ip = new Net::IP ("::ffff:".$ipaddress) or die (Net::IP::Error());
print ("IPV6 : ".$ip->ip()."\n");
print ("IPV6 Integer : ".$ip->intip()."\n");
print ("Version : ".$ip->version()."\n");
print ("Size: ".$ip->size()."\n");
print ("Len : ".$ip->prefixlen()."\n");
print ("Type: ".$ip->iptype()."\n");
print "\n";
# detect the user ip address and convert it
my $user_ip = get_user_ip();
$user_ip ||= $ipaddress; # just for testing on command line
print "Detected User IP address: $user_ip\n";
# if user remote address is IPV4 convert it to IPV6
if ($user_ip =~ /\./) {
# Convert IPV4 to IPV6
$user_ip = Net::IP->new("::ffff:$user_ip");
# Now convert it to Integer
$user_ip = $user_ip->intip();
}
else {
# Already IPV6, just convert to Integer
$user_ip = Net::IP->new($user_ip);
$user_ip = $user_ip->intip();
}
print "User IP address in IPV6 format: $user_ip\n";
#----------------------------------
# Now you can search the geo database with IPV4 and IPV6 stored as decimails
# select * from ip_country where $ipaddress<=ip_to limit 1
#----------------------------------
sub get_user_ip {
foreach (qw(REMOTE_ADDR HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR HTTP_X_FORWARDED HTTP_X_CLUSTER_CLIENT_IP
HTTP_FORWARDED_FOR HTTP_FORWARDED)) {
if ($ENV{$_}) {
return $ENV{$_};
}
}
}
and this is the output of this testing code:
IPV4 : 197.36.107.146
IPV4 Integer : 3307498386
Version : 4
Size: 1
Len : 32
Type: PUBLIC
IPV6 : 0000:0000:0000:0000:0000:ffff:c524:6b92
IPV6 Integer : 281473989241746
Version : 6
Size: 1
Len : 128
Type: IPV4MAP
Detected User IP address: 197.36.107.146
User IP address in IPV6 format: 281473989241746
Searching the database until now shows everything working normal.

How to split Erlang binary in special length?

I open one udp socket and want to split the binary packet I received to every 10 bytes. Is there any api or good method ? thanks!
Here is one way to do it:
split(Bin, LenPart) ->
lists:reverse(split1(Bin, LenPart, [])).
split1(Bin, LenPart, Acc) when byte_size(Bin) =< LenPart ->
[Bin | Acc];
split1(Bin, LenPart, Acc) ->
<<Part:LenPart/binary, Rest/binary>> = Bin,
split1(Rest, LenPart, [Part | Acc]).