int lb_pkt_send(PACKET pkt) { NET netp; IFMIB mib; int length; struct ethhdr * eth; #ifdef ROUTE_TEST struct ip * pip; /* headers for packet alterations */ struct tcphdr * ptcp; #endif /* ROUTE_TEST */ netp = pkt->net; #ifdef NPDEBUG /* Sanity check interface pointer */ if(netp->pkt_send != lb_pkt_send) { dprintf("macloop: bad net\n"); dtrap(); } #endif length= pkt->nb_plen; mib = netp->n_mib; /* Don't send if iface is logically down */ if(mib->ifAdminStatus != NI_UP) { mib->ifOutDiscards++; /* bump mib counter for these */ return ENP_LOGIC; /* right thing to do? */ } /* maintain mib xmit stats */ if (*(pkt->nb_prot + ETHHDR_BIAS) & 0x01) /* see if multicast bit is on */ mib->ifOutNUcastPkts++; else mib->ifOutUcastPkts++; mib->ifOutOctets += length; /* at this point we make the logical switch from sending to receiving. * nb_prot, nb_plen and type should be set to the MAC (ethernet) header * by the send_via_arp() code. */ eth = (struct ethhdr *)(pkt->nb_prot + ETHHDR_BIAS); pkt->type = eth->e_type; pkt->nb_prot += ETHHDR_SIZE; pkt->nb_plen -= ETHHDR_SIZE; mib->ifInOctets += length; #ifdef IEEE_802_3 /* See if sender is legacy IEEE machine. If we were not using the * NF_NBPROT bit in this device we could skip this step and the packet * would get trapped by the logic in pktdemux.c */ if(pkt->type >= 0x0600) { struct snap_hdr * snap; /* set up type and nb_prot for SNAP packet */ snap = (struct snap_hdr *)(((char*)eth) + ETHHDR_SIZE - ETHHDR_BIAS); pkt->type = snap->type; pkt->nb_prot += sizeof(struct snap_hdr); pkt->nb_plen -= sizeof(struct snap_hdr); } #endif #ifdef ROUTE_TEST pip = (struct ip *)pkt->nb_prot; /* hunt for IP header */ /* If the two IP addreses are not both 127.1, then we may be doing a * routing simulation. Try swapping the IP addresses so the "received" * packet doesn't keep looping back to this driver */ if((eth->e_type == htons(0x0800)) && /* make sure we found IP packet */ (pip->ip_ver_ihl == 0x45) && /* and that we found IP header */ (pip->ip_src != pip->ip_dest)) { ip_addr tmp; /* tmp vars for swapping */ unshort port; tmp = pip->ip_src; /* swap IP addresses */ pip->ip_src = pip->ip_dest; pip->ip_dest = tmp; /* If it's UDP or TCP, swap the ports too. This lets us do NAT * simulations. */ if((pip->ip_prot == 6) || /* 6 - TCP */ (pip->ip_prot == 17)) /* 17 - UDP */ { /* use the tcp header struct. The UDP ports are in the same * locations, so this works for UDP too. */ ptcp = (struct tcphdr *)(pip + 1); port = ptcp->th_sport; ptcp->th_sport = ptcp->th_dport; ptcp->th_dport = port; } } #endif /* ROUTE_TEST */ /* queue the packet in rcvdq */ putq(&rcvdq, (q_elt)pkt); /* Most ports should now wake the packet demuxer task */ SignalPktDemux(); return 0; /* OK return */ }
static void dm9000a_isr(int iface) { unsigned char rx_rdy, istatus; unsigned int tmp, rx_sts, i, rx_len; struct ethhdr * eth; PACKET pkt; DM9KA dm9ka = (DM9KA)nets[iface]->n_local; /* mask NIC interrupts IMR: PAR only */ dm9000a_iow(IMR, PAR_set); istatus = dm9000a_ior(ISR); rx_rdy = dm9000a_rxReady(dm9ka); usleep(STD_DELAY); while(rx_rdy == DM9000_PKT_READY) { /* get RX Status & Length from RX SRAM */ /* set MRCMD REG. F2H RX I/O port ready */ IOWR(dm9ka->regbase, IO_addr, MRCMD); usleep(STD_DELAY); rx_sts = IORD(dm9ka->regbase,IO_data); usleep(STD_DELAY); rx_len = IORD(dm9ka->regbase,IO_data); /* Check this packet_status: GOOD or BAD? */ if( !(rx_sts & 0xBF00) && (rx_len < MAX_PACKET_SIZE) ) { if ((pkt = pk_alloc(rx_len + ETHHDR_BIAS)) == NULL) { /* couldn't get a free buffer for rx */ dm9ka->netp->n_mib->ifInDiscards++; /* treat packet as bad, dump it from RX SRAM */ for (i = 0; i < rx_len; i += 2) { usleep(STD_DELAY); tmp = IORD(dm9ka->regbase, IO_data); } } else { /* packet allocation succeeded */ unsigned char* data_ptr = pkt->nb_buff + ETHHDR_BIAS; /* read 1 received packet from RX SRAM into RX packet buffer */ for (i = 0; i < rx_len; i += 2) { usleep(STD_DELAY); tmp = IORD(dm9ka->regbase, IO_data); *data_ptr++ = tmp & 0xFF; *data_ptr++ = (tmp>>8) & 0xFF; } pkt->nb_prot = pkt->nb_buff + ETHHDR_SIZE; pkt->nb_plen = rx_len - 14; pkt->nb_tstamp = cticks; pkt->net = dm9ka->netp; /* set packet type for demux routine */ eth = (struct ethhdr *)(pkt->nb_buff + ETHHDR_BIAS); pkt->type = eth->e_type; /* shove packet into iniche stack's recv queue */ //printf("rx: 0x%x l %d s %x:%x:%x\n", eth->e_type, rx_len, // eth->e_src[0], eth->e_src[1], eth->e_src[2]); putq(&rcvdq, pkt); SignalPktDemux(); } } else { /* this packet is bad, dump it from RX SRAM */ for (i = 0; i < rx_len; i += 2) { usleep(STD_DELAY); tmp = IORD(dm9ka->regbase, IO_data); } rx_len = 0; } usleep(STD_DELAY); rx_rdy = dm9000a_rxReady(dm9ka); usleep(STD_DELAY); }
int lb_raw_send(struct net * netp, char * buffer, unsigned length) { struct ethhdr * eth; IFMIB mib; PACKET pkt; #ifdef NPDEBUG /* Sanity check interface pointer */ if(netp->raw_send != lb_raw_send) { dprintf("macloop: bad net\n"); dtrap(); } #endif /* Don't send if iface is logically down */ if(netp->n_mib->ifAdminStatus != NI_UP) { netp->n_mib->ifOutDiscards++; /* bump mib counter for these */ return ENP_LOGIC; /* right thing to do? */ } /* maintain mib xmit stats */ mib = netp->n_mib; if (*buffer & 0x01) /* see if multicast bit is on */ mib->ifOutNUcastPkts++; else mib->ifOutUcastPkts++; mib->ifOutOctets += length; /* at this point we make the logical switch from sending to receiving */ /* fill in a packet for the "received" buffer */ LOCK_NET_RESOURCE(FREEQ_RESID); pkt = pk_alloc(length); UNLOCK_NET_RESOURCE(FREEQ_RESID); if (!pkt) { mib->ifInDiscards++; return ENP_RESOURCE; } MEMCPY(pkt->nb_buff, buffer, length); pkt->nb_prot = pkt->nb_buff + ETHHDR_SIZE; /* point to IP header */ pkt->nb_plen = length - ETHHDR_SIZE; /* IP length */ pkt->net = netp; eth = (struct ethhdr *)(pkt->nb_buff + ETHHDR_BIAS); MEMCPY(eth->e_dst, (void *)lpbhaddr, 6); MEMCPY(eth->e_src, (void *)lpbhaddr, 6); pkt->type = eth->e_type; mib->ifInOctets += length; /* queue the packet in rcvdq */ putq(&rcvdq, (q_elt)pkt); /* Most ports should now wake the packet demuxer task */ SignalPktDemux(); return 0; /* OK return */ }