| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 | 
							- package ber
 
- import (
 
- 	"bytes"
 
- 	"fmt"
 
- 	"io"
 
- 	"reflect"
 
- )
 
- type Packet struct {
 
- 	ClassType   uint8
 
- 	TagType     uint8
 
- 	Tag         uint8
 
- 	Value       interface{}
 
- 	ByteValue   []byte
 
- 	Data        *bytes.Buffer
 
- 	Children    []*Packet
 
- 	Description string
 
- }
 
- const (
 
- 	TagEOC              = 0x00
 
- 	TagBoolean          = 0x01
 
- 	TagInteger          = 0x02
 
- 	TagBitString        = 0x03
 
- 	TagOctetString      = 0x04
 
- 	TagNULL             = 0x05
 
- 	TagObjectIdentifier = 0x06
 
- 	TagObjectDescriptor = 0x07
 
- 	TagExternal         = 0x08
 
- 	TagRealFloat        = 0x09
 
- 	TagEnumerated       = 0x0a
 
- 	TagEmbeddedPDV      = 0x0b
 
- 	TagUTF8String       = 0x0c
 
- 	TagRelativeOID      = 0x0d
 
- 	TagSequence         = 0x10
 
- 	TagSet              = 0x11
 
- 	TagNumericString    = 0x12
 
- 	TagPrintableString  = 0x13
 
- 	TagT61String        = 0x14
 
- 	TagVideotexString   = 0x15
 
- 	TagIA5String        = 0x16
 
- 	TagUTCTime          = 0x17
 
- 	TagGeneralizedTime  = 0x18
 
- 	TagGraphicString    = 0x19
 
- 	TagVisibleString    = 0x1a
 
- 	TagGeneralString    = 0x1b
 
- 	TagUniversalString  = 0x1c
 
- 	TagCharacterString  = 0x1d
 
- 	TagBMPString        = 0x1e
 
- 	TagBitmask          = 0x1f // xxx11111b
 
- )
 
- var TagMap = map[uint8]string{
 
- 	TagEOC:              "EOC (End-of-Content)",
 
- 	TagBoolean:          "Boolean",
 
- 	TagInteger:          "Integer",
 
- 	TagBitString:        "Bit String",
 
- 	TagOctetString:      "Octet String",
 
- 	TagNULL:             "NULL",
 
- 	TagObjectIdentifier: "Object Identifier",
 
- 	TagObjectDescriptor: "Object Descriptor",
 
- 	TagExternal:         "External",
 
- 	TagRealFloat:        "Real (float)",
 
- 	TagEnumerated:       "Enumerated",
 
- 	TagEmbeddedPDV:      "Embedded PDV",
 
- 	TagUTF8String:       "UTF8 String",
 
- 	TagRelativeOID:      "Relative-OID",
 
- 	TagSequence:         "Sequence and Sequence of",
 
- 	TagSet:              "Set and Set OF",
 
- 	TagNumericString:    "Numeric String",
 
- 	TagPrintableString:  "Printable String",
 
- 	TagT61String:        "T61 String",
 
- 	TagVideotexString:   "Videotex String",
 
- 	TagIA5String:        "IA5 String",
 
- 	TagUTCTime:          "UTC Time",
 
- 	TagGeneralizedTime:  "Generalized Time",
 
- 	TagGraphicString:    "Graphic String",
 
- 	TagVisibleString:    "Visible String",
 
- 	TagGeneralString:    "General String",
 
- 	TagUniversalString:  "Universal String",
 
- 	TagCharacterString:  "Character String",
 
- 	TagBMPString:        "BMP String",
 
- }
 
- const (
 
- 	ClassUniversal   = 0   // 00xxxxxxb
 
- 	ClassApplication = 64  // 01xxxxxxb
 
- 	ClassContext     = 128 // 10xxxxxxb
 
- 	ClassPrivate     = 192 // 11xxxxxxb
 
- 	ClassBitmask     = 192 // 11xxxxxxb
 
- )
 
- var ClassMap = map[uint8]string{
 
- 	ClassUniversal:   "Universal",
 
- 	ClassApplication: "Application",
 
- 	ClassContext:     "Context",
 
- 	ClassPrivate:     "Private",
 
- }
 
