This source file includes following definitions.
- ip_print
- ip_ioctl
- strict_route
- loose_route
- print_ipprot
- ip_route_check
- build_options
- ip_send
- ip_build_header
- do_options
- ip_compute_csum
- ip_csum
- ip_send_check
- ip_forward
- ip_rcv
- ip_queue_xmit
- ip_retransmit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 #include <asm/segment.h>
19 #include <asm/system.h>
20 #include <linux/types.h>
21 #include <linux/kernel.h>
22 #include <linux/sched.h>
23 #include <linux/string.h>
24 #include <linux/errno.h>
25 #include <linux/socket.h>
26 #include <linux/sockios.h>
27 #include <linux/in.h>
28 #include "inet.h"
29 #include "timer.h"
30 #include "dev.h"
31 #include "eth.h"
32 #include "ip.h"
33 #include "protocol.h"
34 #include "route.h"
35 #include "tcp.h"
36 #include "skbuff.h"
37 #include "sock.h"
38 #include "arp.h"
39 #include "icmp.h"
40
41
42 void
43 ip_print(struct iphdr *ip)
44 {
45 unsigned char buff[32];
46 unsigned char *ptr;
47 int addr, len, i;
48
49 if (inet_debug != DBG_IP) return;
50
51
52 printk("IP: ihl=%d, version=%d, tos=%d, tot_len=%d\n",
53 ip->ihl, ip->version, ip->tos, ntohs(ip->tot_len));
54 printk(" id=%X, ttl=%d, prot=%d, check=%X\n",
55 ip->id, ip->ttl, ip->protocol, ip->check);
56 printk(" frag_off=%d\n", ip->frag_off);
57 printk(" soucre=%s ", in_ntoa(ip->saddr));
58 printk("dest=%s\n", in_ntoa(ip->daddr));
59 printk(" ----\n");
60
61
62 ptr = (unsigned char *)(ip + 1);
63 addr = 0;
64 len = ntohs(ip->tot_len) - (4 * ip->ihl);
65 while (len > 0) {
66 printk(" %04X: ", addr);
67 for(i = 0; i < 16; i++) {
68 if (len > 0) {
69 printk("%02X ", (*ptr & 0xFF));
70 buff[i] = *ptr++;
71 if (buff[i] < 32 || buff[i] > 126) buff[i] = '.';
72 } else {
73 printk(" ");
74 buff[i] = ' ';
75 }
76 addr++;
77 len--;
78 };
79 buff[i] = '\0';
80 printk(" \"%s\"\n", buff);
81 }
82 printk(" ----\n\n");
83 }
84
85
86 int
87 ip_ioctl(struct sock *sk, int cmd, unsigned long arg)
88 {
89 switch(cmd) {
90 case DDIOCSDBG:
91 return(dbg_ioctl((void *) arg, DBG_IP));
92 default:
93 return(-EINVAL);
94 }
95 }
96
97
98
99 static void
100 strict_route(struct iphdr *iph, struct options *opt)
101 {
102 }
103
104
105 static void
106 loose_route(struct iphdr *iph, struct options *opt)
107 {
108 }
109
110
111 static void
112 print_ipprot(struct inet_protocol *ipprot)
113 {
114 DPRINTF((DBG_IP, "handler = %X, protocol = %d, copy=%d \n",
115 ipprot->handler, ipprot->protocol, ipprot->copy));
116 }
117
118
119
120 void
121 ip_route_check(unsigned long daddr)
122 {
123 }
124
125
126 #if 0
127
128 static int
129 build_options(struct iphdr *iph, struct options *opt)
130 {
131 unsigned char *ptr;
132
133 ptr = (unsigned char *)(iph+1);
134 *ptr = 0;
135 return (4);
136 }
137 #endif
138
139
140
141 static int
142 ip_send(struct sk_buff *skb, unsigned long daddr, int len, struct device *dev,
143 unsigned long saddr)
144 {
145 unsigned char *ptr;
146 int mac;
147
148 ptr = (unsigned char *)(skb + 1);
149 mac = 0;
150 skb->arp = 1;
151 if (dev->hard_header) {
152 mac = dev->hard_header(ptr, dev, ETH_P_IP, daddr, saddr, len);
153 }
154 if (mac < 0) {
155 mac = -mac;
156 skb->arp = 0;
157 }
158 skb->dev = dev;
159 return(mac);
160 }
161
162
163
164
165
166
167
168
169 int
170 ip_build_header(struct sk_buff *skb, unsigned long saddr, unsigned long daddr,
171 struct device **dev, int type, struct options *opt, int len)
172 {
173 static struct options optmem;
174 struct iphdr *iph;
175 struct rtable *rt;
176 unsigned char *buff;
177 unsigned long raddr;
178 static int count = 0;
179 int tmp;
180
181 if (saddr == 0) saddr = my_addr();
182 DPRINTF((DBG_IP, "ip_build_header (skb=%X, saddr=%X, daddr=%X, *dev=%X,\n"
183 " type=%d, opt=%X, len = %d)\n",
184 skb, saddr, daddr, *dev, type, opt, len));
185 buff = (unsigned char *)(skb + 1);
186
187
188 if (*dev == NULL) {
189 rt = rt_route(daddr, &optmem);
190 if (rt == NULL) return(-ENETUNREACH);
191
192 *dev = rt->rt_dev;
193 if (daddr != 0x0100007F) saddr = rt->rt_dev->pa_addr;
194 raddr = rt->rt_gateway;
195
196 DPRINTF((DBG_IP, "ip_build_header: saddr set to %s\n", in_ntoa(saddr)));
197 opt = &optmem;
198 } else {
199
200 rt = rt_route(daddr, &optmem);
201 raddr = (rt == NULL) ? 0 : rt->rt_gateway;
202 }
203 if (raddr == 0) raddr = daddr;
204
205
206 tmp = ip_send(skb, raddr, len, *dev, saddr);
207 buff += tmp;
208 len -= tmp;
209
210 skb->dev = *dev;
211 skb->saddr = saddr;
212 if (skb->sk) skb->sk->saddr = saddr;
213
214
215 iph = (struct iphdr *)buff;
216 iph->version = 4;
217 iph->tos = 0;
218 iph->frag_off = 0;
219 iph->ttl = 32;
220 iph->daddr = daddr;
221 iph->saddr = saddr;
222 iph->protocol = type;
223 iph->ihl = 5;
224 iph->id = htons(count++);
225
226
227 #ifdef Not_Yet_Avail
228 build_options(iph, opt);
229 #endif
230
231 return(20 + tmp);
232 }
233
234
235 static int
236 do_options(struct iphdr *iph, struct options *opt)
237 {
238 unsigned char *buff;
239 int done = 0;
240 int i, len = sizeof(struct iphdr);
241
242
243 opt->record_route.route_size = 0;
244 opt->loose_route.route_size = 0;
245 opt->strict_route.route_size = 0;
246 opt->tstamp.ptr = 0;
247 opt->security = 0;
248 opt->compartment = 0;
249 opt->handling = 0;
250 opt->stream = 0;
251 opt->tcc = 0;
252 return(0);
253
254
255 buff = (unsigned char *)(iph + 1);
256
257
258 while (!done && len < iph->ihl*4) switch(*buff) {
259 case IPOPT_END:
260 done = 1;
261 break;
262 case IPOPT_NOOP:
263 buff++;
264 len++;
265 break;
266 case IPOPT_SEC:
267 buff++;
268 if (*buff != 11) return(1);
269 buff++;
270 opt->security = ntohs(*(unsigned short *)buff);
271 buff += 2;
272 opt->compartment = ntohs(*(unsigned short *)buff);
273 buff += 2;
274 opt->handling = ntohs(*(unsigned short *)buff);
275 buff += 2;
276 opt->tcc = ((*buff) << 16) + ntohs(*(unsigned short *)(buff+1));
277 buff += 3;
278 len += 11;
279 break;
280 case IPOPT_LSRR:
281 buff++;
282 if ((*buff - 3)% 4 != 0) return(1);
283 len += *buff;
284 opt->loose_route.route_size = (*buff -3)/4;
285 buff++;
286 if (*buff % 4 != 0) return(1);
287 opt->loose_route.pointer = *buff/4 - 1;
288 buff++;
289 buff++;
290 for (i = 0; i < opt->loose_route.route_size; i++) {
291 opt->loose_route.route[i] = *(unsigned long *)buff;
292 buff += 4;
293 }
294 break;
295 case IPOPT_SSRR:
296 buff++;
297 if ((*buff - 3)% 4 != 0) return(1);
298 len += *buff;
299 opt->strict_route.route_size = (*buff -3)/4;
300 buff++;
301 if (*buff % 4 != 0) return(1);
302 opt->strict_route.pointer = *buff/4 - 1;
303 buff++;
304 buff++;
305 for (i = 0; i < opt->strict_route.route_size; i++) {
306 opt->strict_route.route[i] = *(unsigned long *)buff;
307 buff += 4;
308 }
309 break;
310 case IPOPT_RR:
311 buff++;
312 if ((*buff - 3)% 4 != 0) return(1);
313 len += *buff;
314 opt->record_route.route_size = (*buff -3)/4;
315 buff++;
316 if (*buff % 4 != 0) return(1);
317 opt->record_route.pointer = *buff/4 - 1;
318 buff++;
319 buff++;
320 for (i = 0; i < opt->record_route.route_size; i++) {
321 opt->record_route.route[i] = *(unsigned long *)buff;
322 buff += 4;
323 }
324 break;
325 case IPOPT_SID:
326 len += 4;
327 buff +=2;
328 opt->stream = *(unsigned short *)buff;
329 buff += 2;
330 break;
331 case IPOPT_TIMESTAMP:
332 buff++;
333 len += *buff;
334 if (*buff % 4 != 0) return(1);
335 opt->tstamp.len = *buff / 4 - 1;
336 buff++;
337 if ((*buff - 1) % 4 != 0) return(1);
338 opt->tstamp.ptr = (*buff-1)/4;
339 buff++;
340 opt->tstamp.x.full_char = *buff;
341 buff++;
342 for (i = 0; i < opt->tstamp.len; i++) {
343 opt->tstamp.data[i] = *(unsigned long *)buff;
344 buff += 4;
345 }
346 break;
347 default:
348 return(1);
349 }
350
351 if (opt->record_route.route_size == 0) {
352 if (opt->strict_route.route_size != 0) {
353 memcpy(&(opt->record_route), &(opt->strict_route),
354 sizeof(opt->record_route));
355 } else if (opt->loose_route.route_size != 0) {
356 memcpy(&(opt->record_route), &(opt->loose_route),
357 sizeof(opt->record_route));
358 }
359 }
360
361 if (opt->strict_route.route_size != 0 &&
362 opt->strict_route.route_size != opt->strict_route.pointer) {
363 strict_route(iph, opt);
364 return(0);
365 }
366
367 if (opt->loose_route.route_size != 0 &&
368 opt->loose_route.route_size != opt->loose_route.pointer) {
369 loose_route(iph, opt);
370 return(0);
371 }
372
373 return(0);
374 }
375
376
377
378
379
380
381 unsigned short
382 ip_compute_csum(unsigned char * buff, int len)
383 {
384 unsigned long sum = 0;
385
386
387 if (len > 3) {
388 __asm__("\t clc\n"
389 "1:\n"
390 "\t lodsl\n"
391 "\t adcl %%eax, %%ebx\n"
392 "\t loop 1b\n"
393 "\t adcl $0, %%ebx\n"
394 "\t movl %%ebx, %%eax\n"
395 "\t shrl $16, %%eax\n"
396 "\t addw %%ax, %%bx\n"
397 "\t adcw $0, %%bx\n"
398 : "=b" (sum) , "=S" (buff)
399 : "0" (sum), "c" (len >> 2) ,"1" (buff)
400 : "ax", "cx", "si", "bx" );
401 }
402 if (len & 2) {
403 __asm__("\t lodsw\n"
404 "\t addw %%ax, %%bx\n"
405 "\t adcw $0, %%bx\n"
406 : "=b" (sum), "=S" (buff)
407 : "0" (sum), "1" (buff)
408 : "bx", "ax", "si");
409 }
410 if (len & 1) {
411 __asm__("\t lodsb\n"
412 "\t movb $0, %%ah\n"
413 "\t addw %%ax, %%bx\n"
414 "\t adcw $0, %%bx\n"
415 : "=b" (sum), "=S" (buff)
416 : "0" (sum), "1" (buff)
417 : "bx", "ax", "si");
418 }
419 sum =~sum;
420 return(sum & 0xffff);
421 }
422
423
424
425 static int
426 ip_csum(struct iphdr *iph)
427 {
428 if (iph->check == 0) return(0);
429 if (ip_compute_csum((unsigned char *)iph, iph->ihl*4) == 0) return(0);
430 return(1);
431 }
432
433
434
435 static void
436 ip_send_check(struct iphdr *iph)
437 {
438 iph->check = 0;
439 iph->check = ip_compute_csum((unsigned char *)iph, iph->ihl*4);
440 }
441
442
443
444 static void
445 ip_forward(struct sk_buff *skb, struct device *dev)
446 {
447 struct device *dev2;
448 struct iphdr *iph;
449 struct sk_buff *skb2;
450 struct rtable *rt;
451 unsigned char *ptr;
452 unsigned long raddr;
453
454
455
456
457
458
459 iph = skb->h.iph;
460 iph->ttl--;
461 if (iph->ttl <= 0) {
462 DPRINTF((DBG_IP, "\nIP: *** datagram expired: TTL=0 (ignored) ***\n"));
463 DPRINTF((DBG_IP, " SRC = %s ", in_ntoa(iph->saddr)));
464 DPRINTF((DBG_IP, " DST = %s (ignored)\n", in_ntoa(iph->daddr)));
465
466
467 icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, dev);
468 return;
469 }
470
471
472 ip_send_check(iph);
473
474
475
476
477
478 rt = rt_route(iph->daddr, NULL);
479 if (rt == NULL) {
480 DPRINTF((DBG_IP, "\nIP: *** routing (phase I) failed ***\n"));
481
482
483 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, dev);
484 return;
485 }
486
487
488
489
490
491
492
493
494 raddr = rt->rt_gateway;
495 if (raddr != 0) {
496 rt = rt_route(raddr, NULL);
497 if (rt == NULL) {
498 DPRINTF((DBG_IP, "\nIP: *** routing (phase II) failed ***\n"));
499
500
501 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, dev);
502 return;
503 }
504 if (rt->rt_gateway != 0) raddr = rt->rt_gateway;
505 } else raddr = iph->daddr;
506 dev2 = rt->rt_dev;
507
508
509
510
511
512 DPRINTF((DBG_IP, "\nIP: *** fwd %s -> ", in_ntoa(iph->saddr)));
513 DPRINTF((DBG_IP, "%s (via %s), LEN=%d\n",
514 in_ntoa(raddr), dev2->name, skb->len));
515
516 if (dev2->flags & IFF_UP) {
517 skb2 = kmalloc(sizeof(struct sk_buff) +
518 dev2->hard_header_len + skb->len, GFP_ATOMIC);
519 if (skb2 == NULL) {
520 printk("\nIP: No memory available for IP forward\n");
521 return;
522 }
523 ptr = (unsigned char *)(skb2 + 1);
524 skb2->lock = 0;
525 skb2->sk = NULL;
526 skb2->len = skb->len + dev2->hard_header_len;
527 skb2->mem_addr = skb2;
528 skb2->mem_len = sizeof(struct sk_buff) + skb2->len;
529 skb2->next = NULL;
530 skb2->h.raw = ptr;
531
532
533 skb2->h.raw = ptr;
534 memcpy(ptr + dev2->hard_header_len, skb->h.raw, skb->len);
535
536
537 (void) ip_send(skb2, raddr, skb->len, dev2, dev2->pa_addr);
538
539 dev2->queue_xmit(skb2, dev2, SOPRI_NORMAL);
540 }
541 }
542
543
544
545 int
546 ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
547 {
548 struct iphdr *iph;
549 unsigned char hash;
550 unsigned char flag = 0;
551 struct inet_protocol *ipprot;
552 static struct options opt;
553
554 int brd;
555
556 iph = skb->h.iph;
557 memset((char *) &opt, 0, sizeof(opt));
558 DPRINTF((DBG_IP, "<<\n"));
559 ip_print(iph);
560
561
562 if (ip_csum(iph) || do_options(iph, &opt) || iph->version != 4) {
563 DPRINTF((DBG_IP, "\nIP: *** datagram error ***\n"));
564 DPRINTF((DBG_IP, " SRC = %s ", in_ntoa(iph->saddr)));
565 DPRINTF((DBG_IP, " DST = %s (ignored)\n", in_ntoa(iph->daddr)));
566 skb->sk = NULL;
567 kfree_skb(skb, FREE_WRITE);
568 return(0);
569 }
570
571
572 if ((brd = chk_addr(iph->daddr)) == 0) {
573 ip_forward(skb, dev);
574 skb->sk = NULL;
575 kfree_skb(skb, FREE_WRITE);
576 return(0);
577 }
578
579
580
581
582
583
584
585
586
587
588
589
590 if ((iph->frag_off & 32) || (ntohs(iph->frag_off) & 0x1fff)) {
591 printk("\nIP: *** datagram fragmentation not yet implemented ***\n");
592 printk(" SRC = %s ", in_ntoa(iph->saddr));
593 printk(" DST = %s (ignored)\n", in_ntoa(iph->daddr));
594 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
595 skb->sk = NULL;
596 kfree_skb(skb, FREE_WRITE);
597 return(0);
598 }
599
600
601 skb->h.raw += iph->ihl*4;
602 hash = iph->protocol & (MAX_INET_PROTOS -1);
603 for (ipprot = (struct inet_protocol *)inet_protos[hash];
604 ipprot != NULL;
605 ipprot=(struct inet_protocol *)ipprot->next)
606 {
607 struct sk_buff *skb2;
608
609 if (ipprot->protocol != iph->protocol) continue;
610 DPRINTF((DBG_IP, "Using protocol = %X:\n", ipprot));
611 print_ipprot(ipprot);
612
613
614
615
616
617
618 if (ipprot->copy) {
619 skb2 = kmalloc (skb->mem_len, GFP_ATOMIC);
620 if (skb2 == NULL) continue;
621 memcpy(skb2, skb, skb->mem_len);
622 skb2->mem_addr = skb2;
623 skb2->lock = 0;
624 skb2->h.raw = (void *)(
625 (unsigned long)skb2 +
626 (unsigned long) skb->h.raw -
627 (unsigned long)skb);
628 } else {
629 skb2 = skb;
630 }
631 flag = 1;
632
633
634
635
636
637
638 ipprot->handler(skb2, dev, &opt, iph->daddr,
639 (ntohs(iph->tot_len) - (iph->ihl * 4)),
640 iph->saddr, 0, ipprot);
641
642 }
643
644
645
646
647
648
649
650 if (!flag) {
651 if (brd != IS_BROADCAST)
652 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
653 skb->sk = NULL;
654 kfree_skb(skb, FREE_WRITE);
655 }
656
657 return(0);
658 }
659
660
661
662
663
664
665
666
667
668 void
669 ip_queue_xmit(struct sock *sk, struct device *dev,
670 struct sk_buff *skb, int free)
671 {
672 struct iphdr *iph;
673 unsigned char *ptr;
674
675 if (sk == NULL) free = 1;
676 if (dev == NULL) {
677 printk("IP: ip_queue_xmit dev = NULL\n");
678 return;
679 }
680 skb->free = free;
681 skb->dev = dev;
682 skb->when = jiffies;
683
684 DPRINTF((DBG_IP, ">>\n"));
685 ptr = (unsigned char *)(skb + 1);
686 ptr += dev->hard_header_len;
687 iph = (struct iphdr *)ptr;
688 iph->tot_len = ntohs(skb->len - dev->hard_header_len);
689 ip_send_check(iph);
690 ip_print(iph);
691 skb->next = NULL;
692
693
694 skb->magic = 1;
695 if (!free) {
696 skb->link3 = NULL;
697 sk->packets_out++;
698 cli();
699 if (sk->send_head == NULL) {
700 sk->send_tail = skb;
701 sk->send_head = skb;
702 } else {
703
704 if (sk->send_tail == NULL) {
705 extern void sort_send(volatile struct sock *sk);
706
707 printk("IP: ***bug sk->send_tail == NULL != sk->send_head\n");
708 sort_send(sk);
709 } else {
710 sk->send_tail->link3 = skb;
711 sk->send_tail = skb;
712 }
713 }
714 sti();
715 sk->time_wait.len = sk->rtt<<1;
716 sk->timeout = TIME_WRITE;
717 reset_timer ((struct timer *)&sk->time_wait);
718 } else {
719 skb->sk = sk;
720 }
721
722
723 if (dev->flags & IFF_UP) {
724 if (sk != NULL) {
725 dev->queue_xmit(skb, dev, sk->priority);
726 } else {
727 dev->queue_xmit(skb, dev, SOPRI_NORMAL);
728 }
729 } else {
730 if (free) kfree_skb(skb, FREE_WRITE);
731 }
732 }
733
734
735 void
736 ip_retransmit(struct sock *sk, int all)
737 {
738 struct sk_buff * skb;
739 struct proto *prot;
740 struct device *dev;
741
742 prot = sk->prot;
743 skb = sk->send_head;
744 while (skb != NULL) {
745 dev = skb->dev;
746
747
748
749
750
751
752 if (!skb->arp) {
753 if (dev->rebuild_header((struct enet_header *)(skb+1),dev)) {
754 if (!all) break;
755 skb = (struct sk_buff *)skb->link3;
756 continue;
757 }
758 }
759 skb->arp = 1;
760 skb->when = jiffies;
761
762
763 if (dev->flags & IFF_UP) {
764 if (sk) dev->queue_xmit(skb, dev, sk->priority);
765 else dev->queue_xmit(skb, dev, SOPRI_NORMAL );
766 }
767
768 sk->retransmits++;
769 sk->prot->retransmits ++;
770 if (!all) break;
771
772
773 if (sk->retransmits > sk->cong_window) break;
774 skb = (struct sk_buff *)skb->link3;
775 }
776
777
778
779
780
781
782
783 sk->rtt *= 2;
784 sk->time_wait.len = sk->rtt;
785 sk->timeout = TIME_WRITE;
786 reset_timer((struct timer *)&sk->time_wait);
787 }