Monday, April 30, 2012

One interior network, one exterior network

While David is working on trying to speed up the router, I have been working on getting two networks up successfully. We have both ran into a few problems but I will explain my part.
I have successfully gotten two networks to work while also changing my code a bit. The first thing I did was make iproute() return the right interface. Because of this, I got rid of setting the pkt->NET in send_via_arp() that I had done last week. Next I changed one interface's IP to a separate network. With this, the two networks could communicate with each other easily but I quickly ran into a problem when an ARP entry is not in the ARP table. If this happens, it will return the wrong interface and the packet will never be sent (and the route will be added wrongly). I haven't had a chance to try my fix out yet but at the moment it is just checking if there is a valid ARP entry. If not, it will broadcast an ARP request. Otherwise, if it is an IP address that is not in our interior network, it will automatically change the NET interface of the packet to the interface that is connected to the exterior network. I am still trying to make a more elegant fix. This problem only occurs when a Linux machine on the interior network is trying to be accessed through the network with no prior communication from the Linux client. It will not occur if two Windows machines are connected because when Windows sees a network connection, it immediately sends out ARP requests to it's gateway.
Once this is fixed (which it should by the end of tomorrow), I will work on two things: setting up the exterior network interface to act as a DHCP client and setting up some type of address translation for routing.

Sunday, April 29, 2012

[Hardware Router] Layer 3 Perspective


The following is a design specification of the hardware router, from a layer 3 perspective:


  • Receive Packet
    • Delimit data according to Ethernet Standard
    • Store delimited data in 2D Array (memory)
  • Analyze Packet
    • Extract relevant header information
    • Store information in temporary registers for ease of access\
  • Decide what to do with packet
    • Exception for own IP (must respond if valid packet)
    • If unrecognized information, drop packet.
      • Also drop if TTL = 0
    • Associate outbound port with packet by modifying bits directly in the queue
  • Modify Packet Data
    • Change destination IP to destination associated with chosen outbound port
    • Change source address to IP of outbound port
    • Subtract from TTL
    • Recalculate checksum and set it
      • Checksum is the 16-bit one's complement of the one's complement sum of all 16-bit words in the header.
      • Example checksum calculation, for IP Header: 4500003044224000800600008C7C19ACAE241E2B (20 byte header).
        •  4500+0030+4422+4000+8006+0000+8C7C+19AC+AE24+1E2B = 2BBCF
        • 2 + BBCF = BBD1 = 1011101111010001 -> 1's comp = 0100010000101110
        • Checksum = 442E
  • Send Packet
    • Write to outbound port using Ethernet protocol
    • Delete data for sent packet from memory and shift all other members of the array up (FIFO).
This is the top-level design. In order for it to work, we must first implement Ethernet protocol on the board.

Post describing Ethernet implementation will follow.

Saturday, April 28, 2012

NIOSII - Week 10

This week I tried changing the address lines to see if that would solve the problems. I tried shifting the data where the address is assign in the verilog code, however that didn't work and made it worse. I tried changing how the SOPC address line is inputed into the lan91c111 address line, but that doesn't help either. I tried changing the verilog so that address line is size of 4 in the verilog and created the new symbol to match the address by how the NIOS ethernet guide say, address [4:2] goes into address [3:1] in the lan91c111. That also did not work. I tried changing the SOPC so that the lan91c111 is set as onboard ethernet port. For that design I used the ethernet address as told in the  NIOS ethernet guide, and the outcome was that the ethernet acts almost exactly like how I had it last week. The one change was that the MAC address was not able to be found in the flash and had to give it the board number to get its MAC address.

Saturday, April 21, 2012

Packet forwarding with a working routing table on one network

So far, we have gotten a working router with one network per interface. This week, we have gotten all interfaces to work under one network. With a little guidance and a lot of research, we found a semi-efficient way to get all the interfaces on one network to communicate with each other.

So the first thing we changed from last week was the promiscuous mode. Last week, we tried to enable "'ENABLE_PHY_LOOPBACK" but that actually ended up causing us too many problems. From what we could figure out, when this option was enabled, the PHYs would setup differently (The usual start up code did not appear). None of our previous code would work with this setting (notably they would never reach the ARP forwarding we had programmed in). So with the advisement of Professor Pak Chan, we just enabled ALTERA_TSEMAC_CMD_PROMIS_EN_MSK. This would let the PHYs start up the right way and all our code was still intact. From here, we first had to make sure our promiscuous mode worked. We ran the same ARP tests as least week and we could see the ARP replies now.

Next, we started ironing out the details for ARP forwarding. The first thing we did was broadcast any ARP packet coming in that wasn't destined for the interface that the packet was received on. Since our ARP forwarding was already working, we just sent the packet to multiple interfaces except the interface that it was received on. Next we tried to get the ARP reply to forward correctly. The problem was that we didn't have a working ARP table yet so we could not reroute a packet easily. Because of this problem, we worked on getting the ARP table to setup correctly first. We would add an entry for each ARP request and reply (using make_arp_entry()) while also adding the MAC address into the table before each packet is sent back out. Once we could confirm this was working correctly, we finished forwarding the ARP reply part. To do this, we would call find_oldest_arp() (returns either an empty entry or finds the entry you are looking for) to find the ARP table entry that the packet is destined for and send the packet out that way.

Once ARP forwarding was all done, we moved onto working on the routing table. The problem here was that although the ARP packets were moving correctly through the router, any other packets would automatically be routed to interface 1 (eth0). After thinking about it for a while, we realized that because all our interfaces were on one network, we could use the ARP table to help route our packets. As we traced the way the packet would get the net interface, we found that it would often end up at the function send_via_arp() in et_arp.c. We saw that the only reason the packet wasn't actually being sent out the right interface was because the packet struct's NET value is never set to the right interface. So before the et_arp() (will send packet based on ARP information) function is called in send_via_arp(), we would change the interface to whatever interface was returned from an earlier call of find_oldest_arp(). After this slight change, all the packets forwarded to the right place but when investigating the routing table, all of our entries all pointed to the same network interface which is wrong. To fix this, we looked at where add_route is called. This function is mostly called from ip_route() so we looked into how ip_route() would add a route. It turns out it would look at the interface IP address and as long as it matched our destination IP address' subnet, it would add that to the routing table. To fix this, we have ip_route() calling find_oldest_arp() instead and using the ARP entry to add the right interface to the routing table.

After this, we are able to communicate through the network. We have tested using simple pings along with SSH to test TCP packets also. Next, we are going to split up for a bit to look into two parts. I am going to look into how I'm going to route into another network while David is going to look at optimizing packet buffers. After adding another network and routing correctly to it, I will probably have to look into implementing some sort of address translation.

Friday, April 20, 2012

NIOSII - Week 9

I figured out the problem with the daughter card was that it was not reading and writing to the correct registers. Everything in the register was written twice so the offset had to be shifted left to get the correct offset.

Here is the output when I fixed the offset.

Copyright 1996-2008 by InterNiche Technologies. All rights reserved.
Your Ethernet MAC address is 00:07:ed:ff:75:4a
prepped 1 interface, initializing...
Created "Inet main" task (Prio: 2)
Created "clock tick" task (Prio: 3)
smsc91c111 Auto-negotiation: 100 Mbps, Full Duplex
SMSC ethernet Rev: 0x3391, ram: 8192
mctest init called
IP address of et1 : 0.0.0.0

However the DHCP doesn't work, so there are still some problems. I found out the offset only fixed the 16DIRECT RD/WR function, but the 8DIRECT RD/WR function is not RD/WR correctly.
I checked by read the mac address which uses 8DIRECT RD/WR.
Here is what I found.

MAC     Offset     Register Data Written to
0x00      4             8,9
0x07      5             8,9
0xed      6             12,13
0xff       7             12,13
0x75      8             16,17
0x4a      9             16,17

Wednesday, April 18, 2012

Stratix Router Development (4/17)

4/17 - The PHY error was fixed, but still DHCP was unable to be sent/received. The LED light on the board was lit, however. This may not seem like a big issue, since DHCP is low priority for the board's overall function as a router, but the DHCP packets failing to send are a symptom of the issue that the board is still unable to send/receive packets. After investigating the method for packet sending, I added a print statement for debugging purposes. The board sends by setting up a send-queue and by running through it and sending packets as it goes along; it is this that I sought to debug. Printing out the contents of the send queue each time it was added gave us two pieces of information:

  • The contents of the send queue were identical each time something was added into it.
  • The timing of the sends was apparent. Data was added to the send queue (and the print statement was therefore triggered) every few seconds after the board detects an Ethernet link (and the LED therefore turns on).
Wireshark (a packet monitoring software) determined that no data was being actually sent out of the port, not even garbage data. I used an oscilloscope to probe the live pins to confirm this. There is no signal on any of the Tx or Rx pins of the Ethernet cable, even though the LED is lit and the print statement is being triggered, informing us that the send queue is being used. It is still unclear how to solve the problem of packet sending/receiving, but we have learned more about the situation.

Monday, April 16, 2012

Stratix Router Development (4/8 - 4/16)

At the start of the week, I came to the decision that it would be better to focus on moving forward with other parts of the project rather than working on the Stratix board, since it was complicated to arrange a suitable working arrangement for two people using one board. Matthew Luu sent me the routing algorithms and code that he and David had worked on so that I could look at the verilog files and their program and begin to adapt it for use on the Stratix board while Simon was working on setting up Ethernet on the daughter card.

It quickly became apparent that this was a lower priority and should be set aside until the daughter card Ethernet access was up and running. The problems with the daughter card were more severe than I initially anticipated. On Tuesday, April 10th, I began collaborating with Simon again on bringing up the Ethernet card on the Stratix board.

On April 11th, I ran through the pin layout of the daughter card in Altera Quartus Pin Planner and found that the assignments were properly set. I attempted to use an oscilloscope to probe each pin and determine whether correct signals were visible on each of the daughter card's pins. The data was inconclusive. Although many of the signals were properly set, such as both of the clock pins, the pins responsible for data flow were completely blank.

On April 12th, I continued to approach the problem from a physical mindset while Simon worked used SignalTap to trace the signal paths and determine whether accurate results were present. No breakthroughs happened on this day.

On April 14th, Simon received an email from Professor Pak Chan indicating that a register offset of 14 was part of the reason for the problem. After adding the correct values, it appeared that the card's interface initialized properly, but still no data was being sent out. An error was being thrown, saying "s91: No PHY found". After examining the code, I realized that the program was using a simple check to make sure that data pulled from the registers was being compared to the ALTERA_AVALON_LAN91C111_PHY_COMPANY_ID and ..._MFCT_ID registers to determine whether the PHY is functioning. After adding a statement to print the id1 and id2 variables (which should contain the ..._COMPANY_ID and ..._MFCT_ID, it was apparent that no data at all was transmitted, i.e. both IDs had a value of x0.

On April 16th, Simon determined that the reason the PHY was not visible was another register issue. The file altera_avalon_lan91c111_regs.h needed to be modified to produce a correct offset. After this, the issue with the PHY was resolved, but a new error occurred indicating that DHCP was failing.

Saturday, April 14, 2012

Modifying the Lookup Method of the Routing Table and More!

