?? net_core.c
字號:
pkt = NetArpWaitTxPacket; pkt += NetSetEther (pkt, NetArpWaitPacketMAC, PROT_IP); NetSetIP (pkt, dest, dport, sport, len); memcpy(pkt + IP_HDR_SIZE, (uchar *)NetTxPacket + (pkt - (uchar *)NetArpWaitTxPacket) + IP_HDR_SIZE, len); /* size of the waiting packet */ NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE + len; /* and do the ARP request */ NetArpWaitTry = 1; NetArpWaitTimerStart = get_timer(0); ArpRequest(); return 1; /* waiting */ }#if ET_DEBUG printk("sending UDP to ");print_IPaddr(dest); printk(" %02x:%02x:%02x:%02x:%02x:%02x\n", ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);#endif pkt = (uchar *)NetTxPacket; pkt += NetSetEther (pkt, ether, PROT_IP); NetSetIP (pkt, dest, dport, sport, len); (void) eth_send(NetTxPacket, (pkt - NetTxPacket) + IP_HDR_SIZE + len); return 0; /* transmitted */}#ifdef CONFIG_CMD_PINGstatic ushort PingSeqNo;int PingSend(void){ static uchar mac[6]; volatile IP_t *ip; volatile ushort *s; uchar *pkt; /* XXX always send arp request */ memcpy(mac, NetEtherNullAddr, 6);#ifdef ET_DEBUG printk("sending ARP for ");print_IPaddr(NetPingIP);printk("\n");#endif NetArpWaitPacketIP = NetPingIP; NetArpWaitPacketMAC = mac; pkt = NetArpWaitTxPacket; pkt += NetSetEther(pkt, mac, PROT_IP); ip = (volatile IP_t *)pkt; /* * Construct an IP and ICMP header. (need to set no fragment bit - XXX) */ ip->ip_hl_v = 0x45; /* IP_HDR_SIZE / 4 (not including UDP) */ ip->ip_tos = 0; ip->ip_len = htons(IP_HDR_SIZE_NO_UDP + 8); ip->ip_id = htons(NetIPID++); ip->ip_off = htons(0x4000); /* No fragmentation */ ip->ip_ttl = 255; ip->ip_p = 0x01; /* ICMP */ ip->ip_sum = 0; NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */ NetCopyIP((void*)&ip->ip_dst, &NetPingIP); /* - "" - */ ip->ip_sum = ~(NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2)); s = &ip->udp_src; /* XXX ICMP starts here */ s[0] = htons(0x0800); /* echo-request, code */ s[1] = 0; /* checksum */ s[2] = 0; /* identifier */ s[3] = htons(PingSeqNo++); /* sequence number */ s[1] = ~(NetCksum((uchar *)s, 8/2)); /* size of the waiting packet */ NetArpWaitTxPacketSize = (pkt - NetArpWaitTxPacket) + IP_HDR_SIZE_NO_UDP + 8; /* and do the ARP request */ NetArpWaitTry = 1; NetArpWaitTimerStart = get_timer(0); ArpRequest(); return 1; /* waiting */}static voidPingTimeout (void){ eth_halt(); NetState = NETLOOP_FAIL; /* we did not get the reply */}static voidPingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len){ IPaddr_t tmp; volatile IP_t *ip = (volatile IP_t *)pkt; tmp = NetReadIP((void *)&ip->ip_src); printk("get reply from "); print_IPaddr(tmp); printk("\n"); if (tmp != NetPingIP) return; NetState = NETLOOP_SUCCESS;}static void PingStart(void){ NetSetTimeout (10 * CFG_HZ, PingTimeout); NetSetHandler (PingHandler); PingSend();}#endif /* CONFIG_CMD_PING */#ifdef CONFIG_CMD_CDP#define CDP_DEVICE_ID_TLV 0x0001#define CDP_ADDRESS_TLV 0x0002#define CDP_PORT_ID_TLV 0x0003#define CDP_CAPABILITIES_TLV 0x0004#define CDP_VERSION_TLV 0x0005#define CDP_PLATFORM_TLV 0x0006#define CDP_NATIVE_VLAN_TLV 0x000a#define CDP_APPLIANCE_VLAN_TLV 0x000e#define CDP_TRIGGER_TLV 0x000f#define CDP_POWER_CONSUMPTION_TLV 0x0010#define CDP_SYSNAME_TLV 0x0014#define CDP_SYSOBJECT_TLV 0x0015#define CDP_MANAGEMENT_ADDRESS_TLV 0x0016#define CDP_TIMEOUT (CFG_HZ/4) /* one packet every 250ms */static int CDPSeq;static int CDPOK;ushort CDPNativeVLAN;ushort CDPApplianceVLAN;static const uchar CDP_SNAP_hdr[8] = { 0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 };static ushort CDP_compute_csum(const uchar *buff, ushort len){ ushort csum; int odd; ulong result = 0; ushort leftover; if (len > 0) { odd = 1 & (ulong)buff; if (odd) { result = *buff << 8; len--; buff++; } while (len > 1) { result += *((const ushort *)buff)++; if (result & 0x80000000) result = (result & 0xFFFF) + (result >> 16); len -= 2; } if (len) { leftover = (signed short)(*(const signed char *)buff); /* * XXX CISCO SUCKS big time! (and blows too) */ result = (result & 0xffff0000) | ((result + leftover) & 0x0000ffff); } while (result >> 16) result = (result & 0xFFFF) + (result >> 16); if (odd) result = ((result >> 8) & 0xff) | ((result & 0xff) << 8); } /* add up 16-bit and 17-bit words for 17+c bits */ result = (result & 0xffff) + (result >> 16); /* add up 16-bit and 2-bit for 16+c bit */ result = (result & 0xffff) + (result >> 16); /* add up carry.. */ result = (result & 0xffff) + (result >> 16); /* negate */ csum = ~(ushort)result; /* run time endian detection */ if (csum != htons(csum)) /* little endian */ csum = htons(csum); return csum;}int CDPSendTrigger(void){ volatile uchar *pkt; volatile ushort *s; volatile ushort *cp; Ethernet_t *et; int len; ushort chksum;#if defined(CONFIG_CDP_DEVICE_ID) || defined(CONFIG_CDP_PORT_ID) || \ defined(CONFIG_CDP_VERSION) || defined(CONFIG_CDP_PLATFORM) char buf[32];#endif pkt = NetTxPacket; et = (Ethernet_t *)pkt; /* NOTE: trigger sent not on any VLAN */ /* form ethernet header */ memcpy(et->et_dest, NetCDPAddr, 6); memcpy(et->et_src, NetOurEther, 6); pkt += ETHER_HDR_SIZE; /* SNAP header */ memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)); pkt += sizeof(CDP_SNAP_hdr); /* CDP header */ *pkt++ = 0x02; /* CDP version 2 */ *pkt++ = 180; /* TTL */ s = (volatile ushort *)pkt; cp = s; *s++ = htons(0); /* checksum (0 for later calculation) */ /* CDP fields */#ifdef CONFIG_CDP_DEVICE_ID *s++ = htons(CDP_DEVICE_ID_TLV); *s++ = htons(CONFIG_CDP_DEVICE_ID); memset(buf, 0, sizeof(buf)); sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%02X%02X%02X%02X%02X%02X", NetOurEther[0] & 0xff, NetOurEther[1] & 0xff, NetOurEther[2] & 0xff, NetOurEther[3] & 0xff, NetOurEther[4] & 0xff, NetOurEther[5] & 0xff); memcpy((uchar *)s, buf, 16); s += 16 / 2;#endif#ifdef CONFIG_CDP_PORT_ID *s++ = htons(CDP_PORT_ID_TLV); memset(buf, 0, sizeof(buf)); sprintf(buf, CONFIG_CDP_PORT_ID, eth_get_dev_index()); len = strlen(buf); if (len & 1) /* make it even */ len++; *s++ = htons(len + 4); memcpy((uchar *)s, buf, len); s += len / 2;#endif#ifdef CONFIG_CDP_CAPABILITIES *s++ = htons(CDP_CAPABILITIES_TLV); *s++ = htons(8); *(ulong *)s = htonl(CONFIG_CDP_CAPABILITIES); s += 2;#endif#ifdef CONFIG_CDP_VERSION *s++ = htons(CDP_VERSION_TLV); memset(buf, 0, sizeof(buf)); strcpy(buf, CONFIG_CDP_VERSION); len = strlen(buf); if (len & 1) /* make it even */ len++; *s++ = htons(len + 4); memcpy((uchar *)s, buf, len); s += len / 2;#endif#ifdef CONFIG_CDP_PLATFORM *s++ = htons(CDP_PLATFORM_TLV); memset(buf, 0, sizeof(buf)); strcpy(buf, CONFIG_CDP_PLATFORM); len = strlen(buf); if (len & 1) /* make it even */ len++; *s++ = htons(len + 4); memcpy((uchar *)s, buf, len); s += len / 2;#endif#ifdef CONFIG_CDP_TRIGGER *s++ = htons(CDP_TRIGGER_TLV); *s++ = htons(8); *(ulong *)s = htonl(CONFIG_CDP_TRIGGER); s += 2;#endif#ifdef CONFIG_CDP_POWER_CONSUMPTION *s++ = htons(CDP_POWER_CONSUMPTION_TLV); *s++ = htons(6); *s++ = htons(CONFIG_CDP_POWER_CONSUMPTION);#endif /* length of ethernet packet */ len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE); et->et_protlen = htons(len); len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr); chksum = CDP_compute_csum((uchar *)NetTxPacket + len, (uchar *)s - (NetTxPacket + len)); if (chksum == 0) chksum = 0xFFFF; *cp = htons(chksum); (void) eth_send(NetTxPacket, (uchar *)s - NetTxPacket); return 0;}static voidCDPTimeout (void){ CDPSeq++; if (CDPSeq < 3) { NetSetTimeout (CDP_TIMEOUT, CDPTimeout); CDPSendTrigger(); return; } /* if not OK try again */ if (!CDPOK) NetStartAgain(); else NetState = NETLOOP_SUCCESS;}static voidCDPDummyHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len){ /* nothing */}static voidCDPHandler(const uchar * pkt, unsigned len){ const uchar *t; const ushort *ss; ushort type, tlen; uchar applid; ushort vlan, nvlan; /* minimum size? */ if (len < sizeof(CDP_SNAP_hdr) + 4) goto pkt_short; /* check for valid CDP SNAP header */ if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0) return; pkt += sizeof(CDP_SNAP_hdr); len -= sizeof(CDP_SNAP_hdr); /* Version of CDP protocol must be >= 2 and TTL != 0 */ if (pkt[0] < 0x02 || pkt[1] == 0) return; /* if version is greater than 0x02 maybe we'll have a problem; output a warning */ if (pkt[0] != 0x02) printk("** WARNING: CDP packet received with a protocol version %d > 2\n", pkt[0] & 0xff); if (CDP_compute_csum(pkt, len) != 0) return; pkt += 4; len -= 4; vlan = htons(-1); nvlan = htons(-1); while (len > 0) { if (len < 4) goto pkt_short; ss = (const ushort *)pkt; type = ntohs(ss[0]); tlen = ntohs(ss[1]); if (tlen > len) { goto pkt_short; } pkt += tlen; len -= tlen; ss += 2; /* point ss to the data of the TLV */ tlen -= 4; switch (type) { case CDP_DEVICE_ID_TLV: break; case CDP_ADDRESS_TLV: break; case CDP_PORT_ID_TLV: break; case CDP_CAPABILITIES_TLV: break; case CDP_VERSION_TLV: break; case CDP_PLATFORM_TLV: break; case CDP_NATIVE_VLAN_TLV: nvlan = *ss; break; case CDP_APPLIANCE_VLAN_TLV: t = (const uchar *)ss; while (tlen > 0) { if (tlen < 3) goto pkt_short; applid = t[0]; ss = (const ushort *)(t + 1);#ifdef CONFIG_CDP_APPLIANCE_VLAN_TYPE if (applid == CONFIG_CDP_APPLIANCE_VLAN_TYPE) vlan = *ss;#else vlan = ntohs(*ss); /* XXX will this work; dunno */#endif t += 3; tlen -= 3; } break; case CDP_TRIGGER_TLV: break; case CDP_POWER_CONSUMPTION_TLV: break; case CDP_SYSNAME_TLV: break; case CDP_SYSOBJECT_TLV: break; case CDP_MANAGEMENT_ADDRESS_TLV: break; } } CDPApplianceVLAN = vlan; CDPNativeVLAN = nvlan; CDPOK = 1; return; pkt_short: printk("** CDP packet is too short\n"); return;}static void CDPStart(void){ CDPSeq = 0; CDPOK = 0; CDPNativeVLAN = htons(-1); CDPApplianceVLAN = htons(-1); NetSetTimeout (CDP_TIMEOUT, CDPTimeout); NetSetHandler (CDPDummyHandler); CDPSendTrigger();}#endif /* CONFIG_CMD_CDP */voidNetReceive(volatile uchar * inpkt, int len){ Ethernet_t *et; IP_t *ip; ARP_t *arp; IPaddr_t tmp; int x; uchar *pkt;#ifdef CONFIG_CMD_CDP int iscdp;#endif ushort cti = 0, vlanid = VLAN_NONE, myvlanid, mynvlanid; NetRxPkt = inpkt; NetRxPktLen = len; et = (Ethernet_t *)inpkt; /* too small packet? */ if (len < ETHER_HDR_SIZE) return;#ifdef CONFIG_CMD_CDP /* keep track if packet is CDP */ iscdp = memcmp(et->et_dest, NetCDPAddr, 6) == 0;#endif myvlanid = ntohs(NetOurVLAN); if (myvlanid == (ushort)-1) myvlanid = VLAN_NONE; mynvlanid = ntohs(NetOurNativeVLAN); if (mynvlanid == (ushort)-1) mynvlanid = VLAN_NONE; x = ntohs(et->et_protlen);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -