]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_A2F200_SoftConsole/MicroSemi_Code/drivers/mac/tcpip.c
c2d03d8b2cb53a613dfc0b8c21afc5885ff60fca
[freertos] / Demo / CORTEX_A2F200_SoftConsole / MicroSemi_Code / drivers / mac / tcpip.c
1 /*******************************************************************************\r
2  * (c) Copyright 2009 Actel Corporation,All Rights Reserved.  \r
3  * \r
4  *  tcpip.c:TCP/IP implementation for webserver.\r
5  */\r
6 #include "../port_config/cpu_types.h"\r
7 #include "nettype.h"\r
8 #include "../mss_ethernet_mac/mss_ethernet_mac.h"\r
9 #include "../mss_ethernet_mac/mss_ethernet_mac_regs.h"\r
10 #include "tcpip.h"\r
11 #include <string.h>\r
12 #include <stdio.h>\r
13 #include <math.h>\r
14 #define OK  0\r
15 #define ERR 1\r
16 #define MAC_BASE_ADDRESS                        0x40003000\r
17 \r
18 \r
19 extern char ethAddr[6];\r
20 \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
38 \r
39 \r
40 /***************************************************************************//**\r
41  *  See tcpip.h for more information.\r
42  */\r
43 unsigned char send_arp_reply(unsigned char *buf)\r
44 {\r
45     /* Modify the packet in place */\r
46 \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
49 \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
57     num_pkt_tx++;\r
58     MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);\r
59     return OK;\r
60 }\r
61 /***************************************************************************//**\r
62  *  See tcpip.h for more information.\r
63  */\r
64 void send_gratuitous_arp(unsigned char *buf)\r
65 {\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
85     num_pkt_tx++;\r
86     MSS_MAC_tx_packet(buf,42, MSS_MAC_BLOCKING);\r
87 }\r
88 /***************************************************************************//**\r
89  *  See tcpip.h for more information.\r
90  * \r
91  */\r
92 unsigned short int get_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)\r
93 {\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
103         sum += delta; \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
107         } \r
108     } \r
109         if ( len & 1)  {\r
110         delta = (unsigned short int)((unsigned short int)buf[i] << 8); \r
111         sum += delta; \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
115         }                               \r
116         }\r
117     sum = ~sum; \r
118     return sum;\r
119   \r
120 } //end calc_checksum \r
121 /***************************************************************************//**\r
122  *  See tcpip.h for more information.\r
123  */\r
124 unsigned char fix_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos)\r
125 {\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
129     return OK;\r
130 }\r
131 \r
132 /***************************************************************************//**\r
133  *  See tcpip.h for more information.\r
134  */\r
135 unsigned char check_checksum(unsigned char *buf, unsigned short int len, unsigned short int pos, char type)\r
136 {\r
137     unsigned short int sum = get_checksum(buf,len,pos);\r
138     \r
139     if ((buf[pos] != (unsigned char)(sum >> 8)) || \r
140         (buf[pos+1] != (unsigned char) sum)) {\r
141 \r
142         type = 0;           /* get around compiler warning */\r
143         return ERR;\r
144     } else {\r
145         return OK;\r
146     }\r
147 }\r
148 /***************************************************************************//**\r
149  *  See tcpip.h for more information.\r
150  */\r
151 unsigned char send_icmp_echo_reply(unsigned char *buf)\r
152 {\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
162     ip_hdr->ttl--;\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
165     if (elen & 1) {\r
166         ((unsigned char *)icmp_hdr)[elen] = 0;\r
167     }\r
168     fix_checksum((unsigned char *)icmp_hdr, (unsigned short int) elen, (unsigned short int) 2);\r
169     num_pkt_tx++;\r
170     MSS_MAC_tx_packet(buf,elen + sizeof(ether_hdr_t) + sizeof(ip_hdr_t), MSS_MAC_BLOCKING);\r
171     return OK;\r
172 }\r
173 /***************************************************************************//**\r
174  *  See tcpip.h for more information.\r
175  */\r
176 void dtoa_reverse(unsigned short int n, unsigned char *buf)\r
177 {\r
178     buf--;\r
179     if (n == 0) {\r
180         *buf = '0';\r
181         return;\r
182     }\r
183     while (n > 0) {\r
184         *buf-- = (n % 10) + '0';\r
185         n = n / 10;\r
186     }\r
187 }\r
188 /***************************************************************************//**\r
189  *  See tcpip.h for more information.\r
190  */\r
191 void send_bootp_packet (unsigned char *buf)\r
192 {\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
199                                 /* input packet */\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
205     /* Set up Bootp */\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
213     if (buf) {\r
214         if (memcmp(my_mac, ibootp_pkt->chaddr, ETH_ADDR_LEN)) /* not for me ignore */\r
215             return;\r
216         memcpy(my_ip, ibootp_pkt->yiaddr, IP_ADDR_LEN);\r
217         ip_known = 1;\r
218         dhcp_ip_found = 1;\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
221     } else {\r
222         bootp_pkt->xid[0] = 0x90;\r
223     }\r
224     *opts++ = 99;               /* magic number */\r
225     *opts++ = 130;\r
226     *opts++ = 83;\r
227     *opts++ = 99;\r
228     *opts++ = BOOTP_OPTCODE_DHCP_TYPE;\r
229     *opts++ = 1;\r
230     if (buf) {\r
231         *opts++ = DHCP_TYPE_REQUEST;\r
232         *opts++ = BOOTP_OPTCODE_DHCP_SID;\r
233         *opts++ = 4;\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
238     } else {\r
239         *opts++ = DHCP_TYPE_DISCOVER;\r
240     }\r
241     *opts++ = BOOTP_OPTCODE_END;\r
242 \r
243     /* Set up Udp */\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
250     /* leave csum 0 */\r
251 \r
252     /* Set up IP */\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
260     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
270     num_pkt_tx++;\r
271     MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);\r
272 }\r
273 /***************************************************************************//**\r
274  *  See tcpip.h for more information.\r
275  */\r
276 void send_dhcp_server_packet (unsigned char *buf)\r
277 {\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
285 \r
286         /* input packet */\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
292 \r
293     unsigned short int plen;\r
294 \r
295     /* Set up Bootp */\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
303     if (buf) {\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
307     } else {\r
308         bootp_pkt->xid[0] = 0x90;\r
309     }\r
310     *opts++ = 99;               /* magic number */\r
311     *opts++ = 130;\r
312     *opts++ = 83;\r
313     *opts++ = 99;\r
314     *opts++ = BOOTP_OPTCODE_DHCP_TYPE;\r
315     *opts++ = 1;\r
316     if (iopts[6] == DHCP_TYPE_DISCOVER)\r
317     {\r
318         *opts++ = DHCP_TYPE_OFFER;\r
319     }\r
320     else\r
321     {\r
322         *opts++ = DHCP_TYPE_ACK;\r
323     }        \r
324     /* Server ID */\r
325     *opts++ = BOOTP_OPTCODE_DHCP_SID;\r
326     *opts++ = 4;\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
333     *opts++ = 4;\r
334     *opts++ = 0x00;\r
335     *opts++ = 0x00;\r
336     *opts++ = 0x0E;\r
337     *opts++ = 0x10;\r
338     /* Renewal time */\r
339     *opts++ = BOOTP_OPTCODE_DHCP_RENEW;\r
340     *opts++ = 4;\r
341     *opts++ = 0x00;\r
342     *opts++ = 0x00;\r
343     *opts++ = 0x07;\r
344     *opts++ = 0x08;\r
345     /* Rebinding time */\r
346     *opts++ = BOOTP_OPTCODE_DHCP_REBIND;\r
347     *opts++ = 4;\r
348     *opts++ = 0x00;\r
349     *opts++ = 0x00;\r
350     *opts++ = 0x0C;\r
351     *opts++ = 0x4E;\r
352     /* Subnet mask */\r
353     *opts++ = BOOTP_OPTCODE_DHCP_SUBNET;\r
354     *opts++ = 4;\r
355     *opts++ = 0xFF;\r
356     *opts++ = 0xFF;\r
357     *opts++ = 0xFF;\r
358     *opts++ = 0x00;\r
359     /* Router */\r
360     *opts++ = BOOTP_OPTCODE_DHCP_ROUTER;\r
361     *opts++ = 4;\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
366     /* Domain */\r
367     *opts++ = BOOTP_OPTCODE_DHCP_DOMAIN;\r
368     *opts++ = 4;\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
373     \r
374     *opts++ = BOOTP_OPTCODE_END;\r
375 \r
376     /* Set up Udp */\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
383     /* leave csum 0 */\r
384 \r
385     /* Set up IP */\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
393     ip_id++;\r
394     ip_hdr->ttl = 255;\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
399     \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
405     num_pkt_tx++;\r
406     MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);\r
407 }\r
408 /***************************************************************************//**\r
409  *  See tcpip.h for more information.\r
410  */\r
411 unsigned char process_udp_packet (unsigned char *buf)\r
412 {\r
413     \r
414     udp_hdr_xp udp_hdr = (udp_hdr_xp ) (buf + sizeof(ether_hdr_t) + sizeof(ip_hdr_t));\r
415     \r
416     if (udp_hdr->dp[1] != BOOTP_CLIENT_PORT) {\r
417         send_dhcp_server_packet( buf );\r
418         return OK;\r
419     }\r
420     if (ip_known) {\r
421         return ERR;\r
422     }\r
423                                 /* some more error checking here? */\r
424     send_bootp_packet(buf);\r
425     return OK;\r
426 }\r
427 /***************************************************************************//**\r
428  *  See tcpip.h for more information.\r
429  */\r
430 \r
431 void send_tcp_packet (unsigned char control_bits,unsigned short int buflen) \r
432 {\r
433    \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
450     tcb.local_seq++;\r
451     if (buflen) {\r
452         tcb.local_seq += buflen - 1;\r
453     }\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
460     }\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
464     if (buflen & 1) {\r
465         tcp_data[buflen] = 0;\r
466     }\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
477 \r
478     memset(ip_hdr, 0, sizeof(ip_hdr_t));\r
479 \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
486     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
497     num_pkt_tx++;    \r
498     MSS_MAC_tx_packet(tcp_packet,plen + sizeof(ether_hdr_t), MSS_MAC_BLOCKING);\r
499 }\r
500 /***************************************************************************//**\r
501  *  See tcpip.h for more information.\r
502  */\r
503 unsigned char tcp_init(void)\r
504 {\r
505     memset(&tcb,0,sizeof(tcp_control_block_t));\r
506     tcb.state = TCP_STATE_LISTEN;\r
507     ip_id = 0;\r
508     ip_known = 0;\r
509     return OK;\r
510 }\r
511 \r
512 /***************************************************************************//**\r
513  *  See tcpip.h for more information.\r
514  */\r
515 unsigned char hex_digits_to_byte(unsigned char u, unsigned char l) \r
516 {\r
517     if (u > '9')\r
518         u = u - 'A' + 10;\r
519     else\r
520         u = u - '0';\r
521     if (l > '9')\r
522         l = l - 'A' + 10;\r
523     else\r
524         l = l - '0';\r
525     return (u << 4) + l;\r
526 }\r
527 /***************************************************************************//**\r
528  *  See tcpip.h for more information.\r
529  */\r
530 unsigned char process_icmp_packet(unsigned char *buf)\r
531 {\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
537         return ERR;\r
538     if (icmp_hdr->type != ICMP_TYPE_ECHO_REQUEST) {\r
539         return ERR;\r
540     }\r
541     return send_icmp_echo_reply(buf);\r
542 }\r
543 \r
544  /*  See tcpip.h for more information.\r
545  */\r
546 \r
547 /***************************************************************************//**\r
548  *  See tcpip.h for more information.\r
549  */\r
550 unsigned char process_tcp_packet(unsigned char *buf)\r
551 {\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
561         state = tcb.state;\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
568     } \r
569     switch (state) {\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
573                       \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
580             tcb.remote_seq++;\r
581             send_tcp_packet( TCP_CNTRL_SYN | TCP_CNTRL_ACK, 0);\r
582             tcb.state = TCP_STATE_SYN_RECVD;\r
583         } \r
584         break;  \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
589         } \r
590     else {  \r
591     tcb.state = TCP_STATE_LISTEN;\r
592     }   \r
593         break;\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
603             tcb.remote_seq++;\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
607         }\r
608     else if (tcp_hdr->dp[0] != 0 || \\r
609                    tcp_hdr->dp[1] != 80) { /* HTTP Port */\r
610             break;\r
611         }\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
621         } \r
622         break;\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
631             tcb.remote_seq++;\r
632             send_tcp_packet(TCP_CNTRL_ACK, 0);\r
633             tcb.state = TCP_STATE_CLOSED;\r
634         }\r
635         break;\r
636     case TCP_STATE_LAST_ACK:\r
637    \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
641         }\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
645         break;   \r
646     default:\r
647         break;\r
648     }\r
649     return 0;\r
650 }\r
651 /***************************************************************************//**\r
652  *  See tcpip.h for more information.\r
653  */\r
654 unsigned char process_ip_packet(unsigned char *buf)\r
655 {\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
660         if (ip_known) {\r
661             return ERR;\r
662         }\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
665             return ERR;\r
666         }\r
667     }\r
668     if (check_checksum((unsigned char *)ip_hdr, (unsigned short int) 20, (unsigned short int) 10, 'I') != OK)\r
669         return ERR;\r
670     switch (ip_hdr->proto) \r
671     {\r
672     case TCP_PROTO:\r
673             return process_tcp_packet(buf);\r
674     case ICMP_PROTO:\r
675             return process_icmp_packet(buf);\r
676     case UDP_PROTO:\r
677             return process_udp_packet(buf);\r
678     default: {\r
679             return ERR;\r
680     }\r
681     }\r
682     return ERR;\r
683 }\r
684 /***************************************************************************//**\r
685  *  See tcpip.h for more information.\r
686  */\r
687 unsigned char process_arp_packet(unsigned char *buf)\r
688 {\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
692     {           \r
693          if (!memcmp(my_ip, arp_pkt->ip_sa, IP_ADDR_LEN))\r
694          {               \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
697          }              \r
698     }\r
699         return ERR;\r
700     }   \r
701     if (memcmp(my_ip, arp_pkt->ip_ta, IP_ADDR_LEN)) {\r
702         return ERR;\r
703     }   \r
704     return send_arp_reply(buf);\r
705 }\r
706 /***************************************************************************//**\r
707  *  See tcpip.h for more information.\r
708  */\r
709 unsigned char process_packet( unsigned char * buf )\r
710 {\r
711     eth_hdr_xp eth_hdr;\r
712     unsigned char typ;\r
713     eth_hdr = (eth_hdr_xp ) buf;\r
714     typ = eth_hdr->type_code[0];\r
715     if (typ != ETH_TYPE_0)\r
716     {\r
717                 return ERR;\r
718     }\r
719     typ = eth_hdr->type_code[1];\r
720     if (typ == ETH_TYPE_ARP_1) \r
721     {\r
722                 return process_arp_packet(buf);\r
723     }\r
724     else if (typ == ETH_TYPE_IP_1) {\r
725                 return process_ip_packet(buf);\r
726     }   \r
727     else\r
728     {\r
729                 return ERR;\r
730     }\r
731     return ERR;\r
732 }\r
733 /***************************************************************************//**\r
734  *  See tcpip.h for more information.\r
735  */\r
736 unsigned char *xstrcpy(unsigned char *d, const unsigned char *s)\r
737 {\r
738     unsigned char c;\r
739 \r
740     while ((c = *s++)) \r
741     (*d++ = c) ;\r
742     return d;\r
743 }\r
744 /***************************************************************************//**\r
745  *  See tcpip.h for more information.\r
746  */\r
747 // updated html page with fusion board link on page:\r
748 \r