func (c *CIDRs) UnmarshalBinary(b []byte) error { if len(b) < 1 { return fmt.Errorf("compare: missing type byte") } if b[0] != byte(TypeCIDRs) { return fmt.Errorf("compare: expected type %d, got %d", TypeCIDRs, b[0]) } b = b[1:] *c = make(CIDRs, 0, len(b)/ipv4CIDRLen) for len(b) > 0 { var n net.IPNet if b[0]&(1<<7) == 0 { // check top bit of ones byte, if 0, IPv4, if 1, IPv6 if len(b) < ipv4CIDRLen { return fmt.Errorf("compare: unexpected end of buffer decoding IPv4 CIDR") } n.Mask = net.CIDRMask(int(b[0]), ipv4Len*8) n.IP = net.IPv4(b[1], b[2], b[3], b[4]) b = b[5:] } else { if len(b) < ipv6CIDRLen { return fmt.Errorf("compare: unexpected end of buffer decoding IPv6 CIDR") } n.Mask = net.CIDRMask(int(b[0]&^(1<<7)), ipv6Len*8) n.IP = make([]byte, ipv6Len) copy(n.IP, b[1:]) b = b[ipv6CIDRLen:] } *c = append(*c, n) } return nil }
// hasIP6Connected parses the list of remote addresses in /proc/net/{tcp,udp}6 or in // /proc/<pid>/net/{tcp,udp}6 and returns addresses that are contained within // the ipnet submitted. It always uses CIDR inclusion, even when only // searching for a single IP (but assuming a /128 bitmask). // Remote addresses exposed in /proc are in hexadecimal notation, and converted into byte slices // to use in ipnet.Contains() func hasIP6Connected(ip net.IP, ipnet *net.IPNet) (found bool, elements []element, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("hasIP6Connected(): %v", e) } }() lns, err := procIP6Entries() if err != nil { panic(err) } // if the ipnet is nil, assume that its a full 128bits mask if ipnet == nil { ipnet = new(net.IPNet) ipnet.IP = ip ipnet.Mask = net.CIDRMask(net.IPv6len*8, net.IPv6len*8) } for _, ipent := range lns { fields := strings.Fields(ipent.line) if len(fields) < 4 { panic("/proc doesn't respect the expected format") } remote := strings.Split(fields[2], ":") if len(remote) != 2 { panic("remote isn't in the form <ip>:<port>") } remoteIP := hexToIP6(remote[0]) if remoteIP == nil { panic("failed to convert remote IP") } // if we've got a match, store the element if ipnet.Contains(remoteIP) { var el element el.RemoteAddr = remoteIP.String() remotePort, err := strconv.ParseUint(remote[1], 16, 16) if err != nil { panic("failed to convert remote port") } el.RemotePort = float64(remotePort) local := strings.Split(fields[1], ":") if len(local) != 2 { panic("local isn't in the form <ip>:<port>") } localAddr := hexToIP6(local[0]) if localAddr == nil { panic("failed to convert local ip") } el.LocalAddr = localAddr.String() localPort, err := strconv.ParseUint(local[1], 16, 16) if err != nil { panic("failed to convert local port") } el.LocalPort = float64(localPort) el.Namespace = ipent.nsIdentifier elements = append(elements, el) found = true } stats.Examined++ } return }
func (a *Allocator) getAddress(nw *net.IPNet, bitmask *bitseq.Handle, prefAddress net.IP, ipr *AddressRange) (net.IP, error) { var ( ordinal uint64 err error base *net.IPNet ) base = types.GetIPNetCopy(nw) if bitmask.Unselected() <= 0 { return nil, ipamapi.ErrNoAvailableIPs } if ipr == nil && prefAddress == nil { ordinal, err = bitmask.SetAny() } else if prefAddress != nil { hostPart, e := types.GetHostPartIP(prefAddress, base.Mask) if e != nil { return nil, fmt.Errorf("failed to allocate preferred address %s: %v", prefAddress.String(), e) } ordinal = ipToUint64(types.GetMinimalIP(hostPart)) err = bitmask.Set(ordinal) } else { base.IP = ipr.Sub.IP ordinal, err = bitmask.SetAnyInRange(ipr.Start, ipr.End) } if err != nil { return nil, ipamapi.ErrNoAvailableIPs } // Convert IP ordinal for this subnet into IP address return generateAddress(ordinal, base), nil }
func decodeInet(vr *ValueReader) net.IPNet { var zero net.IPNet if vr.Len() == -1 { vr.Fatal(ProtocolError("Cannot decode null into net.IPNet")) return zero } if vr.Type().FormatCode != BinaryFormatCode { vr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", vr.Type().FormatCode))) return zero } pgType := vr.Type() if vr.Len() != 8 && vr.Len() != 20 { vr.Fatal(ProtocolError(fmt.Sprintf("Received an invalid size for a %s: %d", pgType.Name, vr.Len()))) return zero } if pgType.DataType != InetOid && pgType.DataType != CidrOid { vr.Fatal(ProtocolError(fmt.Sprintf("Cannot decode oid %v into %s", pgType.DataType, pgType.Name))) return zero } vr.ReadByte() // ignore family bits := vr.ReadByte() vr.ReadByte() // ignore is_cidr addressLength := vr.ReadByte() var ipnet net.IPNet ipnet.IP = vr.ReadBytes(int32(addressLength)) ipnet.Mask = net.CIDRMask(int(bits), int(addressLength)*8) return ipnet }
func generateRandomNetwork(address *net.IPNet) string { tick := float64(time.Now().UnixNano() / 1000000) ones, bits := address.Mask.Size() zeros := bits - ones uniqIPsAmount := math.Pow(2.0, float64(zeros)) rawIP := math.Mod(tick, uniqIPsAmount) remainder := rawIP remainder, octet4 := math.Modf(remainder / 255.0) remainder, octet3 := math.Modf(remainder / 255.0) remainder, octet2 := math.Modf(remainder / 255.0) base := address.IP address.IP = net.IPv4( byte(remainder)|base[0], byte(octet2*255)|base[1], byte(octet3*255)|base[2], byte(octet4*255)|base[3], ) address.IP.Mask(address.Mask) return address.String() }
// SpanningCIDR computes network covers given IP addresses func SpanningCIDR(first, last net.IP) *net.IPNet { _, bits := last.DefaultMask().Size() var network net.IPNet for ones := bits; !network.Contains(first); ones-- { network.Mask = net.CIDRMask(ones, bits) network.IP = last.Mask(network.Mask) } return &network }
// ParseIPandMask parses a CIDR format address (e.g. 1.1.1.1/8) func ParseIPandMask(s string) (net.IPNet, error) { var i net.IPNet ip, ipnet, err := net.ParseCIDR(s) if err != nil { return i, err } i.IP = ip i.Mask = ipnet.Mask return i, nil }
// highestIP4 returns the highest possible IP address // in an IP network. For example: // // highestIP4(net.IPNet{}IP: net.ParseIP("172.16.0.0"), Mask: net.CIDRMask(16, 32)}) -> 172.16.255.255 // func highestIP4(ipRange *net.IPNet) net.IP { if !isIP4(ipRange.IP) { return nil } newIP := net.IPv4(0, 0, 0, 0) ipRange.IP = ipRange.IP.To4() for i := 0; i < len(ipRange.Mask); i++ { newIP[i+12] = ipRange.IP[i] | ^ipRange.Mask[i] } return newIP }
func parseIPPattern(ipp string) (*net.IPNet, error) { ipnet := net.IPNet{} ipnet.IP = net.ParseIP(ipp) if ipnet.IP != nil { if ipnet.IP.To4() != nil { ipnet.Mask = net.CIDRMask(32, 32) } else { ipnet.Mask = net.CIDRMask(128, 128) } return &ipnet, nil } else { _, ipnet, err := net.ParseCIDR(ipp) if err != nil { return nil, err } return ipnet, nil } }
func decodeInetArray(vr *ValueReader) []net.IPNet { if vr.Len() == -1 { return nil } if vr.Type().DataType != InetArrayOid && vr.Type().DataType != CidrArrayOid { vr.Fatal(ProtocolError(fmt.Sprintf("Cannot decode oid %v into []net.IP", vr.Type().DataType))) return nil } if vr.Type().FormatCode != BinaryFormatCode { vr.Fatal(ProtocolError(fmt.Sprintf("Unknown field description format code: %v", vr.Type().FormatCode))) return nil } numElems, err := decode1dArrayHeader(vr) if err != nil { vr.Fatal(err) return nil } a := make([]net.IPNet, int(numElems)) for i := 0; i < len(a); i++ { elSize := vr.ReadInt32() if elSize == -1 { vr.Fatal(ProtocolError("Cannot decode null element")) return nil } vr.ReadByte() // ignore family bits := vr.ReadByte() vr.ReadByte() // ignore is_cidr addressLength := vr.ReadByte() var ipnet net.IPNet ipnet.IP = vr.ReadBytes(int32(addressLength)) ipnet.Mask = net.CIDRMask(int(bits), int(addressLength)*8) a[i] = ipnet } return a }
func hasSeenIP6(ip net.IP, ipnet *net.IPNet) (found bool, elements []element, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("hasSeenIP6(): %v", e) } }() lns, err := procArpEntries() if err != nil { panic(err) } // if the ipnet is nil, assume that its a full 128bits mask if ipnet == nil { ipnet = new(net.IPNet) ipnet.IP = ip ipnet.Mask = net.CIDRMask(net.IPv6len*8, net.IPv6len*8) } for _, arpent := range lns { fields := strings.Fields(arpent.line) if len(fields) < 4 { continue } remoteIP := net.ParseIP(fields[0]) if remoteIP == nil { panic("failed to convert remote IP") } // if we've got a match, store the element if ipnet.Contains(remoteIP) { var el element el.RemoteAddr = remoteIP.String() el.RemoteMACAddr = fields[3] el.Namespace = arpent.nsIdentifier elements = append(elements, el) found = true } stats.Examined++ } return }
func encodeInet(w *WriteBuf, value interface{}) error { var ipnet net.IPNet switch value := value.(type) { case net.IPNet: ipnet = value case net.IP: ipnet.IP = value bitCount := len(value) * 8 ipnet.Mask = net.CIDRMask(bitCount, bitCount) default: return fmt.Errorf("Expected net.IPNet, received %T %v", value, value) } var size int32 var family byte switch len(ipnet.IP) { case net.IPv4len: size = 8 family = w.conn.pgsql_af_inet case net.IPv6len: size = 20 family = w.conn.pgsql_af_inet6 default: return fmt.Errorf("Unexpected IP length: %v", len(ipnet.IP)) } w.WriteInt32(size) w.WriteByte(family) ones, _ := ipnet.Mask.Size() w.WriteByte(byte(ones)) w.WriteByte(0) // is_cidr is ignored on server w.WriteByte(byte(len(ipnet.IP))) w.WriteBytes(ipnet.IP) return nil }
func HasIPConnected(val string) (found bool, elements []element, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("HasIPConnected(): %v", e) } }() found = false var ipnet *net.IPNet // if val contains a /, treat it as a cidr if strings.IndexAny(val, "/") > 0 { _, ipnet, err = net.ParseCIDR(val) if err != nil { panic(err) } // otherwise assume it's a single address (v4 /32 or v6 /128) } else { ip := net.ParseIP(val) if ip == nil { panic("Invalid IP") } ipnet = new(net.IPNet) ipnet.IP = ip ipnet.Mask = net.CIDRMask(len(ip), len(ip)) } var fam string if len(ipnet.IP) == 4 { fam = "inet" } else { fam = "inet6" } out, err := exec.Command("netstat", "-naW", "-f", fam).Output() if err != nil { panic(err) } buf := bytes.NewReader(out) reader := bufio.NewReader(buf) for { lineBytes, _, err := reader.ReadLine() if err != nil { break } line := fmt.Sprintf("%s", lineBytes) fields := strings.Fields(line) if len(fields) <= 4 { continue } localIP, localPort, err := parseEndpointString(fields[3]) if err != nil { break } remoteIP, remotePort, err := parseEndpointString(fields[4]) if err != nil { break } if remoteIP != nil && ipnet.Contains(remoteIP) { var el element el.RemoteAddr = remoteIP.String() if remotePort != -1 { el.RemotePort = float64(remotePort) } if localIP != nil { el.LocalAddr = localIP.String() } if localPort != -1 { el.LocalPort = float64(localPort) } elements = append(elements, el) found = true } stats.Examined++ } return }
func (p *Parser) parseMX(t *Token) (bool, SPFResult) { result, _ := matchingResult(t.Qualifier) domain := p.setDomain(t) var host string var v4Network *net.IPMask var v6Network *net.IPMask var ok bool ok, host, v4Network, v6Network = splitToHostNetwork(domain) host = NormalizeHost(host) // return Permerror if there was syntax error if !ok { return true, Permerror } var err error // TODO(zaccone): Ensure returned errors are correct. query := new(dns.Msg) query.SetQuestion(host, dns.TypeMX) c := new(dns.Client) response, _, err := c.Exchange(query, Nameserver) if err != nil { fmt.Println(err) return false, None } if response != nil && response.Rcode != dns.RcodeSuccess { if response.Rcode != dns.RcodeNameError { return true, Temperror } else { fmt.Println(err) return false, None } } mxs := make([]string, 0, len(response.Answer)) for _, answer := range response.Answer { if mx, ok := answer.(*dns.MX); ok { mxs = append(mxs, mx.Mx) } } var wg sync.WaitGroup pipe := make(chan bool) wg.Add(len(mxs)) go func() { wg.Wait() close(pipe) }() for _, mmx := range mxs { go func(mx string, v4Network, v6Network *net.IPMask) { defer wg.Done() mx = NormalizeHost(mx) v4Ipnet := net.IPNet{} v4Ipnet.Mask = *v4Network v6Ipnet := net.IPNet{} v6Ipnet.Mask = *v6Network ips4 := make([]net.IP, 0, 1) ips6 := make([]net.IP, 0, 1) var queries [2]dns.Msg queries[0].SetQuestion(mx, dns.TypeA) queries[1].SetQuestion(mx, dns.TypeAAAA) for _, query := range queries { c := new(dns.Client) response, _, err := c.Exchange(&query, Nameserver) if err != nil { pipe <- false return } if response != nil && response.Rcode != dns.RcodeSuccess { pipe <- false return } for _, answer := range response.Answer { if ans, ok := answer.(*dns.A); ok { ips4 = append(ips4, ans.A) } else if ans, ok := answer.(*dns.AAAA); ok { ips6 = append(ips6, ans.AAAA) } } } var contains bool for _, address := range ips4 { v4Ipnet.IP = address contains = v4Ipnet.Contains(p.IP) pipe <- contains } for _, address := range ips6 { v6Ipnet.IP = address contains = v6Ipnet.Contains(p.IP) pipe <- contains } }(mmx, v4Network, v6Network) } verdict := false for subverdict := range pipe { verdict = verdict || subverdict } return verdict, result }
func (p *Parser) parseA(t *Token) (bool, SPFResult) { result, _ := matchingResult(t.Qualifier) domain := p.setDomain(t) var host string var v4Network *net.IPMask var v6Network *net.IPMask var ok bool ips4 := make([]net.IP, 0, 1) ips6 := make([]net.IP, 0, 1) ok, host, v4Network, v6Network = splitToHostNetwork(domain) host = NormalizeHost(host) // return Permerror if there was syntax error if !ok { return true, Permerror } var queries [2]dns.Msg queries[0].SetQuestion(host, dns.TypeA) queries[1].SetQuestion(host, dns.TypeAAAA) for _, query := range queries { c := new(dns.Client) r, _, err := c.Exchange(&query, Nameserver) if err != nil { fmt.Println(err) return true, Temperror } if r != nil && r.Rcode != dns.RcodeSuccess { if r.Rcode != dns.RcodeNameError { fmt.Println(r) return true, Temperror } else { return false, None } } else { for _, answer := range r.Answer { if ans, ok := answer.(*dns.A); ok { ips4 = append(ips4, ans.A) } else if ans, ok := answer.(*dns.AAAA); ok { ips6 = append(ips6, ans.AAAA) } } } } v4Ipnet := net.IPNet{} v4Ipnet.Mask = *v4Network v6Ipnet := net.IPNet{} v6Ipnet.Mask = *v6Network for _, address := range ips4 { v4Ipnet.IP = address if v4Ipnet.Contains(p.IP) { return true, result } } for _, address := range ips6 { v6Ipnet.IP = address if v6Ipnet.Contains(p.IP) { return true, result } } return false, result }
// Parses the command line flags and checks their validity func parseFlags() (int, string, *rsa.PrivateKey, net.Addr) { var ( rsaKey *rsa.PrivateKey ifAddr *net.IPNet ) // Read the command line arguments flag.Usage = usage flag.Parse() // Check the relay port range if *relayPort <= 0 || *relayPort >= 65536 { fmt.Fprintf(os.Stderr, "Invalid relay port: have %v, want [1-65535].\n", *relayPort) os.Exit(-1) } // User random cluster id and RSA key in developer mode if *devMode { // Generate a secure RSA key fmt.Printf("Entering developer mode\n") fmt.Printf("Generating random RSA key... ") if key, err := rsa.GenerateKey(rand.Reader, 2048); err != nil { fmt.Printf("failed: %v\n", err) os.Exit(-2) } else { fmt.Printf("done.\n") rsaKey = key } // Generate a probably unique cluster name fmt.Printf("Generating random cluster name... ") *clusterName = fmt.Sprintf("dev-cluster-%v", rng.Int63()) fmt.Printf("done.\n") fmt.Println() } else { // Production mode, read the cluster id and RSA key from teh arguments if *clusterName == "" { fmt.Fprintf(os.Stderr, "No cluster specified (-net), did you intend developer mode (-dev)?\n") os.Exit(-1) } if *rsaKeyPath == "" { fmt.Fprintf(os.Stderr, "No RSA key specified (-rsa), did you intend developer mode (-dev)?\n") os.Exit(-1) } if rsaData, err := ioutil.ReadFile(*rsaKeyPath); err != nil { fmt.Fprintf(os.Stderr, "Reading RSA key failed: %v.\n", err) os.Exit(-1) } else { // Try processing as PEM format if block, _ := pem.Decode(rsaData); block != nil { if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { fmt.Fprintf(os.Stderr, "Parsing RSA key from PEM format failed: %v.\n", err) os.Exit(-1) } else { rsaKey = key } } else { // Give it a shot as simple binary DER if key, err := x509.ParsePKCS1PrivateKey(rsaData); err != nil { fmt.Fprintf(os.Stderr, "Failed to parse RSA key from both PEM and DER format.\n") os.Exit(-1) } else { rsaKey = key } } } if *interfaceAddr != "" { var ( ip net.IP err error ) ip, ifAddr, err = net.ParseCIDR(*interfaceAddr) if err != nil { fmt.Fprintf(os.Stderr, "Failed to parse the interface address.\n") os.Exit(-1) } ifAddr.IP = ip } } return *relayPort, *clusterName, rsaKey, ifAddr }
// hasIP6Connected parse the list of remote addresses in /proc/net/{tcp,udp}6 and returns addresses // that are contained within the ipnet submitted. It always uses CIDR inclusion, even when only // searching for a single IP (but assuming a /128 bitmask). // Remote addresses exposed in /proc are in hexadecimal notation, and converted into byte slices // to use in ipnet.Contains() func hasIP6Connected(ip net.IP, ipnet *net.IPNet) (found bool, elements []element, err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("hasIP6Connected(): %v", e) } }() var connfiles = [...]string{`/proc/net/tcp6`, `/proc/net/udp6`} // if the ipnet is nil, assume that its a full 128bits mask if ipnet == nil { ipnet = new(net.IPNet) ipnet.IP = ip ipnet.Mask = net.CIDRMask(net.IPv6len*8, net.IPv6len*8) } for _, f := range connfiles { fd, err := os.Open(f) defer fd.Close() if err != nil { panic(err) } scanner := bufio.NewScanner(fd) scanner.Scan() // skip the header for scanner.Scan() { if err := scanner.Err(); err != nil { panic(err) } fields := strings.Fields(scanner.Text()) if len(fields) < 4 { panic("/proc doesn't respect the expected format") } remote := strings.Split(fields[2], ":") if len(remote) != 2 { panic("remote isn't in the form <ip>:<port>") } remoteIP := hexToIP6(remote[0]) if remoteIP == nil { panic("failed to convert remote IP") } // if we've got a match, store the element if ipnet.Contains(remoteIP) { var el element el.RemoteAddr = remoteIP.String() remotePort, err := strconv.ParseUint(remote[1], 16, 16) if err != nil { panic("failed to convert remote port") } el.RemotePort = float64(remotePort) local := strings.Split(fields[1], ":") if len(local) != 2 { panic("local isn't in the form <ip>:<port>") } localAddr := hexToIP6(local[0]) if localAddr == nil { panic("failed to convert local ip") } el.LocalAddr = localAddr.String() localPort, err := strconv.ParseUint(local[1], 16, 16) if err != nil { panic("failed to convert local port") } el.LocalPort = float64(localPort) elements = append(elements, el) found = true } stats.Examined++ } } return }
// NewPrefix returns a new prefix. func NewPrefix(n *net.IPNet) *Prefix { n.IP = n.IP.To16() return &Prefix{IPNet: *n} }
// NgrepUnmarshal parses the ngrep output read from r and stores the result // in the l. func NgrepUnmarshal(r io.Reader, l *Log) error { type state uint8 const ( stHead state = iota stT stRaw ) var ( t *Transmission buf = bufio.NewReader(r) st = stHead ) for { b, err := buf.ReadBytes('\n') if len(b) == 0 { if err == io.EOF { return nil } if err != nil { return err } } switch st { case stRaw: if len(b) == 1 && b[0] == '\n' { st = stT continue } if b[len(b)-2] == '.' { b[len(b)-2] = '\r' } t.Raw = append(t.Raw, b...) case stT: if m := tre.FindStringSubmatch(string(b)); m != nil { l.T = append(l.T, Transmission{}) t = &l.T[len(l.T)-1] if t.Src, err = parseAddr(m[1]); err != nil { return err } if t.Dst, err = parseAddr(m[2]); err != nil { return err } st = stRaw } case stHead: if len(b) == 1 && b[0] == '\n' { st = stT continue } line := string(b) if m := headre[0].FindStringSubmatch(line); m != nil { var network net.IPNet if network.IP = net.ParseIP(m[1]); network.IP == nil { return errors.New("ill-formed IP " + m[1]) } mask := net.ParseIP(m[2]) if mask == nil { return errors.New("ill-formed IP mask " + m[2]) } network.Mask = iptomask(mask) l.Networks = []*net.IPNet{&network} } else if m := headre[1].FindStringSubmatch(line); m != nil { l.Filter = m[1] } } } }