Showing posts with label notes. Show all posts
Showing posts with label notes. Show all posts

Sunday, April 19, 2020

Threads in C - Input and Output

Today, we will see only to pass values to a thread.  Retrieve value from thread.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

//Thread to change value from 20 to 30
void * threadtak (void * poin)
{
    int *inttak = (int *)poin;
    *inttak=30;
    return NULL;
}

//Thread to return a value 60
void * threadret ()
{
  int *ret=malloc(sizeof(int));
  *ret=60;
  printf("%d\n",*ret);
  return ret;
}
int main()
{
    pthread_t tak,ret;
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    int vartak=20;
    pthread_create(&tak, &attr,threadtak, &vartak);
    pthread_join(tak,NULL);
    printf("Modified vartak = %d\n",vartak);

    int *varret;
    pthread_create(&ret, &attr,threadret, NULL);
    pthread_join(ret,(void *)&varret);
    printf("Returned varret=%d\n",*varret);
    
    return 0;
}

Lets break the explanation into 2.

Passing the value

Line 29: Address of vartak is passed as argument
Line 9: As it is declared void pointer, it can take the address of integer/any other data type.
Line 10: Value at inttak is changed to 30
Line 11: Returned as NULL
Line 31: vartak is already changed and can be accessed as normal int


1
2
3
4
5
# gcc -pthread -o a.out main.c
# ./a.out
Modified vartak = 30
60
Returned varret=60

Value is vartak is displayed as 30

Returning the value

Line 33: We try to retrieve the value from threadret into integer pointer.
Line 34: As we are not passing any argument to the thread, we keep it NULL
Line 15: The argument for the thread can be kept blank as no argument is passed
Line 17: We create a memory and assign the value 60
Line 20: Return the address of ret
Line 35: Join should have void **.  We keep it &varret.  Because, *varret is value. varret is the address of *varret. &varret is the address of varret.


1
2
3
4
5
# gcc -pthread -o a.out main.c
# ./a.out
Modified vartak = 30
60
Returned varret=60

Value of varret is displayed as 60.

Sunday, April 12, 2020

Threads in C

We have seen how fork() works in C.  They say, threads are light-weight processes.  Will see how it is done.  Sample program with 3 threads is given here:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void * threadrun (void * poin)
{
    int k=*(int *)poin;
    
    for (int i=1;i<5;i++)
    {
      sleep(2);
      printf("iteration %d of thread %d\n",i,k);
    }
    return NULL;
}

int main()
{
    pthread_t tid1,tid2,tid3;
    pthread_attr_t attr;
    pthread_attr_init(&attr);

    int p=1;
    pthread_create(&tid1, &attr,threadrun, &p);
    int q=2;
    pthread_create(&tid2, &attr,threadrun, &q);
    int r=3;
    pthread_create(&tid3, &attr,threadrun, &r);
    
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);
    
    return 0;
}

The thread function should take in a void pointer, return a void pointer to a pointer.  The function threadrun will print 4 iterations each while sleeping 2 seconds for each iteration.  We are returning NULL.

Thread Creation
Line 19 - Create an identifier
Line 20/21 - Create an attribute structure and initialize
Line 23 - Create a value to pass it to thread, so that we can identify the thread
Line 24 - Start the Thread

After thread is created, they will start executing independent of each other.  You can see the stdout the sequence in which the prints are made.

Thread Join
Line 30 - We wait till thread1 is returned.
Line 31 - We wait till thread2 is returned
Line 32 - We wait till thread3 is returned

As Thread1 is first in line,  even though thread 2 and 3 returns earlier, our program will wait till thread1 is completed.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# ./thread
iteration 1 of thread 1
iteration 1 of thread 3
iteration 1 of thread 2
iteration 2 of thread 1
iteration 2 of thread 2
iteration 2 of thread 3
iteration 3 of thread 3
iteration 3 of thread 2
iteration 3 of thread 1
iteration 4 of thread 3
iteration 4 of thread 2
iteration 4 of thread 1

