unable to set windows server 2019 MTU from Ubuntu by ICMP fragmentaion - networking

I'm trying to set PMTU for windows server 2019(B) on ubuntu 20.0.4(A). In order to
check whether the set succeeds, I need to make the size of packet sent from B to A bigger
than the set PMTU(1300) but less than default PMTU(1500). I know that something like
'verify ping' will make the size of outbound packet same as inbound packet. So I can
send a packet with size 1400 with DF set and check whether the response is
fragmented to make sure the setting is successful. However, I
don't know the official name of it and how to create it with scapy.
OK, I figured that out. PING is enough for that. However, I can't set the MTU for windows server 2019 by scapy. This is the code I used in Ubuntu
import scapy.all as scapy
sip = '192.168.100.4'
dip = '192.168.100.5'
ip = scapy.IP()
icmp = scapy.ICMP()
ip.dst = dip
ip.src = sip
ip.protocol = 1 # ICMP
icmp.type = 3 # Destination Unreachable
# set ICMP code Fragmentation needed but DF set 4
icmp.code = 4 # Fragmentation needed
mtu = 1300
icmp.unused = mtu
# Construct the Inner IP embedded into the ICMP error message to simulate
# the packet which caused the ICMP error
ip_orig = scapy.IP()
# ip_orig.src = '10.10.10.2'
# ip_orig.dst = '10.10.10.1'
ip_orig.src = '192.168.100.5'
ip_orig.dst = '192.168.100.4'
udp_orig = scapy.UDP()
udp_orig.sport = 50000
udp_orig.dport = 50000
udp_orig1 = scapy.UDP()
udp_orig1.sport = 53
udp_orig1.dport = 631
# Send the packet
udp_orig.dport = 631
udp_orig.sport = 88
# scapy.send(ip/udp_orig)
scapy.send (ip/icmp/ip_orig/udp_orig1)
After run it, the PING sent back is still with length 1514.

Related

mariadb cluster synced but one node shows size=0

I use mariadb 10.5 with galera 4. I have a 3 node cluster which worked perfectly for the past 6 months. Lately I have been having problems with very cpu intensive query and had to kill that process. One of the nodes (n1) went out of sync so I recreated it. Everything synced perfectly but since that day n1 shows wsrep_cluster_size=0 and the rest of them show wsrep_cluster_size=3.
After a couple of days I decided to stop n2 and n3 to recreate it from n1. Again everything went smoothly but now n3 shows wsrep_cluster_size=0 and n1,n2 show wsrep_cluster_size=3.
I have no idea what's going on. I've checked all the logs and manually checked all the tables and everything seems ok. Data is synced and database is working just fine.
Heres is my configuration
[mysqld]
binlog_format = ROW
bind-address = 0.0.0.0
# Galera Provider Configuration
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
# Galera Cluster Configuration
wsrep_cluster_name = cluser
wsrep_cluster_address = gcomm://10.0.0.2,10.0.0.3,10.0.0.4
wsrep_node_address = 10.0.0.2
wsrep_node_name = n1
# Galera Synchronization Configuration
wsrep_sst_method = rsync
log_error = /var/lib/mysql/node.log
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_locks_unsafe_for_binlog = 1
innodb_file_per_table = 1
#innodb_thread_concurrency = 0
innodb_buffer_pool_size = 10G
#innodb_log_buffer_size = 64M
innodb_flush_method = O_DIRECT
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
wsrep_slave_threads = 5
innodb_locks_unsafe_for_binlog = 1
innodb_autoinc_lock_mode = 2
skip-name-resolve
lc-messages-dir = /usr/share/mysql
skip-external-locking
key_buffer_size = 16M
max_connections = 300
wait_timeout = 20
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
# * Query Cache Configuration
#
query_cache_limit = 1M
query_cache_size = 16M
expire_logs_days = 10
max_binlog_size = 100M
Here is my SHOW STATUS LIKE 'wsrep%' for 3 nodes
https://pastebin.com/GXj0c38R
And logs
https://pastebin.com/YxJBcguK
This is definitely a bug. Please report it on MariaDB JIRA.
In addition to the wsrep_cluster_size=0 on n3, wsrep_cluster_conf_id is uninitialised (and not the 23 like other nodes) and wsrep_cluster_state_uuid is blank.
For a synced node I'd expect these to have consistent values on all nodes.

