| .. | .. |
|---|
| 47 | 47 | unsigned char *iph = skb_network_header(skb); |
|---|
| 48 | 48 | |
|---|
| 49 | 49 | memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options)); |
|---|
| 50 | | - memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen); |
|---|
| 50 | + memcpy(iph + sizeof(struct iphdr), opt->__data, opt->optlen); |
|---|
| 51 | 51 | opt = &(IPCB(skb)->opt); |
|---|
| 52 | 52 | |
|---|
| 53 | 53 | if (opt->srr) |
|---|
| 54 | | - memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4); |
|---|
| 54 | + memcpy(iph + opt->srr + iph[opt->srr + 1] - 4, &daddr, 4); |
|---|
| 55 | 55 | |
|---|
| 56 | 56 | if (!is_frag) { |
|---|
| 57 | 57 | if (opt->rr_needaddr) |
|---|
| 58 | | - ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, skb, rt); |
|---|
| 58 | + ip_rt_get_source(iph + opt->rr + iph[opt->rr + 2] - 5, skb, rt); |
|---|
| 59 | 59 | if (opt->ts_needaddr) |
|---|
| 60 | | - ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, skb, rt); |
|---|
| 60 | + ip_rt_get_source(iph + opt->ts + iph[opt->ts + 2] - 9, skb, rt); |
|---|
| 61 | 61 | if (opt->ts_needtime) { |
|---|
| 62 | 62 | __be32 midtime; |
|---|
| 63 | 63 | |
|---|
| 64 | 64 | midtime = inet_current_timestamp(); |
|---|
| 65 | | - memcpy(iph+opt->ts+iph[opt->ts+2]-5, &midtime, 4); |
|---|
| 65 | + memcpy(iph + opt->ts + iph[opt->ts + 2] - 5, &midtime, 4); |
|---|
| 66 | 66 | } |
|---|
| 67 | 67 | return; |
|---|
| 68 | 68 | } |
|---|
| 69 | 69 | if (opt->rr) { |
|---|
| 70 | | - memset(iph+opt->rr, IPOPT_NOP, iph[opt->rr+1]); |
|---|
| 70 | + memset(iph + opt->rr, IPOPT_NOP, iph[opt->rr + 1]); |
|---|
| 71 | 71 | opt->rr = 0; |
|---|
| 72 | 72 | opt->rr_needaddr = 0; |
|---|
| 73 | 73 | } |
|---|
| 74 | 74 | if (opt->ts) { |
|---|
| 75 | | - memset(iph+opt->ts, IPOPT_NOP, iph[opt->ts+1]); |
|---|
| 75 | + memset(iph + opt->ts, IPOPT_NOP, iph[opt->ts + 1]); |
|---|
| 76 | 76 | opt->ts = 0; |
|---|
| 77 | 77 | opt->ts_needaddr = opt->ts_needtime = 0; |
|---|
| 78 | 78 | } |
|---|
| .. | .. |
|---|
| 473 | 473 | *info = htonl((pp_ptr-iph)<<24); |
|---|
| 474 | 474 | return -EINVAL; |
|---|
| 475 | 475 | } |
|---|
| 476 | +EXPORT_SYMBOL(__ip_options_compile); |
|---|
| 476 | 477 | |
|---|
| 477 | 478 | int ip_options_compile(struct net *net, |
|---|
| 478 | 479 | struct ip_options *opt, struct sk_buff *skb) |
|---|
| .. | .. |
|---|
| 494 | 495 | void ip_options_undo(struct ip_options *opt) |
|---|
| 495 | 496 | { |
|---|
| 496 | 497 | if (opt->srr) { |
|---|
| 497 | | - unsigned char *optptr = opt->__data+opt->srr-sizeof(struct iphdr); |
|---|
| 498 | | - memmove(optptr+7, optptr+3, optptr[1]-7); |
|---|
| 499 | | - memcpy(optptr+3, &opt->faddr, 4); |
|---|
| 498 | + unsigned char *optptr = opt->__data + opt->srr - sizeof(struct iphdr); |
|---|
| 499 | + |
|---|
| 500 | + memmove(optptr + 7, optptr + 3, optptr[1] - 7); |
|---|
| 501 | + memcpy(optptr + 3, &opt->faddr, 4); |
|---|
| 500 | 502 | } |
|---|
| 501 | 503 | if (opt->rr_needaddr) { |
|---|
| 502 | | - unsigned char *optptr = opt->__data+opt->rr-sizeof(struct iphdr); |
|---|
| 504 | + unsigned char *optptr = opt->__data + opt->rr - sizeof(struct iphdr); |
|---|
| 505 | + |
|---|
| 503 | 506 | optptr[2] -= 4; |
|---|
| 504 | | - memset(&optptr[optptr[2]-1], 0, 4); |
|---|
| 507 | + memset(&optptr[optptr[2] - 1], 0, 4); |
|---|
| 505 | 508 | } |
|---|
| 506 | 509 | if (opt->ts) { |
|---|
| 507 | | - unsigned char *optptr = opt->__data+opt->ts-sizeof(struct iphdr); |
|---|
| 510 | + unsigned char *optptr = opt->__data + opt->ts - sizeof(struct iphdr); |
|---|
| 511 | + |
|---|
| 508 | 512 | if (opt->ts_needtime) { |
|---|
| 509 | 513 | optptr[2] -= 4; |
|---|
| 510 | | - memset(&optptr[optptr[2]-1], 0, 4); |
|---|
| 511 | | - if ((optptr[3]&0xF) == IPOPT_TS_PRESPEC) |
|---|
| 514 | + memset(&optptr[optptr[2] - 1], 0, 4); |
|---|
| 515 | + if ((optptr[3] & 0xF) == IPOPT_TS_PRESPEC) |
|---|
| 512 | 516 | optptr[2] -= 4; |
|---|
| 513 | 517 | } |
|---|
| 514 | 518 | if (opt->ts_needaddr) { |
|---|
| 515 | 519 | optptr[2] -= 4; |
|---|
| 516 | | - memset(&optptr[optptr[2]-1], 0, 4); |
|---|
| 520 | + memset(&optptr[optptr[2] - 1], 0, 4); |
|---|
| 517 | 521 | } |
|---|
| 518 | 522 | } |
|---|
| 519 | 523 | } |
|---|
| 520 | 524 | |
|---|
| 521 | | -static struct ip_options_rcu *ip_options_get_alloc(const int optlen) |
|---|
| 525 | +int ip_options_get(struct net *net, struct ip_options_rcu **optp, |
|---|
| 526 | + sockptr_t data, int optlen) |
|---|
| 522 | 527 | { |
|---|
| 523 | | - return kzalloc(sizeof(struct ip_options_rcu) + ((optlen + 3) & ~3), |
|---|
| 524 | | - GFP_KERNEL); |
|---|
| 525 | | -} |
|---|
| 528 | + struct ip_options_rcu *opt; |
|---|
| 526 | 529 | |
|---|
| 527 | | -static int ip_options_get_finish(struct net *net, struct ip_options_rcu **optp, |
|---|
| 528 | | - struct ip_options_rcu *opt, int optlen) |
|---|
| 529 | | -{ |
|---|
| 530 | + opt = kzalloc(sizeof(struct ip_options_rcu) + ((optlen + 3) & ~3), |
|---|
| 531 | + GFP_KERNEL); |
|---|
| 532 | + if (!opt) |
|---|
| 533 | + return -ENOMEM; |
|---|
| 534 | + if (optlen && copy_from_sockptr(opt->opt.__data, data, optlen)) { |
|---|
| 535 | + kfree(opt); |
|---|
| 536 | + return -EFAULT; |
|---|
| 537 | + } |
|---|
| 538 | + |
|---|
| 530 | 539 | while (optlen & 3) |
|---|
| 531 | 540 | opt->opt.__data[optlen++] = IPOPT_END; |
|---|
| 532 | 541 | opt->opt.optlen = optlen; |
|---|
| .. | .. |
|---|
| 537 | 546 | kfree(*optp); |
|---|
| 538 | 547 | *optp = opt; |
|---|
| 539 | 548 | return 0; |
|---|
| 540 | | -} |
|---|
| 541 | | - |
|---|
| 542 | | -int ip_options_get_from_user(struct net *net, struct ip_options_rcu **optp, |
|---|
| 543 | | - unsigned char __user *data, int optlen) |
|---|
| 544 | | -{ |
|---|
| 545 | | - struct ip_options_rcu *opt = ip_options_get_alloc(optlen); |
|---|
| 546 | | - |
|---|
| 547 | | - if (!opt) |
|---|
| 548 | | - return -ENOMEM; |
|---|
| 549 | | - if (optlen && copy_from_user(opt->opt.__data, data, optlen)) { |
|---|
| 550 | | - kfree(opt); |
|---|
| 551 | | - return -EFAULT; |
|---|
| 552 | | - } |
|---|
| 553 | | - return ip_options_get_finish(net, optp, opt, optlen); |
|---|
| 554 | | -} |
|---|
| 555 | | - |
|---|
| 556 | | -int ip_options_get(struct net *net, struct ip_options_rcu **optp, |
|---|
| 557 | | - unsigned char *data, int optlen) |
|---|
| 558 | | -{ |
|---|
| 559 | | - struct ip_options_rcu *opt = ip_options_get_alloc(optlen); |
|---|
| 560 | | - |
|---|
| 561 | | - if (!opt) |
|---|
| 562 | | - return -ENOMEM; |
|---|
| 563 | | - if (optlen) |
|---|
| 564 | | - memcpy(opt->opt.__data, data, optlen); |
|---|
| 565 | | - return ip_options_get_finish(net, optp, opt, optlen); |
|---|
| 566 | 549 | } |
|---|
| 567 | 550 | |
|---|
| 568 | 551 | void ip_forward_options(struct sk_buff *skb) |
|---|