📄 main.c
字号:
p8bit++;
csum += val16;
}
if (len % 2)
{
/* The segment ends with odd byte, add it. */
csum += *p8bit++;
}
while (csum >> 16)
{
csum = (csum & 0xffff) + (csum >> 16);
/* add in end-around carry */
}
return ~(tU16) csum;
}
/*****************************************************************************
*
* Description:
* Handles an incoming ICMP packet
*
****************************************************************************/
static void
icmpInput(tU8* pBuf,
tU16 len)
{
/*
* +--+--+--+--+
* 0: |ty|co|chsum|
* +--+--+--+--+
*
* ty = type
* co = code
*
*/
tU16 csum = 0;
if(len < 4)
{
return;
}
if(checksum((tU8 *)pBuf, len, 0) != 0)
{
return;
}
if(!(pBuf[0] == 8 && pBuf[1] == 0))
{
/* Only support for Ping */
return;
}
// create reply
pBuf[0] = 0;
pBuf[2] = 0;
pBuf[3] = 0;
csum = checksum(pBuf, len, 0);
pBuf[2] = (csum & 0xff);
pBuf[3] = (csum >> 8);
// create IP header
pBuf -= 20;
len += 20;
// set destination IP address (same as source in input packet)
memcpy(&pBuf[16], &pBuf[12], 4);
// set source IP address
memcpy(&pBuf[12], localIP, 4);
// checksum
pBuf[10] = 0;
pBuf[11] = 0;
csum = checksum(pBuf, 20, 0);
pBuf[10] = (csum & 0xff);
pBuf[11] = (csum >> 8);
// ethernet header
pBuf -= 14;
len += 14;
// destination ethernet address
memcpy(&pBuf[0], &pBuf[6], 6);
memcpy(&pBuf[6], mac, 6);
ethIf_send(pBuf, len);
}
/*****************************************************************************
*
* Description:
* Handles an incoming IP packet
*
****************************************************************************/
static void
ipInput(tU8* pBuf,
tU16 len)
{
tU16 totLen = 0;
/*
* +--+--+--+--+--+--+--+--+
* 0: |vl|TO| len |ident|flags|
* +--+--+--+--+--+--+--+--+
* 8: |TT|pr|chsum| src IP |
* +--+--+--+--+--+--+--+--+
* 16: | dst IP |
* +--+--+--+--+
*
* vl = version and header length
* TO = TOS
* len = total length
* TT = TTL
* pr = protocol
*
*/
if(len < 20)
{
return;
}
// version 4, header length 20 (5 << 2)
if(pBuf[0] != 0x45)
{
return;
}
if (checksum(pBuf, 20, 0) != 0)
{
return;
}
// only accept packets destined directly to local host
if(memcmp(&pBuf[16], localIP, 4) != 0)
{
return;
}
totLen = ((pBuf[2] << 8) | pBuf[3]);
// only accept ICMP
if(pBuf[9] == 1)
icmpInput(pBuf+20, totLen-20);
}
/*****************************************************************************
*
* Description:
* Handles an incoming ARP packet.
*
****************************************************************************/
static void
arpInput(tU8* pBuf,
tU16 len)
{
tBool isLocalTarg = FALSE;
tU16 op = 0;
/*
* +--+--+--+--+--+--+--+--+
* 0: | ht | pt |hs|ps| op |
* +--+--+--+--+--+--+--+--+
* 8: | sender eth | send
* +--+--+--+--+--+--+--+--+
* 16: | IP | target eth |
* +--+--+--+--+--+--+--+--+
* 24: | target IP |
* +--+--+--+--+
*
*
* ht = hardware address type
* pt = protocol address type
* hs = hardware address size
* ps = protocol address size
* op = operation
*
*/
if(len < 28)
return;
op = (pBuf[6] << 8 | pBuf[7]);
isLocalTarg = memcmp(&pBuf[24], localIP, 4) == 0;
if(op == ARP_REQUEST && isLocalTarg == TRUE)
{
// create a reply
// set operation to ARP reply
pBuf[6] = ((ARP_REPLY >> 8) & 0xff);
pBuf[7] = (ARP_REPLY & 0xff);
// copy sender ethernet address to target ethernet address position
memcpy(&pBuf[18], &pBuf[8], 6);
// copy sender IP address to target IP address position
memcpy(&pBuf[24], &pBuf[14], 4);
// copy local mac address to sender ethernet address position
memcpy(&pBuf[8], mac, 6);
// copy local IP address to sender IP address position
memcpy(&pBuf[14], localIP, 4);
// create ethernet header
pBuf -= 14;
// destination ethernet address
memcpy(&pBuf[0], &pBuf[14+18], 6);
// local ethernet address
memcpy(&pBuf[6], mac, 6);
// ethernet type (= ARP, 0x0806)
pBuf[12] = (0x0806 >> 8);
pBuf[13] = (0x0806 & 0xff);
ethIf_send(pBuf, 42);
}
}
/*****************************************************************************
*
* Description:
* Handles an incoming Ethernet packet.
*
****************************************************************************/
static void
ethInput(tU8* pBuf,
tU16 len)
{
/*
* Ethernet header:
*
* | dest addr | src addr | type |
* 6 6 2
*/
tU16 type = 0;
if(len < 14)
return;
type = (pBuf[12] << 8 | pBuf[13]);
/* move data pointer past ethernet header */
pBuf += 14;
len -= 14;
if(type < 0x0800)
{
/* 802.2/802.3 not supported */
return;
}
/* send the packet to the destination protocol */
switch(type)
{
case 0x0800: /* IP packet */
ipInput(pBuf, len);
break;
case 0x0806: /* ARP packet */
arpInput(pBuf, len);
break;
default:
break;
}
}
/*****************************************************************************
*
* Description:
* Main
*
****************************************************************************/
int main(void)
{
tU16 len = 0;
eaInit();
printf("\n*******************************************************\n");
printf("* *\n");
printf("* Welcome to the 10M Ethernet Expansion Board *\n");
printf("* sample Ethernet driver (polled impl.). *\n");
printf("* Version: 1.1 *\n");
printf("* (c) 2006 Embedded Artists *\n");
printf("* *\n");
printf("*******************************************************\n");
//initialize spi and (hard) reset ENC28J60
initSpi();
printf("\nThe MAC address is: %x:%x:%x:%x:%x:%x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
printf("\nand the IP-address is: %d.%d.%d.%d", localIP[0], localIP[1], localIP[2], localIP[3]);
printf("\nTry pinging the board...\n");
// initialize driver
ethIf_init(mac);
while(1)
{
len = ethIf_poll(inBuf, INBUF_LEN);
if(len > 0)
{
ethInput(inBuf, len);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -