github.com/Andyfoo/golang/x/net@v0.0.0-20190901054642-57c1bf301704/ipv4/header_test.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ipv4
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"net"
    11  	"reflect"
    12  	"runtime"
    13  	"strings"
    14  	"testing"
    15  
    16  	"github.com/Andyfoo/golang/x/net/internal/socket"
    17  )
    18  
    19  type headerTest struct {
    20  	wireHeaderFromKernel          []byte
    21  	wireHeaderToKernel            []byte
    22  	wireHeaderFromTradBSDKernel   []byte
    23  	wireHeaderToTradBSDKernel     []byte
    24  	wireHeaderFromFreeBSD10Kernel []byte
    25  	wireHeaderToFreeBSD10Kernel   []byte
    26  	*Header
    27  }
    28  
    29  var headerLittleEndianTests = []headerTest{
    30  	// TODO(mikio): Add platform dependent wire header formats when
    31  	// we support new platforms.
    32  	{
    33  		wireHeaderFromKernel: []byte{
    34  			0x45, 0x01, 0xbe, 0xef,
    35  			0xca, 0xfe, 0x45, 0xdc,
    36  			0xff, 0x01, 0xde, 0xad,
    37  			172, 16, 254, 254,
    38  			192, 168, 0, 1,
    39  		},
    40  		wireHeaderToKernel: []byte{
    41  			0x45, 0x01, 0xbe, 0xef,
    42  			0xca, 0xfe, 0x45, 0xdc,
    43  			0xff, 0x01, 0xde, 0xad,
    44  			172, 16, 254, 254,
    45  			192, 168, 0, 1,
    46  		},
    47  		wireHeaderFromTradBSDKernel: []byte{
    48  			0x45, 0x01, 0xdb, 0xbe,
    49  			0xca, 0xfe, 0xdc, 0x45,
    50  			0xff, 0x01, 0xde, 0xad,
    51  			172, 16, 254, 254,
    52  			192, 168, 0, 1,
    53  		},
    54  		wireHeaderToTradBSDKernel: []byte{
    55  			0x45, 0x01, 0xef, 0xbe,
    56  			0xca, 0xfe, 0xdc, 0x45,
    57  			0xff, 0x01, 0xde, 0xad,
    58  			172, 16, 254, 254,
    59  			192, 168, 0, 1,
    60  		},
    61  		wireHeaderFromFreeBSD10Kernel: []byte{
    62  			0x45, 0x01, 0xef, 0xbe,
    63  			0xca, 0xfe, 0xdc, 0x45,
    64  			0xff, 0x01, 0xde, 0xad,
    65  			172, 16, 254, 254,
    66  			192, 168, 0, 1,
    67  		},
    68  		wireHeaderToFreeBSD10Kernel: []byte{
    69  			0x45, 0x01, 0xef, 0xbe,
    70  			0xca, 0xfe, 0xdc, 0x45,
    71  			0xff, 0x01, 0xde, 0xad,
    72  			172, 16, 254, 254,
    73  			192, 168, 0, 1,
    74  		},
    75  		Header: &Header{
    76  			Version:  Version,
    77  			Len:      HeaderLen,
    78  			TOS:      1,
    79  			TotalLen: 0xbeef,
    80  			ID:       0xcafe,
    81  			Flags:    DontFragment,
    82  			FragOff:  1500,
    83  			TTL:      255,
    84  			Protocol: 1,
    85  			Checksum: 0xdead,
    86  			Src:      net.IPv4(172, 16, 254, 254),
    87  			Dst:      net.IPv4(192, 168, 0, 1),
    88  		},
    89  	},
    90  
    91  	// with option headers
    92  	{
    93  		wireHeaderFromKernel: []byte{
    94  			0x46, 0x01, 0xbe, 0xf3,
    95  			0xca, 0xfe, 0x45, 0xdc,
    96  			0xff, 0x01, 0xde, 0xad,
    97  			172, 16, 254, 254,
    98  			192, 168, 0, 1,
    99  			0xff, 0xfe, 0xfe, 0xff,
   100  		},
   101  		wireHeaderToKernel: []byte{
   102  			0x46, 0x01, 0xbe, 0xf3,
   103  			0xca, 0xfe, 0x45, 0xdc,
   104  			0xff, 0x01, 0xde, 0xad,
   105  			172, 16, 254, 254,
   106  			192, 168, 0, 1,
   107  			0xff, 0xfe, 0xfe, 0xff,
   108  		},
   109  		wireHeaderFromTradBSDKernel: []byte{
   110  			0x46, 0x01, 0xdb, 0xbe,
   111  			0xca, 0xfe, 0xdc, 0x45,
   112  			0xff, 0x01, 0xde, 0xad,
   113  			172, 16, 254, 254,
   114  			192, 168, 0, 1,
   115  			0xff, 0xfe, 0xfe, 0xff,
   116  		},
   117  		wireHeaderToTradBSDKernel: []byte{
   118  			0x46, 0x01, 0xf3, 0xbe,
   119  			0xca, 0xfe, 0xdc, 0x45,
   120  			0xff, 0x01, 0xde, 0xad,
   121  			172, 16, 254, 254,
   122  			192, 168, 0, 1,
   123  			0xff, 0xfe, 0xfe, 0xff,
   124  		},
   125  		wireHeaderFromFreeBSD10Kernel: []byte{
   126  			0x46, 0x01, 0xf3, 0xbe,
   127  			0xca, 0xfe, 0xdc, 0x45,
   128  			0xff, 0x01, 0xde, 0xad,
   129  			172, 16, 254, 254,
   130  			192, 168, 0, 1,
   131  			0xff, 0xfe, 0xfe, 0xff,
   132  		},
   133  		wireHeaderToFreeBSD10Kernel: []byte{
   134  			0x46, 0x01, 0xf3, 0xbe,
   135  			0xca, 0xfe, 0xdc, 0x45,
   136  			0xff, 0x01, 0xde, 0xad,
   137  			172, 16, 254, 254,
   138  			192, 168, 0, 1,
   139  			0xff, 0xfe, 0xfe, 0xff,
   140  		},
   141  		Header: &Header{
   142  			Version:  Version,
   143  			Len:      HeaderLen + 4,
   144  			TOS:      1,
   145  			TotalLen: 0xbef3,
   146  			ID:       0xcafe,
   147  			Flags:    DontFragment,
   148  			FragOff:  1500,
   149  			TTL:      255,
   150  			Protocol: 1,
   151  			Checksum: 0xdead,
   152  			Src:      net.IPv4(172, 16, 254, 254),
   153  			Dst:      net.IPv4(192, 168, 0, 1),
   154  			Options:  []byte{0xff, 0xfe, 0xfe, 0xff},
   155  		},
   156  	},
   157  }
   158  
   159  func TestMarshalHeader(t *testing.T) {
   160  	for i, tt := range []struct {
   161  		h   *Header
   162  		err error
   163  	}{
   164  		{nil, errNilHeader},
   165  		{&Header{Len: HeaderLen - 1}, errHeaderTooShort},
   166  	} {
   167  		if _, err := tt.h.Marshal(); err != tt.err {
   168  			t.Errorf("#%d: got %v; want %v", i, err, tt.err)
   169  		}
   170  	}
   171  
   172  	if socket.NativeEndian != binary.LittleEndian {
   173  		t.Skip("no test for non-little endian machine yet")
   174  	}
   175  	for _, tt := range headerLittleEndianTests {
   176  		b, err := tt.Header.Marshal()
   177  		if err != nil {
   178  			t.Fatal(err)
   179  		}
   180  		var wh []byte
   181  		switch runtime.GOOS {
   182  		case "darwin", "dragonfly", "netbsd":
   183  			wh = tt.wireHeaderToTradBSDKernel
   184  		case "freebsd":
   185  			switch {
   186  			case freebsdVersion < 1000000:
   187  				wh = tt.wireHeaderToTradBSDKernel
   188  			case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
   189  				wh = tt.wireHeaderToFreeBSD10Kernel
   190  			default:
   191  				wh = tt.wireHeaderToKernel
   192  			}
   193  		default:
   194  			wh = tt.wireHeaderToKernel
   195  		}
   196  		if !bytes.Equal(b, wh) {
   197  			t.Fatalf("got %#v; want %#v", b, wh)
   198  		}
   199  	}
   200  }
   201  
   202  func TestParseHeader(t *testing.T) {
   203  	for i, tt := range []struct {
   204  		h   *Header
   205  		wh  []byte
   206  		err error
   207  	}{
   208  		{nil, nil, errNilHeader},
   209  		{&Header{}, nil, errNilHeader},
   210  		{&Header{}, make([]byte, HeaderLen-1), errHeaderTooShort},
   211  		{&Header{}, []byte{
   212  			0x46, 0x00, 0x00, 0x00,
   213  			0x00, 0x00, 0x00, 0x00,
   214  			0x00, 0x00, 0x00, 0x00,
   215  			0x00, 0x00, 0x00, 0x00,
   216  			0x00, 0x00, 0x00, 0x00,
   217  		}, errExtHeaderTooShort},
   218  	} {
   219  		if err := tt.h.Parse(tt.wh); err != tt.err {
   220  			t.Fatalf("#%d: got %v; want %v", i, err, tt.err)
   221  		}
   222  	}
   223  
   224  	if socket.NativeEndian != binary.LittleEndian {
   225  		t.Skip("no test for big endian machine yet")
   226  	}
   227  	for _, tt := range headerLittleEndianTests {
   228  		var wh []byte
   229  		switch runtime.GOOS {
   230  		case "darwin", "dragonfly", "netbsd":
   231  			wh = tt.wireHeaderFromTradBSDKernel
   232  		case "freebsd":
   233  			switch {
   234  			case freebsdVersion < 1000000:
   235  				wh = tt.wireHeaderFromTradBSDKernel
   236  			case 1000000 <= freebsdVersion && freebsdVersion < 1100000:
   237  				wh = tt.wireHeaderFromFreeBSD10Kernel
   238  			default:
   239  				wh = tt.wireHeaderFromKernel
   240  			}
   241  		default:
   242  			wh = tt.wireHeaderFromKernel
   243  		}
   244  		h, err := ParseHeader(wh)
   245  		if err != nil {
   246  			t.Fatal(err)
   247  		}
   248  		if err := h.Parse(wh); err != nil {
   249  			t.Fatal(err)
   250  		}
   251  		if !reflect.DeepEqual(h, tt.Header) {
   252  			t.Fatalf("got %#v; want %#v", h, tt.Header)
   253  		}
   254  		s := h.String()
   255  		if strings.Contains(s, ",") {
   256  			t.Fatalf("should be space-separated values: %s", s)
   257  		}
   258  	}
   259  }