- const (
 
- 	TypePrimitive   = 0  // xx0xxxxxb
 
- 	TypeConstructed = 32 // xx1xxxxxb
 
- 	TypeBitmask     = 32 // xx1xxxxxb
 
- )
 
- var TypeMap = map[uint8]string{
 
- 	TypePrimitive:   "Primative",
 
- 	TypeConstructed: "Constructed",
 
- }
 
- var Debug bool = false
 
- func PrintBytes(buf []byte, indent string) {
 
- 	data_lines := make([]string, (len(buf)/30)+1)
 
- 	num_lines := make([]string, (len(buf)/30)+1)
 
- 	for i, b := range buf {
 
- 		data_lines[i/30] += fmt.Sprintf("%02x ", b)
 
- 		num_lines[i/30] += fmt.Sprintf("%02d ", (i+1)%100)
 
- 	}
 
- 	for i := 0; i < len(data_lines); i++ {
 
- 		fmt.Print(indent + data_lines[i] + "\n")
 
- 		fmt.Print(indent + num_lines[i] + "\n\n")
 
- 	}
 
- }
 
- func PrintPacket(p *Packet) {
 
- 	printPacket(p, 0, false)
 
- }
 
- func printPacket(p *Packet, indent int, printBytes bool) {
 
- 	indent_str := ""
 
- 	for len(indent_str) != indent {
 
- 		indent_str += " "
 
- 	}
 
- 	class_str := ClassMap[p.ClassType]
 
- 	tagtype_str := TypeMap[p.TagType]
 
- 	tag_str := fmt.Sprintf("0x%02X", p.Tag)
 
- 	if p.ClassType == ClassUniversal {
 
- 		tag_str = TagMap[p.Tag]
 
- 	}
 
- 	value := fmt.Sprint(p.Value)
 
- 	description := ""
 
- 	if p.Description != "" {
 
- 		description = p.Description + ": "
 
- 	}
 
- 	fmt.Printf("%s%s(%s, %s, %s) Len=%d %q\n", indent_str, description, class_str, tagtype_str, tag_str, p.Data.Len(), value)
 
- 	if printBytes {
 
- 		PrintBytes(p.Bytes(), indent_str)
 
- 	}
 
- 	for _, child := range p.Children {
 
- 		printPacket(child, indent+1, printBytes)
 
- 	}
 
- }
 
- func resizeBuffer(in []byte, new_size uint64) (out []byte) {
 
- 	out = make([]byte, new_size)
 
- 	copy(out, in)
 
- 	return
 
- }
 
- func readBytes(reader io.Reader, buf []byte) error {
 
- 	idx := 0
 
- 	buflen := len(buf)
 
- 	for idx < buflen {
 
- 		n, err := reader.Read(buf[idx:])
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		idx += n
 
- 	}
 
- 	return nil
 
- }
 
- func ReadPacket(reader io.Reader) (*Packet, error) {
 
- 	buf := make([]byte, 2)
 
- 	err := readBytes(reader, buf)
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	idx := uint64(2)
 
- 	datalen := uint64(buf[1])
 
- 	if Debug {
 
- 		fmt.Printf("Read: datalen = %d len(buf) = %d ", datalen, len(buf))
 
- 		for _, b := range buf {
 
- 			fmt.Printf("%02X ", b)
 
- 		}
 
- 		fmt.Printf("\n")
 
- 	}
 
- 	if datalen&128 != 0 {
 
- 		a := datalen - 128
 
- 		idx += a
 
- 		buf = resizeBuffer(buf, 2+a)
 
- 		err := readBytes(reader, buf[2:])
 
- 		if err != nil {
 
- 			return nil, err
 
- 		}
 
- 		datalen = DecodeInteger(buf[2 : 2+a])
 
- 		if Debug {
 
- 			fmt.Printf("Read: a = %d  idx = %d  datalen = %d  len(buf) = %d", a, idx, datalen, len(buf))
 
- 			for _, b := range buf {
 
- 				fmt.Printf("%02X ", b)
 
- 			}
 
- 			fmt.Printf("\n")
 
- 		}
 
- 	}
 
- 	buf = resizeBuffer(buf, idx+datalen)
 
- 	err = readBytes(reader, buf[idx:])
 
- 	if err != nil {
 
- 		return nil, err
 
- 	}
 
- 	if Debug {
 
- 		fmt.Printf("Read: len( buf ) = %d  idx=%d datalen=%d idx+datalen=%d\n", len(buf), idx, datalen, idx+datalen)
 
- 		for _, b := range buf {
 
- 			fmt.Printf("%02X ", b)
 
- 		}
 
- 	}
 
- 	p := DecodePacket(buf)
 
- 	return p, nil
 
- }
 
- func DecodeString(data []byte) (ret string) {
 
- 	// for _, c := range data {
 
- 	// 	ret += fmt.Sprintf("%c", c)
 
- 	// }
 
- 	return string(data)
 
- }
 
- func DecodeInteger(data []byte) (ret uint64) {
 
- 	for _, i := range data {
 
- 		ret = ret * 256
 
- 		ret = ret + uint64(i)
 
- 	}
 
- 	return
 
- }
 
- func EncodeInteger(val uint64) []byte {
 
- 	var out bytes.Buffer
 
- 	found := false
 
- 	shift := uint(56)
 
- 	mask := uint64(0xFF00000000000000)
 
- 	for mask > 0 {
 
- 		if !found && (val&mask != 0) {
 
- 			found = true
 
- 		}
 
- 		if found || (shift == 0) {
 
- 			out.Write([]byte{byte((val & mask) >> shift)})
 
- 		}
 
- 		shift -= 8
 
- 		mask = mask >> 8
 
- 	}
 
- 	return out.Bytes()
 
- }
 
- func DecodePacket(data []byte) *Packet {
 
- 	p, _ := decodePacket(data)
 
- 	return p
 
- }
 
- func decodePacket(data []byte) (*Packet, []byte) {
 
- 	if Debug {
 
- 		fmt.Printf("decodePacket: enter %d\n", len(data))
 
- 	}
 
- 	p := new(Packet)
 
- 	p.ClassType = data[0] & ClassBitmask
 
- 	p.TagType = data[0] & TypeBitmask
 
- 	p.Tag = data[0] & TagBitmask
 
- 	datalen := DecodeInteger(data[1:2])
 
- 	datapos := uint64(2)
 
- 	if datalen&128 != 0 {
 
- 		datalen -= 128
 
- 		datapos += datalen
 
- 		datalen = DecodeInteger(data[2 : 2+datalen])
 
- 	}
 
- 	p.Data = new(bytes.Buffer)
 
- 	p.Children = make([]*Packet, 0, 2)
 
- 	p.Value = nil
 
- 	value_data := data[datapos : datapos+datalen]
 
- 	if p.TagType == TypeConstructed {
 
- 		for len(value_data) != 0 {
 
- 			var child *Packet
 
- 			child, value_data = decodePacket(value_data)
 
- 			p.AppendChild(child)
 
- 		}
 
- 	} else if p.ClassType == ClassUniversal {
 
- 		p.Data.Write(data[datapos : datapos+datalen])
 
- 		p.ByteValue = value_data
 
- 		switch p.Tag {
 
- 		case TagEOC:
 
- 		case TagBoolean:
 
- 			val := DecodeInteger(value_data)
 
- 			p.Value = val != 0
 
- 		case TagInteger:
 
- 			p.Value = DecodeInteger(value_data)
 
- 		case TagBitString:
 
- 		case TagOctetString:
 
- 			p.Value = DecodeString(value_data)
 
- 		case TagNULL:
 
- 		case TagObjectIdentifier:
 
- 		case TagObjectDescriptor:
 
- 		case TagExternal:
 
- 		case TagRealFloat:
 
- 		case TagEnumerated:
 
- 			p.Value = DecodeInteger(value_data)
 
- 		case TagEmbeddedPDV:
 
- 		case TagUTF8String:
 
- 		case TagRelativeOID:
 
- 		case TagSequence:
 
- 		case TagSet:
 
- 		case TagNumericString:
 
- 		case TagPrintableString:
 
- 			p.Value = DecodeString(value_data)
 
- 		case TagT61String:
 
- 		case TagVideotexString:
 
- 		case TagIA5String:
 
- 		case TagUTCTime:
 
- 		case TagGeneralizedTime:
 
- 		case TagGraphicString:
 
- 		case TagVisibleString:
 
- 		case TagGeneralString:
 
- 		case TagUniversalString:
 
- 		case TagCharacterString:
 
- 		case TagBMPString:
 
- 		}
 
- 	} else {
 
- 		p.Data.Write(data[datapos : datapos+datalen])
 
- 	}
 
- 	return p, data[datapos+datalen:]
 
- }
 