Recently, Matthew and I found out (with the help of Professor Pak) that Altera's built-in programmable promiscuous mode had to be enabled in order for our ARP forwarding to work for interfaces that are linked to the same sub-network.  In networking, promiscuous mode basically means that any packets that go through a certain interface/port will be read through and will not be omitted. In other words, this will help us because once this is enabled, our Altera board will not be able to omit and drop packets with MAC destination addresses that are not destined for the same interface/port.  To enable this mode, I basically looked up where promiscuous mode is set in the C library headers and found that there is a option ('ENABLE_PHY_LOOPBACK') defined to enable two masks ('ALTERA_TSEMAC_CMD_PROMIS_EN_MSK' and 'ALTERA_TSEMAC_CMD_LOOPBACK_MSK'), which overall enables the programmable promiscuous mode.  I haven't been able to test out to see if this mode works since Matthew still needs to revise his application code for ARP forwarding, but conceptually it seems like it should fix most of our problems we're facing at the moment.

Unfortunately, we encountered another problem pertaining to performance of the router board.  When using the evaluation version of PassMark, a benchmark testing software that allows us to test the speed of our router, we were getting very low numbers (average was around 1000kbps, which is far below our expectations for our project.)  Matthew and I figured that the problem might have to do with the initialization of the MAC and the drivers before Simple Socket Server ran.  In particular, I noticed that the initialization routine (tse_mac_init) for the Triple-Speed Ethernet MACs contained a variable 'speed', which may determine how fast the interfaces can be.  For now, I set the variable to be fixed as 1000Mbps for all the interfaces (this routine is called once for each interface), but I have not tested it yet.  This way, I would think that all the interfaces will be able to handle speeds of up to 1000 Mbps.

