]> Cypherpunks.ru repositories - nncp.git/blobdiff - src/cmd/nncp-pkt/main.go
Streamed NNCPE format
[nncp.git] / src / cmd / nncp-pkt / main.go
index 3f42cd260e48a25c2f404b94ea769243f4be68db..c22b1f71038e209bda406fe3c5bf5903420c6291 100644 (file)
@@ -1,6 +1,6 @@
 /*
 NNCP -- Node to Node copy, utilities for store-and-forward data exchange
-Copyright (C) 2016-2020 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2016-2021 Sergey Matveev <stargrave@stargrave.org>
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -29,7 +29,7 @@ import (
 
        xdr "github.com/davecgh/go-xdr/xdr2"
        "github.com/klauspost/compress/zstd"
-       "go.cypherpunks.ru/nncp/v5"
+       "go.cypherpunks.ru/nncp/v8"
 )
 
 func usage() {
@@ -40,6 +40,133 @@ func usage() {
        fmt.Fprintln(os.Stderr, "Packet is read from stdin.")
 }
 
+func doPlain(ctx *nncp.Ctx, pkt nncp.Pkt, dump, decompress bool) {
+       if dump {
+               bufW := bufio.NewWriter(os.Stdout)
+               var r io.Reader
+               r = bufio.NewReader(os.Stdin)
+               if decompress {
+                       decompressor, err := zstd.NewReader(r)
+                       if err != nil {
+                               log.Fatalln(err)
+                       }
+                       r = decompressor
+               }
+               if _, err := io.Copy(bufW, r); err != nil {
+                       log.Fatalln(err)
+               }
+               if err := bufW.Flush(); err != nil {
+                       log.Fatalln(err)
+               }
+               return
+       }
+       payloadType := "unknown"
+       switch pkt.Type {
+       case nncp.PktTypeFile:
+               payloadType = "file"
+       case nncp.PktTypeFreq:
+               payloadType = "file request"
+       case nncp.PktTypeExec:
+               payloadType = "exec compressed"
+       case nncp.PktTypeTrns:
+               payloadType = "transitional"
+       case nncp.PktTypeExecFat:
+               payloadType = "exec uncompressed"
+       case nncp.PktTypeArea:
+               payloadType = "area"
+       }
+       var path string
+       switch pkt.Type {
+       case nncp.PktTypeExec, nncp.PktTypeExecFat:
+               path = string(bytes.Replace(
+                       pkt.Path[:pkt.PathLen], []byte{0}, []byte(" "), -1,
+               ))
+       case nncp.PktTypeTrns:
+               path = nncp.Base32Codec.EncodeToString(pkt.Path[:pkt.PathLen])
+               node, err := ctx.FindNode(path)
+               if err == nil {
+                       path = fmt.Sprintf("%s (%s)", path, node.Name)
+               }
+       case nncp.PktTypeArea:
+               path = nncp.Base32Codec.EncodeToString(pkt.Path[:pkt.PathLen])
+               if areaId, err := nncp.AreaIdFromString(path); err == nil {
+                       path = fmt.Sprintf("%s (%s)", path, ctx.AreaName(areaId))
+               }
+       default:
+               path = string(pkt.Path[:pkt.PathLen])
+       }
+       fmt.Printf(
+               "Packet type: plain\nPayload type: %s\nNiceness: %s (%d)\nPath: %s\n",
+               payloadType, nncp.NicenessFmt(pkt.Nice), pkt.Nice, path,
+       )
+       return
+}
+
+func doEncrypted(
+       ctx *nncp.Ctx,
+       pktEnc nncp.PktEnc,
+       dump bool,
+       beginning []byte,
+) {
+       senderName := "unknown"
+       senderNode := ctx.Neigh[*pktEnc.Sender]
+       if senderNode != nil {
+               senderName = senderNode.Name
+       }
+
+       recipientName := "unknown"
+       var area *nncp.Area
+       recipientNode := ctx.Neigh[*pktEnc.Recipient]
+       if recipientNode == nil {
+               area = ctx.AreaId2Area[nncp.AreaId(*pktEnc.Recipient)]
+               if area != nil {
+                       recipientName = "area " + area.Name
+               }
+       } else {
+               recipientName = recipientNode.Name
+       }
+
+       if !dump {
+               fmt.Printf(`Packet type: encrypted
+Niceness: %s (%d)
+Sender: %s (%s)
+Recipient: %s (%s)
+`,
+                       nncp.NicenessFmt(pktEnc.Nice), pktEnc.Nice,
+                       pktEnc.Sender, senderName,
+                       pktEnc.Recipient, recipientName,
+               )
+               return
+       }
+       if ctx.Self == nil {
+               log.Fatalln("Config lacks private keys")
+       }
+       bufW := bufio.NewWriter(os.Stdout)
+       var err error
+       if area == nil {
+               _, _, _, err = nncp.PktEncRead(
+                       ctx.Self, ctx.Neigh,
+                       io.MultiReader(bytes.NewReader(beginning), bufio.NewReader(os.Stdin)),
+                       bufW, senderNode != nil, nil,
+               )
+       } else {
+               areaNode := nncp.NodeOur{Id: new(nncp.NodeId), ExchPrv: new([32]byte)}
+               copy(areaNode.Id[:], area.Id[:])
+               copy(areaNode.ExchPrv[:], area.Prv[:])
+               _, _, _, err = nncp.PktEncRead(
+                       &areaNode, ctx.Neigh,
+                       io.MultiReader(bytes.NewReader(beginning), bufio.NewReader(os.Stdin)),
+                       bufW, senderNode != nil, nil,
+               )
+       }
+       if err != nil {
+               log.Fatalln(err)
+       }
+       if err = bufW.Flush(); err != nil {
+               log.Fatalln(err)
+       }
+}
+
 func main() {
        var (
                overheads  = flag.Bool("overheads", false, "Print packet overheads")
@@ -49,6 +176,7 @@ func main() {
                version    = flag.Bool("version", false, "Print version information")
                warranty   = flag.Bool("warranty", false, "Print warranty information")
        )
+       log.SetFlags(log.Lshortfile)
        flag.Usage = usage
        flag.Parse()
        if *warranty {
@@ -60,6 +188,11 @@ func main() {
                return
        }
 
+       ctx, err := nncp.CtxFromCmdline(*cfgPath, "", "", false, false, false, false)
+       if err != nil {
+               log.Fatalln("Error during initialization:", err)
+       }
+
        if *overheads {
                fmt.Printf(
                        "Plain: %d\nEncrypted: %d\nSize: %d\n",
@@ -70,97 +203,43 @@ func main() {
                return
        }
 
-       var err error
        beginning := make([]byte, nncp.PktOverhead)
-       if _, err = io.ReadFull(os.Stdin, beginning); err != nil {
+       if _, err := io.ReadFull(os.Stdin, beginning[:nncp.PktEncOverhead]); err != nil {
                log.Fatalln("Not enough data to read")
        }
-       var pkt nncp.Pkt
-       _, err = xdr.Unmarshal(bytes.NewReader(beginning), &pkt)
-       if err == nil && pkt.Magic == nncp.MagicNNCPPv3 {
-               if *dump {
-                       bufW := bufio.NewWriter(os.Stdout)
-                       var r io.Reader
-                       r = bufio.NewReader(os.Stdin)
-                       if *decompress {
-                               decompressor, err := zstd.NewReader(r)
-                               if err != nil {
-                                       log.Fatalln(err)
-                               }
-                               r = decompressor
-                       }
-                       if _, err = io.Copy(bufW, r); err != nil {
-                               log.Fatalln(err)
-                       }
-                       if err = bufW.Flush(); err != nil {
-                               log.Fatalln(err)
-                       }
+       var pktEnc nncp.PktEnc
+       if _, err := xdr.Unmarshal(bytes.NewReader(beginning), &pktEnc); err == nil {
+               switch pktEnc.Magic {
+               case nncp.MagicNNCPEv1.B:
+                       log.Fatalln(nncp.MagicNNCPEv1.TooOld())
+               case nncp.MagicNNCPEv2.B:
+                       log.Fatalln(nncp.MagicNNCPEv2.TooOld())
+               case nncp.MagicNNCPEv3.B:
+                       log.Fatalln(nncp.MagicNNCPEv3.TooOld())
+               case nncp.MagicNNCPEv4.B:
+                       log.Fatalln(nncp.MagicNNCPEv4.TooOld())
+               case nncp.MagicNNCPEv5.B:
+                       log.Fatalln(nncp.MagicNNCPEv5.TooOld())
+               case nncp.MagicNNCPEv6.B:
+                       doEncrypted(ctx, pktEnc, *dump, beginning[:nncp.PktEncOverhead])
                        return
                }
-               payloadType := "unknown"
-               switch pkt.Type {
-               case nncp.PktTypeFile:
-                       payloadType = "file"
-               case nncp.PktTypeFreq:
-                       payloadType = "file request"
-               case nncp.PktTypeExec:
-                       payloadType = "exec"
-               case nncp.PktTypeTrns:
-                       payloadType = "transitional"
-               }
-               var path string
-               switch pkt.Type {
-               case nncp.PktTypeExec:
-                       path = string(bytes.Replace(
-                               pkt.Path[:pkt.PathLen],
-                               []byte{0},
-                               []byte(" "),
-                               -1,
-                       ))
-               case nncp.PktTypeTrns:
-                       path = nncp.ToBase32(pkt.Path[:pkt.PathLen])
-               default:
-                       path = string(pkt.Path[:pkt.PathLen])
-               }
-               fmt.Printf(
-                       "Packet type: plain\nPayload type: %s\nNiceness: %s (%d)\nPath: %s\n",
-                       payloadType, nncp.NicenessFmt(pkt.Nice), pkt.Nice, path,
-               )
-               return
        }
-       var pktEnc nncp.PktEnc
-       _, err = xdr.Unmarshal(bytes.NewReader(beginning), &pktEnc)
-       if err == nil && pktEnc.Magic == nncp.MagicNNCPEv4 {
-               if *dump {
-                       ctx, err := nncp.CtxFromCmdline(*cfgPath, "", "", false, false, false, false)
-                       if err != nil {
-                               log.Fatalln("Error during initialization:", err)
-                       }
-                       if ctx.Self == nil {
-                               log.Fatalln("Config lacks private keys")
-                       }
-                       bufW := bufio.NewWriter(os.Stdout)
-                       if _, _, err = nncp.PktEncRead(
-                               ctx.Self,
-                               ctx.Neigh,
-                               io.MultiReader(
-                                       bytes.NewReader(beginning),
-                                       bufio.NewReader(os.Stdin),
-                               ),
-                               bufW,
-                       ); err != nil {
-                               log.Fatalln(err)
-                       }
-                       if err = bufW.Flush(); err != nil {
-                               log.Fatalln(err)
-                       }
+
+       if _, err := io.ReadFull(os.Stdin, beginning[nncp.PktEncOverhead:]); err != nil {
+               log.Fatalln("Not enough data to read")
+       }
+       var pkt nncp.Pkt
+       if _, err := xdr.Unmarshal(bytes.NewReader(beginning), &pkt); err == nil {
+               switch pkt.Magic {
+               case nncp.MagicNNCPPv1.B:
+                       log.Fatalln(nncp.MagicNNCPPv1.TooOld())
+               case nncp.MagicNNCPPv2.B:
+                       log.Fatalln(nncp.MagicNNCPPv2.TooOld())
+               case nncp.MagicNNCPPv3.B:
+                       doPlain(ctx, pkt, *dump, *decompress)
                        return
                }
-               fmt.Printf(
-                       "Packet type: encrypted\nNiceness: %s (%d)\nSender: %s\nRecipient: %s\n",
-                       nncp.NicenessFmt(pktEnc.Nice), pktEnc.Nice, pktEnc.Sender, pktEnc.Recipient,
-               )
-               return
        }
        log.Fatalln("Unable to determine packet type")
 }