⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethcntl.c

📁 TCP-IP红宝书源代码
💻 C
字号:
/* ethcntl.c - ethcntl */

#include <conf.h>
#include <kernel.h>
#include <network.h>

/*------------------------------------------------------------------------
 * ethcntl - handle ethernet device control() functions
 *------------------------------------------------------------------------
 */
int ethcntl(devptr, func, arg)
struct	devsw	*devptr;
int		func;
char		*arg;		/* contains data for some functions	*/
{
	struct	etblk		*etptr;
        struct	le_init_block	*ib;
	unsigned  int		crc, hash_bit, get_hashbit(), bitindex;
	STATWORD		ps;
	int			reg, bit, i, rv;
	unsigned   char		addr[6];

        etptr = &eth[devptr->dvminor];
        ib    = etptr->etib;
	
	switch ( func )	{
	case EPC_PROMON:		/* turn on promiscuous mode	*/
	        ib->ib_prom = 1;
	        rv = ethstrt(etptr);
		break;
	case EPC_PROMOFF:		/* turn off promiscuous mode	*/
	        ib->ib_prom = 0;
	        rv = ethstrt(etptr);
		break;
	case EPC_MDEL: /* not supported yet */
		rv = OK;
		break;
	case EPC_MADD:
		/* check the limit on no. of addresses */
		disable(ps);
/*	    kprintf("setting etptr->etfilter for %x %x %x %x %x %x\n", 
		arg[0]&0xff, arg[1]&0xff, arg[2]&0xff, arg[3]&0xff,
		arg[4]&0xff, arg[5]&0xff);
*/	
		/* initialize etptr->etfilter */
/*		for (i=0; i < 8; i++)
		    etptr->etfilter[i] = 0;
*/		    
		
		/* reverse address */
		for (i=0; i < EP_ALEN; i++)
		    addr[i] = (unsigned char)arg[5-i]&0xff;
/*    kprintf("recversed address %x %x %x %x %x %x \n", 
	   addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
*/		
		crc = get_hashbit(addr, EP_ALEN); 
#ifdef TESTMULTI
		kprintf("ethcntl: crc 0x%x\n", crc);
#endif		
		hash_bit = crc >> 26;
#ifdef TESTMULTI
		kprintf("ethcntl: hashbit 0x%x\n", hash_bit);
#endif
		reg = hash_bit / 16;
		bit = hash_bit % 16;
#ifdef TESTMULTI
		kprintf("ethcntl: reg %d bit %d\n", reg, bit);
#endif		
		set_bit(&etptr->etfilter[reg*2], bit, 1,2);
#ifdef TESTMULTI
    kprintf("etptr->etfilter is %x %x %x %x %x %x %x %x.\n", 
	etptr->etfilter[0], etptr->etfilter[1], etptr->etfilter[2],
	etptr->etfilter[3], etptr->etfilter[4], etptr->etfilter[5],
	etptr->etfilter[6], etptr->etfilter[7]);

#endif	
		/* now set the etptr->etfilter on the board */
		ib->ib_ladrf[0] = etptr->etfilter[0];
		ib->ib_ladrf[1] = etptr->etfilter[1];
		ib->ib_ladrf[2] = etptr->etfilter[2];
		ib->ib_ladrf[3] = etptr->etfilter[3];
		ib->ib_ladrf[4] = etptr->etfilter[4];
		ib->ib_ladrf[5] = etptr->etfilter[5];
		ib->ib_ladrf[6] = etptr->etfilter[6];
		ib->ib_ladrf[7] = etptr->etfilter[7];
		ethstrt(etptr);
		restore(ps);
		rv = OK;
		break;
	default:
		rv = SYSERR;
	}
	return rv;
}


/*------------------------------------------------------------------------
 * get_hashbit - get hashe value, given an Ethernet address
 *------------------------------------------------------------------------
 */
/* 
calculate a 32-bit CRC redundant checksum
**
** This is hash value specifically  the one calculated by
** the Lance Ethernet chip. In this version, the CRC register
** is initialized to all 1's instead of all 0's. This is the
** reverse of how checksums are done in Stallings & Tanenbaum
** (which are presumably standard ways).
**
*/
#define CRC_BITS 32
#define CHAR_BITS 8
unsigned char poly[4] = {0x04, 0xc1, 0x1d, 0xb6};

unsigned int
get_hashbit(msg, len)
unsigned char *msg;
int len;
{
  unsigned char CRC[4];
  int i, j, carry;

  for (i = 0; i < 4; i++) CRC[i] = 0xff;

  /* for each message bit */
  for (i = 0; i < CHAR_BITS*len; i++) {
    carry = get_bit(msg, i, len) ^ get_bit(CRC, 0, 4);
    /* for each CRC bit */
    for (j = 0; j < CRC_BITS - 1; j++) {
      if (get_bit(poly, CRC_BITS - j - 1, 4))
	set_bit(CRC, j, carry ^ get_bit(CRC, j+1, 4), 4);
      else
	set_bit(CRC, j, get_bit(CRC, j+1, 4), 4);
    }
    set_bit(CRC, CRC_BITS - 1, carry, 4);
  }
  return(*((long *) CRC));
}

/*
** get_bit, set_bit -- bit manipulating operations
**
** bits are numbered starting from 0 at the right end
**
** all values set or returned are treated as 0 or 1
*/

int
get_bit(data, i, len)
unsigned char *data;
int i;
int len;
{
  int byte, bit;

  byte = len - (i / CHAR_BITS) - 1;
  bit = i % CHAR_BITS;

  return(!!(data[byte] & (1 << bit)));
}

set_bit(data, i, value, len)
unsigned char *data;
int i;
int value;
int len;
{
  int byte, bit;

  byte = len - (i / CHAR_BITS) - 1;
  bit = i % CHAR_BITS;

  if (value) 
    data[byte] |= (1<<bit);
  else
    data[byte] &= ~(1<<bit);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -