예제 #1
0
파일: compare.go 프로젝트: ably-forks/flynn
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
}
예제 #2
0
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
}
예제 #3
0
// 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
}
예제 #4
0
파일: gce.go 프로젝트: simia-tech/iris
// Updates the network mask with the real on from the cloud config.
func updateIPNet(ipnet *net.IPNet) error {
	// Retrieve the configuration ids
	projectId, err := fetchProjectId()
	if err != nil {
		return err
	}
	networkId, err := fetchNetworkId()
	if err != nil {
		return err
	}
	// Create a service account connection to the GCE API
	client, err := serviceaccount.NewClient(&serviceaccount.Options{})
	if err != nil {
		return err
	}
	gce, err := compute.New(client)
	if err != nil {
		return err
	}
	// Fetch the network configurations and update the netmask
	network, err := gce.Networks.Get(projectId, networkId).Do()
	if err != nil {
		return err
	}
	_, ipn, err := net.ParseCIDR(network.IPv4Range)
	if err != nil {
		return err
	}
	ipnet.Mask = ipn.Mask
	return nil
}
예제 #5
0
파일: acl.go 프로젝트: firelyu/docker_auth
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
	}
}
예제 #6
0
// 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
}
예제 #7
0
파일: ip.go 프로젝트: vmware/vic
// 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
}
예제 #8
0
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
}
예제 #9
0
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
}
예제 #10
0
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
}
예제 #11
0
// 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
}
예제 #12
0
// Creates a new bootstrapper, configuring to listen on the given interface for
// for incoming requests and scan the same interface for other peers. The magic
// is used to filter multiple Iris networks in the same physical network, while
// the overlay is the TCP listener port of the DHT.
func New(ipnet *net.IPNet, magic []byte, owner *big.Int, endpoint int) (*Bootstrapper, chan *Event, error) {
	logger := log15.New("subsys", "bootstrap", "ipnet", ipnet)
	gobber := gobber.New()
	gobber.Init(new(Message))

	// Do some environment dependent IP black magic
	if detectGoogleComputeEngine() {
		// Google Compute Engine issues /32 addresses, find real subnet
		logger.Info("detected GCE, retrieving real netmask")
		old := ipnet.String()
		if err := updateIPNet(ipnet); err != nil {
			logger.Error("failed to retrieve netmask, defaulting", "error", err)
			ipnet.Mask = ipnet.IP.DefaultMask()
		}
		logger.Info("network subnet mask replaced", "old", old, "new", ipnet)
		logger = log15.New("subsys", "bootstrap", "ipnet", ipnet)
	}
	b := &Bootstrapper{
		ipnet: ipnet,
		magic: magic,
		beats: make(chan *Event, config.BootBeatsBuffer),
		phase: uint32(0),

		gob:      gobber,
		request:  newBootstrapRequest(magic, owner, endpoint, gobber),
		response: newBootstrapResponse(magic, owner, endpoint, gobber),

		// Seeding algorithms and address sinks
		scanSeed:   newScanSeeder(ipnet, logger),
		probeSeed:  newProbeSeeder(ipnet, logger),
		coreOSSeed: newCoreOSSeeder(ipnet, logger),
		scanSink:   make(chan *net.IPAddr, config.BootSeedSinkBuffer),
		probeSink:  make(chan *net.IPAddr, config.BootSeedSinkBuffer),
		coreOSSink: make(chan *net.IPAddr, config.BootSeedSinkBuffer),

		// Maintenance fields
		quit: make(chan chan error),
		log:  logger,
	}
	// Open the server socket
	var err error
	for _, port := range config.BootPorts {
		b.addr, err = net.ResolveUDPAddr("udp", net.JoinHostPort(ipnet.IP.String(), strconv.Itoa(port)))
		if err != nil {
			return nil, nil, err
		}
		b.sock, err = net.ListenUDP("udp", b.addr)
		if err != nil {
			continue
		} else {
			b.addr.Port = b.sock.LocalAddr().(*net.UDPAddr).Port
			b.mask = &ipnet.Mask
			break
		}
	}
	if err != nil {
		return nil, nil, fmt.Errorf("no available ports")
	}
	// Return the ready-to-boot bootstrapper
	return b, b.beats, nil
}
예제 #13
0
파일: parser.go 프로젝트: zaccone/goSPF
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
}
예제 #14
0
파일: parser.go 프로젝트: zaccone/goSPF
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
}
예제 #15
0
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
}
예제 #16
0
파일: ngrep.go 프로젝트: rjeczalik/fakerpc
// 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]
			}
		}
	}
}