[ECOS] What functions should I call in ethernet drv ?

ariga masahiro ariga@link-lab.co.jp
Tue Oct 23 08:23:00 GMT 2007


Hello Gary and others,

I have learned ARP operation.
I've got "TCP/IP illustrated vol2" by W.Richard Stevens.

I have traced to ARP interpreting point.
First I breaked lan91cxx_recv() when received ARP packet,
and next breaked if_ethersubr.c's ether_input(ifp, eh, m) function.
And I traced into ether_demux().

ether_demux(ifp, eh, m)
       594:     switch (ether_type) {
       595: #ifdef INET
       596:     case ETHERTYPE_IP:
       597:         if (ipflow_fastforward(m))
       598:             return;
       599:         schednetisr(NETISR_IP);
       600:         inq = &ipintrq;
       601:         break;
       602:
       603:     case ETHERTYPE_ARP:
       604:         if (ifp->if_flags & IFF_NOARP) {
       605:             /* Discard packet if ARP is disabled on interface */
       606:             m_freem(m);
       607:             return;
       608:         }
       609:         schednetisr(NETISR_ARP);
       610:         inq = &arpintrq;
       611:         break;

and I found ether_type==0x0608,so couldn't recognize ARP.

I concluded entering data in little Endian is wrong,
so as a makeshift I amended source next.

First I concocted get_data_byte(struct eth_drv_sc *sc)
to get data exchangedly like I previously sent the coding.

And I alse concocted in cyg_uint16 get_data_short like below
to echange data.

      1079: cyg_uint16 get_data_short(struct eth_drv_sc *sc)
      1080: {
      1081:     cyg_uint16 val;
      1082:
      1083:     val = get_data_byte(sc);
      1084:     //val |= get_data_byte(sc)<<8;
                val = val<<8 | get_data_byte(sc);  --I concocted to reverse 
data.
      1085:
      1086:     return CYG_LE16_TO_CPU(val);
      1087: }

I know it's bad coding but as I said this is a makeshift and
I expect your best amended source.(on condition I was right)

Anyway I could continue debugging.

After that I confirmed that following interrrupt,
it entered in if_ether.c's arpintr().

Then I traced into in_arpinput(m), and
according to the book,here send ARP-reply.
My expectancy reached high.

But alas,in in_arpinput(m)
didn't go to the point of sending packet.

The reason was, in first part of coding,
       529: in_arpinput(m)
       530:     struct mbuf *m;
       531: {
       532:     register struct ether_arp *ea;
       533:     register struct arpcom *ac = (struct arpcom 
*)m->m_pkthdr.rcvif;
       534:     struct ether_header *eh;
       535:     struct iso88025_header *th = (struct iso88025_header *)0;
       536:     register struct llinfo_arp *la = 0;
       537:     register struct rtentry *rt;
       538:     struct in_ifaddr *ia, *maybe_ia = 0;
       539:     struct sockaddr_dl *sdl;
       540:     struct sockaddr sa;
       541:     struct in_addr isaddr, itaddr, myaddr;
       542:     int op, rif_len;
       543:
       544:     if (m->m_len < sizeof(struct ether_arp) &&
       545:         (m = m_pullup(m, sizeof(struct ether_arp))) == NULL) {
       546:         log(LOG_ERR, "in_arp: runt packet -- m_pullup 
failed\n");
       547:         return;
       548:     }
       549:
       550:     ea = mtod(m, struct ether_arp *);
       551:     op = ntohs(ea->arp_op);
       552:     (void)memcpy(&isaddr, ea->arp_spa, sizeof (isaddr));
       553:     (void)memcpy(&itaddr, ea->arp_tpa, sizeof (itaddr));
       554:     for (ia = in_ifaddrhead.tqh_first; ia; ia = 
ia->ia_link.tqe_next) {
       555:         /*
       556:          * For a bridge, we want to check the address 
irrespective
       557:          * of the receive interface. (This will change slightly
       558:          * when we have clusters of interfaces).
       559:          */
       560: #ifdef BRIDGE
       561: #define BRIDGE_TEST (do_bridge)
       562: #else
       563: #define BRIDGE_TEST (0) /* cc will optimise the test away */
       564: #endif
       565:         if ((BRIDGE_TEST) || (ia->ia_ifp == &ac->ac_if)) {
       566:             maybe_ia = ia;
       567:             if ((itaddr.s_addr == ia->ia_addr.sin_addr.s_addr) 
||
       568:                  (isaddr.s_addr == ia->ia_addr.sin_addr.s_addr)) 
{
       569:                 break;
       570:             }
       571:         }
       572:     }
       573:     if (maybe_ia == 0) {
       574:         m_freem(m);
       575:         return;
       576:     }
       577:     myaddr = ia ? ia->ia_addr.sin_addr : 
maybe_ia->ia_addr.sin_addr;  --ia,ª00

at 554 line,there was nothing in_ifaddrhead.tqh_first,
and at 577, ia became 00000000.

Here,Gary, I sincerely ask your opinion.
The trouble is there is nothing in in_ifaddrhead.tqh_first,
do you have any idea what caused this mishappening ?

I expect your any hints whatever.

Thanks in advance.

Masahiro Ariga



-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss



More information about the Ecos-discuss mailing list