-
Notifications
You must be signed in to change notification settings - Fork 1
/
17mon.lsp
90 lines (78 loc) · 2.61 KB
/
17mon.lsp
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
;;;; author: lu4nx <lx@shellcodes.org>
;;;; date: 2014-05-28
;;;; 17MonIP for newLisp
(context 'MonIP)
; 转换点分IPv4地址到32位整型表示
(define (ip2long ip)
(let ((ip (parse ip "."))
(long-ip 0))
(dolist (i ip)
(setf long-ip (+ (<< long-ip 8)
(int i))))
long-ip))
; 获得点分IPv4地址的A段号
(define (get-ipv4-a ip)
(int (first (parse ip "."))))
; 判断IP的合法
(define (ip? ip)
(if (regex {^\d+\.\d+\.\d+\.\d+$} ip)
true
nil))
; 获得数据库文件的头偏移
(define (get-offset f)
(read f buf 4)
(first (unpack ">lu" buf)))
; 获得索引数据
(define (get-index-data f offset)
(read f buf (- offset 4))
buf)
; 从索引数据中找到A段地址
(define (get-ip-index-start ip-a index-data)
(first (unpack "<lu"
((* ip-a 4) 4 index-data))))
(define (search-address offset start index-data)
(let ((start-offset (+ 1024 (* start 8)))
(max-len (- offset 1028))
(index-offset nil)
(index-length nil)
(find? nil))
(while (and (< start-offset max-len)
(null? find?))
(setf start-offset (+ 8 start-offset))
(if (>= (start-offset 4 index-data) ip)
(begin
(setf index-offset (first (unpack "<lu"
(append ((+ 4 start-offset)
3
index-data)
(char 0)))))
(setf index-length (first (unpack "c" ((+ 7 start-offset)
1
index-data))))
(setf find? true))))
(if (true? find?)
(list index-offset index-length)
nil)))
; 从IP库中的读出地理位置
(define (get-ip-address f offset index-offset index-length)
(seek f (+ offset (- index-offset 1024)))
(read f buf index-length)
(close f)
(parse buf "\t"))
(define (find-ip ip)
(if (null? (ip? ip))
nil
(begin
(letn ((f (open "17monipdb.dat" "read"))
(offset (get-offset f))
(index-data (get-index-data f offset))
(ip-a (get-ipv4-a ip))
(ip (pack ">lu" (ip2long ip)))
(start (get-ip-index-start ip-a index-data))
(search-result (search-address offset start index-data)))
(if search-result
(get-ip-address f offset (nth 0 search-result) (nth 1 search-result))
nil)))))
(context MAIN)
;; Example
;;(println (MonIP:find-ip "8.8.8.8"))