At this moment, I am currently looking up rt_lookup and finding a way to modify the subnet masking algorithm inside it (which tries to match routing table entries with the packet it's trying to forward/route) such that it can work not only on different sub-networks as we tested before, but all through one same sub-network for all the interfaces.  As Matthew explained on his previous post, the forwarding of packets from one interface to another does not work when all the interfaces are on the same subnet.  Right now, it should only use the interface with the best matching IP address based on the masking, which would be the very first interface. I will give further updates about the lookup method over the weekend.

NIOSII - Week 8

For the Stratix board I had a problem with the IOR signal, when IORD_ALTERA_AVALON_LAN91C111_BSR(smsc->regbase) was called in a loop I would get
IOR signal always high which was not correct. So I rebuilt the project and got the IOR signal to alternating which is the correct signal.

Here is output of SSS.

InterNiche Portable TCP/IP, v3.1
Copyright 1996-2008 by InterNiche Technologies. All rights reserved.
Your Ethernet MAC address is 00:07:ed:ff:75:4a
dtrap - needs breakpoint
prepped 1 interface, initializing...
mctest init called
IP address of  : 0.0.0.0
dtrap - needs breakpoint
dtrap - needs breakpoint
Error sending DHCP packet on iface 0.
ip_exit: calling func 0x311cce4
ip_exit: calling func 0x3124874

dtrap - needs breakpoint is outputed because when reading for regbase the value is not 0x3300
when it is  AND with 0xFF00. I was able to get past this error by using a for loop and adding 1 to the regbase untill I get the correct value. Found that if you add 14 to thereg base you get the value you need. So I change the regoffset to 14 and I didn't get the dtrap - needs breakpoint error. Now I get a new error.

Here is output of SSS.

InterNiche Portable TCP/IP, v3.1
Copyright 1996-2008 by InterNiche Technologies. All rights reserved.
Your Ethernet MAC address is 00:07:ed:ff:75:4a
prepped 1 interface, initializing...
s91: No PHY found
SMSC ethernet Rev: 0x1f, ram: 0
mctest init called
IP address of et1 : 0.0.0.0
Created "Inet main" task (Prio: 2)
Created "clock tick" task (Prio: 3)

s91: No PHY found is outputed if the PHY ID in the register doesn't match the PHY ID for lan91c111and is unable to validate a presence of the PHY.

Figured out what the problem is, it is read at the wrong address.

Thursday, April 12, 2012

Putting everything on one network on DE4

Our next task is to put all the ports on one network. We had initially tried this before but decided to test out how the packets were routed first but we ran into problems. We are encountering the same problems but now understand what is happening a bit deeper now.

The first problem has to deal with ARP forwarding. There is really just one big problem here and it is that ARP forwarding doesn't seem like a reality for this project. That's not to say I'm giving up, but the basic ARP forwarding does not seem possible because the interface does not recognize a packet that is not destined for it. To test this, I forwarded the ARP request that would be sent from one client to another. To do this, a few values had to be changed (most importantly the interface to send out of had to be changed). When the other client replied with an ARP reply, it would try to send it to the destination of the original client. Because of this, the packet is never received by the DE4 board (which I find to be strange). To test this out, I made the code print out something every time the SGDMA receive callback function is called. It would never print out that it acquired any sort of ARP reply. Another test I did was to change the original ARP request packet to have the source destination MAC address as other things and no packet would be seen by the DE4 board unless it was destined for the right MAC address (or it was broadcast). I tried to compare using my own D-Link router but the router is able to see packets not destined for the right MAC address. So instead of ARP forwarding, I am going to try to go with setting up something like an ARP proxy. So instead of forwarding ARP requests, I will just use the ARP table for the DE4 board. If an ARP request comes in for an IP that is already in the ARP table, the DE4 board will reply with it's own MAC address and handle the packets as they come in. Otherwise, the DE4 board will broadcast a request and try to build an updated ARP table.

The second problem has to deal with the behavior of rt_lookup() (route lookup) when used with interfaces that are all on the same network. As David has pointed out before, most packets that come in will cause the board to call rt_lookup() before it routes the packet through. Unfortunately, when all the interfaces are all on the same network, rt_lookup() will just return the first interface it is looking at. An example would be that if a client is pinging the board's eth2, all the ping replies will still be sent out eth0. At the moment, David is looking into this while I work on the ARP proxy.

Monday, April 9, 2012

Implementation and Research of the Routing Table Function Calls


Over the past week, I have been working on mainly setting up the rest of the interfaces and getting them to work correctly on the board as well as researching and 'implementing' the routing table with Matthew.  In fact, while researching through the Nichestack functions for anything related to routing tables, most of the functions used to manipulate the routing table are already provided for us by the Nichestack/Simple Socket Server library.

To get the other two interfaces on the board to work with the previous two interfaces that we set up last quarter, I basically revised the SOPC design by adding in two extra Triple-Speed Ethernet MACs (for the PHY layer of the interfaces) as well as two extra sets of SGDMAs (two transmit SGDMAs and recieve SGDMAs) and  that can be used by the MACs to assist on forwarding packets and reducing overhead for the processor on the DE4 board.  The design is then implemented in Verilog code by adding and changing the code that was similarly used to implement the first two interfaces of the board.  Doing this allowed the board to recognize the two new interfaces and different MAC addresses were successfully given to all four ports.  Afterwards, Matthew and I tested the two new interfaces by pinging packets to the different subnetworks created by the four ports.  The ping packets were successfully forwarded to their respective destinations (i.e. 192.168.1.55 was able to ping to 192.168.0.52 by going through the board's two ports with IP addresses 192.168.1.51 and 192.168.0.51)

With forwarding functionality finally implemented on our board, Matthew and I then proceeded to the next agenda in our Gantt Chart: manipulation of the routing table.  Again, pretty much everything essential for a static routing table has been given to us by the Nichestack/Simple Socket Server library, so most of the time, we did research on how each routing table function works as well as where these functions are subsequently called and how they are being used.  The three main routing functions are rt_lookup, which basically looks up for a specific entry in the static routing table, add_route, which adds entries to the routing table, and del_route, which deletes entries in the routing table.

There are two methods in the Altera board support package that call rt_lookup: 'add_share_route' which is located in the file 'ipnet.c', and 'iproute' which is located in the file 'ip.c'.  'add_share_route' basically creates an entry in the routing table such that packets that use the source address of this entry will be forced out the same interface that it came from.  rt_lookup is used in this method to check if the entry is already in the routing table; if the entry is already there, its gets updated. If the entry does not exist yet, 'add_share_route' adds an entry that uses either the gateway address of the interface, the IP address of the interface, or the IP address of the original sender of the packet.  'iproute' is used to correctly route a packet  the correct interface on the board. uses 'rt_lookup' to find the IP address of the next hop/destination link on an entry in the routing table.  The static routing table also uses a single entry cache to determine if the most recently used entry of the routing table is the desired entry.

'add_route' is also called in 'iproute', as well as methods 'icmprcv', 'pcn_init', 'mn_add_route', and 'dhc_reclaim'. 'iproute calls 'add_route' when 'rt_lookup' fails to find a valid entry in the routing table. 'icmprcv' is a callback function that handles incoming received ICMP packets by determining what should be done to them depending on the type of ICMP message (i.e. prints a simple message or forwards it to a particular interface, etc.).  'icmprcv' calls 'add_route' whenever the ICMP packet is of message type 'REDIR' (redirect), which is used to inform a host to update its routing informaion in order to send its packets on an alternative route.  'pcn_init' is also a callback function that keeps track of the time it takes (cycles) to create the net interfaces.  'pcn_init' calls 'add_route' to add a route entry to match the interfaces that were created. I am not exactly sure of what 'mn_add_route' does, but I think it provides a menu interface for the user that allows the user to manually add a routing entry to the routing table.  'add_route' here is obviously called to make 'mn_add_route' functionable.  'dhc_reclaim' is used to work like DHCP Discover, but instead it is specifically used for machines that had a DHCP address before, but wants to reclaim the address back from the server.

The only method that 'del_route' is called in is at 'ni_set_state', which allows a network interface to be turned on or off based on the opcode parameter given to the function itself.  'ni_set_state' uses 'del_route' to flush all the routing table and ARP entries that are assigned to the interface specified by the parameter 'ifp' in 'ni_set_state'.

As of now, Matthew and I are currently trying to figure out on how to get ARP packets to forward correctly when all the interfaces on the router board are all assigned on the same sub-network.  This might be done by bridging the interfaces together, but we're not sure if the static routing table would work afterwards.

Sunday, April 8, 2012

Small update on Stratix board

Software wise, the way the Stratix board starts up its interfaces is a bit different than the way the DE4 starts up its interfaces. For the Stratix board, there is no need for the add_sys() function. Instead, all interfaces start from netmain() through the function call TK_NEWTASK(). This starts up each INSTANCE defined in alt_sys_init.c. This means that each interface should already start up by itself. This also means that we can't define MAC addresses the same we defined them on our DE4 board because a prep function runs once per instance (whereas on the DE4 board, it only runs once overall). So instead, we used a static integer to implement the different MAC addresses.

Right now, it seems the software recognizes that the daughter board is there. I can only assume this because the program will crash if the daughter board isn't there. I can assume the daughter board is recognized because the program is also actively waiting for a packet to come in the second interface. Unfortunately, there still seems to be no power to the daughter board's Ethernet. A computer will not recognize a cable is plugged in if we connect it to the daughter board. Since it is not even recognized, Wireshark does not see any packets. For the DE4 board, even if the interfaces shared MAC addresses, there would still be packets being sent from each interface. In this case, packets are still not being sent.

Routing Table progress

This week, we looked into the routing table. The whole routing table was pretty much built into the niche stack so we just did research to find exactly how it worked. In this entry, I will talk about the main functions of the routing table while David will talk about how they are called in his own blog entry.

First of all, all the routing table functions are in bsp/iniche/src/ip/iproute.c. What these functions do is manipulate (or search) through a routing table variable called rt_mib with the struct type RTMIB. These are the list of essential functions:

rt_lookup(ip_addr host): This function runs through the whole routing table through a for loop. It is looking for a match between the host ip address and an ip address in the routing table. It does a bit by bit comparison and it will have a pointer to the closest match. If an exact match is found, it will stop the for loop and return the pointer to the exact match. Otherwise, it will return either the closest match (closest subnet) or NULL.

add_route(ip_addr dest, ip_addr mask, ip_addr nexthop, int iface, int prot) : This function is supposed to add a route (or update an existing route) directing dest to nexthop. It will return a pointer to the table entry or NULL if there is an error. To work, this function first points to the interface and checks for errors. It will then loop through the whole table using a for loop (similar to rt_lookup). Inside this for loop, if the entry is found, it will update the entry and return the pointer to that entry (ending the function). If the entry is not found (and no empty slot has been previously discovered), it will check if the current spot is empty. If it is, it will make a pointer newrt point to the current entry. If the current slot is not empty, it will check if the priority of prot (from the function argument) is more than the priority of the protocol of the current table entry. If it is, it will point newrt to the entry and then check the priority of newrt against the table entry. It will then mark the entry depending on which pointer to the routing table is more prioritized by pointing newrt to the entry. It will then modify the entry, timestamp it, and return the modified entry.

del_route(ip_addr dest, ip_addr mask, int iface): This function will delete a routing table entry. First it will point ifp to the iface. Next it will go through the routing table using a for loop (like the other two functions) and try to find something with matching credentials to our function arguments.If there is a match, clear the struct (using memset) and clear the cache.

A side note to all of this is that the number of entries in the table (since it is static right now) is 16. This id defined in ipport.h under the varialbe RT_TABS

Friday, April 6, 2012

NIOSII-Week7

Built Nios Stratix schematic and eth 1 works.
Trying to implement ethernet 2 on daughter card.
Address for ethernet 2 have to be hard wired.
Address [11:10] ,[7:4] ,[0] for daughter card are conneted to gnd.
Address [9:8] for daughter card are conneted to vcc.
Address[3:1] for daughter card are conneted to SOPC.
SBHE_n and AEn are conneted to gnd.
IOR, IOW for daughter card are conneted to SOPC
INT for daughter card is is etherenet 2 IRQ.

Used scope to check pin are right.
Used Signal Tap to check components.
Looked though the SSS code to find what problem is.

Figured out that the ethernet driver is for 32 bit and
the daughter card is 16 bit. So we have to change driver
to support 16 bit for daughter card. Ethernet driver
supports only one device, so we have to change it to support two.

Ethetnet 2 currently not working.

Monday, April 2, 2012

Spring Break Progress

We first found out why there was a strange header offset before. The problem we were having was that we put both interfaces on the same network. At first, we tried to go through the ARP functions (et_arp.c) and just forward requests through but upon more research, we found that this was very unsafe. What we didn't know was that when clients try to ping each other on the same network, they send an ARP request packet. The ARP packets have different headers than IP packets which is why we were seeing the offset.So we immediately discarded all of our changes to the et_arp.c file we edited earlier.
The next thing we did to get the packets to start forwarding was to make the interfaces static (whereas before, they were DHCP clients). We set each of our two interfaces on their own network by giving them the IP addresses of 192.168.0.51 and 192.168.1.51. To do this, we had to comment out #define DHCP_CLIENT in our bsp/system.h file but then add #define DHCP_CLIENT 0 to bsp/iniche/src/h/niosii/ipport.h. We then gave each interface it's own IP address.
Now that our two interfaces were up on different networks, we ran into a problem. Our previous algorithm for doing simple packet forwarding seemed to block ARP replies. This was strange because the ARP check would check the packet before sending it to our packet forwarding algorithm anyways. So to bypass this, we removed our simple algorithm, enabled IP_ROUTING, and let the iniche stack do it's own forwarding. So instead of using our own algorithm, we took advantage of the function   ipdemux.c:ip_rcv_phase2 to do the general packet forwarding.