Custom Packets

Hey all,
So if packets are just streams of bytes sent out to a device....

Why is crafting custom packets so hard? Couldn't you just formulate a string of the information, and then send it to the device?

From the Curiously strong mint,
Ari
--------------------------------------------|
If you're not living on the edge,
then you're just wasting space.

Huh?

Coding in assembly isn't "hard" either, in the sense that the basic concepts
aren't all that difficult to understand.

It does, however, require a level of focus and attention to detail that is
much higher than generally needed with the higher level languages most of us
work in most of the time. Making a small mistake in the wrong place lead to
whatever you're trying to build failing horribly in some difficult to debug
fashion...

Custom network protocols (which is, I think, what you're talking about
here?) are probably similar... Sure it's a "just" a stream of bytes, but
they need to be *exactly* the right bytes...

MBL

···

On 9/9/07, Ari Brown <ari@aribrown.com> wrote:

Hey all,
So if packets are just streams of bytes sent out to a device....

Why is crafting custom packets so hard? Couldn't you just formulate a
string of the information, and then send it to the device?

From the Curiously strong mint,
Ari
--------------------------------------------|
If you're not living on the edge,
then you're just wasting space.

So if packets are just streams of bytes sent out to a device....

Why is crafting custom packets so hard? Couldn't you just formulate a string of the information, and then send it to the device?

Hi,

What is this in reference to? Or what is the context?

If you use UDP instead of TCP, you are in effect crafting
your own custom packets. That isn't in itself difficult,
but such packets are not guaranteed to be delivered (and/or
may be delivered multiple times.)

So the tricky part in dealing with "custom packets" usually
centers around what steps you take to ensure reliable and
sequential receipt of the data on the remote end. (If you
care about reliable and sequential delivery, that is.)

Do you have a particular application in mind?

Regards,

Bill

···

From: "Ari Brown" <ari@aribrown.com>

What is this in reference to? Or what is the context?

I just don't want to have to install a bunch of libraries on a bunch of different computers to craft packets. Just looking for a simple In-Ruby method of doing custom packets.

Do you have a particular application in mind?

No, not really. Just basic usage.
~ Ari
English is like a pseudo-random number generator - there are a bajillion rules to it, but nobody cares.

···

On Sep 9, 2007, at 4:53 PM, Bill Kelly wrote:

What is this in reference to? Or what is the context?

I just don't want to have to install a bunch of libraries on a bunch of different computers to craft packets. Just looking for a simple In- Ruby method of doing custom packets.

Do you have a particular application in mind?

No, not really. Just basic usage.

Alright. Well I was asking for specifics because your answer
would dictate which approach I would recommend.

For now I will take you literally when you say you want to do
"custom packets".

For that, you'd generally use the UDP transport layer.

  Transport layer - Wikipedia
  Internet protocol suite - Wikipedia

Here is a ruby example using UDP to create a custom packet, and
query the status of a public Quake II server:

···

From: "Ari Brown" <ari@aribrown.com>

On Sep 9, 2007, at 4:53 PM, Bill Kelly wrote:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#!/bin/env ruby

require 'socket'

abort "Usage: server_addr, server_port, cmd_str" unless ARGV.length == 3

UDP_RECV_TIMEOUT = 3 # seconds

def q2cmd(server_addr, server_port, cmd_str)
  resp, sock = nil, nil
  begin
    cmd = "\377\377\377\377#{cmd_str}\0"
    sock = UDPSocket.open
    sock.send(cmd, 0, server_addr, server_port)
    resp = if select([sock], nil, nil, UDP_RECV_TIMEOUT)
      sock.recvfrom(65536)
    end
    if resp
      resp[0] = resp[0][4..-1] # trim leading 0xffffffff
    end
  rescue IOError, SystemCallError
  ensure
    sock.close if sock
  end
  resp ? resp[0] : nil
end

server, port, cmd = *ARGV
result = q2cmd(server, port, cmd)
puts result

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$ ruby q2cmd.rb tastyspleen.net 27912 status
print
\Q2Admin\1.17.44-tsmod-2\mapname\outpost\anticheat\1\maxspectators\5\gamedate\
May 24 2007\gamename\baseq2\INFO2\NO BOTS, HACKS, CHETS PLEASE\INFO1\
All Skill Levels Welcome\cheats\0\timelimit\20\fraglimit\30\dmflags\16404\
deathmatch\1\version\R1Q2 b7260 i386 Feb 6 2007 Linux\
hostname\tastyspleen.net::vanilla\maxclients\32
0 10 "WallFly[BZZZ]"
18 61 "PeterCottontail"
7 131 "Jago"
0 84 "Turbojugend"
0 22 "crusty"
13 129 "Pnshr"
8 45 "Scratch"
19 61 "Thief"
4 223 "Javier"
0 0 "ScrotBag_Nut"
0 44 "_DrinA_AK-47_"
10 60 "Fore[SIR]"
22 56 "ANALGASSES{KEA}"
16 205 "{TNP}Dukie"
5 146 "Hacho"
10 75 "M^leSkinner BS"
0 133 "M][M Prototype"
8 64 "gro~~ovy"
4 129 "St George"
7 76 "Windows Vista"

Note: If you use UDP, you will need to understand that the packets
you send may or may not arrive at the remote end. Specifically,
they may arrive:

  - not at all
  - multiple times (duplicates)
  - out of sequence

