testing network

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

testing network

Post by GLneo »

hi all, i have a simple question, in maybe qemu or bochs how do i test my NIC driver with no ip, net, etc. just the packet sending driver? I will start my NIC driver soon!

thx!
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Can you receive packets? I'd test that first, because once you can receive packets, you don't need much code to identify an ARP packet, and you can then easily test sending by making it reply ARP packets looking for some hard-coded IP address. You don't need any IP networking for that...

That way if you manage to get it right on the first try, you can simply ping the address hard-coded into the kernel. If you see the ARP request, you'll know you can receive. You can then look at your host ARP tables (in Linux this is "arp" but I just forgot what it's in Windows.. "arp print" I think) and if you see your IP listed with your emulators MAC, you know that sending also works (if it shows 00:00:00:00:00:00 you know it never got a reply). Notice that you won't get any ping replies before you implement enough IP to reply to ICMP echo, but trying to ping will make your other computer first resolve the IP using ARP, and if that much works, you can send/receive at least some packets. :)

Alternatively you could just send some packets to FF:FF:FF:FF:FF:FF (broadcast address) and use something like tcpdump to see if your host got the packets. Don't panic if you see lots of other packets flying around. At least Windows likes to send SMB broadcasts around all the time..

In any case, ARP is a simple protocol, and it's going to be the first protocol you are going to implement (simply because you need ARP to find ethernet addresses) so you could just test with that...
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

You can use a packet sniffer like Ethereal
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Well yeah, ethereal is one option. I like to use plain tcpdump, and if I need to track connections, then ettercap. There are quite a few tools, so pick whichever you happen to like. :)
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

And once you have a working driver, and you need to work with protocols, write a simple program that lets you send arbitrary data via UDP/TCP to hosts on ports of your choice.

I wrote a little test suite that I just have to type in

Code: Select all

sendto udp 192.168.1.109 1024 5 Hello!
and "Hello!" gets sent to my OS on port 1024 (via UDP) with a 5 second timeout.

Also quite useful for testing any type of server...
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

pcmattman wrote:And once you have a working driver, and you need to work with protocols, write a simple program that lets you send arbitrary data via UDP/TCP to hosts on ports of your choice.
Indeed, that's a good idea, though I think you should also receive and print the contents of possible replies as soon as your protocol stack allows that..

For UDP such a program is pretty simple. For TCP that's basicly telnet without the telnet command processing, because unfortunately one has to establish a TCP connection before sending data makes much sense.
and "Hello!" gets sent to my OS on port 1024 (via UDP) with a 5 second timeout.
mmh.. what is the timeout for? I mean, UDP is supposed to be a fire-and-forget protocol, right?
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Timeout is for waiting for a reply... select() function.

My OS will print data it receives, when data gets sent to my program it gets displayed. My program also supports TCP - I tested it on my web server :D and on a timeserver.
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

Post by GLneo »

but will the emulator somehow get an IP address, I'm confused?
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

GLneo wrote:but will the emulator somehow get an IP address, I'm confused?
You assign an IP to the NIC and use that for everything. ARP requests from other PCs talking to your OS in the emulator should be handled by your OS if the IP is the same and your physical address returned.

Once you implement UDP, you can use DHCP.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

pcmattman wrote: Once you implement UDP, you can use DHCP.
Theoretically I guess one could also special case DHCP, as it doesn't follow the normal IP rules of addressing anyway..
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
GLneo
Member
Member
Posts: 237
Joined: Wed Dec 20, 2006 7:56 pm

Post by GLneo »

so i could just set the IP to anything and packets would just make it to my emulated OS somehow ?
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

GLneo wrote:so i could just set the IP to anything and packets would just make it to my emulated OS somehow ?
This is what happens in an ICMP ping:
  • Client checks his ARP cache for the IP
  • If he can't find it, he sends out an ARP request
  • If he can (or if the ARP request is replied to), he sends the request
  • The server replies
You need to implement ARP handling in your OS so that when the ARP request is broadcasted over the network your OS can reply to ones that are destined for the IP you've chosen, then you reply with your physical address.

Ethernet uses physical addresses, not IP addresses. You might like to look into network layer drivers or read up on the subject[/list]
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

GLneo wrote:so i could just set the IP to anything and packets would just make it to my emulated OS somehow ?
Not quite so. Every computer in a TCP/IP network is configured to have at least the following three pieces of information: IP-address, network-mask, and default-gateway. There could be more than one default gateway, or there could be none (standalone network not connected to others), but you can get pretty far ignoring those.

Now, in the Internet, every IP address is given by the god's of internet for you to use. It's typically divided to small blocks and those divided futher and futher and so on, as people create sub-networks and sub-sub-networks and so on, and there's a lot of interesting stuff going on. You can also ignore most of that stuff, until you want to start routing packets yourself.

When a normal person connects his PC to the internet, there are a few possibilities. She could get a static IP/netmask/gateway from her ISP. Or her ISP could just tell her to use DHCP. Most operating systems will configure by DHCP unless you tell them not to, but you can always set the settings manually, and when you don't have a DHCP server somewhere, you have to. Now whether the IP came by paper or automatically by DHCP, it can be either a public IP, which your ISP got from the gods of internet, or it could be a private IP, because when the internet was created, the gods were wise and reserved some addresses for all kinds of private networks.

There are three such blocks. One is 10.x.y.z which is reserved as a single block, and has netmask 255.0.0.0 unless you divide it futher (usually you do). This is big enough space to fit private corporate networks at least most of the time, with potentially huge number of smaller sub-networks of it's own.

Then there's 192.168.x.y, which is a set of 256 networks, each with netmask 255.255.255.0, and each of which has room for 256 IP addresses (or well, 254 as you might not want to use 0 and 255, which have special meanings). You could also use 192.168.x.y as a single 255.255.0.0 network, but usually that's not how it's used.

Then there's a third one, which nobody care about, starting 172...blah. It's nasty area and we don't like it so we'll ignore it. It has a netmask of 255.240.0.0 which is pretty ugly. Not so ugly if you write it as 172.16.0.0/12. We could write 192.168.0.0/16 for the whole 192.168.x.y block, though normally you have 192.168.x.0/24. Hehe, so we indeed often write /x instead of ugly netmask, and that's how many bits in the written-out-mask are ones.

There's some other special networks, 127.0.0.0/8 is looback. It always means the same computer. Most often you see 127.0.0.1 but 127.1.2.3 would be equally valid and it'd still be loopback. Another block you commonly see is 169.254.0.0/16 which is for "auto-DHCP" or dynamic IP addresses without having a DHCP server, as in if you plug a group of laptops into a switch, they'll figure out 169.254.x.y addresses for themselves so you can play Quake without having any network configuration. Not good for much else.

Then there's broadcasts (255 meaning all, say: 255.255.255.255 for everyone in the internet, 192.168.1.255 would be everyone in my home LAN) and this net (192.168.1.0 would be address of that same LAN). Lots of other nasty stuff too, but mostly safe to ignore.

So what do you do with these pieces of info? Say, you picked 192.168.1.0/24 as your local network between your normal computer and your OS. Say, your normal computer is going to be 192.168.1.11 and your OS is going to be 192.168.1.12. And then you have an old Linux box as gateway (at 192.168.1.1) which knows how to do NAT (transparently replace your local 192.168.x.y addresses to public IPs and back).

So if we convert the /24 into bits, we get FF:FF:FF:00 in hex, or 255.255.255.0 in decimal. Now when you wanna send something, you take your own IP address and the netmask, and Bitwise-AND them. For 192.168.1.12 and 255.255.255.0 this gives you 192.168.1.0 (which is "this network" quite surprisingly). Then you take the destination address (say 192.168.1.11) and do the same, giving you either 192.168.1.0 again (if it's in the same network) or something completely different.

If you get the same network address for yourself and the destination, you know it's in the same network, consult ethernet layer for an ethernet address of the destination (which potentially sends some ARP packets) and then you fire the packet directly to where it's going. If it's not in the same network, you need to send it through the gateway. So the IP packet still looks exactly the same, but you instead ask the ethernet layer for the ethernet address of the gateway, and then use that when you put it on wire (IP headers still contain the address of the final destination so the gateway can figure out where to send it next).

So, basicly, you pick up a private network, like 192.168.x.0/24 (with x between 1-254, or 0 for Windows TAP with NAT for QEMU), then allocate different addresses from this to each of the hosts in the network. It's common to have a single gateway get the address x.y.z.1, though my personal home LAN forexample doesn't follow this convention (for historic reasons my gateway is .2).

Then every time you're sending a packet, you ask your ethernet ARP subsystem for either the hosts or the gateways ethernet address, depending on whether it's network address is same or different as yours, which you find out by doing bitwise-and with the network mask for each address and comparing the results. This is called "first-hop" routing btw, and is basicly the over-simplification of what a gateway does when it consults routing tables to figure out what direction it should be sending a given packet. But a simple host can just do first-hop routing and ignore the complexity.

That's about it... if you have more than one computer, I'd start by playing a network admin a bit first.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
omin0us
Member
Member
Posts: 49
Joined: Tue Oct 17, 2006 6:53 pm
Location: Los Angeles, CA
Contact:

Post by omin0us »

rfc's are your friend :]
http://ominos.sourceforge.net - my kernel
#ominos @ irc.freenode.net
http://dtors.ath.cx - my blog
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

omin0us wrote:rfc's are your friend :]
Indeed. Good one to start from is RFC1122. Easy to remember too. ;)
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Post Reply