?
Solved

Raw Sockets - UDP client _  REQUIREMENT

Posted on 2011-03-11
16
Medium Priority
?
1,104 Views
Last Modified: 2012-05-11
Hi Experts

I have the following requirements (on a Linux machine):

1- Spoof multiple source IP addresses (10,000):

Source and destination MAC addresses will be the same.
Source IP addresses will be taken from a text file. Destination IP address will be fixed. Transport protocol will be UDP, source and destination ports will be fixed. Packets created must be valid (checksums/CRC) because they will be sent to a real server.

2- Keep track of the number of packets sent by each IP.  To accomplish this, write a sequence number in the UDP payload - counter will be 32 bit wide. Append to the sequence number created a fixed string of characters.

3- The program should be able to generate half a million to a million of packets per second.
Frames sent will be be at the minimum 120 bytes. Each host will send 5 packets and the program will cycle through all 10,000 hosts.

Desired/Optional:

4- Randomize the amount and the size of of packets sent per host. Maximum packet size will be 320 bytes long.

My preference is to use PERL if it is possible and use Raw sockets. But I am also opened to  C++ if it is an absolute requirement to get this working.

First question ( at 500 points), please indicate the modules I should use if using PERL, or if using C++
please explain your choice and why it must be done that way.

I will raise 4 other questions (at 500 points), one for each of the items described above.

Thank you

PA
0
Comment
Question by:pierre-alex
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 5
16 Comments
 

Author Comment

by:pierre-alex
ID: 35109353
Hi, I work for an Internet Service Provider. I have to design a tool to stress Core backbone equipments. We have tools that can generate far more than 1 million packets per second and can spoof multiple IP addresses,  but unfortunately they are not flexible enough to increment a sequence number inside the payload. Thus my request.
0
 
LVL 79

Accepted Solution

by:
arnold earned 1500 total points
ID: 35110069
Here is an example of raw socket use:
http://www.perlmonks.org/index.pl?node_id=17576&lastnode_id=63535

It depends on the type of stress testing you are looking to perfrm, there might be a tool already.
0
 

Author Comment

by:pierre-alex
ID: 35110346
Hi arnold, thank for the link. I am after UDP stress testing though.

PA
0
U.S. Department of Agriculture and Acronis Access

With the new era of mobile computing, smartphones and tablets, wireless communications and cloud services, the USDA sought to take advantage of a mobilized workforce and the blurring lines between personal and corporate computing resources.

 
LVL 79

Expert Comment

by:arnold
ID: 35110469
change the proto to UDP from 6 to 17
http://rhosted.blogspot.com/2009/08/creating-udp-packetip-spoofing-through.html
follow the link to http://www.networksorcery.com/enp/protocol/ip.htm

The issue I'm seeing is that if you alter the source IP as part of the script, you will not receive a response from the packet you sent. So not sure what you are testing.
A spoof is inevitably a one way test of a DoS.
Is the system on which you plan to run the perl script multihomed i.e. all the IPs are present?
0
 

Author Comment

by:pierre-alex
ID: 35110578
arnold,  I don't need a response from the server.
 The server in question is a Syslog server receiving messages from close to 10,000 devices. The server in question has only have one IP. It receives the messages and store them to disk and that is the end of the story.
0
 

Author Comment

by:pierre-alex
ID: 35111524
How would I modify the code  on the link below to send 10 packets instead of one packet?

http://www.perlmonks.org/index.pl?node_id=17576&lastnode_id=63535

I tried the following :

     for ($count = 10; $count >= 1; $count--)
           {
          send(RAW,$packet,0,$destination);
          }
but got error messages.

0
 

Author Comment

by:pierre-alex
ID: 35112601
OK. I solved the loop part of the problem:

What I did is I populated an array:


$src_host_list[0] = '192.168.100.101';
$src_host_list[1] = '192.168.100.102';
$src_host_list[2] = '192.168.100.103';


Then I did:

  for $src_host (@src_host_list)  
  {

   #print "$src_host\n";
    main();
  }

and that generated packets from different sources.

What I need now is to do the same with UDP. I am concerned however about the checksum  calculation ....

0
 

Author Comment

by:pierre-alex
ID: 35114998
Thanks.

Referring to the example provided:
http://www.perlmonks.org/index.pl?node_id=17576&lastnode_id=63535

I have been trying to make sense of the line below so I can modify (if necessary) for UDP.

setsockopt(RAW, 0, 1, 1);

