OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [ip.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 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
// IP address manipulations
6
//
7
// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
8
// An IPv4 address can be converted to an IPv6 address by
9
// adding a canonical prefix (10 zeros, 2 0xFFs).
10
// This library accepts either size of byte array but always
11
// returns 16-byte addresses.
12
 
13
package net
14
 
15
// IP address lengths (bytes).
16
const (
17
        IPv4len = 4
18
        IPv6len = 16
19
)
20
 
21
// An IP is a single IP address, an array of bytes.
22
// Functions in this package accept either 4-byte (IPv4)
23
// or 16-byte (IPv6) arrays as input.
24
//
25
// Note that in this documentation, referring to an
26
// IP address as an IPv4 address or an IPv6 address
27
// is a semantic property of the address, not just the
28
// length of the byte array: a 16-byte array can still
29
// be an IPv4 address.
30
type IP []byte
31
 
32
// An IP mask is an IP address.
33
type IPMask []byte
34
 
35
// An IPNet represents an IP network.
36
type IPNet struct {
37
        IP   IP     // network number
38
        Mask IPMask // network mask
39
}
40
 
41
// IPv4 returns the IP address (in 16-byte form) of the
42
// IPv4 address a.b.c.d.
43
func IPv4(a, b, c, d byte) IP {
44
        p := make(IP, IPv6len)
45
        copy(p, v4InV6Prefix)
46
        p[12] = a
47
        p[13] = b
48
        p[14] = c
49
        p[15] = d
50
        return p
51
}
52
 
53
var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
54
 
55
// IPv4Mask returns the IP mask (in 4-byte form) of the
56
// IPv4 mask a.b.c.d.
57
func IPv4Mask(a, b, c, d byte) IPMask {
58
        p := make(IPMask, IPv4len)
59
        p[0] = a
60
        p[1] = b
61
        p[2] = c
62
        p[3] = d
63
        return p
64
}
65
 
66
// CIDRMask returns an IPMask consisting of `ones' 1 bits
67
// followed by 0s up to a total length of `bits' bits.
68
// For a mask of this form, CIDRMask is the inverse of IPMask.Size.
69
func CIDRMask(ones, bits int) IPMask {
70
        if bits != 8*IPv4len && bits != 8*IPv6len {
71
                return nil
72
        }
73
        if ones < 0 || ones > bits {
74
                return nil
75
        }
76
        l := bits / 8
77
        m := make(IPMask, l)
78
        n := uint(ones)
79
        for i := 0; i < l; i++ {
80
                if n >= 8 {
81
                        m[i] = 0xff
82
                        n -= 8
83
                        continue
84
                }
85
                m[i] = ^byte(0xff >> n)
86
                n = 0
87
        }
88
        return m
89
}
90
 
91
// Well-known IPv4 addresses
92
var (
93
        IPv4bcast     = IPv4(255, 255, 255, 255) // broadcast
94
        IPv4allsys    = IPv4(224, 0, 0, 1)       // all systems
95
        IPv4allrouter = IPv4(224, 0, 0, 2)       // all routers
96
        IPv4zero      = IPv4(0, 0, 0, 0)         // all zeros
97
)
98
 
99
// Well-known IPv6 addresses
100
var (
101
        IPv6zero                   = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
102
        IPv6unspecified            = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
103
        IPv6loopback               = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
104
        IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
105
        IPv6linklocalallnodes      = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
106
        IPv6linklocalallrouters    = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
107
)
108
 
109
// IsUnspecified returns true if ip is an unspecified address.
110
func (ip IP) IsUnspecified() bool {
111
        if ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified) {
112
                return true
113
        }
114
        return false
115
}
116
 
117
// IsLoopback returns true if ip is a loopback address.
118
func (ip IP) IsLoopback() bool {
119
        if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
120
                return true
121
        }
122
        return ip.Equal(IPv6loopback)
123
}
124
 
125
// IsMulticast returns true if ip is a multicast address.
126
func (ip IP) IsMulticast() bool {
127
        if ip4 := ip.To4(); ip4 != nil && ip4[0]&0xf0 == 0xe0 {
128
                return true
129
        }
130
        return ip[0] == 0xff
131
}
132
 
