| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560 |
- // Copyright 2020 The GoPacket Authors. All rights reserved.
- //
- // Use of this source code is governed by a BSD-style license that can be found
- // in the LICENSE file in the root of the source tree.
- package layers
- import (
- "encoding/binary"
- "fmt"
- "github.com/google/gopacket"
- )
- const (
- // RFC 2865 3. Packet Format
- // `The minimum length is 20 and maximum length is 4096.`
- radiusMinimumRecordSizeInBytes int = 20
- radiusMaximumRecordSizeInBytes int = 4096
- // RFC 2865 5. Attributes
- // `The Length field is one octet, and indicates the length of this Attribute including the Type, Length and Value fields.`
- // `The Value field is zero or more octets and contains information specific to the Attribute.`
- radiusAttributesMinimumRecordSizeInBytes int = 2
- )
- // RADIUS represents a Remote Authentication Dial In User Service layer.
- type RADIUS struct {
- BaseLayer
- Code RADIUSCode
- Identifier RADIUSIdentifier
- Length RADIUSLength
- Authenticator RADIUSAuthenticator
- Attributes []RADIUSAttribute
- }
- // RADIUSCode represents packet type.
- type RADIUSCode uint8
- // constants that define RADIUSCode.
- const (
- RADIUSCodeAccessRequest RADIUSCode = 1 // RFC2865 3. Packet Format
- RADIUSCodeAccessAccept RADIUSCode = 2 // RFC2865 3. Packet Format
- RADIUSCodeAccessReject RADIUSCode = 3 // RFC2865 3. Packet Format
- RADIUSCodeAccountingRequest RADIUSCode = 4 // RFC2865 3. Packet Format
- RADIUSCodeAccountingResponse RADIUSCode = 5 // RFC2865 3. Packet Format
- RADIUSCodeAccessChallenge RADIUSCode = 11 // RFC2865 3. Packet Format
- RADIUSCodeStatusServer RADIUSCode = 12 // RFC2865 3. Packet Format (experimental)
- RADIUSCodeStatusClient RADIUSCode = 13 // RFC2865 3. Packet Format (experimental)
- RADIUSCodeReserved RADIUSCode = 255 // RFC2865 3. Packet Format
- )
- // String returns a string version of a RADIUSCode.
- func (t RADIUSCode) String() (s string) {
- switch t {
- case RADIUSCodeAccessRequest:
- s = "Access-Request"
- case RADIUSCodeAccessAccept:
- s = "Access-Accept"
- case RADIUSCodeAccessReject:
- s = "Access-Reject"
- case RADIUSCodeAccountingRequest:
- s = "Accounting-Request"
- case RADIUSCodeAccountingResponse:
- s = "Accounting-Response"
- case RADIUSCodeAccessChallenge:
- s = "Access-Challenge"
- case RADIUSCodeStatusServer:
- s = "Status-Server"
- case RADIUSCodeStatusClient:
- s = "Status-Client"
- case RADIUSCodeReserved:
- s = "Reserved"
- default:
- s = fmt.Sprintf("Unknown(%d)", t)
- }
- return
- }
- // RADIUSIdentifier represents packet identifier.
- type RADIUSIdentifier uint8
- // RADIUSLength represents packet length.
- type RADIUSLength uint16
- // RADIUSAuthenticator represents authenticator.
- type RADIUSAuthenticator [16]byte
- // RADIUSAttribute represents attributes.
- type RADIUSAttribute struct {
- Type RADIUSAttributeType
- Length RADIUSAttributeLength
- Value RADIUSAttributeValue
- }
- // RADIUSAttributeType represents attribute type.
- type RADIUSAttributeType uint8
- // constants that define RADIUSAttributeType.
- const (
- RADIUSAttributeTypeUserName RADIUSAttributeType = 1 // RFC2865 5.1. User-Name
- RADIUSAttributeTypeUserPassword RADIUSAttributeType = 2 // RFC2865 5.2. User-Password
- RADIUSAttributeTypeCHAPPassword RADIUSAttributeType = 3 // RFC2865 5.3. CHAP-Password
- RADIUSAttributeTypeNASIPAddress RADIUSAttributeType = 4 // RFC2865 5.4. NAS-IP-Address
- RADIUSAttributeTypeNASPort RADIUSAttributeType = 5 // RFC2865 5.5. NAS-Port
- RADIUSAttributeTypeServiceType RADIUSAttributeType = 6 // RFC2865 5.6. Service-Type
- RADIUSAttributeTypeFramedProtocol RADIUSAttributeType = 7 // RFC2865 5.7. Framed-Protocol
- RADIUSAttributeTypeFramedIPAddress RADIUSAttributeType = 8 // RFC2865 5.8. Framed-IP-Address
- RADIUSAttributeTypeFramedIPNetmask RADIUSAttributeType = 9 // RFC2865 5.9. Framed-IP-Netmask
- RADIUSAttributeTypeFramedRouting RADIUSAttributeType = 10 // RFC2865 5.10. Framed-Routing
- RADIUSAttributeTypeFilterId RADIUSAttributeType = 11 // RFC2865 5.11. Filter-Id
- RADIUSAttributeTypeFramedMTU RADIUSAttributeType = 12 // RFC2865 5.12. Framed-MTU
- RADIUSAttributeTypeFramedCompression RADIUSAttributeType = 13 // RFC2865 5.13. Framed-Compression
- RADIUSAttributeTypeLoginIPHost RADIUSAttributeType = 14 // RFC2865 5.14. Login-IP-Host
- RADIUSAttributeTypeLoginService RADIUSAttributeType = 15 // RFC2865 5.15. Login-Service
- RADIUSAttributeTypeLoginTCPPort RADIUSAttributeType = 16 // RFC2865 5.16. Login-TCP-Port
- RADIUSAttributeTypeReplyMessage RADIUSAttributeType = 18 // RFC2865 5.18. Reply-Message
- RADIUSAttributeTypeCallbackNumber RADIUSAttributeType = 19 // RFC2865 5.19. Callback-Number
- RADIUSAttributeTypeCallbackId RADIUSAttributeType = 20 // RFC2865 5.20. Callback-Id
- RADIUSAttributeTypeFramedRoute RADIUSAttributeType = 22 // RFC2865 5.22. Framed-Route
- RADIUSAttributeTypeFramedIPXNetwork RADIUSAttributeType = 23 // RFC2865 5.23. Framed-IPX-Network
- RADIUSAttributeTypeState RADIUSAttributeType = 24 // RFC2865 5.24. State
- RADIUSAttributeTypeClass RADIUSAttributeType = 25 // RFC2865 5.25. Class
- RADIUSAttributeTypeVendorSpecific RADIUSAttributeType = 26 // RFC2865 5.26. Vendor-Specific
- RADIUSAttributeTypeSessionTimeout RADIUSAttributeType = 27 // RFC2865 5.27. Session-Timeout
- RADIUSAttributeTypeIdleTimeout RADIUSAttributeType = 28 // RFC2865 5.28. Idle-Timeout
- RADIUSAttributeTypeTerminationAction RADIUSAttributeType = 29 // RFC2865 5.29. Termination-Action
- RADIUSAttributeTypeCalledStationId RADIUSAttributeType = 30 // RFC2865 5.30. Called-Station-Id
- RADIUSAttributeTypeCallingStationId RADIUSAttributeType = 31 // RFC2865 5.31. Calling-Station-Id
- RADIUSAttributeTypeNASIdentifier RADIUSAttributeType = 32 // RFC2865 5.32. NAS-Identifier
- RADIUSAttributeTypeProxyState RADIUSAttributeType = 33 // RFC2865 5.33. Proxy-State
- RADIUSAttributeTypeLoginLATService RADIUSAttributeType = 34 // RFC2865 5.34. Login-LAT-Service
- RADIUSAttributeTypeLoginLATNode RADIUSAttributeType = 35 // RFC2865 5.35. Login-LAT-Node
- RADIUSAttributeTypeLoginLATGroup RADIUSAttributeType = 36 // RFC2865 5.36. Login-LAT-Group
- RADIUSAttributeTypeFramedAppleTalkLink RADIUSAttributeType = 37 // RFC2865 5.37. Framed-AppleTalk-Link
- RADIUSAttributeTypeFramedAppleTalkNetwork RADIUSAttributeType = 38 // RFC2865 5.38. Framed-AppleTalk-Network
- RADIUSAttributeTypeFramedAppleTalkZone RADIUSAttributeType = 39 // RFC2865 5.39. Framed-AppleTalk-Zone
- RADIUSAttributeTypeAcctStatusType RADIUSAttributeType = 40 // RFC2866 5.1. Acct-Status-Type
- RADIUSAttributeTypeAcctDelayTime RADIUSAttributeType = 41 // RFC2866 5.2. Acct-Delay-Time
- RADIUSAttributeTypeAcctInputOctets RADIUSAttributeType = 42 // RFC2866 5.3. Acct-Input-Octets
- RADIUSAttributeTypeAcctOutputOctets RADIUSAttributeType = 43 // RFC2866 5.4. Acct-Output-Octets
- RADIUSAttributeTypeAcctSessionId RADIUSAttributeType = 44 // RFC2866 5.5. Acct-Session-Id
- RADIUSAttributeTypeAcctAuthentic RADIUSAttributeType = 45 // RFC2866 5.6. Acct-Authentic
- RADIUSAttributeTypeAcctSessionTime RADIUSAttributeType = 46 // RFC2866 5.7. Acct-Session-Time
- RADIUSAttributeTypeAcctInputPackets RADIUSAttributeType = 47 // RFC2866 5.8. Acct-Input-Packets
- RADIUSAttributeTypeAcctOutputPackets RADIUSAttributeType = 48 // RFC2866 5.9. Acct-Output-Packets
- RADIUSAttributeTypeAcctTerminateCause RADIUSAttributeType = 49 // RFC2866 5.10. Acct-Terminate-Cause
- RADIUSAttributeTypeAcctMultiSessionId RADIUSAttributeType = 50 // RFC2866 5.11. Acct-Multi-Session-Id
- RADIUSAttributeTypeAcctLinkCount RADIUSAttributeType = 51 // RFC2866 5.12. Acct-Link-Count
- RADIUSAttributeTypeAcctInputGigawords RADIUSAttributeType = 52 // RFC2869 5.1. Acct-Input-Gigawords
- RADIUSAttributeTypeAcctOutputGigawords RADIUSAttributeType = 53 // RFC2869 5.2. Acct-Output-Gigawords
- RADIUSAttributeTypeEventTimestamp RADIUSAttributeType = 55 // RFC2869 5.3. Event-Timestamp
- RADIUSAttributeTypeCHAPChallenge RADIUSAttributeType = 60 // RFC2865 5.40. CHAP-Challenge
- RADIUSAttributeTypeNASPortType RADIUSAttributeType = 61 // RFC2865 5.41. NAS-Port-Type
- RADIUSAttributeTypePortLimit RADIUSAttributeType = 62 // RFC2865 5.42. Port-Limit
- RADIUSAttributeTypeLoginLATPort RADIUSAttributeType = 63 // RFC2865 5.43. Login-LAT-Port
- RADIUSAttributeTypeTunnelType RADIUSAttributeType = 64 // RFC2868 3.1. Tunnel-Type
- RADIUSAttributeTypeTunnelMediumType RADIUSAttributeType = 65 // RFC2868 3.2. Tunnel-Medium-Type
- RADIUSAttributeTypeTunnelClientEndpoint RADIUSAttributeType = 66 // RFC2868 3.3. Tunnel-Client-Endpoint
- RADIUSAttributeTypeTunnelServerEndpoint RADIUSAttributeType = 67 // RFC2868 3.4. Tunnel-Server-Endpoint
- RADIUSAttributeTypeAcctTunnelConnection RADIUSAttributeType = 68 // RFC2867 4.1. Acct-Tunnel-Connection
- RADIUSAttributeTypeTunnelPassword RADIUSAttributeType = 69 // RFC2868 3.5. Tunnel-Password
- RADIUSAttributeTypeARAPPassword RADIUSAttributeType = 70 // RFC2869 5.4. ARAP-Password
- RADIUSAttributeTypeARAPFeatures RADIUSAttributeType = 71 // RFC2869 5.5. ARAP-Features
- RADIUSAttributeTypeARAPZoneAccess RADIUSAttributeType = 72 // RFC2869 5.6. ARAP-Zone-Access
- RADIUSAttributeTypeARAPSecurity RADIUSAttributeType = 73 // RFC2869 5.7. ARAP-Security
- RADIUSAttributeTypeARAPSecurityData RADIUSAttributeType = 74 // RFC2869 5.8. ARAP-Security-Data
- RADIUSAttributeTypePasswordRetry RADIUSAttributeType = 75 // RFC2869 5.9. Password-Retry
- RADIUSAttributeTypePrompt RADIUSAttributeType = 76 // RFC2869 5.10. Prompt
- RADIUSAttributeTypeConnectInfo RADIUSAttributeType = 77 // RFC2869 5.11. Connect-Info
- RADIUSAttributeTypeConfigurationToken RADIUSAttributeType = 78 // RFC2869 5.12. Configuration-Token
- RADIUSAttributeTypeEAPMessage RADIUSAttributeType = 79 // RFC2869 5.13. EAP-Message
- RADIUSAttributeTypeMessageAuthenticator RADIUSAttributeType = 80 // RFC2869 5.14. Message-Authenticator
- RADIUSAttributeTypeTunnelPrivateGroupID RADIUSAttributeType = 81 // RFC2868 3.6. Tunnel-Private-Group-ID
- RADIUSAttributeTypeTunnelAssignmentID RADIUSAttributeType = 82 // RFC2868 3.7. Tunnel-Assignment-ID
- RADIUSAttributeTypeTunnelPreference RADIUSAttributeType = 83 // RFC2868 3.8. Tunnel-Preference
- RADIUSAttributeTypeARAPChallengeResponse RADIUSAttributeType = 84 // RFC2869 5.15. ARAP-Challenge-Response
- RADIUSAttributeTypeAcctInterimInterval RADIUSAttributeType = 85 // RFC2869 5.16. Acct-Interim-Interval
- RADIUSAttributeTypeAcctTunnelPacketsLost RADIUSAttributeType = 86 // RFC2867 4.2. Acct-Tunnel-Packets-Lost
- RADIUSAttributeTypeNASPortId RADIUSAttributeType = 87 // RFC2869 5.17. NAS-Port-Id
- RADIUSAttributeTypeFramedPool RADIUSAttributeType = 88 // RFC2869 5.18. Framed-Pool
- RADIUSAttributeTypeTunnelClientAuthID RADIUSAttributeType = 90 // RFC2868 3.9. Tunnel-Client-Auth-ID
- RADIUSAttributeTypeTunnelServerAuthID RADIUSAttributeType = 91 // RFC2868 3.10. Tunnel-Server-Auth-ID
- )
- // RADIUSAttributeType represents attribute length.
- type RADIUSAttributeLength uint8
- // RADIUSAttributeType represents attribute value.
- type RADIUSAttributeValue []byte
- // String returns a string version of a RADIUSAttributeType.
- func (t RADIUSAttributeType) String() (s string) {
- switch t {
- case RADIUSAttributeTypeUserName:
- s = "User-Name"
- case RADIUSAttributeTypeUserPassword:
- s = "User-Password"
- case RADIUSAttributeTypeCHAPPassword:
- s = "CHAP-Password"
- case RADIUSAttributeTypeNASIPAddress:
- s = "NAS-IP-Address"
- case RADIUSAttributeTypeNASPort:
- s = "NAS-Port"
- case RADIUSAttributeTypeServiceType:
- s = "Service-Type"
- case RADIUSAttributeTypeFramedProtocol:
- s = "Framed-Protocol"
- case RADIUSAttributeTypeFramedIPAddress:
- s = "Framed-IP-Address"
- case RADIUSAttributeTypeFramedIPNetmask:
- s = "Framed-IP-Netmask"
- case RADIUSAttributeTypeFramedRouting:
- s = "Framed-Routing"
- case RADIUSAttributeTypeFilterId:
- s = "Filter-Id"
- case RADIUSAttributeTypeFramedMTU:
- s = "Framed-MTU"
- case RADIUSAttributeTypeFramedCompression:
- s = "Framed-Compression"
- case RADIUSAttributeTypeLoginIPHost:
- s = "Login-IP-Host"
- case RADIUSAttributeTypeLoginService:
- s = "Login-Service"
- case RADIUSAttributeTypeLoginTCPPort:
- s = "Login-TCP-Port"
- case RADIUSAttributeTypeReplyMessage:
- s = "Reply-Message"
- case RADIUSAttributeTypeCallbackNumber:
- s = "Callback-Number"
- case RADIUSAttributeTypeCallbackId:
- s = "Callback-Id"
- case RADIUSAttributeTypeFramedRoute:
- s = "Framed-Route"
- case RADIUSAttributeTypeFramedIPXNetwork:
- s = "Framed-IPX-Network"
- case RADIUSAttributeTypeState:
- s = "State"
- case RADIUSAttributeTypeClass:
- s = "Class"
- case RADIUSAttributeTypeVendorSpecific:
- s = "Vendor-Specific"
- case RADIUSAttributeTypeSessionTimeout:
- s = "Session-Timeout"
- case RADIUSAttributeTypeIdleTimeout:
- s = "Idle-Timeout"
- case RADIUSAttributeTypeTerminationAction:
- s = "Termination-Action"
- case RADIUSAttributeTypeCalledStationId:
- s = "Called-Station-Id"
- case RADIUSAttributeTypeCallingStationId:
- s = "Calling-Station-Id"
- case RADIUSAttributeTypeNASIdentifier:
- s = "NAS-Identifier"
- case RADIUSAttributeTypeProxyState:
- s = "Proxy-State"
- case RADIUSAttributeTypeLoginLATService:
- s = "Login-LAT-Service"
- case RADIUSAttributeTypeLoginLATNode:
- s = "Login-LAT-Node"
- case RADIUSAttributeTypeLoginLATGroup:
- s = "Login-LAT-Group"
- case RADIUSAttributeTypeFramedAppleTalkLink:
- s = "Framed-AppleTalk-Link"
- case RADIUSAttributeTypeFramedAppleTalkNetwork:
- s = "Framed-AppleTalk-Network"
- case RADIUSAttributeTypeFramedAppleTalkZone:
- s = "Framed-AppleTalk-Zone"
- case RADIUSAttributeTypeAcctStatusType:
- s = "Acct-Status-Type"
- case RADIUSAttributeTypeAcctDelayTime:
- s = "Acct-Delay-Time"
- case RADIUSAttributeTypeAcctInputOctets:
- s = "Acct-Input-Octets"
- case RADIUSAttributeTypeAcctOutputOctets:
- s = "Acct-Output-Octets"
- case RADIUSAttributeTypeAcctSessionId:
- s = "Acct-Session-Id"
- case RADIUSAttributeTypeAcctAuthentic:
- s = "Acct-Authentic"
- case RADIUSAttributeTypeAcctSessionTime:
- s = "Acct-Session-Time"
- case RADIUSAttributeTypeAcctInputPackets:
- s = "Acct-Input-Packets"
- case RADIUSAttributeTypeAcctOutputPackets:
- s = "Acct-Output-Packets"
- case RADIUSAttributeTypeAcctTerminateCause:
- s = "Acct-Terminate-Cause"
- case RADIUSAttributeTypeAcctMultiSessionId:
- s = "Acct-Multi-Session-Id"
- case RADIUSAttributeTypeAcctLinkCount:
- s = "Acct-Link-Count"
- case RADIUSAttributeTypeAcctInputGigawords:
- s = "Acct-Input-Gigawords"
- case RADIUSAttributeTypeAcctOutputGigawords:
- s = "Acct-Output-Gigawords"
- case RADIUSAttributeTypeEventTimestamp:
- s = "Event-Timestamp"
- case RADIUSAttributeTypeCHAPChallenge:
- s = "CHAP-Challenge"
- case RADIUSAttributeTypeNASPortType:
- s = "NAS-Port-Type"
- case RADIUSAttributeTypePortLimit:
- s = "Port-Limit"
- case RADIUSAttributeTypeLoginLATPort:
- s = "Login-LAT-Port"
- case RADIUSAttributeTypeTunnelType:
- s = "Tunnel-Type"
- case RADIUSAttributeTypeTunnelMediumType:
- s = "Tunnel-Medium-Type"
- case RADIUSAttributeTypeTunnelClientEndpoint:
- s = "Tunnel-Client-Endpoint"
- case RADIUSAttributeTypeTunnelServerEndpoint:
- s = "Tunnel-Server-Endpoint"
- case RADIUSAttributeTypeAcctTunnelConnection:
- s = "Acct-Tunnel-Connection"
- case RADIUSAttributeTypeTunnelPassword:
- s = "Tunnel-Password"
- case RADIUSAttributeTypeARAPPassword:
- s = "ARAP-Password"
- case RADIUSAttributeTypeARAPFeatures:
- s = "ARAP-Features"
- case RADIUSAttributeTypeARAPZoneAccess:
- s = "ARAP-Zone-Access"
- case RADIUSAttributeTypeARAPSecurity:
- s = "ARAP-Security"
- case RADIUSAttributeTypeARAPSecurityData:
- s = "ARAP-Security-Data"
- case RADIUSAttributeTypePasswordRetry:
- s = "Password-Retry"
- case RADIUSAttributeTypePrompt:
- s = "Prompt"
- case RADIUSAttributeTypeConnectInfo:
- s = "Connect-Info"
- case RADIUSAttributeTypeConfigurationToken:
- s = "Configuration-Token"
- case RADIUSAttributeTypeEAPMessage:
- s = "EAP-Message"
- case RADIUSAttributeTypeMessageAuthenticator:
- s = "Message-Authenticator"
- case RADIUSAttributeTypeTunnelPrivateGroupID:
- s = "Tunnel-Private-Group-ID"
- case RADIUSAttributeTypeTunnelAssignmentID:
- s = "Tunnel-Assignment-ID"
- case RADIUSAttributeTypeTunnelPreference:
- s = "Tunnel-Preference"
- case RADIUSAttributeTypeARAPChallengeResponse:
- s = "ARAP-Challenge-Response"
- case RADIUSAttributeTypeAcctInterimInterval:
- s = "Acct-Interim-Interval"
- case RADIUSAttributeTypeAcctTunnelPacketsLost:
- s = "Acct-Tunnel-Packets-Lost"
- case RADIUSAttributeTypeNASPortId:
- s = "NAS-Port-Id"
- case RADIUSAttributeTypeFramedPool:
- s = "Framed-Pool"
- case RADIUSAttributeTypeTunnelClientAuthID:
- s = "Tunnel-Client-Auth-ID"
- case RADIUSAttributeTypeTunnelServerAuthID:
- s = "Tunnel-Server-Auth-ID"
- default:
- s = fmt.Sprintf("Unknown(%d)", t)
- }
- return
- }
- // Len returns the length of a RADIUS packet.
- func (radius *RADIUS) Len() (int, error) {
- n := radiusMinimumRecordSizeInBytes
- for _, v := range radius.Attributes {
- alen, err := attributeValueLength(v.Value)
- if err != nil {
- return 0, err
- }
- n += int(alen) + 2 // Added Type and Length
- }
- return n, nil
- }
- // LayerType returns LayerTypeRADIUS.
- func (radius *RADIUS) LayerType() gopacket.LayerType {
- return LayerTypeRADIUS
- }
- // DecodeFromBytes decodes the given bytes into this layer.
- func (radius *RADIUS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
- if len(data) > radiusMaximumRecordSizeInBytes {
- df.SetTruncated()
- return fmt.Errorf("RADIUS length %d too big", len(data))
- }
- if len(data) < radiusMinimumRecordSizeInBytes {
- df.SetTruncated()
- return fmt.Errorf("RADIUS length %d too short", len(data))
- }
- radius.BaseLayer = BaseLayer{Contents: data}
- radius.Code = RADIUSCode(data[0])
- radius.Identifier = RADIUSIdentifier(data[1])
- radius.Length = RADIUSLength(binary.BigEndian.Uint16(data[2:4]))
- if int(radius.Length) > radiusMaximumRecordSizeInBytes {
- df.SetTruncated()
- return fmt.Errorf("RADIUS length %d too big", radius.Length)
- }
- if int(radius.Length) < radiusMinimumRecordSizeInBytes {
- df.SetTruncated()
- return fmt.Errorf("RADIUS length %d too short", radius.Length)
- }
- // RFC 2865 3. Packet Format
- // `If the packet is shorter than the Length field indicates, it MUST be silently discarded.`
- if int(radius.Length) > len(data) {
- df.SetTruncated()
- return fmt.Errorf("RADIUS length %d too big", radius.Length)
- }
- // RFC 2865 3. Packet Format
- // `Octets outside the range of the Length field MUST be treated as padding and ignored on reception.`
- if int(radius.Length) < len(data) {
- df.SetTruncated()
- data = data[:radius.Length]
- }
- copy(radius.Authenticator[:], data[4:20])
- if len(data) == radiusMinimumRecordSizeInBytes {
- return nil
- }
- pos := radiusMinimumRecordSizeInBytes
- for {
- if len(data) == pos {
- break
- }
- if len(data[pos:]) < radiusAttributesMinimumRecordSizeInBytes {
- df.SetTruncated()
- return fmt.Errorf("RADIUS attributes length %d too short", len(data[pos:]))
- }
- attr := RADIUSAttribute{}
- attr.Type = RADIUSAttributeType(data[pos])
- attr.Length = RADIUSAttributeLength(data[pos+1])
- if int(attr.Length) > len(data[pos:]) {
- df.SetTruncated()
- return fmt.Errorf("RADIUS attributes length %d too big", attr.Length)
- }
- if int(attr.Length) < radiusAttributesMinimumRecordSizeInBytes {
- df.SetTruncated()
- return fmt.Errorf("RADIUS attributes length %d too short", attr.Length)
- }
- if int(attr.Length) > radiusAttributesMinimumRecordSizeInBytes {
- attr.Value = make([]byte, attr.Length-2)
- copy(attr.Value[:], data[pos+2:pos+int(attr.Length)])
- radius.Attributes = append(radius.Attributes, attr)
- }
- pos += int(attr.Length)
- }
- for _, v := range radius.Attributes {
- if v.Type == RADIUSAttributeTypeEAPMessage {
- radius.BaseLayer.Payload = append(radius.BaseLayer.Payload, v.Value...)
- }
- }
- return nil
- }
- // SerializeTo writes the serialized form of this layer into the
- // SerializationBuffer, implementing gopacket.SerializableLayer.
- // See the docs for gopacket.SerializableLayer for more info.
- func (radius *RADIUS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
- plen, err := radius.Len()
- if err != nil {
- return err
- }
- if opts.FixLengths {
- radius.Length = RADIUSLength(plen)
- }
- data, err := b.PrependBytes(plen)
- if err != nil {
- return err
- }
- data[0] = byte(radius.Code)
- data[1] = byte(radius.Identifier)
- binary.BigEndian.PutUint16(data[2:], uint16(radius.Length))
- copy(data[4:20], radius.Authenticator[:])
- pos := radiusMinimumRecordSizeInBytes
- for _, v := range radius.Attributes {
- if opts.FixLengths {
- v.Length, err = attributeValueLength(v.Value)
- if err != nil {
- return err
- }
- }
- data[pos] = byte(v.Type)
- data[pos+1] = byte(v.Length)
- copy(data[pos+2:], v.Value[:])
- pos += len(v.Value) + 2 // Added Type and Length
- }
- return nil
- }
- // CanDecode returns the set of layer types that this DecodingLayer can decode.
- func (radius *RADIUS) CanDecode() gopacket.LayerClass {
- return LayerTypeRADIUS
- }
- // NextLayerType returns the layer type contained by this DecodingLayer.
- func (radius *RADIUS) NextLayerType() gopacket.LayerType {
- if len(radius.BaseLayer.Payload) > 0 {
- return LayerTypeEAP
- } else {
- return gopacket.LayerTypeZero
- }
- }
- // Payload returns the EAP Type-Data for EAP-Message attributes.
- func (radius *RADIUS) Payload() []byte {
- return radius.BaseLayer.Payload
- }
- func decodeRADIUS(data []byte, p gopacket.PacketBuilder) error {
- radius := &RADIUS{}
- err := radius.DecodeFromBytes(data, p)
- if err != nil {
- return err
- }
- p.AddLayer(radius)
- p.SetApplicationLayer(radius)
- next := radius.NextLayerType()
- if next == gopacket.LayerTypeZero {
- return nil
- }
- return p.NextDecoder(next)
- }
- func attributeValueLength(v []byte) (RADIUSAttributeLength, error) {
- n := len(v)
- if n > 255 {
- return 0, fmt.Errorf("RADIUS attribute value length %d too long", n)
- } else {
- return RADIUSAttributeLength(n), nil
- }
- }
|