|
7 | 7 | package netstack |
8 | 8 |
|
9 | 9 | import ( |
10 | | - "math" |
11 | | - |
12 | 10 | "github.com/celzero/firestack/intra/core" |
13 | 11 | "github.com/celzero/firestack/intra/log" |
14 | 12 | "gvisor.dev/gvisor/pkg/buffer" |
@@ -482,157 +480,6 @@ func (f *icmpForwarder) icmpErr6(id stack.TransportEndpointID, pkt *stack.Packet |
482 | 480 | return werr |
483 | 481 | } |
484 | 482 |
|
485 | | -// github.com/google/gvisor/blob/738e1d995f/pkg/tcpip/network/ipv4/ipv4.go#L2007 |
486 | | -// optionAction describes possible actions that may be taken on an option |
487 | | -// while processing it. |
488 | | -type optionAction uint8 |
489 | | - |
490 | | -const ( |
491 | | - // optionRemove says that the option should not be in the output option set. |
492 | | - optionRemove optionAction = iota |
493 | | - |
494 | | - // optionProcess says that the option should be fully processed. |
495 | | - optionProcess |
496 | | - |
497 | | - // optionVerify says the option should be checked and passed unchanged. |
498 | | - optionVerify |
499 | | - |
500 | | - // optionPass says to pass the output set without checking. |
501 | | - optionPass |
502 | | -) |
503 | | - |
504 | | -// github.com/google/gvisor/blob/738e1d995f6/pkg/tcpip/network/ipv4/ipv4.go#L2026 |
505 | | -// optionActions list what to do for each option in a given scenario. |
506 | | -type optionActions struct { |
507 | | - // timestamp controls what to do with a Timestamp option. |
508 | | - timestamp optionAction |
509 | | - |
510 | | - // recordRoute controls what to do with a Record Route option. |
511 | | - recordRoute optionAction |
512 | | - |
513 | | - // routerAlert controls what to do with a Router Alert option. |
514 | | - routerAlert optionAction |
515 | | - |
516 | | - // unknown controls what to do with an unknown option. |
517 | | - unknown optionAction |
518 | | -} |
519 | | - |
520 | | -func (f *icmpForwarder) ipOpts(pkt *stack.PacketBuffer, iph header.IPv4) (o header.IPv4Options) { |
521 | | - if opts := iph.Options(); len(opts) != 0 { |
522 | | - // RFC 1122 section 3.2.2.6 (page 43) (and similar for other round trip |
523 | | - // type ICMP packets): |
524 | | - // If a Record Route and/or Time Stamp option is received in an |
525 | | - // ICMP Echo Request, this option (these options) SHOULD be |
526 | | - // updated to include the current host and included in the IP |
527 | | - // header of the Echo Reply message, without "truncation". |
528 | | - // Thus, the recorded route will be for the entire round trip. |
529 | | - // |
530 | | - // So we need to let the option processor know how it should handle them. |
531 | | - echoOps := optionActions{ |
532 | | - timestamp: optionProcess, |
533 | | - recordRoute: optionProcess, |
534 | | - routerAlert: optionVerify, |
535 | | - unknown: optionRemove, |
536 | | - } |
537 | | - var ierr *header.IPv4OptParameterProblem |
538 | | - o, ierr = f.processIPOptions(pkt, opts, echoOps) |
539 | | - if ierr != nil { // always nil for now |
540 | | - log.E("icmp: v4: %s: ipOpts: %v", f.o, ierr) |
541 | | - } |
542 | | - copied := copy(opts, o) |
543 | | - for i := copied; i < len(opts); i++ { |
544 | | - // Pad with 0 (EOL). RFC 791 page 23 says "The padding is zero". |
545 | | - opts[i] = byte(header.IPv4OptionListEndType) |
546 | | - } |
547 | | - } |
548 | | - return |
549 | | -} |
550 | | - |
551 | | -// from: github.com/google/gvisor/blob/738e1d995f/pkg/tcpip/network/ipv4/ipv4.go#L2318 |
552 | | -// processIPOptions parses the IPv4 options and produces a new set of options |
553 | | -// suitable for use in the next step of packet processing as informed by usage. |
554 | | -// The original will not be touched. |
555 | | -// |
556 | | -// If there were no errors during parsing, the new set of options is returned as |
557 | | -// a new buffer. |
558 | | -func (f *icmpForwarder) processIPOptions(pkt *stack.PacketBuffer, opts header.IPv4Options, usage optionActions) (header.IPv4Options, *header.IPv4OptParameterProblem) { |
559 | | - optIter := opts.MakeIterator() |
560 | | - |
561 | | - // Except NOP, each option must only appear at most once (RFC 791 section 3.1, |
562 | | - // at the definition of every type). |
563 | | - // Keep track of each option we find to enable duplicate option detection. |
564 | | - var seenOptions [math.MaxUint8 + 1]bool |
565 | | - |
566 | | - for { |
567 | | - option, done, optProblem := optIter.Next() |
568 | | - if done || optProblem != nil { |
569 | | - return optIter.Finalize(), optProblem |
570 | | - } |
571 | | - if option == nil { // nilaway |
572 | | - return nil, &header.IPv4OptParameterProblem{ |
573 | | - Pointer: optIter.ErrCursor, |
574 | | - NeedICMP: true, |
575 | | - } |
576 | | - } |
577 | | - optType := option.Type() |
578 | | - if optType == header.IPv4OptionNOPType { |
579 | | - optIter.PushNOPOrEnd(optType) |
580 | | - continue |
581 | | - } |
582 | | - if optType == header.IPv4OptionListEndType { |
583 | | - optIter.PushNOPOrEnd(optType) |
584 | | - return optIter.Finalize(), nil |
585 | | - } |
586 | | - |
587 | | - // check for repeating options (multiple NOPs are OK) |
588 | | - if seenOptions[optType] { |
589 | | - return nil, &header.IPv4OptParameterProblem{ |
590 | | - Pointer: optIter.ErrCursor, |
591 | | - NeedICMP: true, |
592 | | - } |
593 | | - } |
594 | | - seenOptions[optType] = true |
595 | | - |
596 | | - optLen, optProblem := func() (int, *header.IPv4OptParameterProblem) { |
597 | | - switch option := option.(type) { |
598 | | - case *header.IPv4OptionTimestamp: |
599 | | - if usage.timestamp != optionRemove { |
600 | | - // clock := f.s.Clock() |
601 | | - newBuffer := optIter.InitReplacement(option) |
602 | | - // todo: optProblem := handleTimestamp(header.IPv4OptionTimestamp(newBuffer), localAddress, clock, usage) |
603 | | - return len(newBuffer), nil |
604 | | - } |
605 | | - |
606 | | - case *header.IPv4OptionRecordRoute: |
607 | | - if usage.recordRoute != optionRemove { |
608 | | - newBuffer := optIter.InitReplacement(option) |
609 | | - // todo: optProblem := handleRecordRoute(header.IPv4OptionRecordRoute(newBuffer), localAddress, usage) |
610 | | - return len(newBuffer), nil |
611 | | - } |
612 | | - |
613 | | - case *header.IPv4OptionRouterAlert: |
614 | | - if usage.routerAlert != optionRemove { |
615 | | - newBuffer := optIter.InitReplacement(option) |
616 | | - // todo: optProblem := handleRouterAlert(header.IPv4OptionRouterAlert(newBuffer)) |
617 | | - return len(newBuffer), nil |
618 | | - } |
619 | | - |
620 | | - default: |
621 | | - if usage.unknown == optionPass { |
622 | | - return len(optIter.InitReplacement(option)), nil |
623 | | - } |
624 | | - } |
625 | | - return 0, nil |
626 | | - }() |
627 | | - |
628 | | - if optProblem != nil { |
629 | | - optProblem.Pointer += optIter.ErrCursor |
630 | | - return nil, optProblem |
631 | | - } |
632 | | - optIter.ConsumeBuffer(optLen) |
633 | | - } |
634 | | -} |
635 | | - |
636 | 483 | func loge(err tcpip.Error) (f log.LogFn) { |
637 | 484 | f = log.E |
638 | 485 | if err == nil { |
|
0 commit comments