133
// IsInterfaceLinkLocalMulticast returns true if ip is
134
// an interface-local multicast address.
135
func (ip IP) IsInterfaceLocalMulticast() bool {
136
        return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
137
}
138
 
139
// IsLinkLocalMulticast returns true if ip is a link-local
140
// multicast address.
141
func (ip IP) IsLinkLocalMulticast() bool {
142
        if ip4 := ip.To4(); ip4 != nil && ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0 {
143
                return true
144
        }
145
        return ip[0] == 0xff && ip[1]&0x0f == 0x02
146
}
147
 
148
// IsLinkLocalUnicast returns true if ip is a link-local
149
// unicast address.
150
func (ip IP) IsLinkLocalUnicast() bool {
151
        if ip4 := ip.To4(); ip4 != nil && ip4[0] == 169 && ip4[1] == 254 {
152
                return true
153
        }
154
        return ip[0] == 0xfe && ip[1]&0xc0 == 0x80
155
}
156
 
157
// IsGlobalUnicast returns true if ip is a global unicast
158
// address.
159
func (ip IP) IsGlobalUnicast() bool {
160
        return !ip.IsUnspecified() &&
161
                !ip.IsLoopback() &&
162
                !ip.IsMulticast() &&
163
                !ip.IsLinkLocalUnicast()
164
}
165
 
166
// Is p all zeros?
167
func isZeros(p IP) bool {
168
        for i := 0; i < len(p); i++ {
169
                if p[i] != 0 {
170
                        return false
171
                }
172
        }
173
        return true
174
}
175
 
176
// To4 converts the IPv4 address ip to a 4-byte representation.
177
// If ip is not an IPv4 address, To4 returns nil.
178
func (ip IP) To4() IP {
179
        if len(ip) == IPv4len {
180
                return ip
181
        }
182
        if len(ip) == IPv6len &&
183
                isZeros(ip[0:10]) &&
184
                ip[10] == 0xff &&
185
                ip[11] == 0xff {
186
                return ip[12:16]
187
        }
188
        return nil
189
}
190
 
191
// To16 converts the IP address ip to a 16-byte representation.
192
// If ip is not an IP address (it is the wrong length), To16 returns nil.
193
func (ip IP) To16() IP {
194
        if len(ip) == IPv4len {
195
                return IPv4(ip[0], ip[1], ip[2], ip[3])
196
        }
197
        if len(ip) == IPv6len {
198
                return ip
199
        }
200
        return nil
201
}
202
 
203
// Default route masks for IPv4.
204
var (
205
        classAMask = IPv4Mask(0xff, 0, 0, 0)
206
        classBMask = IPv4Mask(0xff, 0xff, 0, 0)
207
        classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
208
)
209
 
210
// DefaultMask returns the default IP mask for the IP address ip.
211
// Only IPv4 addresses have default masks; DefaultMask returns
212
// nil if ip is not a valid IPv4 address.
213
func (ip IP) DefaultMask() IPMask {
214
        if ip = ip.To4(); ip == nil {
215
                return nil
216
        }
217
        switch true {
218
        case ip[0] < 0x80:
219
                return classAMask
220
        case ip[0] < 0xC0:
221
                return classBMask
222
        default:
223
                return classCMask
224
        }
225
        return nil // not reached
226
}
227
 
228
func allFF(b []byte) bool {
229
        for _, c := range b {
230
                if c != 0xff {
231
                        return false
232
                }
233
        }
234
        return true
235
}
236
 
237
// Mask returns the result of masking the IP address ip with mask.
238
func (ip IP) Mask(mask IPMask) IP {
239
        if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
240
                mask = mask[12:]
241
        }
242
        if len(mask) == IPv4len && len(ip) == IPv6len && bytesEqual(ip[:12], v4InV6Prefix) {
243
                ip = ip[12:]
244
        }
245
        n := len(ip)
246
        if n != len(mask) {
247
                return nil
248
        }
249
        out := make(IP, n)
250
        for i := 0; i < n; i++ {
251
                out[i] = ip[i] & mask[i]
252
        }
253
        return out
254
}
255
 
