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 }