github.com/gopacket/gopacket@v1.1.0/layers/sip.go (about)

     1  // Copyright 2017 Google, Inc. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style license
     4  // that can be found in the LICENSE file in the root of the source
     5  // tree.
     6  
     7  package layers
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"io"
    13  	"strconv"
    14  	"strings"
    15  
    16  	"github.com/gopacket/gopacket"
    17  )
    18  
    19  // SIPVersion defines the different versions of the SIP Protocol
    20  type SIPVersion uint8
    21  
    22  // Represents all the versions of SIP protocol
    23  const (
    24  	SIPVersion1 SIPVersion = 1
    25  	SIPVersion2 SIPVersion = 2
    26  )
    27  
    28  func (sv SIPVersion) String() string {
    29  	switch sv {
    30  	default:
    31  		// Defaulting to SIP/2.0
    32  		return "SIP/2.0"
    33  	case SIPVersion1:
    34  		return "SIP/1.0"
    35  	case SIPVersion2:
    36  		return "SIP/2.0"
    37  	}
    38  }
    39  
    40  // GetSIPVersion is used to get SIP version constant
    41  func GetSIPVersion(version string) (SIPVersion, error) {
    42  	switch strings.ToUpper(version) {
    43  	case "SIP/1.0":
    44  		return SIPVersion1, nil
    45  	case "SIP/2.0":
    46  		return SIPVersion2, nil
    47  	default:
    48  		return 0, fmt.Errorf("Unknown SIP version: '%s'", version)
    49  
    50  	}
    51  }
    52  
    53  // SIPMethod defines the different methods of the SIP Protocol
    54  // defined in the different RFC's
    55  type SIPMethod uint16
    56  
    57  // Here are all the SIP methods
    58  const (
    59  	SIPMethodInvite    SIPMethod = 1  // INVITE	[RFC3261]
    60  	SIPMethodAck       SIPMethod = 2  // ACK	[RFC3261]
    61  	SIPMethodBye       SIPMethod = 3  // BYE	[RFC3261]
    62  	SIPMethodCancel    SIPMethod = 4  // CANCEL	[RFC3261]
    63  	SIPMethodOptions   SIPMethod = 5  // OPTIONS	[RFC3261]
    64  	SIPMethodRegister  SIPMethod = 6  // REGISTER	[RFC3261]
    65  	SIPMethodPrack     SIPMethod = 7  // PRACK	[RFC3262]
    66  	SIPMethodSubscribe SIPMethod = 8  // SUBSCRIBE	[RFC6665]
    67  	SIPMethodNotify    SIPMethod = 9  // NOTIFY	[RFC6665]
    68  	SIPMethodPublish   SIPMethod = 10 // PUBLISH	[RFC3903]
    69  	SIPMethodInfo      SIPMethod = 11 // INFO	[RFC6086]
    70  	SIPMethodRefer     SIPMethod = 12 // REFER	[RFC3515]
    71  	SIPMethodMessage   SIPMethod = 13 // MESSAGE	[RFC3428]
    72  	SIPMethodUpdate    SIPMethod = 14 // UPDATE	[RFC3311]
    73  	SIPMethodPing      SIPMethod = 15 // PING	[https://tools.ietf.org/html/draft-fwmiller-ping-03]
    74  )
    75  
    76  func (sm SIPMethod) String() string {
    77  	switch sm {
    78  	default:
    79  		return "Unknown method"
    80  	case SIPMethodInvite:
    81  		return "INVITE"
    82  	case SIPMethodAck:
    83  		return "ACK"
    84  	case SIPMethodBye:
    85  		return "BYE"
    86  	case SIPMethodCancel:
    87  		return "CANCEL"
    88  	case SIPMethodOptions:
    89  		return "OPTIONS"
    90  	case SIPMethodRegister:
    91  		return "REGISTER"
    92  	case SIPMethodPrack:
    93  		return "PRACK"
    94  	case SIPMethodSubscribe:
    95  		return "SUBSCRIBE"
    96  	case SIPMethodNotify:
    97  		return "NOTIFY"
    98  	case SIPMethodPublish:
    99  		return "PUBLISH"
   100  	case SIPMethodInfo:
   101  		return "INFO"
   102  	case SIPMethodRefer:
   103  		return "REFER"
   104  	case SIPMethodMessage:
   105  		return "MESSAGE"
   106  	case SIPMethodUpdate:
   107  		return "UPDATE"
   108  	case SIPMethodPing:
   109  		return "PING"
   110  	}
   111  }
   112  
   113  // GetSIPMethod returns the constant of a SIP method
   114  // from its string
   115  func GetSIPMethod(method string) (SIPMethod, error) {
   116  	switch strings.ToUpper(method) {
   117  	case "INVITE":
   118  		return SIPMethodInvite, nil
   119  	case "ACK":
   120  		return SIPMethodAck, nil
   121  	case "BYE":
   122  		return SIPMethodBye, nil
   123  	case "CANCEL":
   124  		return SIPMethodCancel, nil
   125  	case "OPTIONS":
   126  		return SIPMethodOptions, nil
   127  	case "REGISTER":
   128  		return SIPMethodRegister, nil
   129  	case "PRACK":
   130  		return SIPMethodPrack, nil
   131  	case "SUBSCRIBE":
   132  		return SIPMethodSubscribe, nil
   133  	case "NOTIFY":
   134  		return SIPMethodNotify, nil
   135  	case "PUBLISH":
   136  		return SIPMethodPublish, nil
   137  	case "INFO":
   138  		return SIPMethodInfo, nil
   139  	case "REFER":
   140  		return SIPMethodRefer, nil
   141  	case "MESSAGE":
   142  		return SIPMethodMessage, nil
   143  	case "UPDATE":
   144  		return SIPMethodUpdate, nil
   145  	case "PING":
   146  		return SIPMethodPing, nil
   147  	default:
   148  		return 0, fmt.Errorf("Unknown SIP method: '%s'", method)
   149  	}
   150  }
   151  
   152  // Here is a correspondance between long header names and short
   153  // as defined in rfc3261 in section 20
   154  var compactSipHeadersCorrespondance = map[string]string{
   155  	"accept-contact":      "a",
   156  	"allow-events":        "u",
   157  	"call-id":             "i",
   158  	"contact":             "m",
   159  	"content-encoding":    "e",
   160  	"content-length":      "l",
   161  	"content-type":        "c",
   162  	"event":               "o",
   163  	"from":                "f",
   164  	"identity":            "y",
   165  	"refer-to":            "r",
   166  	"referred-by":         "b",
   167  	"reject-contact":      "j",
   168  	"request-disposition": "d",
   169  	"session-expires":     "x",
   170  	"subject":             "s",
   171  	"supported":           "k",
   172  	"to":                  "t",
   173  	"via":                 "v",
   174  }
   175  
   176  // SIP object will contains information about decoded SIP packet.
   177  // -> The SIP Version
   178  // -> The SIP Headers (in a map[string][]string because of multiple headers with the same name
   179  // -> The SIP Method
   180  // -> The SIP Response code (if it's a response)
   181  // -> The SIP Status line (if it's a response)
   182  // You can easily know the type of the packet with the IsResponse boolean
   183  type SIP struct {
   184  	BaseLayer
   185  
   186  	// Base information
   187  	Version SIPVersion
   188  	Method  SIPMethod
   189  	Headers map[string][]string
   190  
   191  	// Request
   192  	RequestURI string
   193  
   194  	// Response
   195  	IsResponse     bool
   196  	ResponseCode   int
   197  	ResponseStatus string
   198  
   199  	// Private fields
   200  	cseq             int64
   201  	contentLength    int64
   202  	lastHeaderParsed string
   203  }
   204  
   205  // decodeSIP decodes the byte slice into a SIP type. It also
   206  // setups the application Layer in PacketBuilder.
   207  func decodeSIP(data []byte, p gopacket.PacketBuilder) error {
   208  	s := NewSIP()
   209  	err := s.DecodeFromBytes(data, p)
   210  	if err != nil {
   211  		return err
   212  	}
   213  	p.AddLayer(s)
   214  	p.SetApplicationLayer(s)
   215  	return nil
   216  }
   217  
   218  // NewSIP instantiates a new empty SIP object
   219  func NewSIP() *SIP {
   220  	s := new(SIP)
   221  	s.Headers = make(map[string][]string)
   222  	return s
   223  }
   224  
   225  // LayerType returns gopacket.LayerTypeSIP.
   226  func (s *SIP) LayerType() gopacket.LayerType {
   227  	return LayerTypeSIP
   228  }
   229  
   230  // Payload returns the base layer payload
   231  func (s *SIP) Payload() []byte {
   232  	return s.BaseLayer.Payload
   233  }
   234  
   235  // CanDecode returns the set of layer types that this DecodingLayer can decode
   236  func (s *SIP) CanDecode() gopacket.LayerClass {
   237  	return LayerTypeSIP
   238  }
   239  
   240  // NextLayerType returns the layer type contained by this DecodingLayer
   241  func (s *SIP) NextLayerType() gopacket.LayerType {
   242  	return gopacket.LayerTypePayload
   243  }
   244  
   245  // DecodeFromBytes decodes the slice into the SIP struct.
   246  func (s *SIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
   247  	// Init some vars for parsing follow-up
   248  	var countLines int
   249  	var line []byte
   250  	var err error
   251  	var offset int
   252  
   253  	// Iterate on all lines of the SIP Headers
   254  	// and stop when we reach the SDP (aka when the new line
   255  	// is at index 0 of the remaining packet)
   256  	buffer := bytes.NewBuffer(data)
   257  
   258  	for {
   259  
   260  		// Read next line
   261  		line, err = buffer.ReadBytes(byte('\n'))
   262  		if err != nil {
   263  			if err == io.EOF {
   264  				if len(bytes.Trim(line, "\r\n")) > 0 {
   265  					df.SetTruncated()
   266  				}
   267  				break
   268  			} else {
   269  				return err
   270  			}
   271  		}
   272  		offset += len(line)
   273  
   274  		// Trim the new line delimiters
   275  		line = bytes.Trim(line, "\r\n")
   276  
   277  		// Empty line, we hit Body
   278  		if len(line) == 0 {
   279  			break
   280  		}
   281  
   282  		// First line is the SIP request/response line
   283  		// Other lines are headers
   284  		if countLines == 0 {
   285  			err = s.ParseFirstLine(line)
   286  			if err != nil {
   287  				return err
   288  			}
   289  
   290  		} else {
   291  			err = s.ParseHeader(line)
   292  			if err != nil {
   293  				return err
   294  			}
   295  		}
   296  
   297  		countLines++
   298  	}
   299  	s.BaseLayer = BaseLayer{Contents: data[:offset], Payload: data[offset:]}
   300  
   301  	return nil
   302  }
   303  
   304  // ParseFirstLine will compute the first line of a SIP packet.
   305  // The first line will tell us if it's a request or a response.
   306  //
   307  // Examples of first line of SIP Prococol :
   308  //
   309  //	Request 	: INVITE bob@example.com SIP/2.0
   310  //	Response 	: SIP/2.0 200 OK
   311  //	Response	: SIP/2.0 501 Not Implemented
   312  func (s *SIP) ParseFirstLine(firstLine []byte) error {
   313  
   314  	var err error
   315  
   316  	// Splits line by space
   317  	splits := strings.SplitN(string(firstLine), " ", 3)
   318  
   319  	// We must have at least 3 parts
   320  	if len(splits) < 3 {
   321  		return fmt.Errorf("invalid first SIP line: '%s'", string(firstLine))
   322  	}
   323  
   324  	// Determine the SIP packet type
   325  	if strings.HasPrefix(splits[0], "SIP") {
   326  
   327  		// --> Response
   328  		s.IsResponse = true
   329  
   330  		// Validate SIP Version
   331  		s.Version, err = GetSIPVersion(splits[0])
   332  		if err != nil {
   333  			return err
   334  		}
   335  
   336  		// Compute code
   337  		s.ResponseCode, err = strconv.Atoi(splits[1])
   338  		if err != nil {
   339  			return err
   340  		}
   341  
   342  		// Compute status line
   343  		s.ResponseStatus = splits[2]
   344  
   345  	} else {
   346  
   347  		// --> Request
   348  
   349  		// Validate method
   350  		s.Method, err = GetSIPMethod(splits[0])
   351  		if err != nil {
   352  			return err
   353  		}
   354  
   355  		s.RequestURI = splits[1]
   356  
   357  		// Validate SIP Version
   358  		s.Version, err = GetSIPVersion(splits[2])
   359  		if err != nil {
   360  			return err
   361  		}
   362  	}
   363  
   364  	return nil
   365  }
   366  
   367  // ParseHeader will parse a SIP Header
   368  // SIP Headers are quite simple, there are colon separated name and value
   369  // Headers can be spread over multiple lines
   370  //
   371  // Examples of header :
   372  //
   373  //	 CSeq: 1 REGISTER
   374  //	 Via: SIP/2.0/UDP there.com:5060
   375  //	 Authorization:Digest username="UserB",
   376  //		  realm="MCI WorldCom SIP",
   377  //	   nonce="1cec4341ae6cbe5a359ea9c8e88df84f", opaque="",
   378  //	   uri="sip:ss2.wcom.com", response="71ba27c64bd01de719686aa4590d5824"
   379  func (s *SIP) ParseHeader(header []byte) (err error) {
   380  
   381  	// Ignore empty headers
   382  	if len(header) == 0 {
   383  		return
   384  	}
   385  
   386  	// Check if this is the following of last header
   387  	// RFC 3261 - 7.3.1 - Header Field Format specify that following lines of
   388  	// multiline headers must begin by SP or TAB
   389  	if header[0] == '\t' || header[0] == ' ' {
   390  
   391  		header = bytes.TrimSpace(header)
   392  		s.Headers[s.lastHeaderParsed][len(s.Headers[s.lastHeaderParsed])-1] += fmt.Sprintf(" %s", string(header))
   393  		return
   394  	}
   395  
   396  	// Find the ':' to separate header name and value
   397  	index := bytes.Index(header, []byte(":"))
   398  	if index >= 0 {
   399  
   400  		headerName := strings.ToLower(string(bytes.Trim(header[:index], " ")))
   401  		headerValue := string(bytes.Trim(header[index+1:], " "))
   402  
   403  		// Add header to object
   404  		s.Headers[headerName] = append(s.Headers[headerName], headerValue)
   405  		s.lastHeaderParsed = headerName
   406  
   407  		// Compute specific headers
   408  		err = s.ParseSpecificHeaders(headerName, headerValue)
   409  		if err != nil {
   410  			return err
   411  		}
   412  	}
   413  
   414  	return nil
   415  }
   416  
   417  // ParseSpecificHeaders will parse some specific key values from
   418  // specific headers like CSeq or Content-Length integer values
   419  func (s *SIP) ParseSpecificHeaders(headerName string, headerValue string) (err error) {
   420  
   421  	switch headerName {
   422  	case "cseq":
   423  
   424  		// CSeq header value is formatted like that :
   425  		// CSeq: 123 INVITE
   426  		// We split the value to parse Cseq integer value, and method
   427  		splits := strings.Split(headerValue, " ")
   428  		if len(splits) > 1 {
   429  
   430  			// Parse Cseq
   431  			s.cseq, err = strconv.ParseInt(splits[0], 10, 64)
   432  			if err != nil {
   433  				return err
   434  			}
   435  
   436  			// Validate method
   437  			if s.IsResponse {
   438  				s.Method, err = GetSIPMethod(splits[1])
   439  				if err != nil {
   440  					return err
   441  				}
   442  			}
   443  		}
   444  
   445  	case "content-length":
   446  
   447  		// Parse Content-Length
   448  		s.contentLength, err = strconv.ParseInt(headerValue, 10, 64)
   449  		if err != nil {
   450  			return err
   451  		}
   452  	}
   453  
   454  	return nil
   455  }
   456  
   457  // GetAllHeaders will return the full headers of the
   458  // current SIP packets in a map[string][]string
   459  func (s *SIP) GetAllHeaders() map[string][]string {
   460  	return s.Headers
   461  }
   462  
   463  // GetHeader will return all the headers with
   464  // the specified name.
   465  func (s *SIP) GetHeader(headerName string) []string {
   466  	headerName = strings.ToLower(headerName)
   467  	h := make([]string, 0)
   468  	if _, ok := s.Headers[headerName]; ok {
   469  		return s.Headers[headerName]
   470  	}
   471  	compactHeader := compactSipHeadersCorrespondance[headerName]
   472  	if _, ok := s.Headers[compactHeader]; ok {
   473  		return s.Headers[compactHeader]
   474  	}
   475  	return h
   476  }
   477  
   478  // GetFirstHeader will return the first header with
   479  // the specified name. If the current SIP packet has multiple
   480  // headers with the same name, it returns the first.
   481  func (s *SIP) GetFirstHeader(headerName string) string {
   482  	headers := s.GetHeader(headerName)
   483  	if len(headers) > 0 {
   484  		return headers[0]
   485  	}
   486  	return ""
   487  }
   488  
   489  //
   490  // Some handy getters for most used SIP headers
   491  //
   492  
   493  // GetAuthorization will return the Authorization
   494  // header of the current SIP packet
   495  func (s *SIP) GetAuthorization() string {
   496  	return s.GetFirstHeader("Authorization")
   497  }
   498  
   499  // GetFrom will return the From
   500  // header of the current SIP packet
   501  func (s *SIP) GetFrom() string {
   502  	return s.GetFirstHeader("From")
   503  }
   504  
   505  // GetTo will return the To
   506  // header of the current SIP packet
   507  func (s *SIP) GetTo() string {
   508  	return s.GetFirstHeader("To")
   509  }
   510  
   511  // GetContact will return the Contact
   512  // header of the current SIP packet
   513  func (s *SIP) GetContact() string {
   514  	return s.GetFirstHeader("Contact")
   515  }
   516  
   517  // GetCallID will return the Call-ID
   518  // header of the current SIP packet
   519  func (s *SIP) GetCallID() string {
   520  	return s.GetFirstHeader("Call-ID")
   521  }
   522  
   523  // GetUserAgent will return the User-Agent
   524  // header of the current SIP packet
   525  func (s *SIP) GetUserAgent() string {
   526  	return s.GetFirstHeader("User-Agent")
   527  }
   528  
   529  // GetContentLength will return the parsed integer
   530  // Content-Length header of the current SIP packet
   531  func (s *SIP) GetContentLength() int64 {
   532  	return s.contentLength
   533  }
   534  
   535  // GetCSeq will return the parsed integer CSeq header
   536  // header of the current SIP packet
   537  func (s *SIP) GetCSeq() int64 {
   538  	return s.cseq
   539  }