ipsearch

package module
v0.0.0-...-319b38e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 9, 2023 License: MIT Imports: 9 Imported by: 0

README

This is a simple library to search for IP addresses for two different IP Databases: IP CIDR List and IP Geo CVS, which go

Table of Contents

1. IP Database

This library can deal with the following IP databases:

  • china_ip_list.txt: A list of IP addresses in China. This list is from the China IP List project.

  • asn-country-ipv4.txt: A list of IP addresses and their ASN and country information. This list is from the IP Location DB project.

To update these two data files, run the following script:

./data/update.sh

Note

  • The CIDRs file must be a plain text file, and each line is a CIDR.
  • The CIDRs cannot be overlapped.

2. Usage

2.1 Check an IP address is in the IP CIDR list
package main

import (
	"fmt"
	"github.com/haoel/ipsearch"
)

func main() {
	search, err := ipsearch.NewIPSearchWithFile("./data/china_ip_list.txt", ipsearch.CIDR)
	if err != nil {
		panic(err)
	}

	ipStr := "114.114.114.114"
	ip := search.Search(ipStr)
	if ip != nil {
		fmt.Printf("IP [%s] is in China\n", ipStr)
	} else {
		fmt.Printf("IP [%s] is not China\n", ipStr)
	}
}

It also supports reading the URL files:

url := "https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt"
search, err := ipsearch.NewIPSearchWithURL(url)
2.2 Get the Country Code of an IP address
package main

import (
	"fmt"
	"github.com/haoel/ipsearch"
)

func main() {
	search, err := ipsearch.NewIPSearchWithFile("./data/asn-country-ipv4.csv", ipsearch.Geo)
	if err != nil {
		panic(err)
	}
	ipStr := "8.8.8.8"
	ip := search.Search(ipStr)
	if ip != nil {
		fmt.Printf("IP [%s] Country Code: %s\n", ipStr, ip.Country())
	} else {
		fmt.Printf("IP [%s] is not found!\n", ipStr)
	}
}

3. Technical Details

The IP search is using the Hash Table and Binary Search algorithm.

The key of the hash table is the first 8 bits of the IP address, and the value is the sorted list of CIDRs that have the same first 8 bits.

[  1 ] -> [1.0.1.0/24],
          [1.0.2.0/23],
          [1.1.4.0/22]
          ...
[ 14 ] -> [14.0.0.0/21],
          [14.0.12.0/22],
          [14.1.0.0/22]
          ...

The IPRangeMapList is the hash table that stores all of the sorted CIDRs lists.

For the GeoIP database, it gives the start and end IP address, this would across the multiple hash table keys, so we need to split it.

For example, if the IP range is 1.1.0.0 - 3.2.2.255, we need to split it into three ranges:

  • 1.1.0.0 - 1.255.255.255
  • 2.0.0.0 - 2.255.255.255
  • 3.0.0.0 - 3.2..2.255

The split algorithm is in the IPRange.Split() function in the iprange.go file.

Note

And I didn't use the standard net/netip library, because of the following two reasons:

  • We can be free to customize and extend the algorithm
  • We can port the algorithm to other languages easily.

4. License

This project is MIT licensed. See the LICENSE file for details.

Documentation

Overview

Package ipsearch provides a simple way to search for IP addresses in a

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetIPSegment

func GetIPSegment(ip string, segment int) uint8

GetIPSegment returns the segment of an IP address.

func IPCIDRRange

func IPCIDRRange(cidr string) (uint32, uint32)

IPCIDRRange returns the start and end IP addresses for a CIDR range.

func IPInCIDR

func IPInCIDR(ip string, cidr string) bool

IPInCIDR checks if an IP address is in a CIDR range.

func IPIntToStr

func IPIntToStr(ip uint32) string

IPIntToStr converts an integer IP address to a string.

func IPStrToInt

func IPStrToInt(ipStr string) uint32

IPStrToInt converts a string IP address to an integer.

func ReadFile

func ReadFile(filename string) ([]string, error)

ReadFile reads a ip list file and returns a slice of strings, one for each line.

func ReadFileFromURL

func ReadFileFromURL(url string) ([]string, error)

ReadFileFromURL from a URL and returns a slice of strings, one for each line.

Types

type IPRange

type IPRange struct {
	// contains filtered or unexported fields
}

IPRange represents an IPv4 CIDR range.

func NewIPCIDR

func NewIPCIDR(cidr string) *IPRange

NewIPCIDR creates a new IPv4 CIDR range.

func NewIPGeo

func NewIPGeo(csv string) *IPRange

NewIPGeo creates a new IPv4 CIDR range with a country code.

func NewIPRange

func NewIPRange(line string, rangeType RangeType) *IPRange

NewIPRange creates a new IPRange.

func NewIPRangeSlice