- func (p *Packet) DataLength() uint64 {
 
- 	return uint64(p.Data.Len())
 
- }
 
- func (p *Packet) Bytes() []byte {
 
- 	var out bytes.Buffer
 
- 	out.Write([]byte{p.ClassType | p.TagType | p.Tag})
 
- 	packet_length := EncodeInteger(p.DataLength())
 
- 	if p.DataLength() > 127 || len(packet_length) > 1 {
 
- 		out.Write([]byte{byte(len(packet_length) | 128)})
 
- 		out.Write(packet_length)
 
- 	} else {
 
- 		out.Write(packet_length)
 
- 	}
 
- 	out.Write(p.Data.Bytes())
 
- 	return out.Bytes()
 
- }
 
- func (p *Packet) AppendChild(child *Packet) {
 
- 	p.Data.Write(child.Bytes())
 
- 	if len(p.Children) == cap(p.Children) {
 
- 		newChildren := make([]*Packet, cap(p.Children)*2)
 
- 		copy(newChildren, p.Children)
 
- 		p.Children = newChildren[0:len(p.Children)]
 
- 	}
 
- 	p.Children = p.Children[0 : len(p.Children)+1]
 
- 	p.Children[len(p.Children)-1] = child
 
- }
 
- func Encode(ClassType, TagType, Tag uint8, Value interface{}, Description string) *Packet {
 
- 	p := new(Packet)
 
- 	p.ClassType = ClassType
 
- 	p.TagType = TagType
 
- 	p.Tag = Tag
 
- 	p.Data = new(bytes.Buffer)
 
- 	p.Children = make([]*Packet, 0, 2)
 
- 	p.Value = Value
 
- 	p.Description = Description
 
- 	if Value != nil {
 
- 		v := reflect.ValueOf(Value)
 
- 		if ClassType == ClassUniversal {
 
- 			switch Tag {
 
- 			case TagOctetString:
 
- 				sv, ok := v.Interface().(string)
 
- 				if ok {
 
- 					p.Data.Write([]byte(sv))
 
- 				}
 
- 			}
 
- 		}
 
- 	}
 
- 	return p
 
- }
 
- func NewSequence(Description string) *Packet {
 
- 	return Encode(ClassUniversal, TypePrimitive, TagSequence, nil, Description)
 
- }
 
- func NewBoolean(ClassType, TagType, Tag uint8, Value bool, Description string) *Packet {
 
- 	intValue := 0
 
- 	if Value {
 
- 		intValue = 1
 
- 	}
 
- 	p := Encode(ClassType, TagType, Tag, nil, Description)
 
- 	p.Value = Value
 
- 	p.Data.Write(EncodeInteger(uint64(intValue)))
 
- 	return p
 
- }
 
- func NewInteger(ClassType, TagType, Tag uint8, Value uint64, Description string) *Packet {
 
- 	p := Encode(ClassType, TagType, Tag, nil, Description)
 
- 	p.Value = Value
 
- 	p.Data.Write(EncodeInteger(Value))
 
- 	return p
 
- }
 
- func NewString(ClassType, TagType, Tag uint8, Value, Description string) *Packet {
 
- 	p := Encode(ClassType, TagType, Tag, nil, Description)
 
- 	p.Value = Value
 
- 	p.Data.Write([]byte(Value))
 
- 	return p
 
- }
 
 
  |