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 Sep 9, 2007, at 4:53 PM, Bill K. 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.
~ Ari
English is like a pseudo-random number generator - there are a
bajillion rules to it, but nobody cares.

From: “Ari B.” [email protected]

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 B.” [email protected]

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:

#!/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

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

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

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.

From: Ari B. [mailto:[email protected]]

- 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 B.” [email protected]

  • 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: “Peña, Botp” [email protected]

From: Ari B. [mailto:[email protected]]

- 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

Ari B. 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…

On 9/10/07, Bill K. [email protected] 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.)

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 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!

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

On 12 Sep 2007, at 12:25, Ari B. wrote:

pcap with a truly native library.

Well, thanks for the help everyone!

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.