|
|
1.1 root 1: /* ip.c */
2: /*
3: Copyright (C) 1992 Ross Biro
4:
5: This program is free software; you can redistribute it and/or modify
6: it under the terms of the GNU General Public License as published by
7: the Free Software Foundation; either version 2, or (at your option)
8: any later version.
9:
10: This program is distributed in the hope that it will be useful,
11: but WITHOUT ANY WARRANTY; without even the implied warranty of
12: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13: GNU General Public License for more details.
14:
15: You should have received a copy of the GNU General Public License
16: along with this program; if not, write to the Free Software
17: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18:
19: The Author may be reached as [email protected] or
20: C/O Department of Mathematics; Stanford University; Stanford, CA 94305
21: */
22:
23: #include <asm/segment.h>
24: #include <asm/system.h>
25: #include <linux/types.h>
26: #include <linux/kernel.h>
27: #include <linux/sched.h>
28: #include <linux/string.h>
29: #include <linux/socket.h>
30: #include <netinet/in.h>
31: #include "timer.h"
32: #include "ip.h"
33: #include "tcp.h"
34: #include "sock.h"
35: #include <linux/errno.h>
36: #include "arp.h"
37: #include "icmp.h"
38:
39: unsigned long ip_addr[MAX_IP_ADDRES]={0,0,0};
40:
41: #undef IP_DEBUG
42: #ifdef IP_DEBUG
43: #define PRINTK printk
44: #else
45: #define PRINTK dummy_routine
46: #endif
47:
48: static struct rtable *rt_base=NULL; /* used to base all the routing data. */
49:
50: struct ip_protocol *ip_protos[MAX_IP_PROTOS] = { NULL, };
51:
52: #if 0
53: static struct ip_protocol *
54: get_protocol(unsigned char prot)
55: {
56: unsigned char hash;
57: struct ip_protocol *p;
58: PRINTK ("get_protocol (%d)\n ", prot);
59: hash = prot & (MAX_IP_PROTOS -1);
60: for (p = ip_protos[hash] ; p != NULL; p=p->next)
61: {
62: PRINTK ("trying protocol %d\n", p->protocol);
63: if (p->protocol == prot)
64: return (p);
65: }
66: return (NULL);
67:
68: }
69: #endif
70:
71: void
72: add_ip_protocol (struct ip_protocol *prot)
73: {
74: unsigned char hash;
75: struct ip_protocol *p2;
76: hash = prot->protocol & (MAX_IP_PROTOS-1);
77: prot ->next = ip_protos[hash];
78: ip_protos[hash] = prot;
79: prot->copy = 0;
80: /* set the copy bit if we need to. */
81: for (p2 = prot->next; p2 != NULL; p2=p2->next)
82: {
83: if (p2->protocol == prot->protocol)
84: {
85: prot->copy = 1;
86: break;
87: }
88: }
89:
90: }
91:
92: int
93: delete_ip_protocol (struct ip_protocol *prot)
94: {
95: struct ip_protocol *p;
96: struct ip_protocol *lp=NULL;
97: unsigned char hash;
98:
99:
100: hash = prot->protocol & (MAX_IP_PROTOS -1);
101: if (prot == ip_protos[hash])
102: {
103: ip_protos[hash]=ip_protos[hash]->next;
104: return (0);
105: }
106:
107: for (p = ip_protos[hash]; p != NULL; p = p->next)
108: {
109: /* we have to worry if the protocol being deleted is the
110: last one on the list, then we may need to reset someones
111: copied bit. */
112: if (p->next != NULL && p->next == prot)
113: {
114: /* if we are the last one with this protocol and
115: there is a previous one, reset its copy bit. */
116:
117: if (p->copy == 0 && lp != NULL)
118: lp->copy = 0;
119: p->next = prot->next;
120: return (0);
121: }
122:
123: if (p->next != NULL && p->next->protocol == prot->protocol)
124: {
125: lp = p;
126: }
127: }
128: return (-1);
129: }
130:
131: /* addr1 is the address which may or may not be broadcast etc.
132: addr2 is the "real addr." */
133:
134: int
135: ip_addr_match (unsigned long addr1, unsigned long addr2)
136: {
137: int i;
138: if (addr1 == addr2) return (1);
139: for (i = 0; i < 4; i++, addr1 >>= 8, addr2 >>= 8)
140: {
141: if ((addr1 & 0xff) != (addr2 & 0xff))
142: {
143: /* the only way this could be a match is for the rest of
144: addr1 to be 0. */
145: if (addr1 != 0)
146: {
147: return (0);
148: }
149: return (1);
150: }
151: }
152: return (1);
153: }
154:
155: int
156: my_ip_addr(unsigned long addr)
157: {
158: int i;
159: for (i = 0; i < MAX_IP_ADDRES; i++)
160: {
161: if (ip_addr[i] == 0) return (0);
162: if (ip_addr_match (addr, ip_addr[i])) return (1);
163: }
164: return (0);
165: }
166:
167: /* these two routines will do routining. */
168: static void
169: strict_route(struct ip_header *iph, struct options *opt)
170: {
171: }
172:
173: static void
174: loose_route(struct ip_header *iph, struct options *opt)
175: {
176: }
177:
178: void
179: print_rt(struct rtable *rt)
180: {
181: PRINTK ("net = %08X router = %08X\n",rt->net, rt->router);
182: PRINTK ("dev = %X, next = %X\n",rt->dev, rt->next);
183: }
184:
185: void
186: print_ipprot (struct ip_protocol *ipprot)
187: {
188: PRINTK ("handler = %X, protocol = %d\n",
189: ipprot->handler, ipprot->protocol);
190: }
191:
192: /* This assumes that address are all in net order. */
193: static struct device *
194: ip_route(struct options *opt, unsigned long daddr , unsigned long *raddr)
195: {
196: struct rtable *rt;
197: /* look through the routing table for some
198: kind of match. */
199: for (rt=rt_base; rt != NULL; rt=rt->next)
200: {
201: /* see if we found one. */
202: if (ip_addr_match (rt->net, daddr))
203: {
204: *raddr = rt->router;
205: return (rt->dev);
206: }
207: }
208: return (NULL);
209: };
210:
211: void
212: add_route (struct rtable *rt)
213: {
214: int mask;
215: struct rtable *r;
216: struct rtable *r1;
217: PRINTK ("add_route (rt=%X):\n",rt);
218: print_rt(rt);
219:
220: if (rt_base == NULL)
221: {
222: rt->next = NULL;
223: rt_base = rt;
224: return;
225: }
226:
227: /* what we have to do is loop though this until we have found the
228: first address which has the same generality as the one in rt. Then
229: we can put rt in after it. */
230: for (mask = 0xff000000; mask != 0xffffffff; mask = (mask >> 8) | mask)
231: {
232: if (mask & rt->net)
233: {
234: mask = mask << 8;
235: break;
236: }
237: }
238: PRINTK ("mask = %X\n",mask);
239: r1=rt_base;
240: for (r=rt_base; r != NULL; r=r->next)
241: {
242: /* see if we are getting a duplicate. */
243: if (r->net == rt->net)
244: {
245: if (r == rt_base)
246: {
247: rt->next = r->next;
248: rt_base = rt;
249: }
250: else
251: {
252: rt->next = r->next;
253: r1->next = rt;
254: }
255: free_s (r, sizeof (*r));
256: return;
257: }
258:
259: if (!(r->net & mask))
260: {
261: PRINTK("adding before r=%X\n",r);
262: print_rt(r);
263: if (r == rt_base)
264: {
265: rt->next = rt_base;
266: rt_base = rt;
267: return;
268: }
269: rt->next = r;
270: r1->next = rt;
271: return;
272: }
273: r1 = r;
274: }
275: PRINTK ("adding after r1=%X\n",r1);
276: print_rt(r1);
277: /* goes at the end. */
278: rt->next = NULL;
279: r1->next = rt;
280: }
281:
282: int
283: ip_set_dev (struct ip_config *u_ipc)
284: {
285: struct rtable *rt;
286: struct device *dev;
287: struct ip_config ipc;
288: static int ip_ads = 0;
289:
290: if (ip_ads >= MAX_IP_ADDRES) return (-EINVAL);
291:
292: verify_area (u_ipc, sizeof (ipc));
293: memcpy_fromfs(&ipc, u_ipc, sizeof (ipc));
294: ipc.name[MAX_IP_NAME-1] = 0;
295: dev = get_dev (ipc.name);
296:
297: if (dev == NULL) return (-EINVAL);
298:
299: /* see if we need to add a broadcast address. */
300: if (ipc.net != -1)
301: {
302: arp_add_broad (ipc.net, dev);
303: rt = malloc (sizeof (*rt));
304: if (rt == NULL) return (-ENOMEM);
305:
306: rt->net = ipc.net;
307: rt->dev = dev;
308: rt->router = 0;
309: add_route (rt);
310: /* dev->net = ipc.net;*/
311: }
312:
313: if (ipc.router != -1)
314: {
315: rt = malloc (sizeof (*rt));
316: if (rt == NULL) return (-ENOMEM);
317: rt->net = 0;
318: rt->dev = dev;
319: rt->router = ipc.router;
320: add_route (rt);
321: }
322:
323: if (dev->loopback)
324: {
325: rt = malloc (sizeof (*rt));
326: if (rt == NULL) return (-ENOMEM);
327: rt->net = ipc.paddr;
328: rt->dev = dev;
329: rt->router = 0;
330: add_route (rt);
331:
332: }
333:
334:
335: if (!my_ip_addr (ipc.paddr))
336: ip_addr[ip_ads++] = ipc.paddr;
337:
338: dev->up = ipc.up;
339: if (dev->up)
340: {
341: if (dev->open)
342: dev->open(dev);
343: }
344: else
345: {
346: if (dev->stop)
347: dev->stop(dev);
348: }
349: return (0);
350:
351: }
352:
353: /* this routine will check to see if we have lost a gateway. */
354: void
355: ip_route_check (unsigned long daddr)
356: {
357: }
358:
359: /* this routine puts the options at the end of an ip header. */
360: static int
361: build_options (struct ip_header *iph, struct options *opt)
362: {
363: unsigned char *ptr;
364: /* currently we don't support any options. */
365: ptr = (unsigned char *)(iph+1);
366: *ptr = 0;
367: return (4);
368: }
369:
370: /* This routine builds the appropriate hardware/ip headers for
371: the routine. It assumes that if *prot != NULL then the
372: protocol knows what it's doing, otherwise it uses the
373: routing/arp tables to select a protocol struct. */
374:
375: int
376: ip_build_header (struct sk_buff *skb, unsigned long saddr,
377: unsigned long daddr, struct device **dev, int type,
378: struct options *opt, int len)
379: {
380: static struct options optmem;
381: struct ip_header *iph;
382: unsigned char *buff;
383: static int count = 0;
384: unsigned long raddr; /* for the router. */
385: int tmp;
386: if (saddr == 0) saddr = MY_IP_ADDR;
387: PRINTK ("ip_build_header (skb=%X, saddr=%X, daddr=%X, *dev=%X,\n"
388: " type=%d, opt=%X, len = %d)\n",
389: skb, saddr, daddr, *dev, type, opt, len);
390: buff = (unsigned char *)(skb + 1);
391: /* see if we need to look up the device. */
392: if (*dev == NULL)
393: {
394: *dev = ip_route(&optmem,daddr, &raddr);
395: if (*dev == NULL)
396: {
397: return (-ENETUNREACH);
398: }
399: opt = &optmem;
400: }
401: else
402: {
403: /* we still need the address of the first hop. */
404: ip_route (&optmem, daddr, &raddr);
405: }
406: if (raddr == 0) raddr = daddr;
407: /* now build the header. */
408: /* we need to worry about routing in here. daddr should
409: really be the address of the next hop. */
410: /* but raddr is . */
411: if ((*dev)->hard_header)
412: {
413: tmp = (*dev)->hard_header(buff, *dev, ETHERTYPE_IP, raddr, saddr, len);
414: }
415: else
416: {
417: tmp = 0;
418: }
419: if (tmp < 0)
420: {
421: tmp = -tmp;
422: skb->arp = 0;
423: }
424: else
425: {
426: skb->arp = 1;
427: }
428: buff += tmp;
429: len -= tmp;
430: skb->dev = *dev;
431: /* now build the ip header. */
432: iph = (struct ip_header *)buff;
433: iph->version = 4;
434: iph->tos = 0;
435: iph->frag_off = 0;
436: iph->ttl = 32;
437: iph->daddr = daddr;
438: iph->saddr = saddr;
439: iph->protocol=type;
440: iph->ihl = 5;
441: iph->id = net16(count++);
442: /* build_options (iph, opt);*/
443: return (20+tmp);
444: }
445:
446: static int
447: do_options(struct ip_header *iph, struct options *opt)
448: {
449: unsigned char *buff;
450: int done = 0;
451: int len=sizeof (*iph);
452: int i;
453: /* zero out the options. */
454: opt->record_route.route_size = 0;
455: opt->loose_route.route_size = 0;
456: opt->strict_route.route_size = 0;
457: opt->tstamp.ptr = 0;
458: opt->security = 0;
459: opt->compartment = 0;
460: opt->handling = 0;
461: opt->stream = 0;
462: opt->tcc = 0;
463: return (0);
464: /* advance the pointer to start at the options. */
465: buff = (unsigned char *)(iph + 1);
466:
467: /*now start the processing. */
468: while (!done && len < iph->ihl*4)
469: {
470: switch (*buff)
471: {
472: case IPOPT_END:
473: done=1;
474: break;
475:
476: case IPOPT_NOOP:
477: buff++;
478: len ++;
479: break;
480:
481: case IPOPT_SEC:
482: buff++;
483: if (*buff != 11)
484: return (1);
485: buff++;
486: opt->security = net16(*(unsigned short *)buff);
487: buff += 2;
488: opt->compartment = net16(*(unsigned short *)buff);
489: buff += 2;
490: opt-> handling = net16(*(unsigned short *)buff);
491: buff += 2;
492: opt->tcc = ((*buff) << 16) + net16(*(unsigned short *)(buff+1));
493: buff += 3;
494: len += 11;
495: break;
496:
497: case IPOPT_LSRR:
498: buff ++;
499: if ((*buff - 3)% 4 != 0) return (1);
500: len += *buff;
501: opt->loose_route.route_size = (*buff -3)/4;
502: buff ++;
503: if (*buff % 4 != 0) return (1);
504: opt->loose_route.pointer = *buff/4 - 1;
505: buff ++;
506: buff ++;
507: for (i = 0; i < opt->loose_route.route_size; i++)
508: {
509: opt->loose_route.route[i]=*(unsigned long *)buff;
510: buff += 4;
511: }
512: break;
513:
514:
515: case IPOPT_SSRR:
516: buff ++;
517: if ((*buff - 3)% 4 != 0) return (1);
518: len += *buff;
519: opt->strict_route.route_size = (*buff -3)/4;
520: buff ++;
521: if (*buff % 4 != 0) return (1);
522: opt->strict_route.pointer = *buff/4 - 1;
523: buff ++;
524: buff ++;
525: for (i = 0; i < opt->strict_route.route_size; i++)
526: {
527: opt->strict_route.route[i]=*(unsigned long *)buff;
528: buff += 4;
529: }
530: break;
531:
532: case IPOPT_RR:
533: buff ++;
534: if ((*buff - 3)% 4 != 0) return (1);
535: len += *buff;
536: opt->record_route.route_size = (*buff -3)/4;
537: buff ++;
538: if (*buff % 4 != 0) return (1);
539: opt->record_route.pointer = *buff/4 - 1;
540: buff ++;
541: buff ++;
542: for (i = 0; i < opt->record_route.route_size; i++)
543: {
544: opt->record_route.route[i]=*(unsigned long *)buff;
545: buff += 4;
546: }
547: break;
548:
549: case IPOPT_SID:
550: len += 4;
551: buff +=2;
552: opt->stream = *(unsigned short *)buff;
553: buff += 2;
554: break;
555:
556: case IPOPT_TIMESTAMP:
557: buff ++;
558: len += *buff;
559: if (*buff % 4 != 0) return (1);
560: opt->tstamp.len = *buff / 4 - 1;
561: buff ++;
562: if ((*buff - 1) % 4 != 0) return (1);
563: opt->tstamp.ptr = (*buff-1)/4;
564: buff ++;
565: opt->tstamp.x.full_char = *buff;
566: buff ++;
567: for (i = 0; i < opt->tstamp.len; i++)
568: {
569: opt->tstamp.data[i] = *(unsigned long *)buff;
570: buff += 4;
571: }
572: break;
573:
574: default:
575: return (1);
576: }
577: }
578: if (opt->record_route.route_size == 0)
579: {
580: if (opt->strict_route.route_size != 0)
581: {
582: memcpy (&(opt->record_route), &(opt->strict_route),
583: sizeof (opt->record_route));
584: }
585: else if (opt->loose_route.route_size != 0)
586: {
587: memcpy (&(opt->record_route), &(opt->loose_route),
588: sizeof (opt->record_route));
589: }
590: }
591:
592: if (opt->strict_route.route_size != 0 &&
593: opt->strict_route.route_size != opt->strict_route.pointer)
594: {
595: strict_route (iph, opt);
596: return (0);
597: }
598:
599: if (opt->loose_route.route_size != 0 &&
600: opt->loose_route.route_size != opt->loose_route.pointer)
601: {
602: loose_route (iph, opt);
603: return (0);
604: }
605:
606: return (0);
607: }
608:
609:
610: /* This routine does all the checksum computations that don't require
611: anything special (like copying or special headers.) */
612:
613: unsigned short
614: ip_compute_csum(unsigned char * buff, int len)
615: {
616: unsigned long sum = 0;
617: if (len > 3)
618: {
619: /* do the first multiple of 4 bytes and convert to 16 bits. */
620: __asm__("\t clc\n"
621: "1:\n"
622: "\t lodsl\n"
623: "\t adcl %%eax, %%ebx\n"
624: "\t loop 1b\n"
625: "\t adcl $0, %%ebx\n"
626: "\t movl %%ebx, %%eax\n"
627: "\t shrl $16, %%eax\n"
628: "\t addw %%ax, %%bx\n"
629: "\t adcw $0, %%bx\n"
630: : "=b" (sum) , "=S" (buff)
631: : "0" (sum), "c" (len >> 2) ,"1" (buff)
632: : "ax", "cx", "si", "bx" );
633: }
634: if (len & 2)
635: {
636: __asm__("\t lodsw\n"
637: "\t addw %%ax, %%bx\n"
638: "\t adcw $0, %%bx\n"
639: : "=b" (sum), "=S" (buff)
640: : "0" (sum), "1" (buff)
641: : "bx", "ax", "si");
642: }
643: if (len & 1)
644: {
645: __asm__("\t lodsb\n"
646: "\t movb $0, %%ah\n"
647: "\t addw %%ax, %%bx\n"
648: "\t adcw $0, %%bx\n"
649: : "=b" (sum), "=S" (buff)
650: : "0" (sum), "1" (buff)
651: : "bx", "ax", "si");
652: }
653: sum =~sum;
654: return (sum&0xffff);
655: }
656:
657: static int
658: ip_csum(struct ip_header *iph)
659: {
660: if (iph->check == 0) return (0);
661: if (ip_compute_csum((unsigned char *)iph, iph->ihl*4) == 0) return (0);
662: return (1);
663: }
664:
665: static void
666: ip_send_check(struct ip_header *iph)
667: {
668: iph->check = 0;
669: iph->check = ip_compute_csum((unsigned char *)iph, iph->ihl*4);
670: }
671:
672: int
673: ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
674: {
675: struct ip_header *iph;
676: unsigned char hash;
677: unsigned char flag=0;
678: static struct options opt; /* since we don't use these yet, and they
679: take up stack space. */
680: struct ip_protocol *ipprot;
681:
682: iph=skb->h.iph;
683:
684: PRINTK("<<\n");
685: print_iph(iph);
686:
687: if (ip_csum (iph) || do_options (iph,&opt) || iph->version != 4)
688: {
689: PRINTK ("ip packet thrown out. \n");
690: skb->sk = NULL;
691: free_skb(skb, 0);
692: return (0);
693: }
694:
695: /* for now we will only deal with packets meant for us. */
696: if (!my_ip_addr(iph->daddr))
697: {
698: PRINTK ("packet meant for someone else.\n");
699: skb->sk = NULL;
700: free_skb(skb, 0);
701: return (0);
702: }
703:
704: /* deal with fragments. or don't for now.*/
705: if ((iph->frag_off & 64) || (net16(iph->frag_off)&0x1fff))
706: {
707: printk ("packet fragmented. \n");
708: skb->sk = NULL;
709: free_skb(skb, 0);
710: return(0);
711: }
712:
713: skb->h.raw += iph->ihl*4;
714:
715: /* add it to the arp table if it's talking to us. That way we
716: will be able to talk to them also. */
717:
718: hash = iph->protocol & (MAX_IP_PROTOS -1);
719: for (ipprot = ip_protos[hash]; ipprot != NULL; ipprot=ipprot->next)
720: {
721: struct sk_buff *skb2;
722: PRINTK ("Using protocol = %X:\n", ipprot);
723: print_ipprot (ipprot);
724: /* pass it off to everyone who wants it. */
725: /* we should check the return values here. */
726: /* see if we need to make a copy of it. This will
727: only be set if more than one protpocol wants it.
728: and then not for the last one. */
729:
730: if (ipprot->copy)
731: {
732: skb2 = malloc (skb->mem_len);
733: if (skb2 == NULL) continue;
734: memcpy (skb2, skb, skb->mem_len);
735: skb2->mem_addr = skb2;
736: }
737: else
738: {
739: skb2 = skb;
740: }
741: flag = 1;
742: ipprot->handler (skb2, dev, &opt, iph->daddr,
743: net16(iph->tot_len) - iph->ihl*4,
744: iph->saddr, 0, ipprot);
745:
746: }
747: if (!flag)
748: {
749: icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
750: skb->sk = NULL;
751: free_skb (skb, 0);
752: }
753:
754:
755: return (0);
756: }
757:
758:
759: /* queues a packet to be sent, and starts the transmitter if
760: necessary. if free = 1 then we free the block after transmit,
761: otherwise we don't. */
762: /* This routine also needs to put in the total length, and compute
763: the checksum. */
764: void
765: ip_queue_xmit (volatile struct sock *sk, struct device *dev,
766: struct sk_buff *skb, int free)
767: {
768: struct ip_header *iph;
769: unsigned char *ptr;
770: if (sk == NULL) free = 1;
771: skb->free = free;
772: skb->dev = dev;
773: skb->when = jiffies;
774: PRINTK(">>\n");
775: ptr = (unsigned char *)(skb + 1);
776: ptr += dev->hard_header_len;
777: iph = (struct ip_header *)ptr;
778: iph->tot_len = net16(skb->len-dev->hard_header_len);
779: ip_send_check (iph);
780: print_iph(iph);
781: skb->next = NULL;
782: if (!free)
783: {
784: skb->link3 = NULL;
785: sk->packets_out++;
786: cli();
787: if (sk->send_tail == NULL)
788: {
789: sk->send_tail = skb;
790: sk->send_head = skb;
791: }
792: else
793: {
794: sk->send_tail->link3 = skb;
795: sk->send_tail = skb;
796: }
797: sti();
798: sk->time_wait.len = sk->rtt*2;
799: sk->timeout=TIME_WRITE;
800: reset_timer ((struct timer *)&sk->time_wait);
801: }
802: else
803: {
804: skb->sk = sk;
805: }
806: if (dev->up)
807: {
808: if (sk)
809: dev->queue_xmit(skb, dev, sk->priority);
810: else
811: dev->queue_xmit (skb, dev, SOPRI_NORMAL);
812: }
813: else
814: {
815: if (free)
816: free_skb (skb, FREE_WRITE);
817: }
818: }
819:
820: void
821: ip_retransmit (volatile struct sock *sk, int all)
822: {
823: struct sk_buff * skb;
824: struct proto *prot;
825: struct device *dev;
826:
827: prot = sk->prot;
828: skb = sk->send_head;
829: while (skb != NULL)
830: {
831: dev = skb->dev;
832: /* rebuild_header sees if the arp is done. If not it sends a new
833: arp, and if so it builds the header. */
834: if (!skb->arp)
835: {
836: if (dev->rebuild_header ((struct enet_header *)(skb+1),dev))
837: {
838: if (!all) break;
839: skb=skb->link3;
840: continue;
841: }
842: }
843: skb->arp = 1;
844: skb->when = jiffies;
845:
846: if (dev->up)
847: if (sk)
848: dev->queue_xmit(skb, dev, sk->priority);
849: else
850: dev->queue_xmit(skb, dev, SOPRI_NORMAL );
851:
852: sk->retransmits++;
853: sk->prot->retransmits ++;
854: if (!all) break;
855: /* this should cut it off before we send too
856: many packets. */
857: if (sk->retransmits > sk->cong_window) break;
858: skb=skb->link3;
859: }
860: sk->time_wait.len = sk->rtt*2;
861: sk->timeout = TIME_WRITE;
862: reset_timer ((struct timer *)&sk->time_wait);
863: }
864:
865: void
866: print_iph (struct ip_header *ip)
867: {
868: PRINTK ("ip header:\n");
869: PRINTK (" ihl = %d, version = %d, tos = %d, tot_len = %d\n",
870: ip->ihl, ip->version, ip->tos, net16(ip->tot_len));
871: PRINTK (" id = %x, ttl = %d, prot = %d, check=%x\n",
872: ip->id, ip->ttl, ip->protocol, ip->check);
873: PRINTK (" frag_off=%d\n", ip->frag_off);
874: PRINTK (" saddr = %X, daddr = %X\n",ip->saddr, ip->daddr);
875: }
876:
877: #if 0
878: int
879: ip_handoff (volatile struct sock *sk)
880: {
881: struct ip_protocol *p;
882: struct sk_buff *skb;
883: p = get_protocol (sk->protocol);
884:
885: if (p == NULL)
886: {
887: /* this can never happen. */
888: printk ("sock_ioctl: protocol not found. \n");
889: /* what else can I do, I suppose I could send a sigkill. */
890: return (-EIO);
891: }
892:
893: while (p->handler != sk->prot->rcv)
894: {
895: p=p->next;
896: if (p == NULL)
897: {
898: /* this can never happen. */
899: printk ("sock_ioctl: protocol not found. \n");
900: /* what else can I do, I suppose I could send a sigkill. */
901: return (-EIO);
902: }
903: }
904: p = p-> next;
905: sk->inuse = 1;
906:
907: /* now we have to remove the top sock buff. If there are none, then
908: we return. */
909: if (sk->rqueue == NULL) return (0);
910: skb = sk->rqueue;
911: if (skb->next == skb)
912: {
913: sk->rqueue = NULL;
914: }
915: else
916: {
917: sk->rqueue = skb->next;
918: skb->next->prev = skb->prev;
919: skb->prev->next = skb->next;
920: }
921: if (p != NULL)
922: {
923: p->handler ((unsigned char *)(skb+1), skb->dev, NULL, skb->saddr,
924: skb->len, skb->daddr, p->protocol, 0);
925: }
926: free_skb (skb, FREE_READ);
927: release_sock (sk);
928: return (0);
929: }
930:
931: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.