2016-10-24 4 views
-1

원본 IP 및 대상 IP에 대한 정보를 nfcapd 바이너리 파일에서 가져와야합니다. 문제는 파일 크기입니다. io 또는 os 패키지로 매우 큰 (1GB 이상) 파일을 열어서 읽는 것은 바람직하지 않다는 것을 알고 있습니다. 나는 동시에 netflowpackage 함께 읽은 후 24 플로우 및 프로세스를 가진 덩어리로 파일을 분할 할큰 nfcapd 바이너리 파일에서 IP 주소 받기

package main 

import (
    "fmt" 
    "time" 
    "os" 
    "github.com/tehmaze/netflow/netflow5" 
    "log" 
    "io" 
    "bytes" 
) 

type Message interface {} 

func main() { 
    startTime := time.Now() 
    getFile := os.Args[1] 
    processFile(getFile) 
    endTime := time.Since(startTime) 
    log.Printf("Program executes in %s", endTime) 
} 

func processFile(fileName string) { 
    file, err := os.Open(fileName) 
    // Check if file is not empty. If it is, then exit from program 
    if err != nil { 
     fmt.Println(err) 
     os.Exit(1) 
    } 

    // Useful to close file after getting information about it 
    defer file.Close() 
    Read(file) 
} 

func Read(r io.Reader) (Message, error) { 
    data := [2]byte{} 
    if _, err := r.Read(data[:]); err != nil { 
     return nil, err 
    } 
    buffer := bytes.NewBuffer(data[:]) 
    mr := io.MultiReader(buffer, r) 
    return netflow5.Read(mr) 
} 

:

은 여기 내 해킹 및 초안 시작이다. 그러나 나는 분열 중에 어떤 데이터도 잃지 않고 그것을하는 방법을 상상하지 못합니다.

코드 또는 설명에 무엇인가 놓친 경우 저를 고쳐주십시오. 나는 웹에서 내 솔루션을 검색하고 다른 가능한 구현에 대해 생각할 때 많은 시간을 보냅니다.

도움이나 조언을 주시면 대단히 감사하겠습니다.

Date first seen   Duration Proto  Src IP Addr:Port   Dst IP Addr:Port Packets Bytes Flows 

모든 속성 자체 열이다 명령 nfdump -r <file_name>

file_name: application/octet-stream; charset=binary

파일의 출력은 다음 구조를 갖는다 :

파일은 다음과 같은 특성 (단말기 명령 file -I <file_name>)을 갖는다.

UPDATE 1 : 불행히도, nfcapd를 통해 디스크에 저장 한 후 때문에 바이너리 파일 구조의 차이에 NetFlow를 패키지 파일을 구문 분석하는 impossible입니다. 이 답변은 nfdump 명의 기여자 중 one에 의해 제공되었습니다.

유일한 방법은 pynfdump과 같은 go 프로그램에서 터미널에서 nfdump를 실행하는 것입니다.

향후 possible 해결책은 gopacket입니다.

+0

이 nfcapd 바이너리 파일의 구조는 무엇입니까? 합리적으로 구조화 된 줄이 포함 된 텍스트 파일입니까? 파일을 효율적으로 읽는 방법을 모르거나 IP 구문 분석과 관련하여 도움이 필요합니까? – HenryTK

+0

내가 GitHub의 요점의 예 출력 파일을 발견했다 : https://gist.githubusercontent.com/asachs/bfbfebdb39b33a5ded61/raw/319f206b29e5b7a046e48768f24b4be0f5e2f07c/gistfile1.txt 나는 그것의 매우 큰 버전을 가정합니다 당신이 다루고있는 것입니다 . – HenryTK

+0

@HenryTK 파일에 대한 추가 정보가 있습니다. 필자는 파일을 효율적으로 읽고 IP를 파싱하는 방법을 알지 못합니다. 나는 골란에 초보자입니다. – memu

답변

0

IO는 파일을 구문 분석 할 때 거의 항상 제한 요소가 될 것이며 계산이 복잡하지 않으면 한 파일을 순차적으로 읽는 것이 처리하는 가장 빠른 방법이 될 것입니다.

랩은 A bufio.Reader에서 파일과는 Read 기능 제공 :이 구문 분석 일단 당신이 별도로 덩어리를 처리해야하는 경우

file, err := os.Open(fileName) 
if err != nil { 
    log.Fatal((err) 
} 
defer file.Close() 

packet, err := netflow5.Read(bufio.NewReader(file)) 

, 그런 다음 레코드를 분할 할 수 있습니다.

+0

상상할 수있는 netflow로이 이진 파일을 읽을 수 없습니다. 이''if if''' 때문에 : https://github.com/tehmaze/netflow/blob/master/netflow5/packet.go#L62 한 번에 전체 파일을 읽을 수 없습니다. 내 목표는 Unmarshall 데이터로 플로우를 보내기 위해 별도로 읽는 것입니다. – memu

+0

@memu : netflow 패키지가 파싱하지 않으면 무언가가 필요합니다. 기본 파싱 없이는 바이너리 파일을 분리 할 수 ​​없습니다. 워크 플로우는 여전히 동일하고 파일을'bufio.Reader'로 랩핑하고 순차적으로 읽습니다. – JimB

+0

"연속 읽기"란 무엇을 의미합니까? 그것은 바이트 배열의 덩어리로 읽고 있습니까? 그렇다면 어떤 크기를 선택해야합니까? – memu