This source file includes following definitions.
- get_protocol
- add_ip_protocol
- delete_ip_protocol
- ip_addr_match
- my_ip_addr
- strict_route
- loose_route
- print_rt
- print_ipprot
- ip_route
- add_route
- ip_set_dev
- ip_route_check
- build_options
- ip_build_header
- do_options
- ip_compute_csum
- ip_csum
- ip_send_check
- ip_rcv
- ip_queue_xmit
- ip_retransmit
- print_iph
- ip_handoff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 #include <asm/segment.h>
53 #include <asm/system.h>
54 #include <linux/types.h>
55 #include <linux/kernel.h>
56 #include <linux/sched.h>
57 #include <linux/string.h>
58 #include <linux/socket.h>
59 #include <netinet/in.h>
60 #include "timer.h"
61 #include "ip.h"
62 #include "tcp.h"
63 #include "sock.h"
64 #include <linux/errno.h>
65 #include "arp.h"
66 #include "icmp.h"
67
68 unsigned long ip_addr[MAX_IP_ADDRES]={0,0,0};
69
70 #undef IP_DEBUG
71 #ifdef IP_DEBUG
72 #define PRINTK printk
73 #else
74 #define PRINTK dummy_routine
75 #endif
76
77 static struct rtable *rt_base=NULL;
78
79 struct ip_protocol *ip_protos[MAX_IP_PROTOS] = { NULL, };
80
81 #if 0
82 static struct ip_protocol *
83 get_protocol(unsigned char prot)
84 {
85 unsigned char hash;
86 struct ip_protocol *p;
87 PRINTK ("get_protocol (%d)\n ", prot);
88 hash = prot & (MAX_IP_PROTOS -1);
89 for (p = ip_protos[hash] ; p != NULL; p=p->next)
90 {
91 PRINTK ("trying protocol %d\n", p->protocol);
92 if (p->protocol == prot)
93 return (p);
94 }
95 return (NULL);
96
97 }
98 #endif
99
100 void
101 add_ip_protocol (struct ip_protocol *prot)
102 {
103 unsigned char hash;
104 struct ip_protocol *p2;
105 hash = prot->protocol & (MAX_IP_PROTOS-1);
106 prot ->next = ip_protos[hash];
107 ip_protos[hash] = prot;
108 prot->copy = 0;
109
110 for (p2 = prot->next; p2 != NULL; p2=p2->next)
111 {
112 if (p2->protocol == prot->protocol)
113 {
114 prot->copy = 1;
115 break;
116 }
117 }
118
119 }
120
121 int
122 delete_ip_protocol (struct ip_protocol *prot)
123 {
124 struct ip_protocol *p;
125 struct ip_protocol *lp=NULL;
126 unsigned char hash;
127
128
129 hash = prot->protocol & (MAX_IP_PROTOS -1);
130 if (prot == ip_protos[hash])
131 {
132 ip_protos[hash]=ip_protos[hash]->next;
133 return (0);
134 }
135
136 for (p = ip_protos[hash]; p != NULL; p = p->next)
137 {
138
139
140
141 if (p->next != NULL && p->next == prot)
142 {
143
144
145
146 if (p->copy == 0 && lp != NULL)
147 lp->copy = 0;
148 p->next = prot->next;
149 return (0);
150 }
151
152 if (p->next != NULL && p->next->protocol == prot->protocol)
153 {
154 lp = p;
155 }
156 }
157 return (-1);
158 }
159
160
161
162
163 int
164 ip_addr_match (unsigned long addr1, unsigned long addr2)
165 {
166 int i;
167 if (addr1 == addr2) return (1);
168 for (i = 0; i < 4; i++, addr1 >>= 8, addr2 >>= 8)
169 {
170 if ((addr1 & 0xff) != (addr2 & 0xff))
171 {
172
173
174 if (addr1 != 0)
175 {
176 return (0);
177 }
178 return (1);
179 }
180 }
181 return (1);
182 }
183
184 int
185 my_ip_addr(unsigned long addr)
186 {
187 int i;
188 for (i = 0; i < MAX_IP_ADDRES; i++)
189 {
190 if (ip_addr[i] == 0) return (0);
191 if (ip_addr_match (addr, ip_addr[i])) return (1);
192 }
193 return (0);
194 }
195
196
197 static void
198 strict_route(struct ip_header *iph, struct options *opt)
199 {
200 }
201
202 static void
203 loose_route(struct ip_header *iph, struct options *opt)
204 {
205 }
206
207 void
208 print_rt(struct rtable *rt)
209 {
210 PRINTK ("net = %08X router = %08X\n",rt->net, rt->router);
211 PRINTK ("dev = %X, next = %X\n",rt->dev, rt->next);
212 }
213
214 void
215 print_ipprot (struct ip_protocol *ipprot)
216 {
217 PRINTK ("handler = %X, protocol = %d, copy=%d \n",
218 ipprot->handler, ipprot->protocol, ipprot->copy);
219 }
220
221
222 static struct device *
223 ip_route(struct options *opt, unsigned long daddr , unsigned long *raddr)
224 {
225 struct rtable *rt;
226
227
228 for (rt=rt_base; rt != NULL; rt=rt->next)
229 {
230
231 if (ip_addr_match (rt->net, daddr))
232 {
233 *raddr = rt->router;
234 return (rt->dev);
235 }
236 }
237 return (NULL);
238 };
239
240 void
241 add_route (struct rtable *rt)
242 {
243 int mask;
244 struct rtable *r;
245 struct rtable *r1;
246 PRINTK ("add_route (rt=%X):\n",rt);
247 print_rt(rt);
248
249 if (rt_base == NULL)
250 {
251 rt->next = NULL;
252 rt_base = rt;
253 return;
254 }
255
256
257
258
259 for (mask = 0xff000000; mask != 0xffffffff; mask = (mask >> 8) | mask)
260 {
261 if (mask & rt->net)
262 {
263 mask = mask << 8;
264 break;
265 }
266 }
267 PRINTK ("mask = %X\n",mask);
268 r1=rt_base;
269 for (r=rt_base; r != NULL; r=r->next)
270 {
271
272 if (r->net == rt->net)
273 {
274 if (r == rt_base)
275 {
276 rt->next = r->next;
277 rt_base = rt;
278 }
279 else
280 {
281 rt->next = r->next;
282 r1->next = rt;
283 }
284 kfree_s (r, sizeof (*r));
285 return;
286 }
287
288 if (!(r->net & mask))
289 {
290 PRINTK("adding before r=%X\n",r);
291 print_rt(r);
292 if (r == rt_base)
293 {
294 rt->next = rt_base;
295 rt_base = rt;
296 return;
297 }
298 rt->next = r;
299 r1->next = rt;
300 return;
301 }
302 r1 = r;
303 }
304 PRINTK ("adding after r1=%X\n",r1);
305 print_rt(r1);
306
307 rt->next = NULL;
308 r1->next = rt;
309 }
310
311 int
312 ip_set_dev (struct ip_config *u_ipc)
313 {
314 struct rtable *rt;
315 struct device *dev;
316 struct ip_config ipc;
317 static int ip_ads = 0;
318
319 if (ip_ads >= MAX_IP_ADDRES) return (-EINVAL);
320
321
322 memcpy_fromfs(&ipc, u_ipc, sizeof (ipc));
323 ipc.name[MAX_IP_NAME-1] = 0;
324 dev = get_dev (ipc.name);
325
326 if (dev == NULL) return (-EINVAL);
327
328
329 if (ipc.net != -1)
330 {
331 arp_add_broad (ipc.net, dev);
332 rt = kmalloc (sizeof (*rt), GFP_KERNEL);
333 if (rt == NULL) return (-ENOMEM);
334
335 rt->net = ipc.net;
336 rt->dev = dev;
337 rt->router = 0;
338 add_route (rt);
339
340 }
341
342 if (ipc.router != -1)
343 {
344 rt = kmalloc (sizeof (*rt),GFP_KERNEL);
345 if (rt == NULL) return (-ENOMEM);
346 rt->net = 0;
347 rt->dev = dev;
348 rt->router = ipc.router;
349 add_route (rt);
350 }
351
352 if (dev->loopback)
353 {
354 rt = kmalloc (sizeof (*rt), GFP_KERNEL);
355 if (rt == NULL) return (-ENOMEM);
356 rt->net = ipc.paddr;
357 rt->dev = dev;
358 rt->router = 0;
359 add_route (rt);
360
361 }
362
363
364 if (!my_ip_addr (ipc.paddr))
365 ip_addr[ip_ads++] = ipc.paddr;
366
367 dev->up = ipc.up;
368 if (dev->up)
369 {
370 if (dev->open)
371 dev->open(dev);
372 }
373 else
374 {
375 if (dev->stop)
376 dev->stop(dev);
377 }
378 return (0);
379
380 }
381
382
383 void
384 ip_route_check (unsigned long daddr)
385 {
386 }
387
388 #if 0
389
390 static int
391 build_options (struct ip_header *iph, struct options *opt)
392 {
393 unsigned char *ptr;
394
395 ptr = (unsigned char *)(iph+1);
396 *ptr = 0;
397 return (4);
398 }
399 #endif
400
401
402
403
404
405
406 int
407 ip_build_header (struct sk_buff *skb, unsigned long saddr,
408 unsigned long daddr, struct device **dev, int type,
409 struct options *opt, int len)
410 {
411 static struct options optmem;
412 struct ip_header *iph;
413 unsigned char *buff;
414 static int count = 0;
415 unsigned long raddr;
416 int tmp;
417 if (saddr == 0) saddr = MY_IP_ADDR;
418 PRINTK ("ip_build_header (skb=%X, saddr=%X, daddr=%X, *dev=%X,\n"
419 " type=%d, opt=%X, len = %d)\n",
420 skb, saddr, daddr, *dev, type, opt, len);
421 buff = (unsigned char *)(skb + 1);
422
423 if (*dev == NULL)
424 {
425 *dev = ip_route(&optmem,daddr, &raddr);
426 if (*dev == NULL)
427 {
428 return (-ENETUNREACH);
429 }
430 opt = &optmem;
431 }
432 else
433 {
434
435 ip_route (&optmem, daddr, &raddr);
436 }
437 if (raddr == 0) raddr = daddr;
438
439
440
441
442 if ((*dev)->hard_header)
443 {
444 tmp = (*dev)->hard_header(buff, *dev, ETHERTYPE_IP, raddr, saddr, len);
445 }
446 else
447 {
448 tmp = 0;
449 }
450 if (tmp < 0)
451 {
452 tmp = -tmp;
453 skb->arp = 0;
454 }
455 else
456 {
457 skb->arp = 1;
458 }
459 buff += tmp;
460 len -= tmp;
461 skb->dev = *dev;
462
463 iph = (struct ip_header *)buff;
464 iph->version = 4;
465 iph->tos = 0;
466 iph->frag_off = 0;
467 iph->ttl = 32;
468 iph->daddr = daddr;
469 iph->saddr = saddr;
470 iph->protocol=type;
471 iph->ihl = 5;
472 iph->id = net16(count++);
473
474 return (20+tmp);
475 }
476
477 static int
478 do_options(struct ip_header *iph, struct options *opt)
479 {
480 unsigned char *buff;
481 int done = 0;
482 int len=sizeof (*iph);
483 int i;
484
485 opt->record_route.route_size = 0;
486 opt->loose_route.route_size = 0;
487 opt->strict_route.route_size = 0;
488 opt->tstamp.ptr = 0;
489 opt->security = 0;
490 opt->compartment = 0;
491 opt->handling = 0;
492 opt->stream = 0;
493 opt->tcc = 0;
494 return (0);
495
496 buff = (unsigned char *)(iph + 1);
497
498
499 while (!done && len < iph->ihl*4)
500 {
501 switch (*buff)
502 {
503 case IPOPT_END:
504 done=1;
505 break;
506
507 case IPOPT_NOOP:
508 buff++;
509 len ++;
510 break;
511
512 case IPOPT_SEC:
513 buff++;
514 if (*buff != 11)
515 return (1);
516 buff++;
517 opt->security = net16(*(unsigned short *)buff);
518 buff += 2;
519 opt->compartment = net16(*(unsigned short *)buff);
520 buff += 2;
521 opt-> handling = net16(*(unsigned short *)buff);
522 buff += 2;
523 opt->tcc = ((*buff) << 16) + net16(*(unsigned short *)(buff+1));
524 buff += 3;
525 len += 11;
526 break;
527
528 case IPOPT_LSRR:
529 buff ++;
530 if ((*buff - 3)% 4 != 0) return (1);
531 len += *buff;
532 opt->loose_route.route_size = (*buff -3)/4;
533 buff ++;
534 if (*buff % 4 != 0) return (1);
535 opt->loose_route.pointer = *buff/4 - 1;
536 buff ++;
537 buff ++;
538 for (i = 0; i < opt->loose_route.route_size; i++)
539 {
540 opt->loose_route.route[i]=*(unsigned long *)buff;
541 buff += 4;
542 }
543 break;
544
545
546 case IPOPT_SSRR:
547 buff ++;
548 if ((*buff - 3)% 4 != 0) return (1);
549 len += *buff;
550 opt->strict_route.route_size = (*buff -3)/4;
551 buff ++;
552 if (*buff % 4 != 0) return (1);
553 opt->strict_route.pointer = *buff/4 - 1;
554 buff ++;
555 buff ++;
556 for (i = 0; i < opt->strict_route.route_size; i++)
557 {
558 opt->strict_route.route[i]=*(unsigned long *)buff;
559 buff += 4;
560 }
561 break;
562
563 case IPOPT_RR:
564 buff ++;
565 if ((*buff - 3)% 4 != 0) return (1);
566 len += *buff;
567 opt->record_route.route_size = (*buff -3)/4;
568 buff ++;
569 if (*buff % 4 != 0) return (1);
570 opt->record_route.pointer = *buff/4 - 1;
571 buff ++;
572 buff ++;
573 for (i = 0; i < opt->record_route.route_size; i++)
574 {
575 opt->record_route.route[i]=*(unsigned long *)buff;
576 buff += 4;
577 }
578 break;
579
580 case IPOPT_SID:
581 len += 4;
582 buff +=2;
583 opt->stream = *(unsigned short *)buff;
584 buff += 2;
585 break;
586
587 case IPOPT_TIMESTAMP:
588 buff ++;
589 len += *buff;
590 if (*buff % 4 != 0) return (1);
591 opt->tstamp.len = *buff / 4 - 1;
592 buff ++;
593 if ((*buff - 1) % 4 != 0) return (1);
594 opt->tstamp.ptr = (*buff-1)/4;
595 buff ++;
596 opt->tstamp.x.full_char = *buff;
597 buff ++;
598 for (i = 0; i < opt->tstamp.len; i++)
599 {
600 opt->tstamp.data[i] = *(unsigned long *)buff;
601 buff += 4;
602 }
603 break;
604
605 default:
606 return (1);
607 }
608 }
609 if (opt->record_route.route_size == 0)
610 {
611 if (opt->strict_route.route_size != 0)
612 {
613 memcpy (&(opt->record_route), &(opt->strict_route),
614 sizeof (opt->record_route));
615 }
616 else if (opt->loose_route.route_size != 0)
617 {
618 memcpy (&(opt->record_route), &(opt->loose_route),
619 sizeof (opt->record_route));
620 }
621 }
622
623 if (opt->strict_route.route_size != 0 &&
624 opt->strict_route.route_size != opt->strict_route.pointer)
625 {
626 strict_route (iph, opt);
627 return (0);
628 }
629
630 if (opt->loose_route.route_size != 0 &&
631 opt->loose_route.route_size != opt->loose_route.pointer)
632 {
633 loose_route (iph, opt);
634 return (0);
635 }
636
637 return (0);
638 }
639
640
641
642
643
644 unsigned short
645 ip_compute_csum(unsigned char * buff, int len)
646 {
647 unsigned long sum = 0;
648 if (len > 3)
649 {
650
651 __asm__("\t clc\n"
652 "1:\n"
653 "\t lodsl\n"
654 "\t adcl %%eax, %%ebx\n"
655 "\t loop 1b\n"
656 "\t adcl $0, %%ebx\n"
657 "\t movl %%ebx, %%eax\n"
658 "\t shrl $16, %%eax\n"
659 "\t addw %%ax, %%bx\n"
660 "\t adcw $0, %%bx\n"
661 : "=b" (sum) , "=S" (buff)
662 : "0" (sum), "c" (len >> 2) ,"1" (buff)
663 : "ax", "cx", "si", "bx" );
664 }
665 if (len & 2)
666 {
667 __asm__("\t lodsw\n"
668 "\t addw %%ax, %%bx\n"
669 "\t adcw $0, %%bx\n"
670 : "=b" (sum), "=S" (buff)
671 : "0" (sum), "1" (buff)
672 : "bx", "ax", "si");
673 }
674 if (len & 1)
675 {
676 __asm__("\t lodsb\n"
677 "\t movb $0, %%ah\n"
678 "\t addw %%ax, %%bx\n"
679 "\t adcw $0, %%bx\n"
680 : "=b" (sum), "=S" (buff)
681 : "0" (sum), "1" (buff)
682 : "bx", "ax", "si");
683 }
684 sum =~sum;
685 return (sum&0xffff);
686 }
687
688 static int
689 ip_csum(struct ip_header *iph)
690 {
691 if (iph->check == 0) return (0);
692 if (ip_compute_csum((unsigned char *)iph, iph->ihl*4) == 0) return (0);
693 return (1);
694 }
695
696 static void
697 ip_send_check(struct ip_header *iph)
698 {
699 iph->check = 0;
700 iph->check = ip_compute_csum((unsigned char *)iph, iph->ihl*4);
701 }
702
703 int
704 ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
705 {
706 struct ip_header *iph;
707 unsigned char hash;
708 unsigned char flag=0;
709 static struct options opt;
710
711 struct ip_protocol *ipprot;
712
713 iph=skb->h.iph;
714
715 PRINTK("<<\n");
716 print_iph(iph);
717
718 if (ip_csum (iph) || do_options (iph,&opt) || iph->version != 4)
719 {
720 PRINTK ("ip packet thrown out. \n");
721 skb->sk = NULL;
722 kfree_skb(skb, 0);
723 return (0);
724 }
725
726
727 if (!my_ip_addr(iph->daddr))
728 {
729 PRINTK ("packet meant for someone else.\n");
730 skb->sk = NULL;
731 kfree_skb(skb, 0);
732 return (0);
733 }
734
735
736 if ((iph->frag_off & 32) || (net16(iph->frag_off)&0x1fff))
737 {
738 printk ("packet fragmented. \n");
739 skb->sk = NULL;
740 kfree_skb(skb, 0);
741 return(0);
742 }
743
744 skb->h.raw += iph->ihl*4;
745
746 hash = iph->protocol & (MAX_IP_PROTOS -1);
747 for (ipprot = ip_protos[hash]; ipprot != NULL; ipprot=ipprot->next)
748 {
749 struct sk_buff *skb2;
750 if (ipprot->protocol != iph->protocol) continue;
751 PRINTK ("Using protocol = %X:\n", ipprot);
752 print_ipprot (ipprot);
753
754
755
756
757
758
759 if (ipprot->copy)
760 {
761 skb2 = kmalloc (skb->mem_len, GFP_ATOMIC);
762 if (skb2 == NULL) continue;
763 memcpy (skb2, skb, skb->mem_len);
764 skb2->mem_addr = skb2;
765 skb2->lock = 0;
766 skb2->h.raw = (void *)((unsigned long)skb2
767 + (unsigned long)skb->h.raw
768 - (unsigned long)skb);
769 }
770 else
771 {
772 skb2 = skb;
773 }
774 flag = 1;
775 ipprot->handler (skb2, dev, &opt, iph->daddr,
776 net16(iph->tot_len) - iph->ihl*4,
777 iph->saddr, 0, ipprot);
778
779 }
780 if (!flag)
781 {
782 icmp_reply (skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, dev);
783 skb->sk = NULL;
784 kfree_skb (skb, 0);
785 }
786
787
788 return (0);
789 }
790
791
792
793
794
795
796
797 void
798 ip_queue_xmit (volatile struct sock *sk, struct device *dev,
799 struct sk_buff *skb, int free)
800 {
801 struct ip_header *iph;
802 unsigned char *ptr;
803 if (sk == NULL) free = 1;
804
805 if (dev == NULL)
806 {
807 printk ("ip.c: ip_queue_xmit dev = NULL\n");
808 return;
809 }
810
811 skb->free = free;
812 skb->dev = dev;
813 skb->when = jiffies;
814 PRINTK(">>\n");
815 ptr = (unsigned char *)(skb + 1);
816 ptr += dev->hard_header_len;
817 iph = (struct ip_header *)ptr;
818 iph->tot_len = net16(skb->len-dev->hard_header_len);
819 ip_send_check (iph);
820 print_iph(iph);
821 skb->next = NULL;
822
823
824
825 skb->magic = 1;
826
827 if (!free)
828 {
829 skb->link3 = NULL;
830 sk->packets_out++;
831 cli();
832 if (sk->send_tail == NULL)
833 {
834 sk->send_tail = skb;
835 sk->send_head = skb;
836 }
837 else
838 {
839 sk->send_tail->link3 = skb;
840 sk->send_tail = skb;
841 }
842 sti();
843 sk->time_wait.len = sk->rtt*2;
844 sk->timeout=TIME_WRITE;
845 reset_timer ((struct timer *)&sk->time_wait);
846 }
847 else
848 {
849 skb->sk = sk;
850 }
851 if (dev->up)
852 {
853 if (sk != NULL)
854 {
855 dev->queue_xmit(skb, dev, sk->priority);
856 }
857 else
858 {
859 dev->queue_xmit (skb, dev, SOPRI_NORMAL);
860 }
861 }
862 else
863 {
864 if (free)
865 kfree_skb (skb, FREE_WRITE);
866 }
867 }
868
869 void
870 ip_retransmit (volatile struct sock *sk, int all)
871 {
872 struct sk_buff * skb;
873 struct proto *prot;
874 struct device *dev;
875
876 prot = sk->prot;
877 skb = sk->send_head;
878 while (skb != NULL)
879 {
880 dev = skb->dev;
881
882
883 if (!skb->arp)
884 {
885 if (dev->rebuild_header ((struct enet_header *)(skb+1),dev))
886 {
887 if (!all) break;
888 skb=skb->link3;
889 continue;
890 }
891 }
892 skb->arp = 1;
893 skb->when = jiffies;
894
895 if (dev->up)
896 if (sk)
897 dev->queue_xmit(skb, dev, sk->priority);
898 else
899 dev->queue_xmit(skb, dev, SOPRI_NORMAL );
900
901 sk->retransmits++;
902 sk->prot->retransmits ++;
903 if (!all) break;
904
905
906
907 if (sk->retransmits > sk->cong_window) break;
908 skb=skb->link3;
909 }
910
911
912
913
914
915
916 sk->rtt *= 2;
917 sk->time_wait.len = sk->rtt;
918 sk->timeout = TIME_WRITE;
919 reset_timer ((struct timer *)&sk->time_wait);
920 }
921
922 void
923 print_iph (struct ip_header *ip)
924 {
925 PRINTK ("ip header:\n");
926 PRINTK (" ihl = %d, version = %d, tos = %d, tot_len = %d\n",
927 ip->ihl, ip->version, ip->tos, net16(ip->tot_len));
928 PRINTK (" id = %x, ttl = %d, prot = %d, check=%x\n",
929 ip->id, ip->ttl, ip->protocol, ip->check);
930 PRINTK (" frag_off=%d\n", ip->frag_off);
931 PRINTK (" saddr = %X, daddr = %X\n",ip->saddr, ip->daddr);
932 }
933
934 #if 0
935 int
936 ip_handoff (volatile struct sock *sk)
937 {
938 struct ip_protocol *p;
939 struct sk_buff *skb;
940 p = get_protocol (sk->protocol);
941
942 if (p == NULL)
943 {
944
945 printk ("sock_ioctl: protocol not found. \n");
946
947 return (-EIO);
948 }
949
950 while (p->handler != sk->prot->rcv)
951 {
952 p=p->next;
953 if (p == NULL)
954 {
955
956 printk ("sock_ioctl: protocol not found. \n");
957
958 return (-EIO);
959 }
960 }
961 p = p-> next;
962 sk->inuse = 1;
963
964
965
966 if (sk->rqueue == NULL) return (0);
967 skb = sk->rqueue;
968 if (skb->next == skb)
969 {
970 sk->rqueue = NULL;
971 }
972 else
973 {
974 sk->rqueue = skb->next;
975 skb->next->prev = skb->prev;
976 skb->prev->next = skb->next;
977 }
978 if (p != NULL)
979 {
980 p->handler ((unsigned char *)(skb+1), skb->dev, NULL, skb->saddr,
981 skb->len, skb->daddr, p->protocol, 0);
982 }
983 kfree_skb (skb, FREE_READ);
984 release_sock (sk);
985 return (0);
986 }
987
988 #endif