256
// String returns the string form of the IP address ip.
257
// If the address is an IPv4 address, the string representation
258
// is dotted decimal ("74.125.19.99").  Otherwise the representation
259
// is IPv6 ("2001:4860:0:2001::68").
260
func (ip IP) String() string {
261
        p := ip
262
 
263
        if len(ip) == 0 {
264
                return ""
265
        }
266
 
267
        // If IPv4, use dotted notation.
268
        if p4 := p.To4(); len(p4) == IPv4len {
269
                return itod(uint(p4[0])) + "." +
270
                        itod(uint(p4[1])) + "." +
271
                        itod(uint(p4[2])) + "." +
272
                        itod(uint(p4[3]))
273
        }
274
        if len(p) != IPv6len {
275
                return "?"
276
        }
277
 
278
        // Find longest run of zeros.
279
        e0 := -1
280
        e1 := -1
281
        for i := 0; i < IPv6len; i += 2 {
282
                j := i
283
                for j < IPv6len && p[j] == 0 && p[j+1] == 0 {
284
                        j += 2
285
                }
286
                if j > i && j-i > e1-e0 {
287
                        e0 = i
288
                        e1 = j
289
                }
290
        }
291
        // The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
292
        if e1-e0 <= 2 {
293
                e0 = -1
294
                e1 = -1
295
        }
296
 
297
        // Print with possible :: in place of run of zeros
298
        var s string
299
        for i := 0; i < IPv6len; i += 2 {
300
                if i == e0 {
301
                        s += "::"
302
                        i = e1
303
                        if i >= IPv6len {
304
                                break
305
                        }
306
                } else if i > 0 {
307
                        s += ":"
308
                }
309
                s += itox((uint(p[i])<<8)|uint(p[i+1]), 1)
310
        }
311
        return s
312
}
313
 
314
// Equal returns true if ip and x are the same IP address.
315
// An IPv4 address and that same address in IPv6 form are
316
// considered to be equal.
317
func (ip IP) Equal(x IP) bool {
318
        if len(ip) == len(x) {
319
                return bytesEqual(ip, x)
320
        }
321
        if len(ip) == IPv4len && len(x) == IPv6len {
322
                return bytesEqual(x[0:12], v4InV6Prefix) && bytesEqual(ip, x[12:])
323
        }
324
        if len(ip) == IPv6len && len(x) == IPv4len {
325
                return bytesEqual(ip[0:12], v4InV6Prefix) && bytesEqual(ip[12:], x)
326
        }
327
        return false
328
}
329
 
330
func bytesEqual(x, y []byte) bool {
331
        if len(x) != len(y) {
332
                return false
333
        }
334
        for i, b := range x {
335
                if y[i] != b {
336
                        return false
337
                }
338
        }
339
        return true
340
}
341
 
342
// If mask is a sequence of 1 bits followed by 0 bits,
343
// return the number of 1 bits.
344
func simpleMaskLength(mask IPMask) int {
345
        var n int
346
        for i, v := range mask {
347
                if v == 0xff {
348
                        n += 8
349
                        continue
350
                }
351
                // found non-ff byte
352
                // count 1 bits
353
                for v&0x80 != 0 {
354
                        n++
355
                        v <<= 1
356
                }
357
                // rest must be 0 bits
358
                if v != 0 {
359
                        return -1
360
                }
361
                for i++; i < len(mask); i++ {
362
                        if mask[i] != 0 {
363
                                return -1
364
                        }
365
                }
366
                break
367
        }
368
        return n
369
}
370
 
371
// Size returns the number of leading ones and total bits in the mask.
372
// If the mask is not in the canonical form--ones followed by zeros--then
373
// Size returns 0, 0.
374
func (m IPMask) Size() (ones, bits int) {
375
        ones, bits = simpleMaskLength(m), len(m)*8
376
        if ones == -1 {
377
                return 0, 0
378
        }
379
        return
380
}
381
 
382
// String returns the hexadecimal form of m, with no punctuation.
383
func (m IPMask) String() string {
384
        s := ""
385
        for _, b := range m {
386
                s += itox(uint(b), 2)
387
        }
388
        if len(s) == 0 {
389
                return ""
390
        }
391
        return s
392
}
393
 