Please see below what I have found. Can you please clarify what the meaning are of LEVEL = 0
OPTNAME = 1 and how I would go about choosing options for UDP?


setsockopt SOCKET,LEVEL,OPTNAME,OPTVAL
Sets the socket option requested. Returns undefined if there is an error. Use integer constants provided by the Socket module for LEVEL and OPNAME. Values for LEVEL can also be obtained from getprotobyname. OPTVAL might either be a packed string or an integer. An integer OPTVAL is shorthand for pack("i", OPTVAL).

Pasted from <http://perldoc.perl.org/5.8.8/functions/setsockopt.html

DESCRIPTION
      The setsockopt() function shall set the option specified by the option_name argument, at the protocol level specified by the level argument, to the value pointed to by the option_value argument for the socket associated with the file descriptor specified by the socket argument.
      The level argument specifies the protocol level at which the option resides. To set options at the socket level, specify the level argument as SOL_SOCKET. To set options at other levels, supply the appropriate level identifier for the protocol controlling the option. 

[…]
For Boolean options, 0 indicates that the option is disabled and 1 indicates that the option is enabled.
Options at other protocol levels vary in format and name.

Pasted from <http://pubs.opengroup.org/onlinepubs/009695399/functions/setsockopt.html
0
 
LVL 79

Expert Comment

by:arnold
ID: 35116225
http://books.google.com/books?id=ptSC4LpwGA0C&pg=PA192&lpg=PA192&dq=setsockopt+W.+Richard+Stevens&source=bl&ots=Kq9GUkckLv&sig=L4Gi9vDHoUYa_A5loxA7ClqA_DE&hl=en&ei=QYt7TfeAJ4r3gAes4bTZBw&sa=X&oi=book_result&ct=result&resnum=1&sqi=2&ved=0CBQQ6AEwAA#v=onepage&q=setsock&f=false

Chapter 7.2

You could use getprotobyname with ipproto_UDP to see what the level should be for UDP.
Level 17 is UDP.
setsockopt (socket_filehandle,17,optional,optional) will set the socket for UDP

137 is currently the higher number in use.
#!/usr/bin/perl

$count=0;
print "Level\tDesc\n";
while ($count<=137) {
$level=getprotobynumber($count);
print "$count\t$level \n";
$count+=1;
}

Open in new window

0
 

Author Comment

by:pierre-alex
ID: 35117922
Hi Arnold, thanks for your help.

I have been able to accomplish the first two objectives successfully, that is:

1- Spoof multiple source IP addresses (10,000) with correct calculation of checksums
2- Keep track of the number of packets sent by each IP using a 32 bit counter.

Now regarding the third objective ( send half a million packets per seconds ) I am a reaching a bottleneck somewhere.  The test server (quad processor 6 GIG of RAM running Ubuntu 64 bit) is only at 25 percent CPU utilization  and 5G free memory, but I am only getting about 85,000 packets per seconds / 88,341,000 bps

I have tried to run the script multiple times, but it seems that the amount of CPU gets divided by the different instances so I never go over 25% CPU utilization.

Is it a limitation of Perl? Problem with the network card buffers?

Any suggestion?

0
 
LVL 79

Expert Comment

by:arnold
ID: 35118264
I am not sure, it might be an issue with the tcp/IP stack dealing with how many entries it can keep.
Not sure whether threaded setup might increase your throughput or whether using fork() within perl is a better alternative.
0
 

Author Comment

by:pierre-alex
ID: 35120121
OK, I will have a look. Thanks
0
 

Author Closing Comment

by:pierre-alex
ID: 35129930
Hi Arnold

I got around the performance issue by:

1) generating udp traffic using the perl script
2_recording the outpug using tcpdump
3) replaying it using a third party tool bittwist.

I managed to generate around 350,000 pps  (a bit short of my objective ) but by combining two servers, I  should be able to get the job done.

Thanks your input

PA
0

Featured Post

What Is Blockchain Technology?

Blockchain is a technology that underpins the success of Bitcoin and other digital currencies, but it has uses far beyond finance. Learn how blockchain works and why it is proving disruptive to other areas of IT.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
It’s 2016. Password authentication should be dead — or at least close to dying. But, unfortunately, it has not traversed Quagga stage yet. Using password authentication is like laundering hotel guest linens with a washboard — it’s Passé.
Connecting to an Amazon Linux EC2 Instance from Windows Using PuTTY.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question