func NewIPRangeSlice(lines []string, rangeType RangeType) []*IPRange

NewIPRangeSlice creates a new slice of IPRange.

func (*IPRange) CIDR

func (ip *IPRange) CIDR() string

CIDR returns the CIDR of the IP range.

func (*IPRange) Country

func (ip *IPRange) Country() string

Country returns the country code of the IP range.

func (*IPRange) Range

func (ip *IPRange) Range() string

Range return the range of the IPs in string format.

func (*IPRange) Split

func (ip *IPRange) Split() []*IPRange

Split splits the IPRange into multiple IPRanges if the first segment is different.

func (*IPRange) String

func (ip *IPRange) String() string

func (*IPRange) Type

func (ip *IPRange) Type() RangeType

Type returns the type of the IP range.

type IPRangeList

type IPRangeList []*IPRange

IPRangeList is a list of IPv4 CIDR ranges.

func NewIPRangeList

func NewIPRangeList(lines []string, rangeType RangeType) IPRangeList

NewIPRangeList creates a new list of IPv4 CIDR ranges.

func (*IPRangeList) Append

func (list *IPRangeList) Append(ip *IPRange)

Append adds a IPv4 range to the list.

func (*IPRangeList) InsertSorted

func (list *IPRangeList) InsertSorted(ip *IPRange)

InsertSorted inserts a IPv4 range to the list, keeping the list sorted.

func (*IPRangeList) Len

func (list *IPRangeList) Len() int

Len returns the length of the list of IPv4 CIDR ranges.

func (*IPRangeList) Range

func (list *IPRangeList) Range() string

Range returns a string representation of the list of IPv4 ranges.

func (*IPRangeList) Search

func (list *IPRangeList) Search(ipStr string) *IPRange

Search search if an IP address is in the list.

func (*IPRangeList) Sort

func (list *IPRangeList) Sort()

Sort sorts the list of IPv4 CIDR ranges.

func (*IPRangeList) String

func (list *IPRangeList) String() string

String returns a string representation of the list of IPv4 CIDR ranges.

type IPRangeMapList

type IPRangeMapList map[uint8]*IPRangeList

IPRangeMapList is a map of lists of IPv4 CIDR ranges.

func NewIPRangeMapList

func NewIPRangeMapList() IPRangeMapList

NewIPRangeMapList creates a new map of lists of IPv4 CIDR ranges.

func (IPRangeMapList) Append

func (m IPRangeMapList) Append(ipRange *IPRange)

Append adds an IPv4 CIDR range to the map of lists of IPv4 CIDR ranges.

func (IPRangeMapList) AppendBatch

func (m IPRangeMapList) AppendBatch(ipRanges []*IPRange)

AppendBatch adds a list of IPv4 CIDR ranges to the map of lists of IPv4 CIDR ranges.

func (IPRangeMapList) InsertSorted

func (m IPRangeMapList) InsertSorted(ipRange *IPRange)

InsertSorted inserts a IPv4 CIDR range to the map of lists of IPv4 CIDR ranges, keeping the lists sorted.

func (IPRangeMapList) InsertSortedCIDRs

func (m IPRangeMapList) InsertSortedCIDRs(ipRanges []*IPRange)

InsertSortedCIDRs inserts a list of IPv4 CIDR ranges to the map of lists of IPv4 CIDR ranges, keeping the lists sorted.

func (IPRangeMapList) Search

func (m IPRangeMapList) Search(ipStr string) *IPRange

Search search if an IP address is in the map of lists.

func (IPRangeMapList) Sort

func (m IPRangeMapList) Sort()

Sort sorts the map of lists of IPv4 CIDR ranges.

type IPSearch

type IPSearch struct {
	// contains filtered or unexported fields
}

IPSearch is a struct that contains a map of IP ranges.

func NewIPSearch

func NewIPSearch(lines []string, rangeType RangeType) *IPSearch

NewIPSearch creates a new IPSearch struct.

func NewIPSearchWithFile

func NewIPSearchWithFile(path string, rangeType RangeType) (*IPSearch, error)

NewIPSearchWithFile creates a new IPSearch struct from a file.

func NewIPSearchWithFileFromURL

func NewIPSearchWithFileFromURL(url string, fileType RangeType) (*IPSearch, error)

NewIPSearchWithFileFromURL creates a new IPSearch struct from a URL.

func (*IPSearch) Search

func (s *IPSearch) Search(ip string) *IPRange

Search search if an IP address is in the map of lists of IPv4 ranges.

type RangeType

type RangeType int

RangeType is the type of file

const (
	// CIDR is a file that contains CIDR ranges
	CIDR RangeType = iota
	// Geo is a file that contains GeoIP ranges and the country code as the CSV format
	Geo
)

Directories

Path Synopsis
package main is the example of using ipsearch.
package main is the example of using ipsearch.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL