📄 eth.c
字号:
/* * Ethernet functions */#include <string.h>#include <net/xilsock.h>struct xilnet_hw_addr_table xilnet_hw_tbl[HW_ADDR_TBL_ENTRIES];unsigned char ishwaddrinit = 0;/* * initialize xilnet hardware address */void xilnet_eth_init_hw_addr(unsigned char* addr) { int k = 0; int j; int sum = 0; int val = 0; for (j = 0; j < 5; j++) { // parse input for colon separated hw address while(addr[k] != ':') { if (addr[k] >= 'a' && addr[k] <= 'f') val = addr[k] - 'a' + 10; else if (addr[k] >= 'A' && addr[k] <= 'F') val = addr[k] - 'A' + 10; else val = addr[k] - '0'; sum = sum * 16 + val; k++; } k++; // move over the colon mb_hw_addr[j] = (unsigned char) sum; sum = 0; } // read last byte of hw address while (addr[k] != '\0') { if (addr[k] >= 'a' && addr[k] <= 'f') val = addr[k] - 'a' + 10; else if (addr[k] >= 'A' && addr[k] <= 'F') val = addr[k] - 'A' + 10; else val = addr[k] - '0'; sum = sum * 16 + val; k++; } mb_hw_addr[5] = (unsigned char) sum;}/* * Receive frame */int xilnet_eth_recv_frame(unsigned char *buf, int len) { struct xilnet_eth_hdr *eth; //device specific routine for getting a frame#ifdef _CONFIG_EMAC_ int size = XEmac_RecvFrame(MYMAC_BASEADDR, buf);#else #ifdef _CONFIG_EMACLITE_ int size = XEmacLite_RecvFrame(MYMAC_BASEADDR, buf);#endif#endif // Strip off the FCS(or CRC) from the received frame buf[size-1] = 0; buf[size-2] = 0; buf[size-3] = 0; buf[size-4] = 0; size -= 4; eth = (struct xilnet_eth_hdr*) buf; switch (eth->type) { case ETH_PROTO_IP: return (xilnet_ip(buf, size)); case ETH_PROTO_ARP: return (xilnet_arp(buf, size)); default: break; } return -1;}/* * Send frame to peer ip addr, peer hw addr */ int xilnet_eth_send_frame(unsigned char *pkt, int len, unsigned char *dip_addr, void *dhw_addr, unsigned short type) { int i; int hw_tbl_index = 0; for (i = 0; i < ETH_ADDR_LEN; i++) { ((struct xilnet_eth_hdr*)pkt)->src_addr[i] = mb_hw_addr[i]; } if (dhw_addr) memcpy(((struct xilnet_eth_hdr*)pkt)->dest_addr, dhw_addr, ETH_ADDR_LEN); else { // find the hw tbl entry index corr to dip_addr hw_tbl_index = xilnet_eth_get_hw_addr(dip_addr); for (i = 0; i < ETH_ADDR_LEN; i++) { ((struct xilnet_eth_hdr*)pkt)->dest_addr[i] = xilnet_hw_tbl[hw_tbl_index].hw_addr[i]; } } ((struct xilnet_eth_hdr*)pkt)->type = type; // pad the ethernet frame if < 60 bytes if (len < 60) { for(i = len; i < ETH_MIN_FRAME_LEN; i++) { pkt[i] = 0; } len = ETH_MIN_FRAME_LEN; } // Write to MAC#ifdef _CONFIG_EMAC_ XEmac_SendFrame(MYMAC_BASEADDR, pkt, len);#else #ifdef _CONFIG_EMACLITE_ XEmacLite_SendFrame(MYMAC_BASEADDR, pkt, len);#endif#endif return len;}/* * Update Hardware Address Table */void xilnet_eth_update_hw_tbl(unsigned char *buf, int proto) { unsigned char ip[IP_VERSION]; unsigned char hw[ETH_ADDR_LEN]; int i, j; struct xilnet_eth_hdr *eth = (struct xilnet_eth_hdr*) buf; // get hw addr for (i = 0; i < ETH_ADDR_LEN; i++) { hw[i] = ((struct xilnet_eth_hdr*)buf)->src_addr[i]; } // get ip addr switch (proto) { case ETH_PROTO_ARP: for (i = 0; i < IP_VERSION; i++) { ip[i] = (buf+ETH_HDR_LEN)[ARP_SIP_OFFSET+i]; } break; case ETH_PROTO_IP: for (i = 0; i < IP_VERSION; i++) { ip[i] = (buf+ETH_HDR_LEN)[IP_SADDR_BASE+i]; } break; } // update the hw addr table for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) { if (xilnet_hw_tbl[i].flag) { if ( (hw[0] == xilnet_hw_tbl[i].hw_addr[0]) && (hw[1] == xilnet_hw_tbl[i].hw_addr[1]) && (hw[2] == xilnet_hw_tbl[i].hw_addr[2]) && (hw[3] == xilnet_hw_tbl[i].hw_addr[3]) && (hw[4] == xilnet_hw_tbl[i].hw_addr[4]) && (hw[5] == xilnet_hw_tbl[i].hw_addr[5]) ) { for (j = 0; j < IP_VERSION; j++) xilnet_hw_tbl[i].ip_addr[j] = ip[j];; xilnet_hw_tbl[i].flag = HW_ADDR_ENTRY_IS_TRUE; return; } } } xilnet_add_hw_tbl_entry(ip, hw);}/* * Add an entry into Hw Addr table */void xilnet_add_hw_tbl_entry(unsigned char *ip, unsigned char *hw) { int i, j; for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) { if (!xilnet_hw_tbl[i].flag) { for (j = 0; j < ETH_ADDR_LEN; j++) { xilnet_hw_tbl[i].hw_addr[j] = hw[j]; } for (j = 0; j < IP_VERSION; j++) { xilnet_hw_tbl[i].ip_addr[j] = ip[j]; } xilnet_hw_tbl[i].flag = HW_ADDR_ENTRY_IS_TRUE; return; } } print("Add entry in Hw tbl Error \n"); exit(1); }/* * Get index into hw tbl for ip_addr */int xilnet_eth_get_hw_addr(unsigned char *ip) { int i; for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) { if (xilnet_hw_tbl[i].flag) if ( (ip[0] == xilnet_hw_tbl[i].ip_addr[0]) && (ip[1] == xilnet_hw_tbl[i].ip_addr[1]) && (ip[2] == xilnet_hw_tbl[i].ip_addr[2]) && (ip[3] == xilnet_hw_tbl[i].ip_addr[3]) ) { return i; } } print("Hw Addr Not found for IP \n"); return -1; }/* * Init the hw addr table */void xilnet_eth_init_hw_addr_tbl() { int i; for (i = 0; i < HW_ADDR_TBL_ENTRIES; i++) { xilnet_hw_tbl[i].flag = HW_ADDR_ENTRY_IS_FALSE; } ishwaddrinit = 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -