func (s *SIP) GetTo() string {
	return s.GetFirstHeader("To")
}
GetTo will return the To
header of the current SIP packet
package layers
import (
	"bytes"
	"fmt"
	"io"
	"strconv"
	"strings"
	"github.com/google/gopacket"
)
type SIPVersion uint8
const (
	SIPVersion1 SIPVersion = 1
	SIPVersion2 SIPVersion = 2
)
func (sv SIPVersion) String() string {
	switch sv {
	default:
		return "SIP/2.0"
	case SIPVersion1:
		return "SIP/1.0"
	case SIPVersion2:
		return "SIP/2.0"
	}
}
func GetSIPVersion(version string) (SIPVersion, error) {
	switch strings.ToUpper(version) {
	case "SIP/1.0":
		return SIPVersion1, nil
	case "SIP/2.0":
		return SIPVersion2, nil
	default:
		return 0, fmt.Errorf("Unknown SIP version: '%s'", version)
	}
}
type SIPMethod uint16
const (
	SIPMethodInvite    SIPMethod = 1   
	SIPMethodAck       SIPMethod = 2   
	SIPMethodBye       SIPMethod = 3   
	SIPMethodCancel    SIPMethod = 4   
	SIPMethodOptions   SIPMethod = 5   
	SIPMethodRegister  SIPMethod = 6   
	SIPMethodPrack     SIPMethod = 7   
	SIPMethodSubscribe SIPMethod = 8   
	SIPMethodNotify    SIPMethod = 9   
	SIPMethodPublish   SIPMethod = 10  
	SIPMethodInfo      SIPMethod = 11  
	SIPMethodRefer     SIPMethod = 12  
	SIPMethodMessage   SIPMethod = 13  
	SIPMethodUpdate    SIPMethod = 14  
	SIPMethodPing      SIPMethod = 15  
)
func (sm SIPMethod) String() string {
	switch sm {
	default:
		return "Unknown method"
	case SIPMethodInvite:
		return "INVITE"
	case SIPMethodAck:
		return "ACK"
	case SIPMethodBye:
		return "BYE"
	case SIPMethodCancel:
		return "CANCEL"
	case SIPMethodOptions:
		return "OPTIONS"
	case SIPMethodRegister:
		return "REGISTER"
	case SIPMethodPrack:
		return "PRACK"
	case SIPMethodSubscribe:
		return "SUBSCRIBE"
	case SIPMethodNotify:
		return "NOTIFY"
	case SIPMethodPublish:
		return "PUBLISH"
	case SIPMethodInfo:
		return "INFO"
	case SIPMethodRefer:
		return "REFER"
	case SIPMethodMessage:
		return "MESSAGE"
	case SIPMethodUpdate:
		return "UPDATE"
	case SIPMethodPing:
		return "PING"
	}
}
func GetSIPMethod(method string) (SIPMethod, error) {
	switch strings.ToUpper(method) {
	case "INVITE":
		return SIPMethodInvite, nil
	case "ACK":
		return SIPMethodAck, nil
	case "BYE":
		return SIPMethodBye, nil
	case "CANCEL":
		return SIPMethodCancel, nil
	case "OPTIONS":
		return SIPMethodOptions, nil
	case "REGISTER":
		return SIPMethodRegister, nil
	case "PRACK":
		return SIPMethodPrack, nil
	case "SUBSCRIBE":
		return SIPMethodSubscribe, nil
	case "NOTIFY":
		return SIPMethodNotify, nil
	case "PUBLISH":
		return SIPMethodPublish, nil
	case "INFO":
		return SIPMethodInfo, nil
	case "REFER":
		return SIPMethodRefer, nil
	case "MESSAGE":
		return SIPMethodMessage, nil
	case "UPDATE":
		return SIPMethodUpdate, nil
	case "PING":
		return SIPMethodPing, nil
	default:
		return 0, fmt.Errorf("Unknown SIP method: '%s'", method)
	}
}
var compactSipHeadersCorrespondance = map[string]string{
	"accept-contact":      "a",
	"allow-events":        "u",
	"call-id":             "i",
	"contact":             "m",
	"content-encoding":    "e",
	"content-length":      "l",
	"content-type":        "c",
	"event":               "o",
	"from":                "f",
	"identity":            "y",
	"refer-to":            "r",
	"referred-by":         "b",
	"reject-contact":      "j",
	"request-disposition": "d",
	"session-expires":     "x",
	"subject":             "s",
	"supported":           "k",
	"to":                  "t",
	"via":                 "v",
}
type SIP struct {
	BaseLayer
	Version SIPVersion
	Method  SIPMethod
	Headers map[string][]string
	RequestURI string
	IsResponse     bool
	ResponseCode   int
	ResponseStatus string
	cseq             int64
	contentLength    int64
	lastHeaderParsed string
}
func decodeSIP(data []byte, p gopacket.PacketBuilder) error {
	s := NewSIP()
	err := s.DecodeFromBytes(data, p)
	if err != nil {
		return err
	}
	p.AddLayer(s)
	p.SetApplicationLayer(s)
	return nil
}
func NewSIP() *SIP {
	s := new(SIP)
	s.Headers = make(map[string][]string)
	return s
}
func (s *SIP) LayerType() gopacket.LayerType {
	return LayerTypeSIP
}
func (s *SIP) Payload() []byte {
	return s.BaseLayer.Payload
}
func (s *SIP) CanDecode() gopacket.LayerClass {
	return LayerTypeSIP
}
func (s *SIP) NextLayerType() gopacket.LayerType {
	return gopacket.LayerTypePayload
}
func (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
	var countLines int
	var line []byte
	var err error
	data = bytes.Trim(data, "\n")
	buffer := bytes.NewBuffer(data)
	for {
		line, err = buffer.ReadBytes(byte('\n'))
		if err != nil {
			if err == io.EOF {
				break
			} else {
				return err
			}
		}
		line = bytes.Trim(line, "\r\n")
		if len(line) == 0 {
			s.BaseLayer.Payload = buffer.Bytes()
			break
		}
		if countLines == 0 {
			err = s.ParseFirstLine(line)
			if err != nil {
				return err
			}
		} else {
			err = s.ParseHeader(line)
			if err != nil {
				return err
			}
		}
		countLines++
	}
	return nil
}
func (s *SIP) ParseFirstLine(firstLine []byte) error {
	var err error
	splits := strings.SplitN(string(firstLine), " ", 3)
	if len(splits) < 3 {
		return fmt.Errorf("invalid first SIP line: '%s'", string(firstLine))
	}
	if strings.HasPrefix(splits[0], "SIP") {
		s.IsResponse = true
		s.Version, err = GetSIPVersion(splits[0])
		if err != nil {
			return err
		}
		s.ResponseCode, err = strconv.Atoi(splits[1])
		if err != nil {
			return err
		}
		s.ResponseStatus = splits[2]
	} else {
		s.Method, err = GetSIPMethod(splits[0])
		if err != nil {
			return err
		}
		s.RequestURI = splits[1]
		s.Version, err = GetSIPVersion(splits[2])
		if err != nil {
			return err
		}
	}
	return nil
}
func (s *SIP) ParseHeader(header []byte) (err error) {
	if len(header) == 0 {
		return
	}
	if header[0] == '\t' || header[0] == ' ' {
		header = bytes.TrimSpace(header)
		s.Headers[s.lastHeaderParsed][len(s.Headers[s.lastHeaderParsed])-1] += fmt.Sprintf(" %s", string(header))
		return
	}
	index := bytes.Index(header, []byte(":"))
	if index >= 0 {
		headerName := strings.ToLower(string(bytes.Trim(header[:index], " ")))
		headerValue := string(bytes.Trim(header[index+1:], " "))
		s.Headers[headerName] = append(s.Headers[headerName], headerValue)
		s.lastHeaderParsed = headerName
		err = s.ParseSpecificHeaders(headerName, headerValue)
		if err != nil {
			return err
		}
	}
	return nil
}
func (s *SIP) ParseSpecificHeaders(headerName string, headerValue string) (err error) {
	switch headerName {
	case "cseq":
		splits := strings.Split(headerValue, " ")
		if len(splits) > 1 {
			s.cseq, err = strconv.ParseInt(splits[0], 10, 64)
			if err != nil {
				return err
			}
			if s.IsResponse {
				s.Method, err = GetSIPMethod(splits[1])
				if err != nil {
					return err
				}
			}
		}
	case "content-length":
		s.contentLength, err = strconv.ParseInt(headerValue, 10, 64)
		if err != nil {
			return err
		}
	}
	return nil
}
func (s *SIP) GetAllHeaders() map[string][]string {
	return s.Headers
}
func (s *SIP) GetHeader(headerName string) []string {
	headerName = strings.ToLower(headerName)
	h := make([]string, 0)
	if _, ok := s.Headers[headerName]; ok {
		if len(s.Headers[headerName]) > 0 {
			return s.Headers[headerName]
		} else if len(s.Headers[compactSipHeadersCorrespondance[headerName]]) > 0 {
			return s.Headers[compactSipHeadersCorrespondance[headerName]]
		}
	}
	return h
}
func (s *SIP) GetFirstHeader(headerName string) string {
	headerName = strings.ToLower(headerName)
	if _, ok := s.Headers[headerName]; ok {
		if len(s.Headers[headerName]) > 0 {
			return s.Headers[headerName][0]
		} else if len(s.Headers[compactSipHeadersCorrespondance[headerName]]) > 0 {
			return s.Headers[compactSipHeadersCorrespondance[headerName]][0]
		}
	}
	return ""
}
func (s *SIP) GetAuthorization() string {
	return s.GetFirstHeader("Authorization")
}
func (s *SIP) GetFrom() string {
	return s.GetFirstHeader("From")
}