Does this sound like what you were looking for? Or did you have
something else in mind?

Regards,

Bill

You are a god among mortals. Thank you!

Quick two questions:
- Can UDP packets be used to emulate basic IP or TCP packets?
- Is there a (slightly) easier way to do it, or should I just start writing a wrapper?

Ari
--------------------------------------------|
If you're not living on the edge,
then you're just wasting space.

···

On Sep 9, 2007, at 5:42 PM, Bill Kelly wrote:

Does this sound like what you were looking for? Or did you have
something else in mind?

# - Is there a (slightly) easier way to do it, or should I just start
# writing a wrapper?

you might want to take a peek at EventMachine..
kind regards -botp

···

From: Ari Brown [mailto:ari@aribrown.com]

Ari Brown wrote:

Quick two questions:
- Can UDP packets be used to emulate basic IP or TCP packets?

TCP is (roughly) a layer on UDP. UDP is like a barnacle spawning, sending thousands of tiny eggs into the currents, so that most can be eaten. TCP is like a bird sitting on a very few large eggs in a nest, and taking care of them until they reach adulthood.

You can invent TCP by adding tickets and acknowledgements on UDP. Each datagram goes out with a relatively unique ticket number, the receiver sends back a UDP with the ticket and an ACK, and the sender resends the unacknowledged tickets.

- Is there a (slightly) easier way to do it, or should I just start writing a wrapper?

I didn't read the whole thread but what is your actual problem? Inventing network layer protocols in Ruby is not going to be pretty...

···

--
  Phlip

- Can UDP packets be used to emulate basic IP or TCP packets?

Not exactly. UDP is a transport layer protocol, at the same
level as TCP. You could emulate the *behavior* of TCP in UDP,
by writing your own streaming protocol on top of UDP.

If you really want to manually construct your own IP packets,
it's possible to use raw sockets.

The IPPROTO_ constants ruby knows about are:

Socket.constants.sort.grep /IPPROTO_/

=> ["IPPROTO_GGP", "IPPROTO_ICMP", "IPPROTO_IDP", "IPPROTO_IGMP",
"IPPROTO_IP", "IPPROTO_MAX", "IPPROTO_ND", "IPPROTO_PUP", "IPPROTO_RAW",
"IPPROTO_TCP", "IPPROTO_UDP"]

For example, this would be creating an ICMP packet:

  sock = Socket.new(Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_ICMP)

To see an example using ICMP packets, gem install net-ping, and look at:
lib/net/ping/icmp.rb.

You could similarly create your own TCP packet:

  sock = Socket.new(Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_TCP)

...constructing the data for a TCP packet properly, I'll leave
to you. :slight_smile: (Note: On some operating systems, I think you may
need admin privileges to use RAW sockets.)

From: Ari Brown [mailto:ari@aribrown.com]
# - Is there a (slightly) easier way to do it, or should I just start
# writing a wrapper?

you might want to take a peek at EventMachine..

I'd second that recommendataion! (Although, if Ari is really
wanting to do raw sockets, EventMachine doesn't support that.)

Regards,

Bill

···

From: "Ari Brown" <ari@aribrown.com>
From: "Peña, Botp" <botp@delmonte-phil.com>

Heh, No, I don't want to invent a network protocol however awesome that would be. Reimplement all of my computer's current protocols in ruby? That would be amazing.

No, I'm just trying to replace Rubyforger (notice the extra r) and pcap with a truly native library.

Well, thanks for the help everyone!

~ Ari
English is like a pseudo-random number generator - there are a bajillion rules to it, but nobody cares.

···

On Sep 12, 2007, at 5:31 AM, Phlip wrote:

I didn't read the whole thread but what is your actual problem? Inventing network layer protocols in Ruby is not going to be pretty...

You need to be root on Unix/Linux systems to be able to use raw
sockets. On Windows XP SP2 raw sockets are limited for security
reasons, even with administrator privilege:

···

On 9/10/07, Bill Kelly <billk@cts.com> wrote:

...constructing the data for a TCP packet properly, I'll leave
to you. :slight_smile: (Note: On some operating systems, I think you may
need admin privileges to use RAW sockets.)

--
普通じゃないのが当然なら答える私は何ができる?
普通でも普通じゃなくて感じるまま感じることだけをするよ!
http://stormwyrm.blogspot.com

You might be interested in some of the code in my RailsConf Europe presentation on DNS and network programming (http://slides.games-with-brains.net/\) although it's mostly focused on doing custom encrypted network messaging there are some ideas in the UDP client/server examples that might give you a good starting point. Incidentally if you want to do reliable transmission with UDP take a look at the RUDP protocol spec as that has lower overhead than TCP and is easily implemented.

Ellie

Being and Doing are merely useful abstractions for the 'time'-dependent asymmetries of phase space.

···

On 12 Sep 2007, at 12:25, Ari Brown wrote:

On Sep 12, 2007, at 5:31 AM, Phlip wrote:

I didn't read the whole thread but what is your actual problem? Inventing network layer protocols in Ruby is not going to be pretty...

Heh, No, I don't want to invent a network protocol however awesome that would be. Reimplement all of my computer's current protocols in ruby? That would be amazing.

No, I'm just trying to replace Rubyforger (notice the extra r) and pcap with a truly native library.

Well, thanks for the help everyone!