Esempio n. 1
0
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 */
}
Esempio n. 2
0
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);    
  }
Esempio n. 3
0
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 */
}