394
func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
395
        if ip = n.IP.To4(); ip == nil {
396
                ip = n.IP
397
                if len(ip) != IPv6len {
398
                        return nil, nil
399
                }
400
        }
401
        m = n.Mask
402
        switch len(m) {
403
        case IPv4len:
404
                if len(ip) != IPv4len {
405
                        return nil, nil
406
                }
407
        case IPv6len:
408
                if len(ip) == IPv4len {
409
                        m = m[12:]
410
                }
411
        default:
412
                return nil, nil
413
        }
414
        return
415
}
416
 
417
// Contains reports whether the network includes ip.
418
func (n *IPNet) Contains(ip IP) bool {
419
        nn, m := networkNumberAndMask(n)
420
        if x := ip.To4(); x != nil {
421
                ip = x
422
        }
423
        l := len(ip)
424
        if l != len(nn) {
425
                return false
426
        }
427
        for i := 0; i < l; i++ {
428
                if nn[i]&m[i] != ip[i]&m[i] {
429
                        return false
430
                }
431
        }
432
        return true
433
}
434
 
435
// String returns the CIDR notation of n like "192.168.100.1/24"
436
// or "2001:DB8::/48" as defined in RFC 4632 and RFC 4291.
437
// If the mask is not in the canonical form, it returns the
438
// string which consists of an IP address, followed by a slash
439
// character and a mask expressed as hexadecimal form with no
440
// punctuation like "192.168.100.1/c000ff00".
441
func (n *IPNet) String() string {
442
        nn, m := networkNumberAndMask(n)
443
        if nn == nil || m == nil {
444
                return ""
445
        }
446
        l := simpleMaskLength(m)
447
        if l == -1 {
448
                return nn.String() + "/" + m.String()
449
        }
450
        return nn.String() + "/" + itod(uint(l))
451
}
452
 
453
// Network returns the address's network name, "ip+net".
454
func (n *IPNet) Network() string { return "ip+net" }
455
 
456
// Parse IPv4 address (d.d.d.d).
457
func parseIPv4(s string) IP {
458
        var p [IPv4len]byte
459
        i := 0
460
        for j := 0; j < IPv4len; j++ {
461
                if i >= len(s) {
462
                        // Missing octets.
463
                        return nil
464
                }
465
                if j > 0 {
466
                        if s[i] != '.' {
467
                                return nil
468
                        }
469
                        i++
470
                }
471
                var (
472
                        n  int
473
                        ok bool
474
                )
475
                n, i, ok = dtoi(s, i)
476
                if !ok || n > 0xFF {
477
                        return nil
478
                }
479
                p[j] = byte(n)
480
        }
481
        if i != len(s) {
482
                return nil
483
        }
484
        return IPv4(p[0], p[1], p[2], p[3])
485
}
486
 
487
// Parse IPv6 address.  Many forms.
488
// The basic form is a sequence of eight colon-separated
489
// 16-bit hex numbers separated by colons,
490
// as in 0123:4567:89ab:cdef:0123:4567:89ab:cdef.
491
// Two exceptions:
492
//      * A run of zeros can be replaced with "::".
493
//      * The last 32 bits can be in IPv4 form.
494
// Thus, ::ffff:1.2.3.4 is the IPv4 address 1.2.3.4.
495
func parseIPv6(s string) IP {
496
        p := make(IP, IPv6len)
497
        ellipsis := -1 // position of ellipsis in p
498
        i := 0         // index in string s
499
 
500
        // Might have leading ellipsis
501
        if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
502
                ellipsis = 0
503
                i = 2
504
                // Might be only ellipsis
505
                if i == len(s) {
506
                        return p
507
                }
508
        }
509
 
510
        // Loop, parsing hex numbers followed by colon.
511
        j := 0
