network device module equivalent to ping - c

I have made a module which is transmitting but I don't know whether the packet which I am transmitting is a ping packet or not. Code is shown below:
icmp.type = 8;
icmp.code = 0;
icmp.un.echo.sequence = i;
ip4.protocol = 1; //for icmp protocol
ip4.frag_off = 0;
ip4.daddr = in_aton(procfs_buffer);
ip4.saddr = in_aton(ifr->ifr_addr.sa_data);
len = sizeof(data);
skb = dev_alloc_skb(1500);
skb->dev = __dev_get_by_name(&init_net,"wlan0");
skb_reserve(skb,NET_IP_ALIGN); // header of 2 bytes; increments tail and
// data pointer
skb->data = skb_put(skb,sizeof(len)); // increments all pointer or adds data
memcpy(data,skb->data,len);
skb->transport_header =skb_push(skb,sizeof(icmp));
memset(skb->transport_header,0,sizeof(struct icmphdr));
memcpy(skb->transport_header,&icmp,sizeof(struct icmphdr));
skb->network_header=skb_push(skb,sizeof(ip4));
memset(skb->network_header,0,sizeof(struct iphdr));
memcpy(skb->network_header,&ip4,sizeof(struct iphdr));
// printk("i::%d\n",i);
// skb->mac_header = skb_push(skb,6*sizeof(0xFF));
// memset(skb->mac_header,0xFF,6*sizeof(0xFF));
dev_queue_xmit(skb);
kfree(skb);
How can I know that it is a ping packet which I am creating and transmitting? Further I want to receieve the ping packet in response to my ping packet which I have transmitted. I would like to use napi but wont mind any other suggestions.
please read a topic : reception napi mode here i could nt understand what to do from the link above.....

You can use wireshark to capture all network traffic going in and out of one of your network interface. You'll be able to check that the packet has been sent and if it was actually what you expect it to be. You'll also be able to see if there is an answer to your ping.
Regarding your question on how to intercept the ping answer from your module, you can use the netfilter API offered by the kernel. Here is a good article to start with using netfilter.