Malformed IP Scapy

My goal is to develop a script that can send IP packets to any host to any other host in a different subnet. Right now everything is seemingly working, except my IP packet is malformed so scapy cannot send it.
def sendIPMessage(interfaceName, dst_ip, routerIP, message):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", port))
src_addr = get_mac_address(interface=interfaceName)
my_ip = get_ip_address(interfaceName)
netmask = ipaddress.ip_address(dst_ip) in ipaddress.ip_network(my_ip)
if netmask is True: # if dst is in the same network
arp_MAC = sendArpMesage(interfaceName, dst_ip)
else:
arp_MAC = sendArpMesage(interfaceName, routerIP)
ether = Ether(src=str(src_addr), dst=str(arp_MAC))
print(ether.show())
size = len(message) + 14
ip = IP(src=my_ip, dst=dst_ip, proto=17, ihl=5, len=size, ttl=5, chksum=0)
#print(ip.show())
payload = Raw(message)
packet = ether / ip / msg
del packet[IP].chksum
packet = packet.__class__(bytes(packet)) # same as packet.show2()
print(packet.show())
success = send(packet)
if success is not None:
print(success.show)
else:
print("success is None")
Here is the show() information
Begin emission:
*Finished sending 1 packets.
Received 1 packets, got 1 answers, remaining 0 packets
###[ Ethernet ]###
dst = 4e:98:22:86:f6:75
src = 00:00:00:00:00:11
type = LOOP
None
###[ Ethernet ]###
dst = 4e:98:22:86:f6:75
src = 00:00:00:00:00:11
type = IPv4
###[ IP ]###
version = 4
ihl = 5
tos = 0x0
len = 28
id = 1
flags =
frag = 0
ttl = 5
proto = udp
chksum = 0xe9c2
src = 192.168.1.101
dst = 10.0.0.1
\options \
###[ UDP ]###
sport = 21608
dport = 26995
len = 8297
chksum = 0x7320
###[ Padding ]###
load = 'a test'
None
.
Sent 1 packets.
success is None
And this is what wireshark currently looks like
I am not sure if the problem is because the checksum values do not align, but any help creating this packet would be appreciated

I dont get HTTP answer with sr function. Just an ACK