Sunday, August 25, 2019

Basic Demo of Default Gateway

I got a host having a IP Address 192.168.10.176.  We will see how it reacts when it wants to reach out to different IP Addresses.



IP Addresses within Network

In the above picture, whenever the host wants to reach to any IP Address within the network, it sends out ARP Request to resolve the MAC Address.  To demonstrate, we tried to ping 192.168.10.177, 192.168.10.178 and 192.168.10.190.  As I connect only *.177 PC there was reply from only that machine.  It is not important.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# ping -c 1 192.168.10.177
PING 192.168.10.177 (192.168.10.177): 56 data bytes
64 bytes from 192.168.10.177: seq=0 ttl=64 time=0.724 ms

--- 192.168.10.177 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.724/0.724/0.724 ms
#
# ping -c 1 192.168.10.178
PING 192.168.10.178 (192.168.10.178): 56 data bytes
^C
--- 192.168.10.178 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# ping -c 1 192.168.10.190
PING 192.168.10.190 (192.168.10.190): 56 data bytes
^C
--- 192.168.10.190 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# 

 Analysing the following sniffer capture.


Note those ARP Requests that our host generates.  It requests MAC only for *.177, *.178 and *.190.  The conclusion is for all the IPs that are within the network host will directly requests for MAC addresses of those machines.

IP Address outside Network

I try to ping some IP Address outside its network that do not exist.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# ping -c 1 192.168.10.200
PING 192.168.10.200 (192.168.10.200): 56 data bytes
^C
--- 192.168.10.200 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# ping -c 1 192.168.1.20
PING 192.168.1.20 (192.168.1.20): 56 data bytes
^C
--- 192.168.1.20 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

# ping -c 1 1.3.2.4
PING 1.3.2.4 (1.3.2.4): 56 data bytes

--- 1.3.2.4 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#

As there are no hosts with those IPs, all pings fail.  Let us analyze the sniffer capture:

Here the host wanted to reach out to an IP Address that is not in its configured network interface.  The sequence of things that happened here:

  1. Requests for the MAC Address of 'Default Gateway' that is configured(i.e. 192.168.1.177).
  2. Host took note of the MAC address of gateway, say it gw-mac
  3. Following packets destined to that IP address will have destination mac as gw-mac. Other elements like source mac, source IP and destination IP will be as usual 
The aim here is -- Host has to deliver the packet to the gateway that is capable of routing. That is why the destination mac is of the gateway's.  The gateway must be configured such that the packet is routing to its desired network.


Tuesday, August 13, 2019

Proxy ARP in Linux

In my previous post, you have seen how proxy arp was configured on cisco router.  Now, we do a demo on a linux machines FC19.



Briefly,
  • Without proxyarp, Multihost will respond for all configured IPs
  • With proxyarp, Multihost will respond for all connected network IPs(except the interface on which it receives arp request)
Here, I will discuss only about how multicast responds to ARP and not about Ping.  To simplify our explanation we use a tool 'arping'.  It is usually inbuilt in all machines.


Without proxyarp, Multihost will respond for all configured IPs

No proxyarp is enabled in Multihost.  'eth0' on Multihost will arp respond to its configured IP addresses '172.16.0.10' and '192.168.1.8'.  The way I use arping below to direct arp request is self-explanatory.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[root@abc12end1 ~]$arping -I enp0s20u4 -f 172.16.0.10
ARPING 172.16.0.10 from 172.16.0.1 enp0s20u4
Unicast reply from 172.16.0.10 [00:FF:18:B4:CC:6F]  0.811ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.8
ARPING 192.168.1.8 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.8 [00:FF:18:B4:CC:6F]  0.799ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.1
ARPING 192.168.1.1 from 172.16.0.1 enp0s20u4
^CSent 2 probes (2 broadcast(s))
Received 0 response(s)

