-/*******************************************************************************\r
- * (c) Copyright 2009 Actel Corporation,All Rights Reserved. \r
- * \r
- * tcpip.c:TCP/IP implementation for webserver.\r
- */\r
-#include "../port_config/cpu_types.h"\r
-#include "nettype.h"\r
-#include "../mss_ethernet_mac/mss_ethernet_mac.h"\r
-#include "../mss_ethernet_mac/mss_ethernet_mac_regs.h"\r
-#include "tcpip.h"\r
-#include <string.h>\r
-#include <stdio.h>\r
-#include <math.h>\r
-#define OK 0\r
-#define ERR 1\r
-#define MAC_BASE_ADDRESS 0x40003000\r
-\r
-\r
-extern char ethAddr[6];\r
-\r
-unsigned char my_ip[IP_ADDR_LEN]={192,168,0,14};\r
-unsigned char my_mac[ETH_ADDR_LEN]={0xAA,0xBB,0xCC,0x11,0x22,0x33};\r
-unsigned char tcp_packet[1532];\r
-unsigned char ip_known;\r
-unsigned char dhcp_ip_found;\r
-unsigned short int ip_id;\r
-unsigned char selected_mode = 0;\r
-unsigned char selectedwaveform = 0;\r
-unsigned char rtc_count[5]={0,0,0,0,0};\r
-unsigned char rtc_match_count[5]={0,5,0,0,0};\r
-unsigned char get_count[5];\r
-unsigned int num_pkt_tx = 0,num_pkt_rx = 0;\r
-#define TCP_START_SEQ 0x10203040\r
-static const unsigned char g_client_ip[IP_ADDR_LEN] = { 192, 168, 1, 10 };\r
-unsigned char oled_string[20];\r
-tcp_control_block_t tcb;\r
-MAC_instance_t g_mac;\r
-\r
-\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char send_arp_reply(unsigned char *buf)\r
-{\r
- /* Modify the packet in place */\r
-\r
- arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));\r
- eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;\r
-\r
- memcpy(eth_hdr->da, eth_hdr->sa, ETH_ADDR_LEN);\r
- memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);\r
- arp_pkt->opcode[1] = ARP_OPCODE_REPLY_1;\r
- memcpy(arp_pkt->mac_ta, arp_pkt->mac_sa, ETH_ADDR_LEN);\r
- memcpy(arp_pkt->ip_ta, arp_pkt->ip_sa, IP_ADDR_LEN);\r
- memcpy(arp_pkt->mac_sa, my_mac, ETH_ADDR_LEN);\r
- memcpy(arp_pkt->ip_sa, my_ip, IP_ADDR_LEN);\r
- num_pkt_tx++;\r
- MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);\r
- return OK;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-void send_gratuitous_arp(unsigned char *buf)\r
-{\r
- arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));\r
- eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;\r
- memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */\r
- memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);\r
- eth_hdr->type_code[0] = ETH_TYPE_0;\r
- eth_hdr->type_code[1] = ETH_TYPE_ARP_1;\r
- arp_pkt->hw_type[0] = ARP_HW_TYPE_0;\r
- arp_pkt->hw_type[1] = ARP_HW_TYPE_1;\r
- arp_pkt->proto_type[0] = ETH_TYPE_0;\r
- arp_pkt->proto_type[1] = ETH_TYPE_IP_1;\r
- arp_pkt->hw_addr_len = ETH_ADDR_LEN;\r
- arp_pkt->proto_addr_len = IP_ADDR_LEN;\r
- arp_pkt->opcode[0] = ARP_OPCODE_0;\r
- arp_pkt->opcode[1] = ARP_OPCODE_REQ_1;\r
- memcpy(arp_pkt->mac_sa, my_mac, ETH_ADDR_LEN);\r
- memcpy(arp_pkt->ip_sa, my_ip, IP_ADDR_LEN);\r
- memset(arp_pkt->mac_ta, 0x00, ETH_ADDR_LEN);\r
- memcpy(arp_pkt->ip_ta, my_ip, IP_ADDR_LEN);\r
- //mac_tx_send(buf,42,0);\r
- num_pkt_tx++;\r
- MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- * \r
- */\r
-unsigned short int get_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)\r
-{\r
- unsigned int sum; /* our accumulated sum */\r
- unsigned short int delta; /* the next 16-bit quantity to add */\r
- unsigned short int i; \r
- unsigned short int ilen; \r
- sum = (unsigned int) 0; \r
- ilen=(len&1)?len-1:len; \r
- for (i = 0; i < ilen; i += 2) { \r
- if (i == pos) continue;\r
- delta = (unsigned short int)buf[i+1] + (unsigned short int)((unsigned short int)buf[i] << 8); \r
- sum += delta; \r
- if (sum & (unsigned int) 0x10000) { /* if there's a carry... */\r
- sum &= 0xffff; /* get rid of the carry bit */\r
- sum++; /* and move it down here */\r
- } \r
- } \r
- if ( len & 1) {\r
- delta = (unsigned short int)((unsigned short int)buf[i] << 8); \r
- sum += delta; \r
- if (sum & (unsigned int) 0x10000) { /* if there's a carry... */\r
- sum &= 0xffff; /* get rid of the carry bit */\r
- sum++; /* and move it down here */\r
- } \r
- }\r
- sum = ~sum; \r
- return sum;\r
- \r
-} //end calc_checksum \r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char fix_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)\r
-{\r
- unsigned short int sum = get_checksum(buf,len,pos); \r
- buf[pos] = (unsigned char)(sum >> 8);\r
- buf[pos+1] = (unsigned char)sum;\r
- return OK;\r
-}\r
-\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char check_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos, char type)\r
-{\r
- unsigned short int sum = get_checksum(buf,len,pos);\r
- \r
- if ((buf[pos] != (unsigned char)(sum >> 8)) || \r
- (buf[pos+1] != (unsigned char) sum)) {\r
-\r
- type = 0; /* get around compiler warning */\r
- return ERR;\r
- } else {\r
- return OK;\r
- }\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char send_icmp_echo_reply(unsigned char *buf)\r
-{\r
- eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;\r
- ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));\r
- icmp_hdr_xp icmp_hdr = (icmp_hdr_xp ) \r
- (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));\r
- unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);\r
- memcpy(eth_hdr->da, eth_hdr->sa, ETH_ADDR_LEN);\r
- memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);\r
- memcpy(ip_hdr->da, ip_hdr->sa, IP_ADDR_LEN);\r
- memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);\r
- ip_hdr->ttl--;\r
- fix_checksum((unsigned char *)ip_hdr, (unsigned short int) 20, (unsigned short int) 10);\r
- icmp_hdr->type = ICMP_TYPE_ECHO_REPLY;\r
- if (elen & 1) {\r
- ((unsigned char *)icmp_hdr)[elen] = 0;\r
- }\r
- fix_checksum((unsigned char *)icmp_hdr, (unsigned short int) elen, (unsigned short int) 2);\r
- num_pkt_tx++;\r
- MSS_MAC_tx_packet(buf,elen + sizeof(ether_hdr_t) + sizeof(ip_hdr_t), MSS_MAC_BLOCKING);\r
- return OK;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-void dtoa_reverse(unsigned short int n, unsigned char *buf)\r
-{\r
- buf--;\r
- if (n == 0) {\r
- *buf = '0';\r
- return;\r
- }\r
- while (n > 0) {\r
- *buf-- = (n % 10) + '0';\r
- n = n / 10;\r
- }\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-void send_bootp_packet (unsigned char *buf)\r
-{\r
- /* output packet */\r
- eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;\r
- ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));\r
- udp_hdr_xp udp_hdr = (udp_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));\r
- bootp_pkt_xp bootp_pkt = (bootp_pkt_xp )((unsigned char *)udp_hdr + sizeof(udp_hdr_t));\r
- unsigned char *opts = bootp_pkt->vend;\r
- /* input packet */\r
- // eth_hdr_xp ieth_hdr = (eth_hdr_xp ) buf;\r
- // ip_hdr_xp iip_hdr = (ip_hdr_xp ) (buf + sizeof(ether_hdr_t));\r
- udp_hdr_xp iudp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));\r
- bootp_pkt_xp ibootp_pkt = (bootp_pkt_xp )((unsigned char *)iudp_hdr + sizeof(udp_hdr_t));\r
- unsigned short int plen;\r
- /* Set up Bootp */\r
- memset(bootp_pkt, 0, sizeof(bootp_pkt_t));\r
- bootp_pkt->op = BOOTP_OP_REQUEST;\r
- bootp_pkt->hwtype = BOOTP_HWTYPE_ETH;\r
- bootp_pkt->hlen = ETH_ADDR_LEN;\r
- bootp_pkt->secs[1] = 0x64;\r
- memcpy(bootp_pkt->chaddr, my_mac, ETH_ADDR_LEN);\r
- bootp_pkt->flags[0] = 0x80; /* ask for a broadcast */\r
- if (buf) {\r
- if (memcmp(my_mac, ibootp_pkt->chaddr, ETH_ADDR_LEN)) /* not for me ignore */\r
- return;\r
- memcpy(my_ip, ibootp_pkt->yiaddr, IP_ADDR_LEN);\r
- ip_known = 1;\r
- dhcp_ip_found = 1;\r
- memcpy(bootp_pkt->ciaddr, ibootp_pkt->yiaddr, IP_ADDR_LEN);\r
- memcpy(bootp_pkt->xid, ibootp_pkt->xid, BOOTP_XID_LEN);\r
- } else {\r
- bootp_pkt->xid[0] = 0x90;\r
- }\r
- *opts++ = 99; /* magic number */\r
- *opts++ = 130;\r
- *opts++ = 83;\r
- *opts++ = 99;\r
- *opts++ = BOOTP_OPTCODE_DHCP_TYPE;\r
- *opts++ = 1;\r
- if (buf) {\r
- *opts++ = DHCP_TYPE_REQUEST;\r
- *opts++ = BOOTP_OPTCODE_DHCP_SID;\r
- *opts++ = 4;\r
- *opts++ = ibootp_pkt->siaddr[0];\r
- *opts++ = ibootp_pkt->siaddr[1];\r
- *opts++ = ibootp_pkt->siaddr[2];\r
- *opts++ = ibootp_pkt->siaddr[3];\r
- } else {\r
- *opts++ = DHCP_TYPE_DISCOVER;\r
- }\r
- *opts++ = BOOTP_OPTCODE_END;\r
-\r
- /* Set up Udp */\r
- memset(udp_hdr, 0, sizeof(udp_hdr_t));\r
- udp_hdr->sp[1] = BOOTP_CLIENT_PORT;\r
- udp_hdr->dp[1] = BOOTP_SERVER_PORT;\r
- plen = sizeof(udp_hdr_t) + sizeof(bootp_pkt_t);\r
- udp_hdr->len[0] = plen >> 8;\r
- udp_hdr->len[1] = (unsigned char) plen;\r
- /* leave csum 0 */\r
-\r
- /* Set up IP */\r
- memset(ip_hdr, 0, sizeof(ip_hdr_t));\r
- ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */\r
- plen += sizeof(ip_hdr_t);\r
- ip_hdr->tlen[0] = plen >> 8;\r
- ip_hdr->tlen[1] = (unsigned char) plen;\r
- ip_hdr->id[0] = ip_id >> 8;\r
- ip_hdr->id[1] = (unsigned char) ip_id;\r
- ip_id++;\r
- ip_hdr->ttl = 32; /* max 32 hops */\r
- ip_hdr->proto = UDP_PROTO; \r
- memset(ip_hdr->da, 0xFF, IP_ADDR_LEN);\r
- fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);\r
- /* Set up Ethernet */\r
- eth_hdr->type_code[0] = ETH_TYPE_0;\r
- eth_hdr->type_code[1] = ETH_TYPE_IP_1;\r
- memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);\r
- memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */\r
- num_pkt_tx++;\r
- MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-void send_dhcp_server_packet (unsigned char *buf)\r
-{\r
- unsigned char * tcp_packet = tcp_packet;\r
- /* output packet */\r
- eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;\r
- ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));\r
- udp_hdr_xp udp_hdr = (udp_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));\r
- bootp_pkt_xp bootp_pkt = (bootp_pkt_xp )((unsigned char *)udp_hdr + sizeof(udp_hdr_t));\r
- unsigned char *opts = bootp_pkt->vend;\r
-\r
- /* input packet */\r
- eth_hdr_xp ieth_hdr = (eth_hdr_xp ) buf;\r
- // ip_hdr_xp iip_hdr = (ip_hdr_xp ) (buf + sizeof(ether_hdr_t));\r
- udp_hdr_xp iudp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));\r
- bootp_pkt_xp ibootp_pkt = (bootp_pkt_xp )((unsigned char *)iudp_hdr + sizeof(udp_hdr_t));\r
- unsigned char *iopts = ibootp_pkt->vend;\r
-\r
- unsigned short int plen;\r
-\r
- /* Set up Bootp */\r
- memset(bootp_pkt, 0, sizeof(bootp_pkt_t));\r
- bootp_pkt->op = BOOTP_OP_REPLY;\r
- bootp_pkt->hwtype = BOOTP_HWTYPE_ETH;\r
- bootp_pkt->hlen = ETH_ADDR_LEN;\r
- bootp_pkt->secs[1] = 0x64;\r
- memcpy(bootp_pkt->chaddr, ieth_hdr->sa, ETH_ADDR_LEN);\r
- bootp_pkt->flags[0] = 0x00;\r
- if (buf) {\r
- memcpy(bootp_pkt->ciaddr, ibootp_pkt->yiaddr, IP_ADDR_LEN);\r
- memcpy(bootp_pkt->yiaddr, g_client_ip, IP_ADDR_LEN);\r
- memcpy(bootp_pkt->xid, ibootp_pkt->xid, BOOTP_XID_LEN);\r
- } else {\r
- bootp_pkt->xid[0] = 0x90;\r
- }\r
- *opts++ = 99; /* magic number */\r
- *opts++ = 130;\r
- *opts++ = 83;\r
- *opts++ = 99;\r
- *opts++ = BOOTP_OPTCODE_DHCP_TYPE;\r
- *opts++ = 1;\r
- if (iopts[6] == DHCP_TYPE_DISCOVER)\r
- {\r
- *opts++ = DHCP_TYPE_OFFER;\r
- }\r
- else\r
- {\r
- *opts++ = DHCP_TYPE_ACK;\r
- } \r
- /* Server ID */\r
- *opts++ = BOOTP_OPTCODE_DHCP_SID;\r
- *opts++ = 4;\r
- *opts++ = my_ip[0];\r
- *opts++ = my_ip[1];\r
- *opts++ = my_ip[2];\r
- *opts++ = my_ip[3];\r
- /* Lease time (1 our) */\r
- *opts++ = BOOTP_OPTCODE_DHCP_LEASE;\r
- *opts++ = 4;\r
- *opts++ = 0x00;\r
- *opts++ = 0x00;\r
- *opts++ = 0x0E;\r
- *opts++ = 0x10;\r
- /* Renewal time */\r
- *opts++ = BOOTP_OPTCODE_DHCP_RENEW;\r
- *opts++ = 4;\r
- *opts++ = 0x00;\r
- *opts++ = 0x00;\r
- *opts++ = 0x07;\r
- *opts++ = 0x08;\r
- /* Rebinding time */\r
- *opts++ = BOOTP_OPTCODE_DHCP_REBIND;\r
- *opts++ = 4;\r
- *opts++ = 0x00;\r
- *opts++ = 0x00;\r
- *opts++ = 0x0C;\r
- *opts++ = 0x4E;\r
- /* Subnet mask */\r
- *opts++ = BOOTP_OPTCODE_DHCP_SUBNET;\r
- *opts++ = 4;\r
- *opts++ = 0xFF;\r
- *opts++ = 0xFF;\r
- *opts++ = 0xFF;\r
- *opts++ = 0x00;\r
- /* Router */\r
- *opts++ = BOOTP_OPTCODE_DHCP_ROUTER;\r
- *opts++ = 4;\r
- *opts++ = my_ip[0];\r
- *opts++ = my_ip[1];\r
- *opts++ = my_ip[2];\r
- *opts++ = my_ip[3];\r
- /* Domain */\r
- *opts++ = BOOTP_OPTCODE_DHCP_DOMAIN;\r
- *opts++ = 4;\r
- *opts++ = my_ip[0];\r
- *opts++ = my_ip[1];\r
- *opts++ = my_ip[2];\r
- *opts++ = my_ip[3];\r
- \r
- *opts++ = BOOTP_OPTCODE_END;\r
-\r
- /* Set up Udp */\r
- memset(udp_hdr, 0, sizeof(udp_hdr_t));\r
- udp_hdr->sp[1] = BOOTP_SERVER_PORT;\r
- udp_hdr->dp[1] = BOOTP_CLIENT_PORT;\r
- plen = sizeof(udp_hdr_t) + sizeof(bootp_pkt_t);\r
- udp_hdr->len[0] = plen >> 8;\r
- udp_hdr->len[1] = (unsigned char) plen;\r
- /* leave csum 0 */\r
-\r
- /* Set up IP */\r
- memset(ip_hdr, 0, sizeof(ip_hdr_t));\r
- ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */\r
- plen += sizeof(ip_hdr_t);\r
- ip_hdr->tlen[0] = plen >> 8;\r
- ip_hdr->tlen[1] = (unsigned char) plen;\r
- ip_hdr->id[0] = ip_id >> 8;\r
- ip_hdr->id[1] = (unsigned char) ip_id;\r
- ip_id++;\r
- ip_hdr->ttl = 255;\r
- ip_hdr->proto = UDP_PROTO;\r
- memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);\r
- memset(ip_hdr->da, 0xFF, IP_ADDR_LEN);\r
- fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);\r
- \r
- /* Set up Ethernet */\r
- eth_hdr->type_code[0] = ETH_TYPE_0;\r
- eth_hdr->type_code[1] = ETH_TYPE_IP_1;\r
- memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN); \r
- memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */\r
- num_pkt_tx++;\r
- MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char process_udp_packet (unsigned char *buf)\r
-{\r
- \r
- udp_hdr_xp udp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));\r
- \r
- if (udp_hdr->dp[1] != BOOTP_CLIENT_PORT) {\r
- send_dhcp_server_packet( buf );\r
- return OK;\r
- }\r
- if (ip_known) {\r
- return ERR;\r
- }\r
- /* some more error checking here? */\r
- send_bootp_packet(buf);\r
- return OK;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-\r
-void send_tcp_packet (unsigned char control_bits,unsigned short int buflen) \r
-{\r
- \r
- eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;\r
- ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));\r
- tcp_hdr_xp tcp_hdr = (tcp_hdr_xp ) \r
- (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));\r
- tcp_pseudo_hdr_xp tcp_pseudo_hdr = (tcp_pseudo_hdr_xp )\r
- (((unsigned char *)tcp_hdr) - sizeof(tcp_pseudo_hdr_t));\r
- unsigned char *tcp_data = tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t) + sizeof (tcp_hdr_t);\r
- unsigned char *seqp = (unsigned char *)(&tcb.local_seq);\r
- unsigned short int plen;\r
- memset(tcp_hdr, 0, sizeof(tcp_hdr_t));\r
- memcpy(tcp_hdr->sp, tcb.local_port, TCP_PORT_LEN);\r
- memcpy(tcp_hdr->dp, tcb.remote_port, TCP_PORT_LEN);\r
- tcp_hdr->seqnum[0] = seqp[3];\r
- tcp_hdr->seqnum[1] = seqp[2];\r
- tcp_hdr->seqnum[2] = seqp[1];\r
- tcp_hdr->seqnum[3] = seqp[0];\r
- tcb.local_seq++;\r
- if (buflen) {\r
- tcb.local_seq += buflen - 1;\r
- }\r
- if (control_bits & TCP_CNTRL_ACK) {\r
- seqp = (unsigned char *)(&tcb.remote_seq);\r
- tcp_hdr->acknum[3] = seqp[0];\r
- tcp_hdr->acknum[2] = seqp[1];\r
- tcp_hdr->acknum[1] = seqp[2];\r
- tcp_hdr->acknum[0] = seqp[3];\r
- }\r
- tcp_hdr->data_off = 0x50; /* always 5 32 bit words for us */\r
- tcp_hdr->urg_ack_psh_rst_syn_fin = control_bits;\r
- tcp_hdr->wsize[0] = 0x08; /* this is 0x0800, which is 2K */\r
- if (buflen & 1) {\r
- tcp_data[buflen] = 0;\r
- }\r
- /* memset(tcp_pseudo_hdr, 0, sizeof(tcp_pseudo_hdr_t)); */\r
- memcpy(tcp_pseudo_hdr->sa, my_ip, IP_ADDR_LEN);\r
- memcpy(tcp_pseudo_hdr->da, tcb.remote_addr, IP_ADDR_LEN);\r
- tcp_pseudo_hdr->zero = 0;\r
- tcp_pseudo_hdr->proto = TCP_PROTO;\r
- plen = buflen + sizeof(tcp_hdr_t);\r
- tcp_pseudo_hdr->plen[0] = plen >> 8;\r
- tcp_pseudo_hdr->plen[1] = (unsigned char)plen;\r
- fix_checksum((unsigned char *)tcp_pseudo_hdr, \r
- (unsigned short int)(plen + sizeof(tcp_pseudo_hdr_t)), (unsigned short int)28);\r
-\r
- memset(ip_hdr, 0, sizeof(ip_hdr_t));\r
-\r
- ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */\r
- plen += sizeof(ip_hdr_t); /* add the size of the IP Header */\r
- ip_hdr->tlen[0] = plen >> 8;\r
- ip_hdr->tlen[1] = (unsigned char) plen;\r
- ip_hdr->id[0] = ip_id >> 8;\r
- ip_hdr->id[1] = (unsigned char) ip_id;\r
- ip_id++;\r
- ip_hdr->ttl = 32; /* max 32 hops */\r
- ip_hdr->proto = TCP_PROTO;\r
- memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);\r
- memcpy(ip_hdr->da, tcb.remote_addr, IP_ADDR_LEN);\r
- fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);\r
- /* Fix the Ethernet Header */\r
- eth_hdr->type_code[0] = ETH_TYPE_0;\r
- eth_hdr->type_code[1] = ETH_TYPE_IP_1;\r
- memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);\r
- memcpy(eth_hdr->da, tcb.remote_mac, ETH_ADDR_LEN); /* should be table lookup */\r
- num_pkt_tx++; \r
- MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char tcp_init(void)\r
-{\r
- memset(&tcb,0,sizeof(tcp_control_block_t));\r
- tcb.state = TCP_STATE_LISTEN;\r
- ip_id = 0;\r
- ip_known = 0;\r
- return OK;\r
-}\r
-\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char hex_digits_to_byte(unsigned char u, unsigned char l) \r
-{\r
- if (u > '9')\r
- u = u - 'A' + 10;\r
- else\r
- u = u - '0';\r
- if (l > '9')\r
- l = l - 'A' + 10;\r
- else\r
- l = l - '0';\r
- return (u << 4) + l;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char process_icmp_packet(unsigned char *buf)\r
-{\r
- ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));\r
- icmp_hdr_xp icmp_hdr = (icmp_hdr_xp ) \r
- (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));\r
- unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);\r
- if (check_checksum((unsigned char *)icmp_hdr, (unsigned short int) elen, (unsigned short int) 2, 'M') != OK) \r
- return ERR;\r
- if (icmp_hdr->type != ICMP_TYPE_ECHO_REQUEST) {\r
- return ERR;\r
- }\r
- return send_icmp_echo_reply(buf);\r
-}\r
-\r
- /* See tcpip.h for more information.\r
- */\r
-\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char process_tcp_packet(unsigned char *buf)\r
-{\r
- eth_hdr_xp eth_hdr = (eth_hdr_xp )buf;\r
- ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));\r
- tcp_hdr_xp tcp_hdr = (tcp_hdr_xp ) \r
- (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));\r
- unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);\r
- unsigned char state;\r
- if ( !memcmp(tcb.remote_addr, ip_hdr->sa, IP_ADDR_LEN) && /* same source IP */\r
- !memcmp(tcb.remote_port, tcp_hdr->sp, TCP_PORT_LEN) && /* same source port */\r
- !memcmp(tcb.local_port, tcp_hdr->dp, TCP_PORT_LEN)) { /* same dest port */\r
- state = tcb.state;\r
- } else { /* copy it over, a new IP wants in */\r
- memcpy(tcb.remote_addr, ip_hdr->sa, IP_ADDR_LEN);\r
- memcpy(tcb.remote_port, tcp_hdr->sp, TCP_PORT_LEN);\r
- memcpy(tcb.local_port, tcp_hdr->dp, TCP_PORT_LEN);\r
- memcpy(tcb.remote_mac, eth_hdr->sa, ETH_ADDR_LEN);\r
- state = TCP_STATE_LISTEN;\r
- } \r
- switch (state) {\r
- case TCP_STATE_LISTEN:\r
- if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_SYN) {\r
- /* recd SYN : new connection; send SYN+ACK */ \r
- \r
- tcb.local_seq = TCP_START_SEQ;\r
- tcb.remote_seq = 0;\r
- tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]); \r
- tcb.remote_seq++;\r
- send_tcp_packet( TCP_CNTRL_SYN | TCP_CNTRL_ACK, 0);\r
- tcb.state = TCP_STATE_SYN_RECVD;\r
- } \r
- break; \r
- case TCP_STATE_SYN_RECVD: \r
- if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_ACK) { \r
- /* recd ack; send nothing */\r
- tcb.state = TCP_STATE_ESTABLISHED;\r
- } \r
- else { \r
- tcb.state = TCP_STATE_LISTEN;\r
- } \r
- break;\r
- case TCP_STATE_ESTABLISHED: \r
- if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_FIN) {\r
- /* recd fin; send ack */\r
- /* skip CLOSE_WAIT state; send fin along with ack */\r
- tcb.remote_seq = 0;\r
- tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]); \r
- tcb.remote_seq++;\r
- send_tcp_packet(TCP_CNTRL_ACK | TCP_CNTRL_FIN, 0);\r
- tcb.state = TCP_STATE_LAST_ACK; \r
- /* Default scroll message on OLED */\r
- }\r
- else if (tcp_hdr->dp[0] != 0 || \\r
- tcp_hdr->dp[1] != 80) { /* HTTP Port */\r
- break;\r
- }\r
- else if (elen > sizeof(tcp_hdr_t)) { /* dont respond to empty packets*/\r
- tcb.remote_seq = 0;\r
- tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]); \r
- tcb.remote_seq += (unsigned long) (elen - sizeof(tcp_hdr_t));\r
- //send_http_response(((unsigned char *)(tcp_hdr)) + sizeof (tcp_hdr_t));\r
- tcb.state = TCP_STATE_MY_LAST; \r
- } \r
- break;\r
- case TCP_STATE_MY_LAST: \r
- if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_FIN) {\r
- /* sent fin, got fin, ack the fin */\r
- tcb.remote_seq = 0;\r
- tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);\r
- tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]); \r
- tcb.remote_seq++;\r
- send_tcp_packet(TCP_CNTRL_ACK, 0);\r
- tcb.state = TCP_STATE_CLOSED;\r
- }\r
- break;\r
- case TCP_STATE_LAST_ACK:\r
- \r
- if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_ACK) {\r
- /* recd ack; send nothing */\r
- tcb.state = TCP_STATE_CLOSED;\r
- }\r
- /* no break here... go on to CLOSED directly */\r
- case TCP_STATE_CLOSED: \r
- memset (&tcb, 0, sizeof (tcp_control_block_t));\r
- break; \r
- default:\r
- break;\r
- }\r
- return 0;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char process_ip_packet(unsigned char *buf)\r
-{\r
- ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));\r
- /* Is the incoming pkt for me?\r
- (either explicity addressed to me or a broadcast address) */\r
- if (memcmp(my_ip, ip_hdr->da, IP_ADDR_LEN)) /* not my IP */ {\r
- if (ip_known) {\r
- return ERR;\r
- }\r
- if (ip_hdr->da[0] != 0xFF || ip_hdr->da[1] != 0xFF ||\r
- ip_hdr->da[2] != 0xFF || ip_hdr->da[3] != 0xFF) {\r
- return ERR;\r
- }\r
- }\r
- if (check_checksum((unsigned char *)ip_hdr, (unsigned short int) 20, (unsigned short int) 10, 'I') != OK)\r
- return ERR;\r
- switch (ip_hdr->proto) \r
- {\r
- case TCP_PROTO:\r
- return process_tcp_packet(buf);\r
- case ICMP_PROTO:\r
- return process_icmp_packet(buf);\r
- case UDP_PROTO:\r
- return process_udp_packet(buf);\r
- default: {\r
- return ERR;\r
- }\r
- }\r
- return ERR;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char process_arp_packet(unsigned char *buf)\r
-{\r
- arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));\r
- if (arp_pkt->opcode[1] != ARP_OPCODE_REQ_1) { \r
- if (arp_pkt->opcode[1] == ARP_OPCODE_REPLY_1)\r
- { \r
- if (!memcmp(my_ip, arp_pkt->ip_sa, IP_ADDR_LEN))\r
- { \r
- //printf("IP conflict with MAC");\r
- //printf("%02x:%02x:%02x:%02x:%02x:%02x",arp_pkt->mac_sa[0],arp_pkt->mac_sa[1],arp_pkt->mac_sa[2],arp_pkt->mac_sa[3],arp_pkt->mac_sa[4],arp_pkt->mac_sa[5]);\r
- } \r
- }\r
- return ERR;\r
- } \r
- if (memcmp(my_ip, arp_pkt->ip_ta, IP_ADDR_LEN)) {\r
- return ERR;\r
- } \r
- return send_arp_reply(buf);\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char process_packet( unsigned char * buf )\r
-{\r
- eth_hdr_xp eth_hdr;\r
- unsigned char typ;\r
- eth_hdr = (eth_hdr_xp ) buf;\r
- typ = eth_hdr->type_code[0];\r
- if (typ != ETH_TYPE_0)\r
- {\r
- return ERR;\r
- }\r
- typ = eth_hdr->type_code[1];\r
- if (typ == ETH_TYPE_ARP_1) \r
- {\r
- return process_arp_packet(buf);\r
- }\r
- else if (typ == ETH_TYPE_IP_1) {\r
- return process_ip_packet(buf);\r
- } \r
- else\r
- {\r
- return ERR;\r
- }\r
- return ERR;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-unsigned char *xstrcpy(unsigned char *d, const unsigned char *s)\r
-{\r
- unsigned char c;\r
-\r
- while ((c = *s++)) \r
- (*d++ = c) ;\r
- return d;\r
-}\r
-/***************************************************************************//**\r
- * See tcpip.h for more information.\r
- */\r
-// updated html page with fusion board link on page:\r
-\r