I am trying to send an HTTP GET request to google.com, but the answer I get is an ACK and not the HTML file. Here is the code:
def Make_Get():
synR = IP(dst = 'www.google.com', ttl = 64)/TCP(dport = 80,sport = randint(1024,65535), flags = 'S')
synAckAN = sr1(synR)
req = (IP(dst='www.google.com') / TCP(dport=80, sport=synAckAN[TCP].dport, seq=synAckAN[TCP].ack, ack=synAckAN[TCP].seq + 1, flags='A')/"GET / HTTP/1.0 \n\n")
ans, a = sr(req)
return ans
and this are the two packets I got in return of this function:
###[ IP ]###
version = 4
ihl = None
tos = 0x0
len = None
id = 1
flags =
frag = 0
ttl = 64
proto = tcp
chksum = None
src = 192.168.233.128
dst = 216.58.214.100
\options \
###[ TCP ]###
sport = 35534
dport = http
seq = 1
ack = 1964930533
dataofs = None
reserved = 0
flags = A
window = 8192
chksum = None
urgptr = 0
options = {}
###[ Raw ]###
load = 'GET / HTTP/1.0 \n\n'
None
###[ IP ]###
version = 4L
ihl = 5L
tos = 0x0
len = 40
id = 32226
flags =
frag = 0L
ttl = 128
proto = tcp
chksum = 0x6425
src = 216.58.214.100
dst = 192.168.233.128
\options \
###[ TCP ]###
sport = http
dport = 35534
seq = 1964930533
ack = 18
dataofs = 5L
reserved = 0L
flags = A
window = 64240
chksum = 0xe5e6
urgptr = 0
options = {}
###[ Padding ]###
load = '\x00\x00\x00\x00\x00\x00'
None
When I sniffed the traffic while I sent this packet, I got this:
###[ Ethernet ]###
dst= 00:0c:29:bb:8e:79
src= 00:50:56:e9:b8:b1
type= 0x800
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 517
id= 32136
flags=
frag= 0L
ttl= 128
proto= tcp
chksum= 0x5004
src= 172.217.20.100
dst= 192.168.233.128
\options\
###[ TCP ]###
sport= http
dport= 1928
seq= 1828330545
ack= 18
dataofs= 5L
reserved= 0L
flags= FPA
window= 64240
chksum= 0x8b5f
urgptr= 0
options= []
###[ HTTP ]###
###[ HTTP Response ]###
Status-Line= u'HTTP/1.0 302 Found'
Accept-Ranges= None
Age= None
E-Tag= None
Location= u'http://www.google.co.il/?gfe_rd=cr&ei=9fiTV6P6FuWg8weei7rQDA'
Proxy-Authenticate= None
Retry-After= None
Server= None
Vary= None
WWW-Authenticate= None
Cache-Control= u'private'
Connection= None
Date= u'Sat, 23 Jul 2016 23:08:37 GMT'
Pragma= None
Trailer= None
Transfer-Encoding= None
Upgrade= None
Via= None
Warning= None
Keep-Alive= None
Allow= None
Content-Encoding= None
Content-Language= None
Content-Length= u'261'
Content-Location= None
Content-MD5= None
Content-Range= None
Content-Type= u'text/html; charset=UTF-8'
Expires= None
Last-Modified= None
Headers= u'Date: Sat, 23 Jul 2016 23:08:37 GMT\r\nContent-Length: 261\r\nContent-Type: text/html; charset=UTF-8\r\nLocation: http://www.google.co.il/?gfe_rd=cr&ei=9fiTV6P6FuWg8weei7rQDA\r\nCache-Control: private'
Additional-Headers= None
###[ Raw ]###
load= '<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">\n<TITLE>302 Moved</TITLE></HEAD><BODY>\n<H1>302 Moved</H1>\nThe document has moved\nhere.\r\n</BODY></HTML>\r\n'
As you can see, the last layer in this one, contain the code I need.
my question is:
Why don't I get the packet with sr() and how can I obtain it to collect the HTML code?
EDIT:
The call to the function:
print Make_Get('www.google.com')[0][Raw]
The function:
def Make_Get(ipp):
ip = DNS_Req(ipp)
synR = IP(dst = ip)/TCP(dport = 80,sport = randint(1024,65535), flags = 'S')
syn_ack = sr1(synR)
getStr = "GET / HTTP/1.1\r\nHost: {}\r\n\r\n".format(ip)
request = (IP(dst= ip) / TCP(dport=80, sport=syn_ack[TCP].dport, seq=syn_ack[TCP].ack, ack=syn_ack[TCP].seq + 1, flags='A')/getStr)
an = sr(request)
return an
The resuls:
Begin emission:
.Finished to send 1 packets.
*
Received 2 packets, got 1 answers, remaining 0 packets
Begin emission:
*Finished to send 1 packets.
Received 1 packets, got 1 answers, remaining 0 packets
[]
First, in HTTP, a correct newline is "\r\n", not "\n".
Second, is there any reason why you use HTTP/1.0 and not HTTP/1.1? If not, you should change your request to:
GET / HTTP/1.1\r\n
Host: www.google.com\r\n
\r\n
Third, the ACK you are getting is usually sent by the server before sending the actual HTTP response to acknowledge your request faster. A second segment is then sent with the HTTP response. You are missing this one in your first show() example.
Have a look here.
To catch this segment, you can use sr() function with its parameter timeout and multi:
ans, unans = sr(request, timeout=2, multi=True)
for c, s in ans:
if s.haslayer(Raw):
print b[Raw]
print("-----------") # just a delimiter
timeout is used to ensure that sr() will stop (value 2 is arbitrary).
multi mean "accept multiple answers for the same stimulus" unless it is there, sr() will stop sniffing after one answer to the request sent.

