Page 2 of 4

Posted: Sun Apr 15, 2007 10:53 am
by mystran
Yeah ok, I started writing my own NE2k driver (and ethernet code and what not) for my kernel, and after puzzling a bit with datasheets and docs, and other peoples code, and datasheets again, it basicly seems that your method of getting the MAC is right... but what you must do (besides storing it for your own use) is to write it into PAR0-PAR5 after you've initialized the NIC.

Once you've written the MAC you read from the card ROM into PAR0-PAR5, you can receive packets just fine without promiscuous.

As for your promisc image, yeah, it gets PING in fine, I forgot to disable my local firewall (which is a bit aggressive at times).
tcpdump: listening on eth1
20:02:36.991123 wall.local.foo > 192.168.1.109: icmp: echo request (DF)
20:02:37.009216 192.168.1.109 > wall.local.foo: icmp: echo reply
20:02:38.005814 wall.local.foo > 192.168.1.109: icmp: echo request (DF)
20:02:38.022424 192.168.1.109 > wall.local.foo: icmp: echo reply
20:02:39.005044 wall.local.foo > 192.168.1.109: icmp: echo request (DF)
20:02:39.017319 192.168.1.109 > wall.local.foo: icmp: echo reply
20:02:40.004943 wall.local.foo > 192.168.1.109: icmp: echo request (DF)
20:02:40.024266 192.168.1.109 > wall.local.foo: icmp: echo reply
20:02:41.004932 wall.local.foo > 192.168.1.109: icmp: echo request (DF)
20:02:41.017637 192.168.1.109 > wall.local.foo: icmp: echo reply
20:02:41.984804 arp who-has 192.168.1.109 tell wall.local.foo
20:02:41.992531 arp reply 192.168.1.109 is-at b0:c4:20:0:0:0
20:02:42.004847 wall.local.foo > 192.168.1.109: icmp: echo request (DF)
20:02:42.017633 192.168.1.109 > wall.local.foo: icmp: echo reply
There's probably something wrong with the ICMP echo reply packet itself, since ping still reports 100% packet loss. But your packets are sent fine.

Sorry for slow reply, I had to sleep and do some other stuff.. ;)

Posted: Sun Apr 15, 2007 10:57 am
by mystran
Oh and sorry for complaining about these Bochs messages:

Code: Select all

00021196309i[NE2K ] RCR write, monitor bit set!
00021196317i[NE2K ] TCR write, loop mode 1 not supported
It seems to be perfectly valid (and probably necessary) stuff to do for a real NIC, and doesn't hurt anything on Bochs, even if it complains about not supporting them.. stupid Bochs (I should have checked better, really sorry about that).

Posted: Sun Apr 15, 2007 11:04 am
by mystran
I've configured Bochs to use the PCI version btw, as I have no intentions of ever bothering with the ISA version myself..

Posted: Sun Apr 15, 2007 3:07 pm
by pcmattman
This morning I figured out that I could set the PAR0-PAR5 registers after retrieving it the old way...

I also figured out last night at about midnight that the address I put in the IP header for the 'source' is in host order, not network order :roll: .

I'll change it today and see if it works.

Posted: Sun Apr 15, 2007 3:24 pm
by Kevin McGuire
14:24:18.004407 IP Matthew > 192.168.1.109: ICMP echo request, id 512, seq 1537, length 40
E..<I)....ml...n...m..E[....abcdefghijklmnopqrstuvwabcdefghi
14:24:18.010338 IP 192.168.1.109 > Matthew: ICMP echo reply, id 512, seq 1281, length 40
E..<....@......m...n........abcdefghijklmnopqrstuvwabcdefghi
m is 109 and n is 108 and they are in host order.

I knew there was something funny about the looks of those packets. I kept reading and found out you already knew but strange that it was right in front of you, huh.

But, even these should match but be reversed. They do not match.

Code: Select all

E..<I)....ml
E..<....@...
There might be something else wrong?

Posted: Sun Apr 15, 2007 3:27 pm
by pcmattman
I just then swapped the byte order to the appropriate values...

Still doesn't work :?

Maybe the packets get modified too much, but all I do for an echo reply is change the type to 0 (ECHO REPLY) and redo the checksum.

Posted: Sun Apr 15, 2007 3:34 pm
by Kevin McGuire
Oh. You only gave us the IP layer and above. That is a dirty shame.

Posted: Sun Apr 15, 2007 3:37 pm
by pcmattman
You can view the code if you want, it's in the 'net' folder of my CVS repository.

Edit: Here's the packets:

Code: Select all

07:49:17.000273 IP Matthew > 192.168.1.109: ICMP echo request, id 512, seq 23297, length 40
E..<C%....sp...n...m...Z..[.abcdefghijklmnopqrstuvwabcdefghi
07:49:17.006101 IP 192.168.1.109 > Matthew: ICMP echo reply, id 512, seq 23297, length 40
E..<[email protected]......[.abcdefghijklmnopqrstuvwabcdefghi
The two addresses switch because of the reply... it still doesn't look right though.

Edit: I have come to the conclusion that somewhere during the send routines something goes wrong with the packet creation. Could someone please look over my code (eth_lib.c, ip_lib.c and icmp_lib.c) and tell me what I'm doing wrong?

Posted: Sun Apr 15, 2007 4:01 pm
by Kevin McGuire
[edit]
I give up. I am completely wrong here. Forgive me for posting! I am just going to leave the original message anyhow.
[/edit]
07:49:17.000273 IP Matthew > 192.168.1.109: ICMP echo request, id 512, seq 23297, length 40
E..<C%....sp.. .n ...m ...Z ..[. abcdefghijklmnopqrstuvwabcdefghi
07:49:17.006101 IP 192.168.1.109 > Matthew: ICMP echo reply, id 512, seq 23297, length 40
E..<....@..... .m ...n .... ..[. abcdefghijklmnopqrstuvwabcdefghi
Listen. "E" is 0x46 in hex. The six means that many thirty-two bit fields in the header. You have that many plus four bytes since I assume the letter "a" should be the first byte of the data packet.

Also using that way of thinking leaves.
E..<C%....sp...n...m...Z..[. abcdefghijklmnopqrstuvwabcdefghi

That is twenty eight bytes. So lets take four off.
E..<C%....sp...n...m...Z
The options field should be next. ...Z
The IP address should be next.
E..<C%....sp...n...m
...n...m
Which are in network byte order, and even were in the previous posts you made. I am sorry I somehow had a brain glitch and though they were wrong. I still have a question then... If you thought they were reversed before. Then you reversed the byte order for correction..then why are they still in the same order?? Even though they are correct.

You need to make posts like that in hex instead of ASCII. You just make it extremely hard for us to decipher it correctly AND include the MAC layer too. Not just the layer that you feel is relevant, please.

Posted: Sun Apr 15, 2007 4:03 pm
by pcmattman
Here's the sniffer dump in hex:

Packet 1 (sent TO os):

Code: Select all

4500003C5B13000080015B82C0A8016EC0A8016D0800D25A020079016162636465666768696A6B6C6D6E6F7071727374757677616263646566676869
Packet 2 (sent FROM OS):

Code: Select all

4500003C000100004001F694C0A8016DC0A8016E000084FE020079016162636465666768696A6B6C6D6E6F7071727374757677616263646566676869
I took out the reversing when I realized they were reversed already.

Posted: Sun Apr 15, 2007 6:28 pm
by Kevin McGuire
Try checking the checksums. I had a lot of problem when doing checksums for the first time. I tried blanking the checksum field in you're header and kept getting a different value that should be there when calculating the checksum for the IP header.

I got 0xe89b. I remember reading a few months back that you can place that number there in little endian or big endian - does not matter.

http://www.netfor2.com/ipsum.htm

Code: Select all

u16 ip_sum_calc(u16 len_ip_header, u16 *buff)
{
u16 word16;
u32 sum=0;
u16 i;
    
	// make 16 bit words out of every two adjacent 8 bit words in the packet
	// and add them up
	for (i=0;i<len_ip_header;i=i+2){
		word16 =((buff[i]<<8)&0xFF00)+(buff[i+1]&0xFF);
		sum = sum + (u32) word16;	
	}
	
	// take only 16 bits out of the 32 bit sum and add up the carries
	while (sum>>16)
	  sum = (sum & 0xFFFF)+(sum >> 16);

	// one's complement the result
	sum = ~sum;
	
return ((u16) sum);
}

Posted: Sun Apr 15, 2007 6:46 pm
by Kevin McGuire
As a matter of fact this is kicking my @$$.

Okay. I got the checksum working and came up with the correct one in both.. so never mind that.

Posted: Mon Apr 16, 2007 12:50 am
by pcmattman
Is there any way that Windows can tell me that the checksum was wrong?

These packets are definitely correct in their fields, can you check my checksums?

Code: Select all

Sent to OS:
E71D2346540A03004A0000004A000000B0C420000000000FEAA015AF08004500003CA635000080011060C0A8016EC0A8016D0800C25A020089016162636465666768696A6B6C6D6E6F7071727374757677616263646566676869E7
Sent from OS:
1D23465CF903004A0000004A000000000FEAA015AFB0C42000000008004500003C00010000400121BEC0A8016DC0A8016E0000E368020089016162636465666768696A6B6C6D6E6F7071727374757677616263646566676869
The above is including everything :D, timestamp, etc... and the MAC addresses:
OS: B0:C4:20:00:00:00
My PC: 00:0F:EA:A0:15:AF

Posted: Mon Apr 16, 2007 5:46 am
by mystran
IP header checksum should be over the IP header (including options if any). As for the ICMP checksum the following is from RFC 792:

Code: Select all

   Header Checksum

      The 16 bit one's complement of the one's complement sum of all 16
      bit words in the header.  For computing the checksum, the checksum
      field should be zero.  This checksum may be replaced in the
      future.
But the following is from RFC 950:

Code: Select all

         Checksum

            The checksum is the 16-bit one's complement of the one's
            complement sum of the ICMP message starting with the ICMP
            Type.  For computing the checksum, the checksum field should
            be zero.  This checksum may be replaced in the future.
In fact, RFC 950 lists for all packet types it mentions, that Checksum is over the whole message (not including IP headers, ofcourse).

As for everything else in the message, yeah they look fine to me.

Notice that those obviously need to be stored in network byte order (like everything else).

Posted: Mon Apr 16, 2007 5:53 am
by pcmattman
So... I should compute checksums over the entire packet and one's complement the one's complement of the sum? And send in network order. Sounds easy enough :D