* reordered a little bit
[mascara-docs.git] / i86 / elks / elksnet / ktcp / ip.c
blobe16459013071cbf1621a191e0e53b9e7cb312f92
1 /*
2 * This file is part of the ELKS TCP/IP stack
4 * (C) 2001 Harry Kalogirou (harkal@rainbow.cs.unipi.gr)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
13 * TODO : IP fragmentation and reassemply of fragmented IP packets
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
20 #include "ip.h"
21 #include "icmp.h"
22 #include "tcp.h"
23 #include "mylib.h"
25 #if 0
26 #define IP_VERSION(s) ((s)->version_ihl>>4&0xf)
27 #define IP_IHL(s) ((s)->version_ihl&0xf)
28 #define IP_FLAGS(s) ((s)->frag_off>>13)
29 #endif
31 /*#define DEBUG*/
32 #define USE_ASM
34 static char ipbuf[1024];
36 int ip_init(void)
38 return 0;
41 #ifndef USE_ASM
42 __u16 ip_calc_chksum(char *data, int len)
44 __u32 sum = 0;
45 int i;
46 __u16 *p = (__u16 *) data;
48 len >>= 1;
50 for (i=0; i < len ; i++){
51 sum += *p++;
54 return ~((sum & 0xffff) + ((sum >> 16) & 0xffff));
56 #else
57 #asm
58 /*__u16 ip_calc_chksum(char *data, int len)*/
59 .text
60 .globl _ip_calc_chksum
61 _ip_calc_chksum:
63 push bp
64 mov bp,sp
65 push di
67 mov cx, 6[bp]
68 shr cx, 1
69 shr cx, 1
70 mov di, 4[bp]
71 xor ax, ax
72 loop1:
73 adc ax, [di]
74 inc di
75 inc di
76 adc ax, [di]
77 inc di
78 inc di
80 loop loop1
82 adc ax, 0
83 not ax
85 pop di
86 pop bp
88 ret
89 #endasm
92 #endif
94 void ip_print(struct iphdr_s *head)
96 #ifdef DEBUG
97 int i;
98 __u8 *addr;
100 printf("Version/IHL : %d/%d\n",IP_VERSION(head),IP_IHL(head));
101 printf("TypeOfService/Length : %d/%d\n",head->tos,ntohs(head->tot_len));
102 printf("Id/flags/fragment offset : %d/%d\n",head->id,head->frag_off);
103 printf("ttl : %d\n",head->ttl);
104 printf("Protocol : %d\n",head->protocol);
106 addr = (__u8 *)&head->saddr;
107 printf("saddr : %d.%d.%d.%d \n",addr[0],addr[1],addr[2],addr[3]);
108 addr = (__u8 *)&head->daddr;
109 printf("daddr : %d.%d.%d.%d \n",addr[0],addr[1],addr[2],addr[3]);
111 printf("check sum = %d\n",ip_calc_chksum(head, 4 * IP_IHL(head)));
113 addr = (__u8 *)head + 4 * IP_IHL(head);
114 for( i = 0 ; i < ntohs(head->tot_len) - 20 ; i++ )
115 printf("%x ",addr[i]);
117 printf("\n");
118 #endif
121 void ip_recvpacket(char *packet,int size)
123 struct iphdr_s *iphdr;
124 __u8 *addr, *data;
126 iphdr = (struct iphdr_s *)packet;
128 /*printf("IP: Got packet of size : %d \n",size,*packet);
129 ip_print(iphdr);*/
131 if(IP_VERSION(iphdr) != 4){
132 #ifdef DEBUG
133 printf("IP : Bad IP version\n");
134 #endif
135 return;
138 if(IP_IHL(iphdr) < 5){
139 #ifdef DEBUG
140 printf("IP : Bad IHL\n");
141 #endif
142 return;
145 data = packet + 4 * IP_IHL(iphdr);
147 switch (iphdr->protocol) {
148 case PROTO_ICMP:
149 #ifdef DEBUG
150 printf("IP : ICMP packet\n");
151 #endif
153 icmp_process(iphdr, data);
154 break;
156 case PROTO_TCP:
157 #ifdef DEBUG
158 printf("IP : TCP packet\n");
159 #endif
160 tcp_process(iphdr);
161 break;
163 default:
164 break;
169 void ip_sendpacket(char *packet,int len,struct addr_pair *apair)
171 struct iphdr_s *iph = (struct iphdr_s *)&ipbuf;
172 __u16 tlen;
174 iph->version_ihl = 0x45;
176 tlen = 4 * IP_IHL(iph);
178 iph->tos = 0;
179 iph->tot_len = htons(tlen + len);
180 iph->id = 0;
181 iph->frag_off = 0;
182 iph->ttl = 64;
183 iph->protocol = apair->protocol;
184 iph->daddr = apair->daddr;
185 iph->saddr = apair->saddr;
187 iph->check = 0;
188 iph->check = ip_calc_chksum((char *)iph, tlen);
190 memcpy(&ipbuf[tlen], packet, len);
192 /* "route" */
193 if(iph->daddr == local_ip && iph->daddr == 0x0100007f) {
194 /* 127.0.0.1 */
195 /* TODO */
196 } else
197 slip_send(&ipbuf, tlen + len);