a ping packet is simply icmp packet with code 8, with timestamp in its data
icmp echo reply (ping reply) just copies the data from the icmp echo request and sends it back, this way ping can tell you how much time it took for the round trip (now - prev' sended time)
i am not very familiar with the linux kernel, but be sure to calculate the correct ip and icmp checksums
also for receiving, it might be better to use netfilter

Related

2 program get same udp packets from a port

there is a server will send some UDP packets to my localhost, for example: if it send some UDP packets to my localhost and destination port is 5000. and there will have a client program to receive it on port 5000. but, what I want is to create another program, it will try to receive the same packets on port 5000.
if the server send packets p1, p2, p3....pn to my localhost port 5000, I want to both client programs will receive same packets. (client program 1: p1, p2, p3....pn, client program 2: p1, p2, p3...pn)
I tried to use pcap to do this, but seems lost some packets in sometimes.(the server will send some video stream to client)
You need to use multicast if you want to do this with a single send / sendto on the server process. Here are quick examples done in Python 2.7.x for the sake of brevity / reuse of code I had laying around.
It's import for the transmit side to set IP_MULTICAST_LOOP if you are going to use this method with transmitter & receivers running on the same host.
sender.py:
#!/usr/bin/env python
import socket
import sys
MCAST_GROUP=sys.argv[1]
MCAST_PORT=int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt( socket.SOL_SOCKET, socket.IP_MULTICAST_LOOP, 1 )
for ii in xrange(10):
msg = 'message %d' %ii
print 'sending: "%s"' %msg
s.sendto( msg, (MCAST_GROUP, MCAST_PORT)
receiver.py:
#!/usr/bin/env python
import socket
import sys
import struct
MCAST_GROUP=sys.argv[1]
MCAST_PORT=int(sys.argv[2])
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
s.bind( (MCAST_GROUP, MCAST_PORT) )
# In C, you'll want to use struct ip_mreq here. See 'man 7 ip' for details.
# Python's socket module doesn't define a convenient way to do this, hence the
# 'manual' struct.pack
mreq = struct.pack( '4sI', socket.inet_aton(MCAST_GROUP), socket.INADDR_ANY )
s.setsockopt( socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq )
while True:
rx_data = s.recv(1000)
print 'received: "%s"' %rx_data
Both programs expect two command line arguments, an IPv4 multicast IP (224.0.0.0 - 239.255.255.255), and a port. For example (./sender.py 239.10.10.10 5000).
You should be able to run as many instances of receiver.py as you like in different terminals, and see that a single instance of sender.py will transmit to all receivers.
To translate this to C, it's basically:
Convert s = socket.socket(...) -> s = socket(...)
Convert s.X(...) to X(s, ...) for X={setsockopt, bind, send, recv}
See notes about ip_mreq.
Once you read/recv on the socket the messages will be gone from the socket, so even if you use SO_REUSEADDR/ SO_REUSEPORT, I don't think you will be able to read the packets with both clients.
I think the easiest option is to have a local service running on port 5000 which then forwards all packets to the other services. Whether you write that as a server pub/sub style or hard-code it is probably something to decide based on how much effort you want to put into this.

How do I cause a message to be dropped after 1 second? (UDP client/server in C)

I have a UDP client based off of http://cs.baylor.edu/~donahoo/practical/CSockets/code/UDPEchoClient.c
where the client sends a message and the server echos it back. I have a configurable server where I can drop packets, and I am sending multiple messages instead of just 1 in the code linked above. How do I make the message drop if it takes more than 1 second? As of right now, I am checking each message after I get it in recvfrom(), but I want my whole program to run in under ~1.5s because I do not want to wait 1 second for each message (this would take forever if there were a lot of messages). Is there a way to attach like a timer or something to each message so that it considers itself dropped if its not received within 1 second? Thanks!
Use TTL for UDP packets
int ttl = 60; /* max = 255 */
setsockopt(s, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));

RAW TCP socket in windows with C?

I am writing a proxy in C (Windows 8.1 Environment). I did the same in Linux without any trouble but in windows things look different.
First of all, I am aware of MS Windows restrictions for sending RAW TCP Data and read this post. I also found WinPcap as a potential solution. The difference is I need to add Ethernet frame (DstMac, SrcMac, and Protocol Type) and ran the following codes:
if ((fp = pcap_open_live(d->name, // name of the device
65536, // portion of the packet to capture. It doesn't matter in this case
1, // promiscuous mode (nonzero means promiscuous)
1000, // read timeout
errbuf // error buffer
)) == NULL)
{
fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
}
then I created a packet:
u_char * data;
data = (u_char *)malloc(sizeof(u_char)*(ip_size+14));
memcpy((void*)data, (void*)dmac, 6);
memcpy((void*)(data + 6), (void*)smac, 6);
USHORT TmpType = 8;
memcpy((void*)(data + 12), (void*)&TmpType, 2);
memcpy(data+14, iphdr, ip_size); //iphdr is the full packet -(minus) ethernet header
//ip_size is the sizeof(iphdr)
pcap_sendpacket(fp, data, ip_size+14); //14: size of ethernet header
free(data);
In my test the first iphdr is a TCP Syn packet. When I send it to the network, I can capture it in Wireshark. However, the remote server does not respond to this packet and I got [TCP Out-of-Ordfer] messages and then a few RST packet and nothing happens.
my questions are:
1- Is winpcap the only feasible solution in windows with C?
2- If no, could you please provide any example/resource for developing RAW TCP sockets in C?
3- If yes, what causes the server does not response my manually crafted TCP Syn.
PS: I use the same code for creating TCP SYN in linux and it works perfectly. So, I have no doubt the tcphdr contain the IP header, TCP header and payload with correct checksums in both IP, and TCP headers.

Error:Socket Select() function always return zero..?

can any one tell me why the following code always return 0 . the socket descriptor value is 3.
i am using the open suse TFTP server . which is listening on port 69 in Local host.
connect() function return success ..
connection_timer.tv_sec = 2; // s
connection_timer.tv_usec = 0;
FD_ZERO(&fd_reader);
// laukiam, kol bus ka nuskaityti
FD_SET(socket_descriptor, &fd_reader);
int select_ready = select(socket_descriptor + 1, &fd_reader, NULL, NULL, &connection_timer);
When i use TCPdump to check the packet it send the first packet then the connection is closed in somewhere before receive Ack received..
You will get a return code of 0 from select it the timer (connection_timer in your example) expires before any descriptor has become interesting.
So it's not an error. It seems most likely you didn't initialize connection_timer properly.
I suspect that you are not receiving the response because you used connect() on a UDP socket, which made it so that you only accept datagrams from the connected destination.
Since the TFTP reply does not come from port 69, but rather from an ephemeral port, the acknowledgement is never received.
Solution: Don't connect() your UDP socket until after you finish the initial connection.
WSAStartup functions needs to be called.
I do have the same problem and that got resolved after calling this startup function.

C pcap detecting inbound datagrams

In C I bind a datagram socket (AF_INET, SOCK_DGRAM) to INADDR_ANY. I then periodically use this socket to send and receive datagrams, and monitor the flow of packets with pcap. The problem is, I can't tell whether a packet is incoming or outgoing using pcap.
The transmission/receiving and the pcap monitoring are running in separate threads, and for synchronisation reasons they can't communicate. I only want to track the incoming packets, not the ones being sent, so does anyone have an idea as to how I can do that?
I thought already of testing the destination ip address, but I can't figure out any way to get my local ip. the machine this is running on doesn't have a static ip, much less an assigned domain name, and it seems that getsockname doesn't work on sockets bound to INADDR_ANY. Also tried using ioctl(sockfd, SIOCGIFCONF, &buffer), which didn't work either - sets buffer.ifc_len=0.
Found a solution. I can get my own ip using this:
char *command = malloc(100);
sprintf(command,"ifconfig %s|grep -o \"inet addr:[^ ]\"|grep -o -e \"[0-9]\.[0-9]\.[0-9]\.[0-9]*\"",device);
char path[1035];
FILE *fp;
fp = popen(command,"r");
fgets(path, 1034, fp);
pclose(fp);
my_ip = malloc(sizeof(char)*(1+strlen(path)));
memcpy(my_ip, path, strlen(path)-1);
my_ip[strlen(path)-1] = 0;

Resources