512
        for j < IPv6len {
513
                // Hex number.
514
                n, i1, ok := xtoi(s, i)
515
                if !ok || n > 0xFFFF {
516
                        return nil
517
                }
518
 
519
                // If followed by dot, might be in trailing IPv4.
520
                if i1 < len(s) && s[i1] == '.' {
521
                        if ellipsis < 0 && j != IPv6len-IPv4len {
522
                                // Not the right place.
523
                                return nil
524
                        }
525
                        if j+IPv4len > IPv6len {
526
                                // Not enough room.
527
                                return nil
528
                        }
529
                        p4 := parseIPv4(s[i:])
530
                        if p4 == nil {
531
                                return nil
532
                        }
533
                        p[j] = p4[12]
534
                        p[j+1] = p4[13]
535
                        p[j+2] = p4[14]
536
                        p[j+3] = p4[15]
537
                        i = len(s)
538
                        j += IPv4len
539
                        break
540
                }
541
 
542
                // Save this 16-bit chunk.
543
                p[j] = byte(n >> 8)
544
                p[j+1] = byte(n)
545
                j += 2
546
 
547
                // Stop at end of string.
548
                i = i1
549
                if i == len(s) {
550
                        break
551
                }
552
 
553
                // Otherwise must be followed by colon and more.
554
                if s[i] != ':' || i+1 == len(s) {
555
                        return nil
556
                }
557
                i++
558
 
559
                // Look for ellipsis.
560
                if s[i] == ':' {
561
                        if ellipsis >= 0 { // already have one
562
                                return nil
563
                        }
564
                        ellipsis = j
565
                        if i++; i == len(s) { // can be at end
566
                                break
567
                        }
568
                }
569
        }
570
 
571
        // Must have used entire string.
572
        if i != len(s) {
573
                return nil
574
        }
575
 
576
        // If didn't parse enough, expand ellipsis.
577
        if j < IPv6len {
578
                if ellipsis < 0 {
579
                        return nil
580
                }
581
                n := IPv6len - j
582
                for k := j - 1; k >= ellipsis; k-- {
583
                        p[k+n] = p[k]
584
                }
585
                for k := ellipsis + n - 1; k >= ellipsis; k-- {
586
                        p[k] = 0
587
                }
588
        }
589
        return p
590
}
591
 
592
// A ParseError represents a malformed text string and the type of string that was expected.
593
type ParseError struct {
594
        Type string
595
        Text string
596
}
597
 
598
func (e *ParseError) Error() string {
599
        return "invalid " + e.Type + ": " + e.Text
600
}
601
 
602
func parseIP(s string) IP {
603
        if p := parseIPv4(s); p != nil {
604
                return p
605
        }
606
        if p := parseIPv6(s); p != nil {
607
                return p
608
        }
609
        return nil
610
}
611
 
612
// ParseIP parses s as an IP address, returning the result.
613
// The string s can be in dotted decimal ("74.125.19.99")
614
// or IPv6 ("2001:4860:0:2001::68") form.
615
// If s is not a valid textual representation of an IP address,
616
// ParseIP returns nil.
617
func ParseIP(s string) IP {
618
        if p := parseIPv4(s); p != nil {
619
                return p
620
        }
621
        return parseIPv6(s)
622
}
623
 
624
// ParseCIDR parses s as a CIDR notation IP address and mask,
625
// like "192.168.100.1/24" or "2001:DB8::/48", as defined in
626
// RFC 4632 and RFC 4291.
627
//
628
// It returns the IP address and the network implied by the IP
629
// and mask.  For example, ParseCIDR("192.168.100.1/16") returns
630
// the IP address 192.168.100.1 and the network 192.168.0.0/16.
631
func ParseCIDR(s string) (IP, *IPNet, error) {
632
        i := byteIndex(s, '/')
633
        if i < 0 {
634
                return nil, nil, &ParseError{"CIDR address", s}
635
        }
636
        ipstr, maskstr := s[:i], s[i+1:]
637
        iplen := IPv4len
638
        ip := parseIPv4(ipstr)
639
        if ip == nil {
640
                iplen = IPv6len
641
                ip = parseIPv6(ipstr)
642
        }
643
        n, i, ok := dtoi(maskstr, 0)
644
        if ip == nil || !ok || i != len(maskstr) || n < 0 || n > 8*iplen {
645
                return nil, nil, &ParseError{"CIDR address", s}
646
        }
647
        m := CIDRMask(n, 8*iplen)
648
        return ip, &IPNet{ip.Mask(m), m}, nil
649
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.