rtentry and rtrequest
Alan Garfield
alan at fromorbit.com
Thu Apr 19 01:56:58 UTC 2007
On Wed, 2007-04-18 at 16:06 +0400, Yar Tikhiy wrote:
>
> > I just want an idea of the structures involved, and what I need to
> > implement to intercept and injecting a fake MAC so my buffer driver can
> > communicate with the other side without ARP errors.
>
> Could you tell more details on the problem you are trying to solve
> now. Sorry, but I fail to see what errors you get, and why. Doesn't
> the Service Processor on the other side of that little Ethernet
> link behave as a conventional IP host?
Well it sort of does and it sort of doesn't unfortunately. It's MAC
addresses are faked in the driver on both sides, and any ARP requests
are caught and a fake response is generated. It's a wee bit ugly.
>From the GPL Linux driver
----
int jnet_tx(struct sk_buff *skb, struct net_device *dev)
{
[...]
if(htons(eth->h_proto) == ETH_P_ARP &&
arp->ar_op == ARPOP_REQUEST) {
//send fake response.
jnet_arpResponse(dev);
netif_wake_queue(jnet_devs);
priv->fifoFull = FALSE;
dev_kfree_skb(skb); // Free the SKB for arps too.
} else {
//so send the data
[...]
}
}
----
void jnet_arpResponse( struct net_device *dev )
{
[...]
//Fill in all the blanks.
memcpy(ðArp.eth.h_dest, localMac, sizeof(localMac));
memcpy(ðArp.eth.h_source, remoteMac, sizeof(remoteMac));
ethArp.eth.h_proto = ETH_P_ARP;
ethArp.arp.ar_hrd = htons(ARPHRD_ETHER);
ethArp.arp.ar_pro = htons(ETH_P_IP);
ethArp.arp.ar_hln = sizeof(localMac);
ethArp.arp.ar_pln = sizeof(uint32_t);
ethArp.arp.ar_op = htons(ARPOP_REPLY);
memcpy(ðArp.ar_sha, remoteMac, sizeof(remoteMac));
memcpy(ðArp.ar_sip, &priv->myConfigIpSettings.platIp,
sizeof(uint32_t));
memcpy(ðArp.ar_tha, localMac, sizeof(localMac));
memcpy(ðArp.ar_tip, &priv->myConfigIpSettings.spIp,
sizeof(uint32_t));
[...]
}
----
The problem I'm really seeing is I'm getting no mbuf's in my
jnet_start(). It always returns zero.
----
static void
jnet_start_locked(struct ifnet* ifp)
{
// {{{
struct jnet_softc *sc = ifp->if_softc;
struct mbuf *m0, *m;
device_printf(sc->dev, "jnet_start_locked() called.\n");
JNET_ASSERT_LOCKED(sc);
outputloop:
// Check if there are buffered packets and an we're idle which
// shouldn't happen at this point
if (sc->txb_inuse && (sc->tx_busy == 0)) {
device_printf(sc->dev, "packets buffered, but tx
idle.\n");
jnet_tx(sc);
}
// Check if there is room to put another packet in the buffer.
if (sc->txb_inuse == sc->txb_cnt) {
device_printf(sc->dev, "No room left in tx buffer.\n");
// No room left. Set OACTIVE to tell everyone
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
return;
}
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
if (m == 0) {
device_printf(sc->dev, "m == 0.\n");
// If buffers aren't filled we can still accept
// more packets. So reset OACTIVE
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
return;
}
// Copy mbuf to PRS
m0 = m;
//set address counter to zero, then read the entire fifo
//bus_space_write_1(sc->iot[JNET_IOREGS], sc->ioh[JNET_IOREGS],
JNET_STS_OFFSET, 0x00);
device_printf(sc->dev, "mbuf len: %i.\n", m0->m_len);
// Output to PRS buffer
[...]
sc->txb_inuse++;
m_freem(m0);
// Loop to top to possibly buffer more packets
goto outputloop;
// }}}
}
----
... and I get these ARP errors.
----
jnet0: <JNet Ethernet System Interface> port 0xa8,0xae-0xaf irq 19 on
acpi0
jnet0: Ethernet address: 00:09:3d:00:00:03
jnet0: jnet_start_locked() called.
jnet0: m == 0.
jnet0: RTM_ADD.
arplookup 169.254.101.2 failed: could not allocate llinfo
arpresolve: can't allocate route for 169.254.101.2
----
... whenever I try and send anything.
Many thanks for you continued help.
Alan.
More information about the freebsd-net
mailing list