MTU 1500: fragment packets after 1472 bytes

I have couple of VMs running on Openstack. I have one data network gateway assigned into the switch with MTU=1500, where VMs has to running.
Also in Openstack, I have set the default MTU=1500 of the network.
I am trying to ping from the VM to gateway (OR any ip on same network) of the switch with 1500 packetsize, it's de-fragmenting the packet.
localhost:~# ping -M do -s 1500 10.4.14.18
PING 10.4.14.18 (10.4.14.18) 1500(1528) bytes of data.
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 10.4.14.17 icmp_seq=1 Frag needed and DF set (mtu = 1500
Instead, If I am sending packets with smaller mtu (1472) it works,
localhost:~# ping -M do -s 1472 10.4.14.18
PING 10.4.14.18 (10.4.14.18) 1472(1500) bytes of data.
1480 bytes from 10.4.14.18: icmp_seq=1 ttl=64 time=0.965 ms
1480 bytes from 10.4.14.18: icmp_seq=2 ttl=64 time=0.515 ms
^C
--- 10.4.14.18 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1875ms
rtt min/avg/max/mdev = 0.515/0.740/0.965/0.225 ms
I can see 28 bytes of difference, i don't understand, where this 28 bytes are being utilised ?
The 1500 byte MTU holds for standard Ethernet at the network layer. In other words: 1500 byte can be transmitted in Ethernet frames without being fragmented. However, further protocols on top of Ethernet of course cut into the maximum payload.
In your case (the case of ping) the additional protocols are IP and ICMP. They both have headers with lengths 20 byte and 8 byte, respectively.
This means that you can transmit at most
1500 bytes (Ethernet mtu) - 20 byte (IP header) - 8 byte (ICMP header)
= 1472 byte
See also this question regarding MTU for UDP.
Ping will add 28 bytes header and then send it.
So if you want to send -s 1500, the actual size is 1500 + 28 = 1528 bytes.

Subtract value from data with keys through multiple columns in R

I have two data.tables with multiple columns as keys (they consists of the columns record, dstPort, srcPort, proto, dstIP, and srcIP).
Both have the same format.
dataset_1:
record dstPort srcPort proto dstIP srcIP state timestamp
1: state 80 32768 tcp 192.168.101.5 192.168.101.89 syn 1466580661185059
2: state 80 32768 tcp 192.168.101.5 192.168.101.89 syn_ack 1466520661604781
3: state 80 32768 tcp 192.168.101.5 192.168.101.89 close 1466532661885439
4: state 80 55555 tcp 192.168.101.5 192.168.101.89 syn 1466532661885440
and dataset_2:
record dstPort srcPort proto dstIP srcIP state timestamp
1: state 80 32768 tcp 192.168.101.5 192.168.101.89 established 1466537661727619
2: state 80 32768 tcp 192.168.101.5 192.168.101.89 close 1466532661986891
3: state 80 44444 tcp 192.168.101.5 192.168.101.89 established 1466537661727619
The following is what I would like to do for every key in the dataset:
I want to find the records (rows) with the same key and where a given state is available (i.e. state syn in dataset_1 and established in dataset_2 ).
For these records I want to subtract the timestamps from each other.
I.e.:
For every Key in dataset_1, i.e.:
state 80 32768 tcp 192.168.101.5 192.168.101.89 for state syn gives timestamp 1466580661185059
and Key in dataset_2:
state 80 32768 tcp 192.168.101.5 192.168.101.89 for state established gives timestamp 1466537661727619
After subtracting timestamps:
1466580661185059-1466537661727619 = 42999457440
It could be that there is no record for a key in dataset_2. This is why sorting does not work (which is what all my tries were based to).
An exemplary try is (after having them sort which is not possible anymore):
dt_state1 <- subset(dt, state == 'established')
dt_state2 <- subset(dt, state == 'syn')
dt_delta_test <- data.table(x=(dt_state1$timestamp/1000)- (dt_state2$timestamp/1000),'timestamp'= dt_state1$timestamp-min(dt_state1$timestamp))
Update 1:
#lmo:
F1_in = as.data.table(read.csv(file=Filename, header=TRUE, sep=","))
keys=c("record","dstPort","srcPort","dstIP","srcIP")
state1 = 'syn'
state2 = 'established'
dt_state1 <- subset(F1_in, state == state2)
setkey(dt_state1, keys)
Error in setkeyv(x, cols, verbose = verbose, physical = physical) : some columns are not in the data.table: keys
dt_state2 <- subset(F1_in, state == state1)
setkey(dt_state2, keys)
Error in setkeyv(x, cols, verbose = verbose, physical = physical) : some columns are not in the data.table: keys
dt_state1[dt_state2, timestamp - i.timestamp]
Error in `[.data.table`(dt_state1, dt_state2, timestamp - i.timestamp) :
When i is a data.table (or character vector), x must be keyed (i.e. sorted, and, marked as sorted) so data.table knows which columns to join to and take advantage of x being sorted. Call setkey(x,...) first, see ?setkey.
I don't know why this error occurs..
#toni057 Your solution does not change anything for me (I had to do some changes because it threw some errors). I tried the following code:
F1_in = as.data.table(read.csv(file=Filename, header=TRUE, sep=","))
keys=c("record","dstPort","srcPort","dstIP","srcIP")
state1 = 'syn'
state2 = 'established'
dt_state1 <- subset(F1_in, state == state2)
setkey(dt_state1, keys)
dt_state2 <- subset(F1_in, state == state1)
setkey(dt_state2, keys)
dt_state1 %>%
filter("state" == 'syn') %>%
left_join(filter(dt_state2, "state" == 'established'), by = keys) %>%
mutate(timestamp_diff = timestamp.x - timestamp.y)
I also changed the dt of the second filter. But there is no change in dt_state1 at all..
If your goal is to take differences of the timestamps between the two data.tables where they both share the same key, you could use left join, and then calculate the difference:
# get stuff set up
library(data.table)
# convert data.frames to data.tables by reference
setDT(dt_state1)
setDT(dt_state2)
# set keys
setkey(dt_state1, record, dstPort, srcPort, proto, dstIP, srcIP)
setkey(dt_state2, record, dstPort, srcPort, proto, dstIP, srcIP)
# perform left join and get timestamp difference
dt_state1[dt_state2, timestamp - i.timestamp]
[1] 42999457440 -17000122838 -4999842180 47999198168 -12000382110 -101452 NA
This performs a left join (which subsets the observations in dt_state1 to include only those present in dt_state2) and subtracts dt_state2's timestamp from dt_state1.
The first entry of the returned vector is the value you listed in your example.
data
dt_state1 <- read.table(header=T, text="
record dstPort srcPort proto dstIP srcIP state timestamp
1: state 80 32768 tcp 192.168.101.5 192.168.101.89 syn 1466580661185059
2: state 80 32768 tcp 192.168.101.5 192.168.101.89 syn_ack 1466520661604781
3: state 80 32768 tcp 192.168.101.5 192.168.101.89 close 1466532661885439
4: state 80 55555 tcp 192.168.101.5 192.168.101.89 syn 1466532661885440")
dt_state2 <- read.table(header=T, text="
record dstPort srcPort proto dstIP srcIP state timestamp
1: state 80 32768 tcp 192.168.101.5 192.168.101.89 established 1466537661727619
2: state 80 32768 tcp 192.168.101.5 192.168.101.89 close 1466532661986891
3: state 80 44444 tcp 192.168.101.5 192.168.101.89 established 1466537661727619")
library(dplyr)
dt_state1 %>%
filter(state == 'syn') %>%
left_join(filter(dt_state2, state == 'established), by = insert all you keys here) %>%
mutate(timestamp_diff = timestamp.x - timestamp.y)

Resources