LINUX.ORG.RU

слияние диапазонов ip адресов


0

1

Предположим есть источника групп ip адресов ( в виде диапазонов ) с каким либо признаком. Нужно слить эти 2 источника в один с приоритетом на 1 источник ( соотв группы могут пересекаться неполностью ). преобразовывать эти группы в ip и проверять каждый ip и после сливать в группы дело долгое и неблагодарное. Есть ли более быстрые варианты ?



Последнее исправление: Jopich (всего исправлений: 1)

ЯННП. В каком виде эти адреса хранятся? Что за задача решается, какие инструменты используются?

anonymous
()

Есть ли более быстрые варианты ?

Есть всякие утилитки, например

$ hath reduced <<< "10.0.0.0/24 10.0.1.0/24"
10.0.0.0/23
Правда еще собрать надо, но потом можно и удалит ghc-platform, останется бинарь на пару метров.

anonymous
()

Надо было список мультикастных фидов (IP + port) расфасовать по нескольким диапазонам, чтобы пакетный фильтр в железке настроить (у него штук 5 диапазонов можно было выставить). Смотреть на gen-range-mask и самый внутренний loop:

;; -*- mode:lisp -*-

(defclass packet-filter-base-class (core-base-class) ())

(def-core-setup packet-filter-base-class
  ((mac-ini :settings-name mac :type :string :required nil)
   (feeds :settings-name feeds-file :type :feeds :required nil)
   (udp-payload-only    :type :yes-or-no :default "yes" :required nil))
  (labels ((n-binary-sort (feeds i)
             (loop with ht = (make-hash-table)
                   for feed in feeds
                   for ip = (getf feed :ip)
                   for port = (getf feed :port)
                   do (push (cons ip port) (gethash (ldb (byte (- 32 i) i) ip) ht))
                   finally (return ht)))
           (fit-feeds-in-buckets (feeds)
             (loop for i from 0 below 32
                   for ht = (n-binary-sort feeds i)
                   until (<= (hash-table-count ht) (ip-check-count core))
                   finally (return ht)))
           (gen-range-mask (min max bits)
             (logxor (1- (ash 1 bits))
                     (1- (ash 1 (integer-length (logxor min max))))))
           (find-good-ip/port-masks (feeds)
             ;; find widest port-mask
             (loop with tmp2 =
                ;; hash with key = ip mask, value = list of all possible port masks
               (loop with tmp1 = (make-hash-table)
                     for (net ip-mask port port-mask) in
                     ;; find ip/port masks for all buckets
                      (loop with sorted-feeds = (fit-feeds-in-buckets feeds)
                            for k being each hash-key of sorted-feeds
                            for v = (gethash k sorted-feeds)
                            for (ip-min ip-max port-min port-max)
                            ;; find min/max ip/ports for bucket
                              = (loop for (ip . port) in v
                                      minimize ip into ip-min
                                      maximize ip into ip-max
                                      minimize port into port-min
                                      maximize port into port-max
                                      finally (return (list ip-min ip-max port-min port-max)))
                            for ip-mask = (gen-range-mask ip-min ip-max 32)
                            for port-mask = (gen-range-mask port-min port-max 16)
                            collect (list (logand ip-min ip-mask) ip-mask (logand port-min port-mask)  port-mask))
                     do (push (list net ip-mask port port-mask) (gethash net tmp1))
                     finally (return tmp1))
                   for k being each hash-key of tmp2
                   for v = (gethash k tmp2)
                   for vs = (sort v #'< :key #'cadddr) ;; sort by port-mask
                   collect (car vs))))
    (let* ((slot (mezz-slot (core-chain core)))
           (mac (mac-address-to-string
                 (calculate-mezz-mac (board-parent (gateware-parent (core-parent core)))
                                     slot mac-ini)))
           (buckets (find-good-ip/port-masks feeds)))
      (loop for (net ip-mask port port-mask) in buckets
            collect net into nets
            collect ip-mask into ip-masks
            collect (+ port (ash port-mask 16)) into ports+masks
            finally (setf (ip core) (mapcar #'ip-address-to-string nets)
                          (ip-mask core) (mapcar #'ip-address-to-string ip-masks)
                          (port+mask core) ports+masks))
      (setf (accept-unicast core) :mac-only
            (unicast-mac core) mac
            (udp-payload-only core) udp-payload-only))))

mv ★★★★★
()

Если диапазоны IP-адресов заданы в виде подсетей, то операции их объединения или пересечения можно делать при помощи обхода дерева radix (patricia).

Sorcerer ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.