Observe that I requested for 192.168.1.1 for which Multihost didn't respond.

With proxyarp, Multihost will respond for all connected network IPs


Now, I enable proxyarp using the following commands.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# cat /proc/sys/net/ipv4/conf/all/proxy_arp
0
# cat /proc/sys/net/ipv4/ip_forward
0

# echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp
# echo 1 > /proc/sys/net/ipv4/ip_forward

# cat /proc/sys/net/ipv4/conf/all/proxy_arp
1
# cat /proc/sys/net/ipv4/ip_forward
1
 

Now issue arp request for any of the IP address in 192.168.1.x network.  Irrespective of whether the host exists or not, eth0 will respond with its MAC address.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.8
ARPING 192.168.1.8 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.8 [00:FF:18:B4:CC:6F]  0.802ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.1
ARPING 192.168.1.1 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.1 [00:FF:18:B4:CC:6F]  444.585ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

[root@abc12end1 ~]$arping -I enp0s20u4 -f 192.168.1.2
ARPING 192.168.1.2 from 172.16.0.1 enp0s20u4
Unicast reply from 192.168.1.2 [00:FF:18:B4:CC:6F]  126.458ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)

Here 192.168.1.1 and 192.168.1.2 hosts do not exist.  But Multihost's eth0 responded with its MAC Address.

Thursday, August 1, 2019

Proxy ARP in Packet Tracer

I believe the following diagram will give a brief idea about what Proxy ARP does.  By default all cisco routers will have proxy arp enabled over the interfaces.

Description

Typically, any interface having IP address 'IP1' after receiving an arp request(for IP1) it sends arp response with its MAC address.  

Suppose 'proxy arp' is enabled in any interface(say Gi0/1), and the other interfaces(Gi0/2, Gi0/3) of the network device are configured with other networks(IP2, IP3).  If Gi0/1 receives any arp request for any of the IP addresses in IP2 or IP3, Gi0/1 sends out ARP response with its own MAC Address.
'Proxy ARP' configuration gives the authority for that interface.

Demonstration

I picked a router with following interfaces and IP addresses.

Topology

Configurations in the router will be as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
Router(config)#
Router(config)#int gigabitEthernet 0/0
Router(config-if)#ip address 192.168.0.1 255.255.255.0
Router(config-if)#no shut
Router(config-if)#exit
Router(config)#int gigabitEthernet 0/1
Router(config-if)#ip address 192.168.1.1 255.255.255.0
Router(config-if)#no shut
Router(config-if)#exit
Router(config)#int gigabitEthernet 0/2
Router(config-if)#ip address 192.168.2.1 255.255.255.0
Router(config-if)#no shut
Router(config-if)#exit

If you observe, Laptop0 has subnet mask 255.0.0.0 while others have 255.255.255.0.   I did it for a reason.  If I ping to 192.168.2.x or 192.168.3.x from Laptop0, it initially generates ARP request for that particular IP address.  If I keep subnet as 255.255.255.0 and issue a ping to 192.168.2.x or 192.168.3.x, it will generate ARP for the default IP address configured.  Explanation of this needs a separate post which I am planning to do later.

For this post, just remember that with this configuration I will be able to generate ARP requests for 192.168.2.x or 192.168.3.x IP addresses.


C:\>arp -a
No ARP Entries Found

C:\>ping -n 1 192.168.0.1
Pinging 192.168.0.1 with 32 bytes of data:
Reply from 192.168.0.1: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.0.1:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),

C:\>ping -n 1 192.168.1.1
Pinging 192.168.1.1 with 32 bytes of data:
Reply from 192.168.1.1: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.1.1:
    Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),

C:\>ping -n 1 192.168.1.100
Pinging 192.168.1.100 with 32 bytes of data:
Request timed out.
Ping statistics for 192.168.1.100:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -n 1 192.168.1.101
Pinging 192.168.1.101 with 32 bytes of data:
Request timed out.
Ping statistics for 192.168.1.101:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>ping -n 1 192.168.2.1

Pinging 192.168.2.1 with 32 bytes of data:

Request timed out.

Ping statistics for 192.168.2.1:

    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

Initially we made sure ARP entries are not present.  We have issued ping to
  • 192.168.0.1 (its own network on Gi 0/0)
  • 192.168.1.1 and 192.168.1.100 (other interface's Gi0/1 network address) (Existing IP address)
  • 192.168.1.101 (other interface's Gi0/1 network address) (This IP address not present)
  • 192.168.2.1 (other interface's Gi0/2 network address) (Existing IP address)
When we look at arp entries:

1
2
3
4
5
6
C:\>arp -a
  Internet Address      Physical Address      Type
  192.168.0.1           0040.0b1a.9a01        dynamic
  192.168.1.1           0040.0b1a.9a01        dynamic
  192.168.1.100         0040.0b1a.9a01        dynamic
  192.168.1.101         0040.0b1a.9a01        dynamic

Line 3, its conventional arp response of Gi0/0 MAC address.
Line 4 and 5, Gi0/0 responded with its own MAC address for the network present in Gi0/1
Line 6, Irrespective whether the IP address exists or not, if it gets arp request for any of the IP address in 192.168.1.x network it responds with its own MAC address.

Bonus Tip

You must have noticed that I issued ping to 192.168.2.1 (Gi0/2), but the arp entry is not present.  This is because that operational status is down.  So, we placed a switch to make it 'up'.  Now proxy-arp works as usual.

Placed a switch to make Gig0/2 operational status 'up'


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
C:\>arp -a
No ARP Entries Found

C:\>ping 192.168.2.1
Pinging 192.168.2.1 with 32 bytes of data:
Reply from 192.168.2.1: bytes=32 time=1ms TTL=255
Reply from 192.168.2.1: bytes=32 time<1ms TTL=255
Ping statistics for 192.168.2.1:
    Packets: Sent = 2, Received = 2, Lost = 0 (0% loss),

C:\>ping 192.168.2.100
Pinging 192.168.2.100 with 32 bytes of data:
Ping statistics for 192.168.2.100:
    Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),

C:\>arp -a
  Internet Address      Physical Address      Type
  192.168.2.1           0040.0b1a.9a01        dynamic
  192.168.2.100         0040.0b1a.9a01        dynamic


Sunday, August 26, 2018

TCP open connection with scapy

Today, I am going to try to create TCP 3-way connection with the help of scapy and iperf.  The full wireshark capture is
TCP 3-way Connection

192.168.1.10 (client: port 40508: scapy) ------->> 192.168.1.200 (server: port 5000: iperf)

As we donot have a conventional TCP client program running on the client side.  Whenever server sends SYN-ACK packet to client, the kernel on the client responds with Reset TCP connection.  To avoid this, we should place a rule in IPTables, to drop any Reset's packets initiated from client side.  This can be done using the following command on the client side:

# iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.10 -j DROP

On the server side, we create a server listening on port 5000, using 

# iperf -s -p 5000
------------------------------------------------------------
Server listening on TCP port 5000
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

In another session, observe that the output of netstat command, its in listen state

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN

On the client side, we open scapy session, send a TCP SYN packet and receive the response.  sr1 implies send (ip/SYN) and wait till ONE response is received.


# scapy
INFO: Can't import python gnuplot wrapper . Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
INFO: Can't import python Crypto lib. Won't be able to decrypt WEP.
INFO: Can't import python Crypto lib. Disabled certificate manipulation tools
Welcome to Scapy (2.2.0)
>>>
>>> ip=IP(src="192.168.1.10",dst="192.168.1.200")
>>> SYN=TCP(sport=40508,dport=5000,flags="S",seq=0)
>>> SYNACK=sr1(ip/SYN)
Begin emission:
.......Finished to send 1 packets.
.*
Received 9 packets, got 1 answers, remaining 0 packets

Netstat on the server side, the state would have been

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.200:5000      192.168.1.10:40508      SYN_RECV

Now, on the client, we create and send the 3rd handshake message ACK to complete the TCP connection. This has to be sent as quick as possible, because there is a chance that the server may have timed out and dropped the TCP connection.

>>> ACK=TCP(sport=40508,dport=5000,flags="A",seq=SYNACK.ack+1,ack=SYNACK.seq+1)
>>> send(ip/ACK)
.
Sent 1 packets.

Netstat shows that the TCP connection is established.

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.200:5000      192.168.1.10:40508      ESTABLISHED

Tuesday, July 31, 2018

DHCP Broadcast - Notes

In my last post on DHCP, DHCP Offer and DHCP ACK were unicast frames.

DHCP Unicast Flag
In the Bootp Flags, the broadcast bit is set to 0(means unicast).  It means DHCP Client tells that it is expecting unicast responses from DHCP server.  So, the reply from DHCP server(DHCP Offer and DHCP ACK) will have Unicast MAC and IP Addresses. 

On a linux machine, this can be seen using command 'dhclient eth0'

Broadcast

There are cases when they will be broadcast.  From linux machine, we can use 'dhclient -B eth0' to request Broadcast responses.  Most of the times, DHCP starts from DHCP Offer, instead of Discovery.  So, by googling I found that we had to release the existing IP address for the transaction to happen from Discovery.  Like this

# dhclient -r  eth0
# dhclient -B  eth0

DHCP Broadcast
Observe that the Bootp flag here is '1'(means Broadcast flag set).  Client is asking the server to give broadcast responses.  Therefore, the DHCP Offer and ACK from the server has broadcast MAC and IP addresses.


Sunday, July 29, 2018

DHCP Notes

Dynamic Host Configuration Protocol.  Server automatically gives IP address to those machine that request it.

  • Message Exchanges (DORA), Discovery, Offer, Request, Acknowledgement.  
  • UDP Protocol - port 68 (server) - port 67 (client)
  • Wireshark decodes it as Bootp Protocol, because Bootp also uses same port numbers
  • Transaction ID same for one transaction of DHCP packets

DHCP

DHCP Discovery

  • DHCP Client ---> DHCP Server
  • Source MAC is client's MAC.  Destinatation MAC is FF:FF:FF:FF:FF:FF 
  • Source IP is 00:00:00:00 (it was not configured with any IP address yet)
  • Destination IP is FF:FF:FF:FF (not sure which one is DHCP server)
DHCP Discovery

DHCP Offer

  • DHCP Server ----> DHCP Client
  • Source MAC and Destination MAC self-explanatory
  • Source IP (Server)
  • Destination IP(Client).  
  • This packet is unicast, but client's IP address is not yet configured. Some cases, the packet will be broadcast.  This needs explanation and it will be done in the next tutorial with Scapy.
  • 'Your (client) IP address' is the IP address given by server to client
  • Rest of the fields are self-explanatory
DHCP Offer

DHCP Request

  • DHCP Client ---> DHCP Server
  • Source MAC is client's MAC.  Destinatation MAC is FF:FF:FF:FF:FF:FF 
  • Source IP is 00:00:00:00 (it was not configured with any IP address yet)
  • Destination IP is FF:FF:FF:FF 
  • The reason why destination MAC and IP are broadcast, even though the client is aware about the server IP address is:  It helps other DHCP servers in the network to be aware that the client has already got hold of another DHCP server and it can reallocate the client-offered IP address to some other machine.
  • Client requests the IP address to the server, and configures IP address on its interface
DHCP Request

DHCP Acknowledge

  • DHCP Server ---> DHCP Client
  • Client would have configured IP address by now, so Destination MAC and IP will be of Client's.
  • All the properties will be the same that of DHCP Offered packet
DHCP Ack