00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
#include <asm/uaccess.h>
00044
#include <asm/system.h>
00045
#include <linux/types.h>
00046
#include <linux/kernel.h>
00047
#include <linux/sched.h>
00048
#include <linux/mm.h>
00049
#include <linux/string.h>
00050
#include <linux/errno.h>
00051
#include <linux/config.h>
00052
00053
#include <linux/socket.h>
00054
#include <linux/sockios.h>
00055
#include <linux/in.h>
00056
#include <linux/inet.h>
00057
#include <linux/netdevice.h>
00058
#include <linux/etherdevice.h>
00059
#include <linux/proc_fs.h>
00060
#include <linux/stat.h>
00061
#include <linux/init.h>
00062
00063
#include <net/snmp.h>
00064
#include <net/ip.h>
00065
#include <net/protocol.h>
00066
#include <net/route.h>
00067
#include <net/tcp.h>
00068
#include <net/udp.h>
00069
#include <linux/skbuff.h>
00070
#include <net/sock.h>
00071
#include <net/arp.h>
00072
#include <net/icmp.h>
00073
#include <net/raw.h>
00074
#include <net/checksum.h>
00075
#include <net/inetpeer.h>
00076
#include <linux/igmp.h>
00077
#include <linux/netfilter_ipv4.h>
00078
#include <linux/mroute.h>
00079
#include <linux/netlink.h>
00080
00081
00082
00083
00084
00085 int sysctl_ip_dynaddr = 0;
00086 int sysctl_ip_default_ttl =
IPDEFTTL;
00087
00088
00089 __inline__
void ip_send_check(
struct iphdr *iph)
00090 {
00091 iph->
check = 0;
00092 iph->
check =
ip_fast_csum((
unsigned char *)iph, iph->ihl);
00093 }
00094
00095
00096 static int ip_dev_loopback_xmit(
struct sk_buff *newskb)
00097 {
00098 newskb->
mac.raw = newskb->
data;
00099
__skb_pull(newskb, newskb->
nh.raw - newskb->
data);
00100 newskb->
pkt_type = PACKET_LOOPBACK;
00101 newskb->
ip_summed =
CHECKSUM_UNNECESSARY;
00102 BUG_TRAP(newskb->
dst);
00103
00104
#ifdef CONFIG_NETFILTER_DEBUG
00105
nf_debug_ip_loopback_xmit(newskb);
00106
#endif
00107
netif_rx(newskb);
00108
return 0;
00109 }
00110
00111
00112
00113
static inline int
00114 output_maybe_reroute(
struct sk_buff *skb)
00115 {
00116
return skb->
dst->
output(skb);
00117 }
00118
00119
00120
00121
00122 int ip_build_and_send_pkt(
struct sk_buff *skb,
struct sock *sk,
00123 u32 saddr, u32 daddr,
struct ip_options *opt)
00124 {
00125
struct rtable *rt = (
struct rtable *)skb->
dst;
00126
struct iphdr *iph;
00127
00128
00129
if (opt)
00130 iph=(
struct iphdr *)
skb_push(skb,
sizeof(
struct iphdr) + opt->
optlen);
00131
else
00132 iph=(
struct iphdr *)
skb_push(skb,
sizeof(
struct iphdr));
00133
00134 iph->version = 4;
00135 iph->ihl = 5;
00136 iph->tos = sk->
protinfo.af_inet.tos;
00137
if (
ip_dont_fragment(sk, &rt->u.dst))
00138 iph->frag_off = htons(
IP_DF);
00139
else
00140 iph->frag_off = 0;
00141 iph->ttl = sk->
protinfo.af_inet.ttl;
00142 iph->daddr = rt->rt_dst;
00143 iph->saddr = rt->rt_src;
00144 iph->protocol = sk->
protocol;
00145 iph->tot_len = htons(skb->
len);
00146
ip_select_ident(iph, &rt->u.dst, sk);
00147 skb->
nh.iph = iph;
00148
00149
if (opt && opt->
optlen) {
00150 iph->ihl += opt->
optlen>>2;
00151
ip_options_build(skb, opt, daddr, rt, 0);
00152 }
00153
ip_send_check(iph);
00154
00155
00156
return NF_HOOK(PF_INET,
NF_IP_LOCAL_OUT, skb, NULL, rt->u.
dst.
dev,
00157
output_maybe_reroute);
00158 }
00159
00160 static inline int ip_finish_output2(
struct sk_buff *skb)
00161 {
00162
struct dst_entry *dst = skb->
dst;
00163
struct hh_cache *hh = dst->
hh;
00164
00165
#ifdef CONFIG_NETFILTER_DEBUG
00166
nf_debug_ip_finish_output2(skb);
00167
#endif
00168
00169
if (hh) {
00170
int hh_alen;
00171
00172 read_lock_bh(&hh->hh_lock);
00173 hh_alen =
HH_DATA_ALIGN(hh->hh_len);
00174 memcpy(skb->
data - hh_alen, hh->hh_data, hh_alen);
00175 read_unlock_bh(&hh->hh_lock);
00176
skb_push(skb, hh->hh_len);
00177
return hh->hh_output(skb);
00178 }
else if (dst->neighbour)
00179
return dst->neighbour->output(skb);
00180
00181
if (
net_ratelimit())
00182 printk(KERN_DEBUG
"ip_finish_output2: No header cache and no neighbour!\n");
00183
kfree_skb(skb);
00184
return -EINVAL;
00185 }
00186
00187 __inline__
int ip_finish_output(
struct sk_buff *skb)
00188 {
00189
struct net_device *dev = skb->
dst->
dev;
00190
00191 skb->
dev = dev;
00192 skb->
protocol = htons(ETH_P_IP);
00193
00194
return NF_HOOK(PF_INET,
NF_IP_POST_ROUTING, skb, NULL, dev,
00195
ip_finish_output2);
00196 }
00197
00198 int ip_mc_output(
struct sk_buff *skb)
00199 {
00200
struct sock *sk = skb->
sk;
00201
struct rtable *rt = (
struct rtable*)skb->
dst;
00202
struct net_device *dev = rt->u.dst.
dev;
00203
00204
00205
00206
00207
IP_INC_STATS(IpOutRequests);
00208
#ifdef CONFIG_IP_ROUTE_NAT
00209
if (rt->rt_flags & RTCF_NAT)
00210
ip_do_nat(skb);
00211
#endif
00212
00213 skb->
dev = dev;
00214 skb->
protocol = htons(ETH_P_IP);
00215
00216
00217
00218
00219
00220
if (rt->rt_flags&RTCF_MULTICAST) {
00221
if ((!sk || sk->protinfo.af_inet.mc_loop)
00222
#ifdef CONFIG_IP_MROUTE
00223
00224
00225
00226
00227
00228
00229
00230
00231 && ((rt->rt_flags&RTCF_LOCAL) || !(
IPCB(skb)->flags&
IPSKB_FORWARDED))
00232
#endif
00233
) {
00234
struct sk_buff *newskb =
skb_clone(skb, GFP_ATOMIC);
00235
if (newskb)
00236
NF_HOOK(PF_INET,
NF_IP_POST_ROUTING, newskb, NULL,
00237 newskb->dev,
00238
ip_dev_loopback_xmit);
00239 }
00240
00241
00242
00243
if (skb->
nh.iph->ttl == 0) {
00244
kfree_skb(skb);
00245
return 0;
00246 }
00247 }
00248
00249
if (rt->rt_flags&RTCF_BROADCAST) {
00250
struct sk_buff *newskb =
skb_clone(skb, GFP_ATOMIC);
00251
if (newskb)
00252
NF_HOOK(PF_INET,
NF_IP_POST_ROUTING, newskb, NULL,
00253 newskb->dev,
ip_dev_loopback_xmit);
00254 }
00255
00256
return ip_finish_output(skb);
00257 }
00258
00259 int ip_output(
struct sk_buff *skb)
00260 {
00261
#ifdef CONFIG_IP_ROUTE_NAT
00262
struct rtable *rt = (
struct rtable*)skb->
dst;
00263
#endif
00264
00265
IP_INC_STATS(IpOutRequests);
00266
00267
#ifdef CONFIG_IP_ROUTE_NAT
00268
if (rt->rt_flags&RTCF_NAT)
00269
ip_do_nat(skb);
00270
#endif
00271
00272
return ip_finish_output(skb);
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 static inline int ip_queue_xmit2(
struct sk_buff *skb)
00285 {
00286
struct sock *sk = skb->
sk;
00287
struct rtable *rt = (
struct rtable *)skb->
dst;
00288
struct net_device *dev;
00289
struct iphdr *iph = skb->
nh.iph;
00290
00291 dev = rt->u.dst.dev;
00292
00293
00294
00295
00296
00297
00298
if (
skb_headroom(skb) < dev->hard_header_len && dev->hard_header) {
00299
struct sk_buff *skb2;
00300
00301 skb2 =
skb_realloc_headroom(skb, (dev->hard_header_len + 15) & ~15);
00302
kfree_skb(skb);
00303
if (skb2 == NULL)
00304
return -ENOMEM;
00305
if (sk)
00306
skb_set_owner_w(skb2, sk);
00307 skb = skb2;
00308 iph = skb->
nh.iph;
00309 }
00310
00311
if (skb->
len > rt->u.dst.pmtu)
00312
goto fragment;
00313
00314
ip_select_ident(iph, &rt->u.dst, sk);
00315
00316
00317
ip_send_check(iph);
00318
00319 skb->
priority = sk->priority;
00320
return skb->
dst->
output(skb);
00321
00322 fragment:
00323
if (
ip_dont_fragment(sk, &rt->u.dst)) {
00324
00325
00326
00327
NETDEBUG(printk(KERN_DEBUG
"sending pkt_too_big (len[%u] pmtu[%u]) to self\n",
00328 skb->
len, rt->u.dst.pmtu));
00329
00330
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
00331 htonl(rt->u.dst.pmtu));
00332
kfree_skb(skb);
00333
return -EMSGSIZE;
00334 }
00335
ip_select_ident(iph, &rt->u.dst, sk);
00336
if (skb->
ip_summed ==
CHECKSUM_HW &&
00337 (skb =
skb_checksum_help(skb)) == NULL)
00338
return -ENOMEM;
00339
return ip_fragment(skb, skb->dst->output);
00340 }
00341
00342 int ip_queue_xmit(
struct sk_buff *skb,
int ipfragok)
00343 {
00344
struct sock *sk = skb->
sk;
00345
struct ip_options *opt = sk->
protinfo.af_inet.opt;
00346
struct rtable *rt;
00347
struct iphdr *iph;
00348
00349
00350
00351
00352 rt = (
struct rtable *) skb->
dst;
00353
if (rt != NULL)
00354
goto packet_routed;
00355
00356
00357 rt = (
struct rtable *)
__sk_dst_check(sk, 0);
00358
if (rt == NULL) {
00359 u32 daddr;
00360
00361
00362 daddr = sk->daddr;
00363
if(opt && opt->srr)
00364 daddr = opt->faddr;
00365
00366
00367
00368
00369
00370
if (
ip_route_output(&rt, daddr, sk->saddr,
00371
RT_CONN_FLAGS(sk),
00372 sk->bound_dev_if))
00373
goto no_route;
00374
__sk_dst_set(sk, &rt->u.dst);
00375 sk->route_caps = rt->u.dst.dev->features;
00376 }
00377 skb->
dst =
dst_clone(&rt->u.dst);
00378
00379 packet_routed:
00380
if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
00381
goto no_route;
00382
00383
00384 iph = (
struct iphdr *)
skb_push(skb,
sizeof(
struct iphdr) + (opt ? opt->optlen : 0));
00385 *((__u16 *)iph) = htons((4 << 12) | (5 << 8) | (sk->protinfo.af_inet.tos & 0xff));
00386 iph->tot_len = htons(skb->
len);
00387
if (
ip_dont_fragment(sk, &rt->u.dst) && !ipfragok)
00388 iph->frag_off = htons(
IP_DF);
00389
else
00390 iph->frag_off = 0;
00391 iph->ttl = sk->protinfo.af_inet.ttl;
00392 iph->protocol = sk->protocol;
00393 iph->saddr = rt->rt_src;
00394 iph->daddr = rt->rt_dst;
00395 skb->
nh.iph = iph;
00396
00397
00398
if(opt && opt->optlen) {
00399 iph->ihl += opt->optlen >> 2;
00400
ip_options_build(skb, opt, sk->daddr, rt, 0);
00401 }
00402
00403
return NF_HOOK(PF_INET,
NF_IP_LOCAL_OUT, skb, NULL, rt->u.
dst.
dev,
00404
ip_queue_xmit2);
00405
00406 no_route:
00407
IP_INC_STATS(IpOutNoRoutes);
00408
kfree_skb(skb);
00409
return -EHOSTUNREACH;
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 static int ip_build_xmit_slow(
struct sock *sk,
00433
int getfrag (
const void *,
00434
char *,
00435
unsigned int,
00436
unsigned int),
00437
const void *frag,
00438
unsigned length,
00439
struct ipcm_cookie *ipc,
00440
struct rtable *rt,
00441
int flags)
00442 {
00443
unsigned int fraglen, maxfraglen, fragheaderlen;
00444
int err;
00445
int offset, mf;
00446
int mtu;
00447 u16
id;
00448
00449
int hh_len = (rt->
u.dst.dev->hard_header_len + 15)&~15;
00450
int nfrags=0;
00451
struct ip_options *opt = ipc->
opt;
00452
int df = 0;
00453
00454 mtu = rt->
u.dst.pmtu;
00455
if (
ip_dont_fragment(sk, &rt->
u.dst))
00456 df = htons(
IP_DF);
00457
00458 length -=
sizeof(
struct iphdr);
00459
00460
if (opt) {
00461 fragheaderlen =
sizeof(
struct iphdr) + opt->optlen;
00462 maxfraglen = ((mtu-
sizeof(
struct iphdr)-opt->optlen) & ~7) + fragheaderlen;
00463 }
else {
00464 fragheaderlen =
sizeof(
struct iphdr);
00465
00466
00467
00468
00469
00470
00471 maxfraglen = ((mtu-
sizeof(
struct iphdr)) & ~7) + fragheaderlen;
00472 }
00473
00474
if (length + fragheaderlen > 0xFFFF) {
00475
ip_local_error(sk, EMSGSIZE, rt->
rt_dst, sk->
dport, mtu);
00476
return -EMSGSIZE;
00477 }
00478
00479
00480
00481
00482
00483 offset = length - (length % (maxfraglen - fragheaderlen));
00484
00485
00486
00487
00488
00489 fraglen = length - offset + fragheaderlen;
00490
00491
if (length-offset==0) {
00492 fraglen = maxfraglen;
00493 offset -= maxfraglen-fragheaderlen;
00494 }
00495
00496
00497
00498
00499
00500 mf = 0;
00501
00502
00503
00504
00505
00506
if (offset > 0 && sk->
protinfo.af_inet.pmtudisc==
IP_PMTUDISC_DO) {
00507
ip_local_error(sk, EMSGSIZE, rt->
rt_dst, sk->
dport, mtu);
00508
return -EMSGSIZE;
00509 }
00510
if (flags&MSG_PROBE)
00511
goto out;
00512
00513
00514
00515
00516
00517
id = sk->
protinfo.af_inet.id++;
00518
00519
do {
00520
char *data;
00521
struct sk_buff * skb;
00522
00523
00524
00525
00526
if (!(flags & MSG_DONTWAIT) || nfrags == 0) {
00527 skb =
sock_alloc_send_skb(sk, fraglen + hh_len + 15,
00528 (flags & MSG_DONTWAIT), &err);
00529 }
else {
00530
00531
00532
00533 skb =
sock_wmalloc(sk, fraglen + hh_len + 15, 1,
00534 sk->
allocation);
00535
if (!skb)
00536 err = -ENOBUFS;
00537 }
00538
if (skb == NULL)
00539
goto error;
00540
00541
00542
00543
00544
00545 skb->priority = sk->
priority;
00546 skb->dst =
dst_clone(&rt->
u.dst);
00547
skb_reserve(skb, hh_len);
00548
00549
00550
00551
00552
00553 data =
skb_put(skb, fraglen);
00554 skb->nh.iph = (
struct iphdr *)data;
00555
00556
00557
00558
00559
00560 {
00561
struct iphdr *iph = (
struct iphdr *)data;
00562
00563 iph->version = 4;
00564 iph->ihl = 5;
00565
if (opt) {
00566 iph->ihl += opt->optlen>>2;
00567
ip_options_build(skb, opt,
00568 ipc->
addr, rt, offset);
00569 }
00570 iph->tos = sk->
protinfo.af_inet.tos;
00571 iph->tot_len = htons(fraglen - fragheaderlen + iph->ihl*4);
00572 iph->frag_off = htons(offset>>3)|mf|df;
00573 iph->id =
id;
00574
if (!mf) {
00575
if (offset || !df) {
00576
00577
00578
00579
00580
__ip_select_ident(iph, &rt->
u.dst);
00581
id = iph->id;
00582 }
00583
00584
00585
00586
00587 mf = htons(
IP_MF);
00588 }
00589
if (rt->
rt_type == RTN_MULTICAST)
00590 iph->ttl = sk->
protinfo.af_inet.mc_ttl;
00591
else
00592 iph->ttl = sk->
protinfo.af_inet.ttl;
00593 iph->protocol = sk->
protocol;
00594 iph->check = 0;
00595 iph->saddr = rt->
rt_src;
00596 iph->daddr = rt->
rt_dst;
00597 iph->check =
ip_fast_csum((
unsigned char *)iph, iph->ihl);
00598 data += iph->ihl*4;
00599 }
00600
00601
00602
00603
00604
00605
if (getfrag(frag, data, offset, fraglen-fragheaderlen)) {
00606 err = -EFAULT;
00607
kfree_skb(skb);
00608
goto error;
00609 }
00610
00611 offset -= (maxfraglen-fragheaderlen);
00612 fraglen = maxfraglen;
00613
00614 nfrags++;
00615
00616 err =
NF_HOOK(PF_INET,
NF_IP_LOCAL_OUT, skb, NULL,
00617 skb->dst->dev,
output_maybe_reroute);
00618
if (err) {
00619
if (err > 0)
00620 err = sk->
protinfo.af_inet.recverr ?
net_xmit_errno(err) : 0;
00621
if (err)
00622
goto error;
00623 }
00624 }
while (offset >= 0);
00625
00626
if (nfrags>1)
00627
ip_statistics[smp_processor_id()*2 + !in_softirq()].
IpFragCreates += nfrags;
00628 out:
00629
return 0;
00630
00631
error:
00632
IP_INC_STATS(IpOutDiscards);
00633
if (nfrags>1)
00634
ip_statistics[smp_processor_id()*2 + !in_softirq()].
IpFragCreates += nfrags;
00635
return err;
00636 }
00637
00638
00639
00640
00695 int ip_build_xmit(
struct sock *sk,
00696
int getfrag (
const void *,
00697
char *,
00698
unsigned int,
00699
unsigned int),
00700
const void *frag,
00701
unsigned length,
00702
struct ipcm_cookie *ipc,
00703
struct rtable *rt,
00704
int flags)
00705 {
00706
int err;
00707
struct sk_buff *skb;
00708
int df;
00709
struct iphdr *iph;
00710
00711
00712
00713
00714
00715
00716
if (!sk->
protinfo.af_inet.hdrincl) {
00717 length +=
sizeof(
struct iphdr);
00718
00719
00720
00721
00722
if (length > rt->
u.dst.pmtu || ipc->
opt != NULL)
00723
return ip_build_xmit_slow(sk,getfrag,frag,length,ipc,rt,flags);
00724 }
else {
00725
if (length > rt->
u.dst.dev->mtu) {
00726
ip_local_error(sk, EMSGSIZE, rt->
rt_dst, sk->
dport, rt->
u.dst.dev->mtu);
00727
return -EMSGSIZE;
00728 }
00729 }
00730
if (flags&MSG_PROBE)
00731
goto out;
00732
00733
00734
00735
00736 df = 0;
00737
if (
ip_dont_fragment(sk, &rt->
u.dst))
00738 df = htons(
IP_DF);
00739
00740
00741
00742
00743 {
00744
int hh_len = (rt->
u.dst.dev->hard_header_len + 15)&~15;
00745
00746 skb =
sock_alloc_send_skb(sk, length+hh_len+15,
00747 flags&MSG_DONTWAIT, &err);
00748
if(skb==NULL)
00749
goto error;
00750
skb_reserve(skb, hh_len);
00751 }
00752
00753 skb->priority = sk->
priority;
00754 skb->dst =
dst_clone(&rt->
u.dst);
00755
00756 skb->nh.iph = iph = (
struct iphdr *)
skb_put(skb, length);
00757
00758
if(!sk->
protinfo.af_inet.hdrincl) {
00759 iph->version=4;
00760 iph->ihl=5;
00761 iph->tos=sk->
protinfo.af_inet.tos;
00762 iph->tot_len = htons(length);
00763 iph->frag_off = df;
00764 iph->ttl=sk->
protinfo.af_inet.mc_ttl;
00765
ip_select_ident(iph, &rt->
u.dst, sk);
00766
if (rt->
rt_type != RTN_MULTICAST)
00767 iph->ttl=sk->
protinfo.af_inet.ttl;
00768 iph->protocol=sk->
protocol;
00769 iph->saddr=rt->
rt_src;
00770 iph->daddr=rt->
rt_dst;
00771 iph->check=0;
00772 iph->check =
ip_fast_csum((
unsigned char *)iph, iph->ihl);
00773 err = getfrag(frag, ((
char *)iph)+iph->ihl*4,0, length-iph->ihl*4);
00774 }
00775
else
00776 err = getfrag(frag, (
void *)iph, 0, length);
00777
00778
if (err)
00779
goto error_fault;
00780
00781 err =
NF_HOOK(PF_INET,
NF_IP_LOCAL_OUT, skb, NULL, rt->
u.dst.dev,
00782
output_maybe_reroute);
00783
if (err > 0)
00784 err = sk->
protinfo.af_inet.recverr ?
net_xmit_errno(err) : 0;
00785
if (err)
00786
goto error;
00787 out:
00788
return 0;
00789
00790 error_fault:
00791 err = -EFAULT;
00792
kfree_skb(skb);
00793
error:
00794
IP_INC_STATS(IpOutDiscards);
00795
return err;
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 int ip_fragment(
struct sk_buff *skb,
int (*output)(
struct sk_buff*))
00808 {
00809
struct iphdr *iph;
00810
int raw = 0;
00811
int ptr;
00812
struct net_device *dev;
00813
struct sk_buff *skb2;
00814
unsigned int mtu, hlen, left, len;
00815
int offset;
00816
int not_last_frag;
00817
struct rtable *rt = (
struct rtable*)skb->
dst;
00818
int err = 0;
00819
00820 dev = rt->u.dst.
dev;
00821
00822
00823
00824
00825
00826 iph = skb->
nh.iph;
00827
00828
00829
00830
00831
00832 hlen = iph->ihl * 4;
00833 left = skb->
len - hlen;
00834 mtu = rt->u.dst.pmtu - hlen;
00835 ptr = raw + hlen;
00836
00837
00838
00839
00840
00841 offset = (ntohs(iph->frag_off) &
IP_OFFSET) << 3;
00842 not_last_frag = iph->frag_off & htons(
IP_MF);
00843
00844
00845
00846
00847
00848
while(left > 0) {
00849 len = left;
00850
00851
if (len > mtu)
00852 len = mtu;
00853
00854
00855
if (len < left) {
00856 len &= ~7;
00857 }
00858
00859
00860
00861
00862
if ((skb2 =
alloc_skb(len+hlen+dev->hard_header_len+15,GFP_ATOMIC)) == NULL) {
00863
NETDEBUG(printk(KERN_INFO
"IP: frag: no memory for new fragment!\n"));
00864 err = -ENOMEM;
00865
goto fail;
00866 }
00867
00868
00869
00870
00871
00872 skb2->pkt_type = skb->
pkt_type;
00873 skb2->priority = skb->
priority;
00874
skb_reserve(skb2, (dev->hard_header_len+15)&~15);
00875
skb_put(skb2, len + hlen);
00876 skb2->nh.raw = skb2->data;
00877 skb2->h.raw = skb2->data + hlen;
00878 skb2->protocol = skb->
protocol;
00879 skb2->security = skb->
security;
00880
00881
00882
00883
00884
00885
00886
if (skb->
sk)
00887
skb_set_owner_w(skb2, skb->
sk);
00888 skb2->dst =
dst_clone(skb->
dst);
00889 skb2->dev = skb->
dev;
00890
00891
00892
00893
00894
00895 memcpy(skb2->nh.raw, skb->
data, hlen);
00896
00897
00898
00899
00900
if (
skb_copy_bits(skb, ptr, skb2->
h.raw, len))
00901 BUG();
00902 left -= len;
00903
00904
00905
00906
00907 iph = skb2->nh.iph;
00908 iph->frag_off = htons((offset >> 3));
00909
00910
00911
00912
00913
00914
00915
00916
if (offset == 0)
00917
ip_options_fragment(skb);
00918
00919
00920
IPCB(skb2)->flags =
IPCB(skb)->flags;
00921
00922
00923
00924
00925
00926
if (left > 0 || not_last_frag)
00927 iph->frag_off |= htons(
IP_MF);
00928 ptr += len;
00929 offset += len;
00930
00931
#ifdef CONFIG_NET_SCHED
00932
skb2->tc_index = skb->tc_index;
00933
#endif
00934
#ifdef CONFIG_NETFILTER
00935
skb2->nfmark = skb->nfmark;
00936 skb2->nfcache = skb->nfcache;
00937
00938 skb2->nfct = skb->nfct;
00939 nf_conntrack_get(skb2->nfct);
00940
#ifdef CONFIG_NETFILTER_DEBUG
00941
skb2->nf_debug = skb->nf_debug;
00942
#endif
00943
#endif
00944
00945
00946
00947
00948
00949
IP_INC_STATS(IpFragCreates);
00950
00951 iph->tot_len = htons(len + hlen);
00952
00953
ip_send_check(iph);
00954
00955 err = output(skb2);
00956
if (err)
00957
goto fail;
00958 }
00959
kfree_skb(skb);
00960
IP_INC_STATS(IpFragOKs);
00961
return err;
00962
00963 fail:
00964
kfree_skb(skb);
00965
IP_INC_STATS(IpFragFails);
00966
return err;
00967 }
00968
00969
00970
00971
00972 static int ip_reply_glue_bits(
const void *dptr,
char *to,
unsigned int offset,
00973
unsigned int fraglen)
00974 {
00975
struct ip_reply_arg *dp = (
struct ip_reply_arg*)dptr;
00976 u16 *pktp = (u16 *)to;
00977
struct iovec *iov;
00978
int len;
00979
int hdrflag = 1;
00980
00981 iov = &dp->iov[0];
00982
if (offset >= iov->iov_len) {
00983 offset -= iov->iov_len;
00984 iov++;
00985 hdrflag = 0;
00986 }
00987 len = iov->iov_len - offset;
00988
if (fraglen > len) {
00989 dp->csum =
csum_partial_copy_nocheck(iov->iov_base+offset, to, len,
00990 dp->csum);
00991 offset = 0;
00992 fraglen -= len;
00993 to += len;
00994 iov++;
00995 }
00996
00997 dp->csum =
csum_partial_copy_nocheck(iov->iov_base+offset, to, fraglen,
00998 dp->csum);
00999
01000
if (hdrflag && dp->csumoffset)
01001 *(pktp + dp->csumoffset) =
csum_fold(dp->csum);
01002
return 0;
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012 void ip_send_reply(
struct sock *sk,
struct sk_buff *skb,
struct ip_reply_arg *arg,
01013
unsigned int len)
01014 {
01015
struct {
01016
struct ip_options opt;
01017
char data[40];
01018 } replyopts;
01019
struct ipcm_cookie ipc;
01020 u32 daddr;
01021
struct rtable *rt = (
struct rtable*)skb->
dst;
01022
01023
if (
ip_options_echo(&replyopts.opt, skb))
01024
return;
01025
01026 daddr = ipc.
addr = rt->rt_src;
01027 ipc.
opt = NULL;
01028
01029
if (replyopts.opt.optlen) {
01030 ipc.
opt = &replyopts.opt;
01031
01032
if (ipc.
opt->
srr)
01033 daddr = replyopts.opt.
faddr;
01034 }
01035
01036
if (
ip_route_output(&rt, daddr, rt->rt_spec_dst, RT_TOS(skb->
nh.iph->tos), 0))
01037
return;
01038
01039
01040
01041
01042
01043
01044
01045
bh_lock_sock(sk);
01046 sk->
protinfo.af_inet.tos = skb->
nh.iph->tos;
01047 sk->
priority = skb->
priority;
01048 sk->
protocol = skb->
nh.iph->protocol;
01049
ip_build_xmit(sk,
ip_reply_glue_bits, arg, len, &ipc, rt, MSG_DONTWAIT);
01050
bh_unlock_sock(sk);
01051
01052
ip_rt_put(rt);
01053 }
01054
01055
01056
01057
01058
01059 static struct packet_type ip_packet_type =
01060 {
01061 __constant_htons(ETH_P_IP),
01062 NULL,
01063
ip_rcv,
01064 (
void*)1,
01065 NULL,
01066 };
01067
01068
01069
01070
01071
01072 void __init
ip_init(
void)
01073 {
01074
dev_add_pack(&
ip_packet_type);
01075
01076
ip_rt_init();
01077
inet_initpeers();
01078
01079
#ifdef CONFIG_IP_MULTICAST
01080
proc_net_create(
"igmp", 0,
ip_mc_procinfo);
01081
#endif
01082
proc_net_create(
"mcfilter", 0,
ip_mcf_procinfo);
01083 }