|
|
|
@ -32,6 +32,9 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
cs := 0 |
|
|
|
p := 0 |
|
|
|
pe := len(data) |
|
|
|
//eof := len(data) |
|
|
|
//stack := make([]int, 2) |
|
|
|
//top := 0 |
|
|
|
line := 1 |
|
|
|
linep := 0 |
|
|
|
buf := make([]byte, len(data)) |
|
|
|
@ -39,8 +42,9 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
mark := 0 |
|
|
|
clen := 0 |
|
|
|
ctype := "" |
|
|
|
// var b1 string |
|
|
|
var b1 string |
|
|
|
var hex byte |
|
|
|
var dest *string |
|
|
|
|
|
|
|
%%{ |
|
|
|
action break { |
|
|
|
@ -103,51 +107,28 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
msg.Phrase = string(buf[0:amt]) |
|
|
|
} |
|
|
|
|
|
|
|
action extHeaderName { |
|
|
|
b1 = string(bytes.ToLower(data[mark:p])) |
|
|
|
} |
|
|
|
|
|
|
|
action extHeaderValue { |
|
|
|
if msg.Headers == nil { |
|
|
|
msg.Headers = Headers{} |
|
|
|
} |
|
|
|
msg.Headers[b1] = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Accept { |
|
|
|
msg.Accept = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action AcceptValue { |
|
|
|
msg.AcceptContact = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action AcceptEncoding { |
|
|
|
msg.AcceptEncoding = string(data[mark:p]) |
|
|
|
action header { |
|
|
|
fgoto header; |
|
|
|
} |
|
|
|
|
|
|
|
action AcceptLanguage { |
|
|
|
msg.AcceptLanguage = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Allow { |
|
|
|
msg.Allow = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action AllowEvents { |
|
|
|
msg.AllowEvents = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action AlertInfo { |
|
|
|
msg.AlertInfo = string(data[mark:p]) |
|
|
|
action hname { |
|
|
|
b1 = string(bytes.ToLower(data[mark:p])) |
|
|
|
} |
|
|
|
|
|
|
|
action AuthenticationInfo { |
|
|
|
msg.AuthenticationInfo = string(data[mark:p]) |
|
|
|
action svalue { |
|
|
|
fhold; |
|
|
|
fgoto svalue; |
|
|
|
} |
|
|
|
|
|
|
|
action Authorization { |
|
|
|
msg.Authorization = string(data[mark:p]) |
|
|
|
action svalueDone { |
|
|
|
if dest != nil { |
|
|
|
*dest = string(data[mark:p - 1]) |
|
|
|
} else { |
|
|
|
if msg.Headers == nil { |
|
|
|
msg.Headers = Headers{} |
|
|
|
} |
|
|
|
msg.Headers[b1] = string(data[mark:p]) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
action CallID { |
|
|
|
@ -160,22 +141,10 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
for *contactp != nil { contactp = &(*contactp).Next } |
|
|
|
} |
|
|
|
|
|
|
|
action ContentDisposition { |
|
|
|
msg.ContentDisposition = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ContentLanguage { |
|
|
|
msg.ContentLanguage = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ContentLength { |
|
|
|
clen = clen * 10 + (int(fc) - 0x30) |
|
|
|
} |
|
|
|
|
|
|
|
action ContentEncoding { |
|
|
|
msg.ContentEncoding = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ContentType { |
|
|
|
ctype = string(data[mark:p]) |
|
|
|
} |
|
|
|
@ -188,22 +157,6 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
msg.CSeqMethod = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action CallInfo { |
|
|
|
msg.CallInfo = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Date { |
|
|
|
msg.Date = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ErrorInfo { |
|
|
|
msg.ErrorInfo = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Event { |
|
|
|
msg.Event = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Expires { |
|
|
|
msg.Expires = msg.Expires * 10 + (int(fc) - 0x30) |
|
|
|
} |
|
|
|
@ -213,14 +166,6 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
if err != nil { return nil, err } |
|
|
|
} |
|
|
|
|
|
|
|
action InReplyTo { |
|
|
|
msg.InReplyTo = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action MaxForwardsZero { |
|
|
|
msg.MaxForwards = 0 |
|
|
|
} |
|
|
|
|
|
|
|
action MaxForwards { |
|
|
|
msg.MaxForwards = msg.MaxForwards * 10 + (int(fc) - 0x30) |
|
|
|
} |
|
|
|
@ -229,115 +174,39 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
msg.MinExpires = msg.MinExpires * 10 + (int(fc) - 0x30) |
|
|
|
} |
|
|
|
|
|
|
|
action ReplyTo { |
|
|
|
msg.ReplyTo = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action MIMEVersion { |
|
|
|
msg.MIMEVersion = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Organization { |
|
|
|
msg.Organization = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action PAssertedIdentity { |
|
|
|
msg.PAssertedIdentity, err = ParseAddr(string(data[mark:p])) |
|
|
|
if err != nil { return nil, err } |
|
|
|
} |
|
|
|
|
|
|
|
action Priority { |
|
|
|
msg.Priority = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ProxyAuthenticate { |
|
|
|
msg.ProxyAuthenticate = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ProxyAuthorization { |
|
|
|
msg.ProxyAuthorization = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ProxyRequire { |
|
|
|
msg.ProxyRequire = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action RecordRoute { |
|
|
|
*rroutep, err = ParseAddr(string(data[mark:p])) |
|
|
|
if err != nil { return nil, err } |
|
|
|
for *rroutep != nil { rroutep = &(*rroutep).Next } |
|
|
|
} |
|
|
|
|
|
|
|
action ReferTo { |
|
|
|
msg.ReferTo = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action ReferredBy { |
|
|
|
msg.ReferredBy = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action RemotePartyID { |
|
|
|
msg.RemotePartyID, err = ParseAddr(string(data[mark:p])) |
|
|
|
if err != nil { return nil, err } |
|
|
|
} |
|
|
|
|
|
|
|
action Require { |
|
|
|
msg.Require = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action RetryAfter { |
|
|
|
msg.RetryAfter = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Route { |
|
|
|
*routep, err = ParseAddr(string(data[mark:p])) |
|
|
|
if err != nil { return nil, err } |
|
|
|
for *routep != nil { routep = &(*routep).Next } |
|
|
|
} |
|
|
|
|
|
|
|
action Server { |
|
|
|
msg.Server = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Subject { |
|
|
|
msg.Subject = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Supported { |
|
|
|
msg.Supported = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Timestamp { |
|
|
|
msg.Timestamp = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action To { |
|
|
|
msg.To, err = ParseAddr(string(data[mark:p])) |
|
|
|
if err != nil { return nil, err } |
|
|
|
} |
|
|
|
|
|
|
|
action Unsupported { |
|
|
|
msg.Unsupported = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action UserAgent { |
|
|
|
msg.UserAgent = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action Via { |
|
|
|
*viap, err = ParseVia(string(data[mark:p])) |
|
|
|
if err != nil { return nil, err } |
|
|
|
for *viap != nil { viap = &(*viap).Next } |
|
|
|
} |
|
|
|
|
|
|
|
action Warning { |
|
|
|
msg.Warning = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action WWWAuthenticate { |
|
|
|
msg.WWWAuthenticate = string(data[mark:p]) |
|
|
|
} |
|
|
|
|
|
|
|
action lookAheadWSP { p + 2 < pe && (data[p+2] == ' ' || data[p+2] == '\t') } |
|
|
|
|
|
|
|
# https://tools.ietf.org/html/rfc2234 |
|
|
|
@ -357,10 +226,8 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," ; |
|
|
|
mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" ; |
|
|
|
unreserved = alpha | digit | mark ; |
|
|
|
HCOLON = WSP* ":" SWS ; |
|
|
|
tokenc = alpha | digit | "-" | "." | "!" | "%" | "*" | "_" |
|
|
|
| "+" | "`" | "'" | "~" ; |
|
|
|
token = tokenc+ >mark ; |
|
|
|
separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" |
|
|
|
| "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP |
|
|
|
| HTAB ; |
|
|
|
@ -378,6 +245,7 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
COMMA = SWS "," SWS ; |
|
|
|
SEMI = SWS ";" SWS ; |
|
|
|
COLON = SWS ":" SWS ; |
|
|
|
HCOLON = WSP* ":" SWS ; |
|
|
|
LDQUOT = SWS "\"" ; |
|
|
|
RDQUOT = "\"" SWS ; |
|
|
|
ctext = 0x21..0x27 | 0x2A..0x5B | 0x5D..0x7E | UTF8_NONASCII | LWS ; |
|
|
|
@ -389,6 +257,7 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
uric = reserved | unreserved | escaped ; |
|
|
|
uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | "&" | "=" |
|
|
|
| "+" | "$" | "," ; |
|
|
|
token = tokenc+ >mark ; |
|
|
|
reasonc = reserved | unreserved | UTF8_NONASCII | SP | HTAB ; |
|
|
|
reasonmc = escaped | ( reasonc @append ) ; |
|
|
|
cid = word ( "@" word )? ; |
|
|
|
@ -399,69 +268,72 @@ func ParseMsgBytes(data []byte) (msg *Msg, err error) { |
|
|
|
StatusCode = ( digit @StatusCode ) {3}; |
|
|
|
ReasonPhrase = reasonmc+ >start %ReasonPhrase; |
|
|
|
hval = ( UTF8 | LWS )* >mark; |
|
|
|
extHeader = token %extHeaderName HCOLON hval %extHeaderValue; |
|
|
|
|
|
|
|
# http://www.iana.org/assignments/sip-parameters/sip-parameters.xhtml |
|
|
|
stdHeader = "Accept"i HCOLON hval %Accept |
|
|
|
| ("Accept-Contact"i | "a"i) HCOLON hval %AcceptValue |
|
|
|
| "Accept-Encoding"i HCOLON hval %AcceptEncoding |
|
|
|
| "Accept-Language"i HCOLON hval %AcceptLanguage |
|
|
|
| ("Allow"i | "u"i) HCOLON hval %Allow |
|
|
|
| ("Allow-Events"i | "u"i) HCOLON hval %AllowEvents |
|
|
|
| "Alert-Info"i HCOLON hval %AlertInfo |
|
|
|
| "Authentication-Info"i HCOLON hval %AuthenticationInfo |
|
|
|
| "Authorization"i HCOLON hval %Authorization |
|
|
|
| ("Call-ID"i | "i"i) HCOLON cid >mark %CallID |
|
|
|
| ("Contact"i | "m"i) HCOLON hval %Contact |
|
|
|
| "Content-Disposition"i HCOLON hval %ContentDisposition |
|
|
|
| "Content-Language"i HCOLON hval %ContentLanguage |
|
|
|
| ("Content-Length"i | "l"i) HCOLON digit+ @ContentLength |
|
|
|
| ("Content-Encoding"i | "e"i) HCOLON hval %ContentEncoding |
|
|
|
| ("Content-Type"i | "c"i) HCOLON hval %ContentType |
|
|
|
| "CSeq"i HCOLON (digit+ @CSeq) LWS token >mark %CSeqMethod |
|
|
|
| "Call-Info"i HCOLON hval %CallInfo |
|
|
|
| "Date"i HCOLON hval %Date |
|
|
|
| "Error-Info"i HCOLON hval %ErrorInfo |
|
|
|
| ("Event"i | "o"i) HCOLON hval %Event |
|
|
|
| ("Expires"i | "l"i) HCOLON digit+ @Expires |
|
|
|
| ("From"i | "f"i) HCOLON hval %From |
|
|
|
| "In-Reply-To"i HCOLON hval %InReplyTo |
|
|
|
| ("Max-Forwards"i | "l"i) HCOLON digit+ >MaxForwardsZero @MaxForwards |
|
|
|
| ("Min-Expires"i | "l"i) HCOLON digit+ @MinExpires |
|
|
|
| "Reply-To"i HCOLON hval %ReplyTo |
|
|
|
| "MIME-Version"i HCOLON hval %MIMEVersion |
|
|
|
| "Organization"i HCOLON hval %Organization |
|
|
|
| "P-Asserted-Identity"i HCOLON hval %PAssertedIdentity |
|
|
|
| "Priority"i HCOLON hval %Priority |
|
|
|
| "Proxy-Authenticate"i HCOLON hval %ProxyAuthenticate |
|
|
|
| "Proxy-Authorization"i HCOLON hval %ProxyAuthorization |
|
|
|
| "Proxy-Require"i HCOLON hval %ProxyRequire |
|
|
|
| "Record-Route"i HCOLON hval %RecordRoute |
|
|
|
| ("Refer-To"i | "r"i) HCOLON hval %ReferTo |
|
|
|
| ("Referred-By"i | "b"i) HCOLON hval %ReferredBy |
|
|
|
| "Remote-Party-ID"i HCOLON hval %RemotePartyID |
|
|
|
| "Require"i HCOLON hval %Require |
|
|
|
| "Retry-After"i HCOLON hval %RetryAfter |
|
|
|
| "Route"i HCOLON hval %Route |
|
|
|
| "Server"i HCOLON hval %Server |
|
|
|
| ("Subject"i | "s"i) HCOLON hval %Subject |
|
|
|
| ("Supported"i | "k"i) HCOLON hval %Supported |
|
|
|
| "Timestamp"i HCOLON hval %Timestamp |
|
|
|
| ("To"i | "t"i) HCOLON hval %To |
|
|
|
| "Unsupported"i HCOLON hval %Unsupported |
|
|
|
| "User-Agent"i HCOLON hval %UserAgent |
|
|
|
| ("Via"i | "v"i) HCOLON hval %Via |
|
|
|
| "Warning"i HCOLON hval %Warning |
|
|
|
| "WWW-Authenticate"i HCOLON hval %WWWAuthenticate |
|
|
|
; |
|
|
|
|
|
|
|
header = stdHeader CRLF; |
|
|
|
headers = header* CR LF @break; |
|
|
|
|
|
|
|
cheader = ("Call-ID"i | "i"i) HCOLON cid >mark %CallID |
|
|
|
| ("Contact"i | "m"i) HCOLON <: hval %Contact |
|
|
|
| ("Content-Length"i | "l"i) HCOLON digit+ >{clen=0} @ContentLength |
|
|
|
| ("Content-Type"i | "c"i) HCOLON <: hval %ContentType |
|
|
|
| "CSeq"i HCOLON (digit+ @CSeq) LWS token %CSeqMethod |
|
|
|
| ("Expires"i | "l"i) HCOLON digit+ >{msg.Expires=0} @Expires |
|
|
|
| ("From"i | "f"i) HCOLON <: hval %From |
|
|
|
| ("Max-Forwards"i | "l"i) HCOLON digit+ >{msg.MaxForwards=0} @MaxForwards |
|
|
|
| ("Min-Expires"i | "l"i) HCOLON digit+ >{msg.MinExpires=0} @MinExpires |
|
|
|
| "P-Asserted-Identity"i HCOLON <: hval %PAssertedIdentity |
|
|
|
| "Record-Route"i HCOLON <: hval %RecordRoute |
|
|
|
| "Remote-Party-ID"i HCOLON <: hval %RemotePartyID |
|
|
|
| "Route"i HCOLON <: hval %Route |
|
|
|
| ("To"i | "t"i) HCOLON <: hval %To |
|
|
|
| ("Via"i | "v"i) HCOLON <: hval %Via |
|
|
|
; |
|
|
|
|
|
|
|
sname = "Accept"i %{dest=&msg.Accept} |
|
|
|
| ("Accept-Contact"i | "a"i) %{dest=&msg.AcceptContact} |
|
|
|
| "Accept-Encoding"i %{dest=&msg.AcceptEncoding} |
|
|
|
| "Accept-Language"i %{dest=&msg.AcceptLanguage} |
|
|
|
| ("Allow"i | "u"i) %{dest=&msg.Allow} |
|
|
|
| ("Allow-Events"i | "u"i) %{dest=&msg.AllowEvents} |
|
|
|
| "Alert-Info"i %{dest=&msg.AlertInfo} |
|
|
|
| "Authentication-Info"i %{dest=&msg.AuthenticationInfo} |
|
|
|
| "Authorization"i %{dest=&msg.Authorization} |
|
|
|
| "Content-Disposition"i %{dest=&msg.ContentDisposition} |
|
|
|
| "Content-Language"i %{dest=&msg.ContentLanguage} |
|
|
|
| ("Content-Encoding"i | "e"i) %{dest=&msg.ContentEncoding} |
|
|
|
| "Call-Info"i %{dest=&msg.CallInfo} |
|
|
|
| "Date"i %{dest=&msg.Date} |
|
|
|
| "Error-Info"i %{dest=&msg.ErrorInfo} |
|
|
|
| ("Event"i | "o"i) %{dest=&msg.Event} |
|
|
|
| "In-Reply-To"i %{dest=&msg.InReplyTo} |
|
|
|
| "Reply-To"i %{dest=&msg.ReplyTo} |
|
|
|
| "MIME-Version"i %{dest=&msg.MIMEVersion} |
|
|
|
| "Organization"i %{dest=&msg.Organization} |
|
|
|
| "Priority"i %{dest=&msg.Priority} |
|
|
|
| "Proxy-Authenticate"i %{dest=&msg.ProxyAuthenticate} |
|
|
|
| "Proxy-Authorization"i %{dest=&msg.ProxyAuthorization} |
|
|
|
| "Proxy-Require"i %{dest=&msg.ProxyRequire} |
|
|
|
| ("Refer-To"i | "r"i) %{dest=&msg.ReferTo} |
|
|
|
| ("Referred-By"i | "b"i) %{dest=&msg.ReferredBy} |
|
|
|
| "Require"i %{dest=&msg.Require} |
|
|
|
| "Retry-After"i %{dest=&msg.RetryAfter} |
|
|
|
| "Server"i %{dest=&msg.Server} |
|
|
|
| ("Subject"i | "s"i) %{dest=&msg.Subject} |
|
|
|
| ("Supported"i | "k"i) %{dest=&msg.Supported} |
|
|
|
| "Timestamp"i %{dest=&msg.Timestamp} |
|
|
|
| "Unsupported"i %{dest=&msg.Unsupported} |
|
|
|
| "User-Agent"i %{dest=&msg.UserAgent} |
|
|
|
| "Warning"i %{dest=&msg.Warning} |
|
|
|
| "WWW-Authenticate"i %{dest=&msg.WWWAuthenticate} |
|
|
|
; |
|
|
|
|
|
|
|
svalue := hval CR LF @svalueDone @header; |
|
|
|
xheader = token %hname HCOLON @{dest=nil} @svalue; |
|
|
|
header := CR LF @break |
|
|
|
| sname HCOLON <: any @svalue |
|
|
|
| cheader CR LF @header |
|
|
|
; |
|
|
|
|
|
|
|
SIPVersion = "SIP/" SIPVersionNo; |
|
|
|
RequestLine = Method SP RequestURI SP SIPVersion CRLF; |
|
|
|
StatusLine = SIPVersion SP StatusCode SP ReasonPhrase CRLF; |
|
|
|
Request = RequestLine headers; |
|
|
|
Response = StatusLine headers; |
|
|
|
Request = Method SP RequestURI SP SIPVersion CR LF @header; |
|
|
|
Response = SIPVersion SP StatusCode SP ReasonPhrase CR LF @header; |
|
|
|
main := Request | Response; |
|
|
|
|
|
|
|
write init; |
|
|
|
|