Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Low level networking in assembler (x86 compatible)

I wish to write a bootable program in assembler that would be capable of sending and receiving network packets. I do not wish to use any libraries, I'd like to create it all by myself (and also learn while doing so). Unfortunately, I was unable to find any information regarding communication with the network card on the lowest level (sending raw sockets). I believe it's necessary to use OUT and IN instructions, although I couldn't find any information about the port that is assigned to the network card (or how to find it, if it's not always the same). Could anybody point me in the right direction? ;-)

like image 671
Neo_b Avatar asked Sep 01 '10 20:09

Neo_b


People also ask

Is x86 assembly a low level language?

It is used to produce object code for the x86 class of processors. Regarded as a programming language, assembly is machine-specific and low-level.

How does x86 assembly work?

The most basic x86 arithmetic instructions operate on two 32-bit registers. The first operand acts as a source, and the second operand acts as both a source and destination. For example: addl %ecx, %eax – in C notation, this means: eax = eax + ecx; , where eax and ecx have the type uint32_t .

Is x86 64 an assembly language?

x86-64 assembly language is a human-readable version of this machine code. x86-64 has hundreds of instructions, and compiling programs to the most efficient machine code requires a good understanding of all of them–indeed, the fastest C compiler for x86-64 processors is developed by Intel!

How do you comment on x86?

In assembly, comments are usually denoted by a semicolon ; , although GAS uses # for single line comments and /* … */ for block comments possibly spanning multiple lines. Here is an example: xor rax, rax ; rax ≔ false ; divisibility by four test rcx, 3 ; are the two right-most bits set?


2 Answers

This is quite a large problem to solve. Even getting to the point of "raw sockets" is going to be quite a bit of work.

First, with a modern BIOS, your network card won't normally be configured by default, so you'll need to deal with PCI configuration to configure it to have some ports that are visible to the processor. This will give you the basic capability of getting the CPU to actually talk to the network card.

Second, you'll have to find some documentation on the particular chipset it happens to use so you'll know how to read and write network data. With some older cards this was pretty easy, but most newer ones act as bus masters with scatter/gather hardware. Programming them to do even a simple transfer can be non-trivial. This depends completely on the hardware though.

Third, you'll need to develop a substantial part of an IP stack to be able to use even raw sockets. At the hardware level, you basically have two capabilities: receive whatever packets happen to arrive, and send packets to specified MAC addresses -- or other hardware addresses, if your card isn't (and doesn't look/act like) Ethernet.

The next couple of layers on top of that would be an ARP resolver (to let you use IP addresses instead of MAC addresses) and a DNS client (so you can use normal address names instead of something like dotted quads. Along with that, you'll probably want to build software that knows how to create/understand IP datagrams.

like image 56
Jerry Coffin Avatar answered Oct 02 '22 04:10

Jerry Coffin


Different network cards have different hardware interfaces (which is why they have different device drivers).

You might get information about the hardware from the device manufacturer (or you might not: they might regard that as proprietary information, and write their own device drivers).

You might also get that information by looking at the source code of open source network cards: for example, I'd guess, for Linux; or, perhaps, the Crynwr packet drivers.

like image 28
ChrisW Avatar answered Oct 02 '22 06:10

ChrisW