-
Notifications
You must be signed in to change notification settings - Fork 3
/
GoIPQSDBReader.go
106 lines (83 loc) · 2.6 KB
/
GoIPQSDBReader.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package GoIPQSDBReader;
import (
"os";
"bytes";
"errors";
"encoding/binary";
);
var GOLANG_IPQS_READER_VERSION = byte(1);
func Open(filename string) (*FileReader, error) {
file := &FileReader{Columns: make(map[int]*Column)};
var ferr error;
fileBytes, ferr := os.ReadFile(filename)
if ferr != nil {
return file, ferr
}
file.Handler = *bytes.NewReader(fileBytes)
header := make([]byte, 11);
bl, err := file.Handler.Read(header);
if(err != nil || bl != 11){
return file, err;
}
fileheader := &BinaryOption{Data: Bit(header[0])};
file.BinaryData = fileheader.Has(BinaryData);
if(fileheader.Has(IPv4Map)){
file.Valid = true;
file.IPv6 = false;
}
if(fileheader.Has(IPv6Map)){
file.Valid = true;
file.IPv6 = true;
}
if(fileheader.Has(IsBlacklistFile)){
file.BlacklistFile = true;
}
if(file.Valid == false){
return file, errors.New("Invalid file format, invalid first byte, EID 1.");
}
if(header[1] != GOLANG_IPQS_READER_VERSION){
return file, errors.New("Invalid file version, EID 1.");
}
bytedata, _ := binary.Uvarint(header[2:5]);
if(bytedata == uint64(0)){
return file, errors.New("Invalid file format, invalid header bytes, EID 2.");
}
file.RecordBytes, _ = binary.Uvarint(header[5:7]);
if(file.RecordBytes == uint64(0)){
return file, errors.New("Invalid file format, invalid record bytes, EID 3.");
}
file.TotalBytes = uint64(binary.LittleEndian.Uint32(header[7:11]));
if(file.TotalBytes == uint64(0)){
return file, errors.New("Invalid file format, EID 4.");
}
file.TreeStart = int64(bytedata);
columns := make([]byte, bytedata - 11);
bl, err = file.Handler.Read(columns);
if(err != nil || bl != (int(bytedata) - 11)){
return file, err;
}
for i:=0;i<((int(bytedata) - 11)/24);i++ {
file.Columns[i] = &Column{
Name: string(bytes.Trim(columns[(i*24):((i+1)*24)-2], "\x00")),
Type: &RecordType{Data: Bit(columns[(i*24)+23:((i+1)*24)][0])},
};
}
if(len(file.Columns) == 0){
return file, errors.New("File does not appear to be valid, no column data found. EID: 5");
}
treeheader := make([]byte, 5);
bl, err = file.Handler.Read(treeheader);
if(err != nil || bl != 5){
return file, err;
}
treetype := &RecordType{Data: Bit(treeheader[0])};
if(!treetype.Has(TreeData)){
return file, errors.New("File does not appear to be valid, bad binary tree. EID: 6");
}
totaltree := uint64(binary.LittleEndian.Uint32(treeheader[1:5]));
if(totaltree == 0){
return file, errors.New("File does not appear to be valid, tree size is too small. EID: 7");
}
file.TreeEnd = file.TreeStart + int64(totaltree);
return file, nil;
}