1 /*******************************************************************************
\r
2 * (c) Copyright 2009 Actel Corporation,All Rights Reserved.
\r
4 * tcpip.c:TCP/IP implementation for webserver.
\r
6 #include "../port_config/cpu_types.h"
\r
8 #include "../mss_ethernet_mac/mss_ethernet_mac.h"
\r
9 #include "../mss_ethernet_mac/mss_ethernet_mac_regs.h"
\r
16 #define MAC_BASE_ADDRESS 0x40003000
\r
19 extern char ethAddr[6];
\r
21 unsigned char my_ip[IP_ADDR_LEN]={192,168,0,14};
\r
22 unsigned char my_mac[ETH_ADDR_LEN]={0xAA,0xBB,0xCC,0x11,0x22,0x33};
\r
23 unsigned char tcp_packet[1532];
\r
24 unsigned char ip_known;
\r
25 unsigned char dhcp_ip_found;
\r
26 unsigned short int ip_id;
\r
27 unsigned char selected_mode = 0;
\r
28 unsigned char selectedwaveform = 0;
\r
29 unsigned char rtc_count[5]={0,0,0,0,0};
\r
30 unsigned char rtc_match_count[5]={0,5,0,0,0};
\r
31 unsigned char get_count[5];
\r
32 unsigned int num_pkt_tx = 0,num_pkt_rx = 0;
\r
33 #define TCP_START_SEQ 0x10203040
\r
34 static const unsigned char g_client_ip[IP_ADDR_LEN] = { 192, 168, 1, 10 };
\r
35 unsigned char oled_string[20];
\r
36 tcp_control_block_t tcb;
\r
37 MAC_instance_t g_mac;
\r
40 /***************************************************************************//**
\r
41 * See tcpip.h for more information.
\r
43 unsigned char send_arp_reply(unsigned char *buf)
\r
45 /* Modify the packet in place */
\r
47 arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));
\r
48 eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;
\r
50 memcpy(eth_hdr->da, eth_hdr->sa, ETH_ADDR_LEN);
\r
51 memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
\r
52 arp_pkt->opcode[1] = ARP_OPCODE_REPLY_1;
\r
53 memcpy(arp_pkt->mac_ta, arp_pkt->mac_sa, ETH_ADDR_LEN);
\r
54 memcpy(arp_pkt->ip_ta, arp_pkt->ip_sa, IP_ADDR_LEN);
\r
55 memcpy(arp_pkt->mac_sa, my_mac, ETH_ADDR_LEN);
\r
56 memcpy(arp_pkt->ip_sa, my_ip, IP_ADDR_LEN);
\r
58 MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);
\r
61 /***************************************************************************//**
\r
62 * See tcpip.h for more information.
\r
64 void send_gratuitous_arp(unsigned char *buf)
\r
66 arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));
\r
67 eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;
\r
68 memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */
\r
69 memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
\r
70 eth_hdr->type_code[0] = ETH_TYPE_0;
\r
71 eth_hdr->type_code[1] = ETH_TYPE_ARP_1;
\r
72 arp_pkt->hw_type[0] = ARP_HW_TYPE_0;
\r
73 arp_pkt->hw_type[1] = ARP_HW_TYPE_1;
\r
74 arp_pkt->proto_type[0] = ETH_TYPE_0;
\r
75 arp_pkt->proto_type[1] = ETH_TYPE_IP_1;
\r
76 arp_pkt->hw_addr_len = ETH_ADDR_LEN;
\r
77 arp_pkt->proto_addr_len = IP_ADDR_LEN;
\r
78 arp_pkt->opcode[0] = ARP_OPCODE_0;
\r
79 arp_pkt->opcode[1] = ARP_OPCODE_REQ_1;
\r
80 memcpy(arp_pkt->mac_sa, my_mac, ETH_ADDR_LEN);
\r
81 memcpy(arp_pkt->ip_sa, my_ip, IP_ADDR_LEN);
\r
82 memset(arp_pkt->mac_ta, 0x00, ETH_ADDR_LEN);
\r
83 memcpy(arp_pkt->ip_ta, my_ip, IP_ADDR_LEN);
\r
84 //mac_tx_send(buf,42,0);
\r
86 MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);
\r
88 /***************************************************************************//**
\r
89 * See tcpip.h for more information.
\r
92 unsigned short int get_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)
\r
94 unsigned int sum; /* our accumulated sum */
\r
95 unsigned short int delta; /* the next 16-bit quantity to add */
\r
96 unsigned short int i;
\r
97 unsigned short int ilen;
\r
98 sum = (unsigned int) 0;
\r
99 ilen=(len&1)?len-1:len;
\r
100 for (i = 0; i < ilen; i += 2) {
\r
101 if (i == pos) continue;
\r
102 delta = (unsigned short int)buf[i+1] + (unsigned short int)((unsigned short int)buf[i] << 8);
\r
104 if (sum & (unsigned int) 0x10000) { /* if there's a carry... */
\r
105 sum &= 0xffff; /* get rid of the carry bit */
\r
106 sum++; /* and move it down here */
\r
110 delta = (unsigned short int)((unsigned short int)buf[i] << 8);
\r
112 if (sum & (unsigned int) 0x10000) { /* if there's a carry... */
\r
113 sum &= 0xffff; /* get rid of the carry bit */
\r
114 sum++; /* and move it down here */
\r
120 } //end calc_checksum
\r
121 /***************************************************************************//**
\r
122 * See tcpip.h for more information.
\r
124 unsigned char fix_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)
\r
126 unsigned short int sum = get_checksum(buf,len,pos);
\r
127 buf[pos] = (unsigned char)(sum >> 8);
\r
128 buf[pos+1] = (unsigned char)sum;
\r
132 /***************************************************************************//**
\r
133 * See tcpip.h for more information.
\r
135 unsigned char check_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos, char type)
\r
137 unsigned short int sum = get_checksum(buf,len,pos);
\r
139 if ((buf[pos] != (unsigned char)(sum >> 8)) ||
\r
140 (buf[pos+1] != (unsigned char) sum)) {
\r
142 type = 0; /* get around compiler warning */
\r
148 /***************************************************************************//**
\r
149 * See tcpip.h for more information.
\r
151 unsigned char send_icmp_echo_reply(unsigned char *buf)
\r
153 eth_hdr_xp eth_hdr = (eth_hdr_xp ) buf;
\r
154 ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
\r
155 icmp_hdr_xp icmp_hdr = (icmp_hdr_xp )
\r
156 (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));
\r
157 unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);
\r
158 memcpy(eth_hdr->da, eth_hdr->sa, ETH_ADDR_LEN);
\r
159 memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
\r
160 memcpy(ip_hdr->da, ip_hdr->sa, IP_ADDR_LEN);
\r
161 memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);
\r
163 fix_checksum((unsigned char *)ip_hdr, (unsigned short int) 20, (unsigned short int) 10);
\r
164 icmp_hdr->type = ICMP_TYPE_ECHO_REPLY;
\r
166 ((unsigned char *)icmp_hdr)[elen] = 0;
\r
168 fix_checksum((unsigned char *)icmp_hdr, (unsigned short int) elen, (unsigned short int) 2);
\r
170 MSS_MAC_tx_packet(buf,elen + sizeof(ether_hdr_t) + sizeof(ip_hdr_t), MSS_MAC_BLOCKING);
\r
173 /***************************************************************************//**
\r
174 * See tcpip.h for more information.
\r
176 void dtoa_reverse(unsigned short int n, unsigned char *buf)
\r
184 *buf-- = (n % 10) + '0';
\r
188 /***************************************************************************//**
\r
189 * See tcpip.h for more information.
\r
191 void send_bootp_packet (unsigned char *buf)
\r
193 /* output packet */
\r
194 eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;
\r
195 ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));
\r
196 udp_hdr_xp udp_hdr = (udp_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
\r
197 bootp_pkt_xp bootp_pkt = (bootp_pkt_xp )((unsigned char *)udp_hdr + sizeof(udp_hdr_t));
\r
198 unsigned char *opts = bootp_pkt->vend;
\r
200 // eth_hdr_xp ieth_hdr = (eth_hdr_xp ) buf;
\r
201 // ip_hdr_xp iip_hdr = (ip_hdr_xp ) (buf + sizeof(ether_hdr_t));
\r
202 udp_hdr_xp iudp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
\r
203 bootp_pkt_xp ibootp_pkt = (bootp_pkt_xp )((unsigned char *)iudp_hdr + sizeof(udp_hdr_t));
\r
204 unsigned short int plen;
\r
206 memset(bootp_pkt, 0, sizeof(bootp_pkt_t));
\r
207 bootp_pkt->op = BOOTP_OP_REQUEST;
\r
208 bootp_pkt->hwtype = BOOTP_HWTYPE_ETH;
\r
209 bootp_pkt->hlen = ETH_ADDR_LEN;
\r
210 bootp_pkt->secs[1] = 0x64;
\r
211 memcpy(bootp_pkt->chaddr, my_mac, ETH_ADDR_LEN);
\r
212 bootp_pkt->flags[0] = 0x80; /* ask for a broadcast */
\r
214 if (memcmp(my_mac, ibootp_pkt->chaddr, ETH_ADDR_LEN)) /* not for me ignore */
\r
216 memcpy(my_ip, ibootp_pkt->yiaddr, IP_ADDR_LEN);
\r
219 memcpy(bootp_pkt->ciaddr, ibootp_pkt->yiaddr, IP_ADDR_LEN);
\r
220 memcpy(bootp_pkt->xid, ibootp_pkt->xid, BOOTP_XID_LEN);
\r
222 bootp_pkt->xid[0] = 0x90;
\r
224 *opts++ = 99; /* magic number */
\r
228 *opts++ = BOOTP_OPTCODE_DHCP_TYPE;
\r
231 *opts++ = DHCP_TYPE_REQUEST;
\r
232 *opts++ = BOOTP_OPTCODE_DHCP_SID;
\r
234 *opts++ = ibootp_pkt->siaddr[0];
\r
235 *opts++ = ibootp_pkt->siaddr[1];
\r
236 *opts++ = ibootp_pkt->siaddr[2];
\r
237 *opts++ = ibootp_pkt->siaddr[3];
\r
239 *opts++ = DHCP_TYPE_DISCOVER;
\r
241 *opts++ = BOOTP_OPTCODE_END;
\r
244 memset(udp_hdr, 0, sizeof(udp_hdr_t));
\r
245 udp_hdr->sp[1] = BOOTP_CLIENT_PORT;
\r
246 udp_hdr->dp[1] = BOOTP_SERVER_PORT;
\r
247 plen = sizeof(udp_hdr_t) + sizeof(bootp_pkt_t);
\r
248 udp_hdr->len[0] = plen >> 8;
\r
249 udp_hdr->len[1] = (unsigned char) plen;
\r
253 memset(ip_hdr, 0, sizeof(ip_hdr_t));
\r
254 ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */
\r
255 plen += sizeof(ip_hdr_t);
\r
256 ip_hdr->tlen[0] = plen >> 8;
\r
257 ip_hdr->tlen[1] = (unsigned char) plen;
\r
258 ip_hdr->id[0] = ip_id >> 8;
\r
259 ip_hdr->id[1] = (unsigned char) ip_id;
\r
261 ip_hdr->ttl = 32; /* max 32 hops */
\r
262 ip_hdr->proto = UDP_PROTO;
\r
263 memset(ip_hdr->da, 0xFF, IP_ADDR_LEN);
\r
264 fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);
\r
265 /* Set up Ethernet */
\r
266 eth_hdr->type_code[0] = ETH_TYPE_0;
\r
267 eth_hdr->type_code[1] = ETH_TYPE_IP_1;
\r
268 memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
\r
269 memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */
\r
271 MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);
\r
273 /***************************************************************************//**
\r
274 * See tcpip.h for more information.
\r
276 void send_dhcp_server_packet (unsigned char *buf)
\r
278 unsigned char * tcp_packet = tcp_packet;
\r
279 /* output packet */
\r
280 eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;
\r
281 ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));
\r
282 udp_hdr_xp udp_hdr = (udp_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
\r
283 bootp_pkt_xp bootp_pkt = (bootp_pkt_xp )((unsigned char *)udp_hdr + sizeof(udp_hdr_t));
\r
284 unsigned char *opts = bootp_pkt->vend;
\r
287 eth_hdr_xp ieth_hdr = (eth_hdr_xp ) buf;
\r
288 // ip_hdr_xp iip_hdr = (ip_hdr_xp ) (buf + sizeof(ether_hdr_t));
\r
289 udp_hdr_xp iudp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
\r
290 bootp_pkt_xp ibootp_pkt = (bootp_pkt_xp )((unsigned char *)iudp_hdr + sizeof(udp_hdr_t));
\r
291 unsigned char *iopts = ibootp_pkt->vend;
\r
293 unsigned short int plen;
\r
296 memset(bootp_pkt, 0, sizeof(bootp_pkt_t));
\r
297 bootp_pkt->op = BOOTP_OP_REPLY;
\r
298 bootp_pkt->hwtype = BOOTP_HWTYPE_ETH;
\r
299 bootp_pkt->hlen = ETH_ADDR_LEN;
\r
300 bootp_pkt->secs[1] = 0x64;
\r
301 memcpy(bootp_pkt->chaddr, ieth_hdr->sa, ETH_ADDR_LEN);
\r
302 bootp_pkt->flags[0] = 0x00;
\r
304 memcpy(bootp_pkt->ciaddr, ibootp_pkt->yiaddr, IP_ADDR_LEN);
\r
305 memcpy(bootp_pkt->yiaddr, g_client_ip, IP_ADDR_LEN);
\r
306 memcpy(bootp_pkt->xid, ibootp_pkt->xid, BOOTP_XID_LEN);
\r
308 bootp_pkt->xid[0] = 0x90;
\r
310 *opts++ = 99; /* magic number */
\r
314 *opts++ = BOOTP_OPTCODE_DHCP_TYPE;
\r
316 if (iopts[6] == DHCP_TYPE_DISCOVER)
\r
318 *opts++ = DHCP_TYPE_OFFER;
\r
322 *opts++ = DHCP_TYPE_ACK;
\r
325 *opts++ = BOOTP_OPTCODE_DHCP_SID;
\r
327 *opts++ = my_ip[0];
\r
328 *opts++ = my_ip[1];
\r
329 *opts++ = my_ip[2];
\r
330 *opts++ = my_ip[3];
\r
331 /* Lease time (1 our) */
\r
332 *opts++ = BOOTP_OPTCODE_DHCP_LEASE;
\r
339 *opts++ = BOOTP_OPTCODE_DHCP_RENEW;
\r
345 /* Rebinding time */
\r
346 *opts++ = BOOTP_OPTCODE_DHCP_REBIND;
\r
353 *opts++ = BOOTP_OPTCODE_DHCP_SUBNET;
\r
360 *opts++ = BOOTP_OPTCODE_DHCP_ROUTER;
\r
362 *opts++ = my_ip[0];
\r
363 *opts++ = my_ip[1];
\r
364 *opts++ = my_ip[2];
\r
365 *opts++ = my_ip[3];
\r
367 *opts++ = BOOTP_OPTCODE_DHCP_DOMAIN;
\r
369 *opts++ = my_ip[0];
\r
370 *opts++ = my_ip[1];
\r
371 *opts++ = my_ip[2];
\r
372 *opts++ = my_ip[3];
\r
374 *opts++ = BOOTP_OPTCODE_END;
\r
377 memset(udp_hdr, 0, sizeof(udp_hdr_t));
\r
378 udp_hdr->sp[1] = BOOTP_SERVER_PORT;
\r
379 udp_hdr->dp[1] = BOOTP_CLIENT_PORT;
\r
380 plen = sizeof(udp_hdr_t) + sizeof(bootp_pkt_t);
\r
381 udp_hdr->len[0] = plen >> 8;
\r
382 udp_hdr->len[1] = (unsigned char) plen;
\r
386 memset(ip_hdr, 0, sizeof(ip_hdr_t));
\r
387 ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */
\r
388 plen += sizeof(ip_hdr_t);
\r
389 ip_hdr->tlen[0] = plen >> 8;
\r
390 ip_hdr->tlen[1] = (unsigned char) plen;
\r
391 ip_hdr->id[0] = ip_id >> 8;
\r
392 ip_hdr->id[1] = (unsigned char) ip_id;
\r
395 ip_hdr->proto = UDP_PROTO;
\r
396 memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);
\r
397 memset(ip_hdr->da, 0xFF, IP_ADDR_LEN);
\r
398 fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);
\r
400 /* Set up Ethernet */
\r
401 eth_hdr->type_code[0] = ETH_TYPE_0;
\r
402 eth_hdr->type_code[1] = ETH_TYPE_IP_1;
\r
403 memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
\r
404 memset(eth_hdr->da, 0xFF, ETH_ADDR_LEN); /* broadcast */
\r
406 MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);
\r
408 /***************************************************************************//**
\r
409 * See tcpip.h for more information.
\r
411 unsigned char process_udp_packet (unsigned char *buf)
\r
414 udp_hdr_xp udp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
\r
416 if (udp_hdr->dp[1] != BOOTP_CLIENT_PORT) {
\r
417 send_dhcp_server_packet( buf );
\r
423 /* some more error checking here? */
\r
424 send_bootp_packet(buf);
\r
427 /***************************************************************************//**
\r
428 * See tcpip.h for more information.
\r
431 void send_tcp_packet (unsigned char control_bits,unsigned short int buflen)
\r
434 eth_hdr_xp eth_hdr = (eth_hdr_xp ) tcp_packet;
\r
435 ip_hdr_xp ip_hdr = (ip_hdr_xp ) (tcp_packet + sizeof(ether_hdr_t));
\r
436 tcp_hdr_xp tcp_hdr = (tcp_hdr_xp )
\r
437 (tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));
\r
438 tcp_pseudo_hdr_xp tcp_pseudo_hdr = (tcp_pseudo_hdr_xp )
\r
439 (((unsigned char *)tcp_hdr) - sizeof(tcp_pseudo_hdr_t));
\r
440 unsigned char *tcp_data = tcp_packet + sizeof(ether_hdr_t) + sizeof(ip_hdr_t) + sizeof (tcp_hdr_t);
\r
441 unsigned char *seqp = (unsigned char *)(&tcb.local_seq);
\r
442 unsigned short int plen;
\r
443 memset(tcp_hdr, 0, sizeof(tcp_hdr_t));
\r
444 memcpy(tcp_hdr->sp, tcb.local_port, TCP_PORT_LEN);
\r
445 memcpy(tcp_hdr->dp, tcb.remote_port, TCP_PORT_LEN);
\r
446 tcp_hdr->seqnum[0] = seqp[3];
\r
447 tcp_hdr->seqnum[1] = seqp[2];
\r
448 tcp_hdr->seqnum[2] = seqp[1];
\r
449 tcp_hdr->seqnum[3] = seqp[0];
\r
452 tcb.local_seq += buflen - 1;
\r
454 if (control_bits & TCP_CNTRL_ACK) {
\r
455 seqp = (unsigned char *)(&tcb.remote_seq);
\r
456 tcp_hdr->acknum[3] = seqp[0];
\r
457 tcp_hdr->acknum[2] = seqp[1];
\r
458 tcp_hdr->acknum[1] = seqp[2];
\r
459 tcp_hdr->acknum[0] = seqp[3];
\r
461 tcp_hdr->data_off = 0x50; /* always 5 32 bit words for us */
\r
462 tcp_hdr->urg_ack_psh_rst_syn_fin = control_bits;
\r
463 tcp_hdr->wsize[0] = 0x08; /* this is 0x0800, which is 2K */
\r
465 tcp_data[buflen] = 0;
\r
467 /* memset(tcp_pseudo_hdr, 0, sizeof(tcp_pseudo_hdr_t)); */
\r
468 memcpy(tcp_pseudo_hdr->sa, my_ip, IP_ADDR_LEN);
\r
469 memcpy(tcp_pseudo_hdr->da, tcb.remote_addr, IP_ADDR_LEN);
\r
470 tcp_pseudo_hdr->zero = 0;
\r
471 tcp_pseudo_hdr->proto = TCP_PROTO;
\r
472 plen = buflen + sizeof(tcp_hdr_t);
\r
473 tcp_pseudo_hdr->plen[0] = plen >> 8;
\r
474 tcp_pseudo_hdr->plen[1] = (unsigned char)plen;
\r
475 fix_checksum((unsigned char *)tcp_pseudo_hdr,
\r
476 (unsigned short int)(plen + sizeof(tcp_pseudo_hdr_t)), (unsigned short int)28);
\r
478 memset(ip_hdr, 0, sizeof(ip_hdr_t));
\r
480 ip_hdr->ver_hlen = 0x45; /* IPv4 with 20 byte header */
\r
481 plen += sizeof(ip_hdr_t); /* add the size of the IP Header */
\r
482 ip_hdr->tlen[0] = plen >> 8;
\r
483 ip_hdr->tlen[1] = (unsigned char) plen;
\r
484 ip_hdr->id[0] = ip_id >> 8;
\r
485 ip_hdr->id[1] = (unsigned char) ip_id;
\r
487 ip_hdr->ttl = 32; /* max 32 hops */
\r
488 ip_hdr->proto = TCP_PROTO;
\r
489 memcpy(ip_hdr->sa, my_ip, IP_ADDR_LEN);
\r
490 memcpy(ip_hdr->da, tcb.remote_addr, IP_ADDR_LEN);
\r
491 fix_checksum((unsigned char *)ip_hdr, sizeof(ip_hdr_t), 10);
\r
492 /* Fix the Ethernet Header */
\r
493 eth_hdr->type_code[0] = ETH_TYPE_0;
\r
494 eth_hdr->type_code[1] = ETH_TYPE_IP_1;
\r
495 memcpy(eth_hdr->sa, my_mac, ETH_ADDR_LEN);
\r
496 memcpy(eth_hdr->da, tcb.remote_mac, ETH_ADDR_LEN); /* should be table lookup */
\r
498 MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);
\r
500 /***************************************************************************//**
\r
501 * See tcpip.h for more information.
\r
503 unsigned char tcp_init(void)
\r
505 memset(&tcb,0,sizeof(tcp_control_block_t));
\r
506 tcb.state = TCP_STATE_LISTEN;
\r
512 /***************************************************************************//**
\r
513 * See tcpip.h for more information.
\r
515 unsigned char hex_digits_to_byte(unsigned char u, unsigned char l)
\r
525 return (u << 4) + l;
\r
527 /***************************************************************************//**
\r
528 * See tcpip.h for more information.
\r
530 unsigned char process_icmp_packet(unsigned char *buf)
\r
532 ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
\r
533 icmp_hdr_xp icmp_hdr = (icmp_hdr_xp )
\r
534 (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));
\r
535 unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);
\r
536 if (check_checksum((unsigned char *)icmp_hdr, (unsigned short int) elen, (unsigned short int) 2, 'M') != OK)
\r
538 if (icmp_hdr->type != ICMP_TYPE_ECHO_REQUEST) {
\r
541 return send_icmp_echo_reply(buf);
\r
544 /* See tcpip.h for more information.
\r
547 /***************************************************************************//**
\r
548 * See tcpip.h for more information.
\r
550 unsigned char process_tcp_packet(unsigned char *buf)
\r
552 eth_hdr_xp eth_hdr = (eth_hdr_xp )buf;
\r
553 ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
\r
554 tcp_hdr_xp tcp_hdr = (tcp_hdr_xp )
\r
555 (buf + sizeof (ether_hdr_t) + sizeof(ip_hdr_t));
\r
556 unsigned short int elen = ((unsigned short int)ip_hdr->tlen[0] << 8) + (unsigned short int)ip_hdr->tlen[1] - sizeof(ip_hdr_t);
\r
557 unsigned char state;
\r
558 if ( !memcmp(tcb.remote_addr, ip_hdr->sa, IP_ADDR_LEN) && /* same source IP */
\r
559 !memcmp(tcb.remote_port, tcp_hdr->sp, TCP_PORT_LEN) && /* same source port */
\r
560 !memcmp(tcb.local_port, tcp_hdr->dp, TCP_PORT_LEN)) { /* same dest port */
\r
562 } else { /* copy it over, a new IP wants in */
\r
563 memcpy(tcb.remote_addr, ip_hdr->sa, IP_ADDR_LEN);
\r
564 memcpy(tcb.remote_port, tcp_hdr->sp, TCP_PORT_LEN);
\r
565 memcpy(tcb.local_port, tcp_hdr->dp, TCP_PORT_LEN);
\r
566 memcpy(tcb.remote_mac, eth_hdr->sa, ETH_ADDR_LEN);
\r
567 state = TCP_STATE_LISTEN;
\r
570 case TCP_STATE_LISTEN:
\r
571 if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_SYN) {
\r
572 /* recd SYN : new connection; send SYN+ACK */
\r
574 tcb.local_seq = TCP_START_SEQ;
\r
575 tcb.remote_seq = 0;
\r
576 tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
\r
577 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
\r
578 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
\r
579 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
\r
581 send_tcp_packet( TCP_CNTRL_SYN | TCP_CNTRL_ACK, 0);
\r
582 tcb.state = TCP_STATE_SYN_RECVD;
\r
585 case TCP_STATE_SYN_RECVD:
\r
586 if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_ACK) {
\r
587 /* recd ack; send nothing */
\r
588 tcb.state = TCP_STATE_ESTABLISHED;
\r
591 tcb.state = TCP_STATE_LISTEN;
\r
594 case TCP_STATE_ESTABLISHED:
\r
595 if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_FIN) {
\r
596 /* recd fin; send ack */
\r
597 /* skip CLOSE_WAIT state; send fin along with ack */
\r
598 tcb.remote_seq = 0;
\r
599 tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
\r
600 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
\r
601 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
\r
602 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
\r
604 send_tcp_packet(TCP_CNTRL_ACK | TCP_CNTRL_FIN, 0);
\r
605 tcb.state = TCP_STATE_LAST_ACK;
\r
606 /* Default scroll message on OLED */
\r
608 else if (tcp_hdr->dp[0] != 0 || \
\r
609 tcp_hdr->dp[1] != 80) { /* HTTP Port */
\r
612 else if (elen > sizeof(tcp_hdr_t)) { /* dont respond to empty packets*/
\r
613 tcb.remote_seq = 0;
\r
614 tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
\r
615 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
\r
616 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
\r
617 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
\r
618 tcb.remote_seq += (unsigned long) (elen - sizeof(tcp_hdr_t));
\r
619 //send_http_response(((unsigned char *)(tcp_hdr)) + sizeof (tcp_hdr_t));
\r
620 tcb.state = TCP_STATE_MY_LAST;
\r
623 case TCP_STATE_MY_LAST:
\r
624 if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_FIN) {
\r
625 /* sent fin, got fin, ack the fin */
\r
626 tcb.remote_seq = 0;
\r
627 tcb.remote_seq = (tcb.remote_seq | tcp_hdr->seqnum[0]);
\r
628 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[1]);
\r
629 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[2]);
\r
630 tcb.remote_seq = ((tcb.remote_seq << 8) |tcp_hdr->seqnum[3]);
\r
632 send_tcp_packet(TCP_CNTRL_ACK, 0);
\r
633 tcb.state = TCP_STATE_CLOSED;
\r
636 case TCP_STATE_LAST_ACK:
\r
638 if (tcp_hdr->urg_ack_psh_rst_syn_fin & TCP_CNTRL_ACK) {
\r
639 /* recd ack; send nothing */
\r
640 tcb.state = TCP_STATE_CLOSED;
\r
642 /* no break here... go on to CLOSED directly */
\r
643 case TCP_STATE_CLOSED:
\r
644 memset (&tcb, 0, sizeof (tcp_control_block_t));
\r
651 /***************************************************************************//**
\r
652 * See tcpip.h for more information.
\r
654 unsigned char process_ip_packet(unsigned char *buf)
\r
656 ip_hdr_xp ip_hdr = (ip_hdr_xp ) (buf + sizeof (ether_hdr_t));
\r
657 /* Is the incoming pkt for me?
\r
658 (either explicity addressed to me or a broadcast address) */
\r
659 if (memcmp(my_ip, ip_hdr->da, IP_ADDR_LEN)) /* not my IP */ {
\r
663 if (ip_hdr->da[0] != 0xFF || ip_hdr->da[1] != 0xFF ||
\r
664 ip_hdr->da[2] != 0xFF || ip_hdr->da[3] != 0xFF) {
\r
668 if (check_checksum((unsigned char *)ip_hdr, (unsigned short int) 20, (unsigned short int) 10, 'I') != OK)
\r
670 switch (ip_hdr->proto)
\r
673 return process_tcp_packet(buf);
\r
675 return process_icmp_packet(buf);
\r
677 return process_udp_packet(buf);
\r
684 /***************************************************************************//**
\r
685 * See tcpip.h for more information.
\r
687 unsigned char process_arp_packet(unsigned char *buf)
\r
689 arp_pkt_xp arp_pkt = (arp_pkt_xp )(buf + sizeof(ether_hdr_t));
\r
690 if (arp_pkt->opcode[1] != ARP_OPCODE_REQ_1) {
\r
691 if (arp_pkt->opcode[1] == ARP_OPCODE_REPLY_1)
\r
693 if (!memcmp(my_ip, arp_pkt->ip_sa, IP_ADDR_LEN))
\r
695 //printf("IP conflict with MAC");
\r
696 //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
701 if (memcmp(my_ip, arp_pkt->ip_ta, IP_ADDR_LEN)) {
\r
704 return send_arp_reply(buf);
\r
706 /***************************************************************************//**
\r
707 * See tcpip.h for more information.
\r
709 unsigned char process_packet( unsigned char * buf )
\r
711 eth_hdr_xp eth_hdr;
\r
713 eth_hdr = (eth_hdr_xp ) buf;
\r
714 typ = eth_hdr->type_code[0];
\r
715 if (typ != ETH_TYPE_0)
\r
719 typ = eth_hdr->type_code[1];
\r
720 if (typ == ETH_TYPE_ARP_1)
\r
722 return process_arp_packet(buf);
\r
724 else if (typ == ETH_TYPE_IP_1) {
\r
725 return process_ip_packet(buf);
\r
733 /***************************************************************************//**
\r
734 * See tcpip.h for more information.
\r
736 unsigned char *xstrcpy(unsigned char *d, const unsigned char *s)
\r
740 while ((c = *s++))
\r
744 /***************************************************************************//**
\r
745 * See tcpip.h for more information.
\r
747 // updated html page with fusion board link on page:
\r