packages feed

radius (empty) → 0.1.0.0

raw patch · 6 files changed

+665/−0 lines, 6 filesdep +basedep +binarydep +bytestringsetup-changed

Dependencies added: base, binary, bytestring, iproute, pretty-hex

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Erick Gonzalez (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,6 @@+# Remote Authentication Dial In User Service (RADIUS)++This module compiles RADIUS packet definitions and different attributes as specified in RFC 2865, as well as de/coding functions to serialize and deserialize RADIUS packets to/from binary data. ++RADIUS extensions in RFC 2869 are also supported, as well as RFC 3162 for IPv6 related attributes+
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ radius.cabal view
@@ -0,0 +1,30 @@+name:                radius+version:             0.1.0.0+synopsis:            Remote Authentication Dial In User Service (RADIUS)+description:         This module provides types and on the wire de/coding of RADIUS packets as per RFC2865+homepage:            https://github.com/erickg/radius#readme+license:             BSD3+license-file:        LICENSE+author:              Erick Gonzalez+maintainer:          erick@codemonkeylabs.de+copyright:           2017 Erick Gonzalez+category:            Network+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Network.RADIUS.Encoding+                     , Network.RADIUS.Types+  build-depends:       base >= 4.7 && < 5+                     , binary+                     , bytestring+                     , iproute+                     , pretty-hex+  default-language:    Haskell2010+  ghc-options:         -Wall++source-repository head+  type:     git+  location: https://github.com/erickg/radius
+ src/Network/RADIUS/Encoding.hs view
@@ -0,0 +1,339 @@+{-# LANGUAGE RecordWildCards #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-|+Module      : Network.RADIUS.Encoding+Description : Provides on the wire de/coding of RADIUS packets as per RFC 3748+Copyright   : (c) Erick Gonzalez, 2017+License     : BSD3+Maintainer  : erick@codemonkeylabs.de+Stability   : experimental+Portability : POSIX++This module provides Binary instances for the RADIUS Packet type and attributes. So you basically decode a (lazy) ByteString and get a RADIUS Packet back or you can encode a RADIUS Packet to a ByteString, which you can then send on the wire as is, etc. Simple as that.++-}++module Network.RADIUS.Encoding where++import Control.Monad               (when)+import Data.Binary                 (Binary(..), encode)+import Data.Binary.Put             (Put, putLazyByteString, putWord8, putWord16be, putWord32be)+import Data.Binary.Get             (Get, getLazyByteString, getWord8, getWord16be, isEmpty)+import Data.ByteString.Lazy.Char8  (ByteString)+import Data.IP                     (IPv4, IPv6)+import Data.Int                    (Int64)+import Data.Word                   (Word8, Word16, Word32)+import Network.RADIUS.Types+import Debug.Trace++import qualified Data.ByteString.Lazy.Char8 as B++-- | Self explanatory. It can be useful when reading a RADIUS packet from a socket for example,+-- so one can retrieve the packet header (containing the packet length) first and then use that+-- to figure out how much data is left to read+radiusHeaderSize :: Word16+radiusHeaderSize = 20++-- | Fixed authenticator length as per RFC 2865+authenticatorLength :: Int64+authenticatorLength = 16++instance Binary Packet where+    put Packet{ getHeader = Header{..} , .. } = do+      let iD         = fromIntegral $ getPacketId+          authLen    = B.length getPacketAuthenticator+          attributes = encodeAttributes getPacketAttributes+          attrsLen   = fromIntegral . B.length $ attributes+      when (authLen /= authenticatorLength) $+           fail $ "RADIUS.Encoding: Invalid Authenticator length " ++ show authLen+      put getPacketType+      putWord8 iD+      putWord16be $ attrsLen + radiusHeaderSize+      putLazyByteString getPacketAuthenticator+      putLazyByteString attributes+    get = do+      header <- decodeHeader+      decodePacket header++-- | Allows decoding of a RADIUS header in the Get Monad+decodeHeader :: Get Header+decodeHeader = do+  packetType    <- get+  iD            <- getWord8+  packetLength  <- getWord16be+  authenticator <- getLazyByteString authenticatorLength+  return Header { getPacketType          = packetType,+                  getPacketId            = iD,+                  getPacketLength        = packetLength,+                  getPacketAuthenticator = authenticator }++-- | Given an already decoded header, this function can be used to decode the complete packet+-- from the available data+decodePacket :: Header -> Get Packet+decodePacket header@Header{..} = do+  attributes <- decodeAttributes []+  return Packet { getHeader           = header,+                  getPacketAttributes = attributes }++instance Binary PacketType where+    put = putEnum+    get = getEnum++-- | Used internally to encode a list of RADIUS attributes. You probably don't need this.+encodeAttributes :: [PacketAttribute] -> ByteString+encodeAttributes = B.concat . fmap encode++-- | Used internally to decode a list of RADIUS attributes. You probably don't need this.+decodeAttributes :: [PacketAttribute] -> Get [PacketAttribute]+decodeAttributes acc = do+  done <- isEmpty+  if done+    then return . reverse $ acc+    else do+      attribute <- get+      decodeAttributes $ attribute : acc++instance Binary IPv4+instance Binary IPv6++instance Binary PacketAttribute where+    put (UserNameAttribute str)                 = putAttributeStr   1 str+    put (UserPasswordAttribute str)             = putAttributeStr   2 str+    put (FramedIPv6Route str)                   = putAttributeStr  99 str+    put (FramedIPv6Pool str)                    = putAttributeStr 100 str+    put (FilterIdAttribute str)                 = putAttributeStr  11 str+    put (ReplyMessageAttribute str)             = putAttributeStr  18 str+    put (CallbackNumberAttribute str)           = putAttributeStr  19 str+    put (CallbackIdAttribute str)               = putAttributeStr  20 str+    put (FramedRouteAttribute str)              = putAttributeStr  22 str+    put (StateAttribute str)                    = putAttributeStr  24 str+    put (ClassAttribute str)                    = putAttributeStr  25 str+    put (CalledStationIdAttribute str)          = putAttributeStr  30 str+    put (CallingStationIdAttribute str)         = putAttributeStr  31 str+    put (NASIdentifierAttribute str)            = putAttributeStr  32 str+    put (ProxyStateAttribute str)               = putAttributeStr  33 str+    put (LoginLATServiceAttribute str)          = putAttributeStr  34 str+    put (LoginLATNodeAttribute str)             = putAttributeStr  35 str+    put (LoginLATGroupAttribute str)            = putAttributeStr  36 str+    put (FramedAppleTalkZoneAttribute str)      = putAttributeStr  39 str+    put (CHAPChallengeAttribute str)            = putAttributeStr  60 str+    put (LoginLATPortAttribute str)             = putAttributeStr  63 str+    put (ARAPPasswordAttribute str)             = putAttributeStr  70 str+    put (ARAPFeaturesAttribute str)             = putAttributeStr  71 str+    put (ARAPSecurityDataAttribute str)         = putAttributeStr  74 str+    put (ConnectInfoAttribute str)              = putAttributeStr  77 str+    put (ConfigurationTokenAttribute str)       = putAttributeStr  78 str+    put (EAPMessageAttribute str)               = putAttributeStr  79 str+    put (MessageAuthenticatorAttribute str)     = putAttributeStr  80 str+    put (ARAPChallengeResponseAttribute str)    = putAttributeStr  84 str+    put (NASPortIdAttribute str)                = putAttributeStr  87 str+    put (FramedPoolAttribute str)               = putAttributeStr  88 str+    put (NASPortAttribute value)                = putAttribute      5 value+    put (FramedMTUAttribute value)              = putAttribute     12 value+    put (LoginTCPPortAttribute value)           = putAttribute     16 value+    put (FramedIPXNetworkAttribute value)       = putAttribute     23 value+    put (SessionTimeoutAttribute value)         = putAttribute     27 value+    put (IdleTimeoutAttribute value)            = putAttribute     28 value+    put (FramedAppleTalkLinkAttribute value)    = putAttribute     37 value+    put (FramedAppleTalkNetworkAttribute value) = putAttribute     38 value+    put (PortLimitAttribute value)              = putAttribute     62 value+    put (NASIPAddress value)                    = putAttribute      4 value+    put (NASIPv6Address value)                  = putAttribute     95 value+    put (ServiceTypeAttribute value)            = putAttribute      6 value+    put (FramedProtocolAttribute value)         = putAttribute      7 value+    put (FramedIPAddressAttribute value)        = putAttribute      8 value+    put (FramedIPNetmaskAttribute value)        = putAttribute      9 value+    put (FramedRoutingAttribute value)          = putAttribute     10 value+    put (FramedCompressionAttribute value)      = putAttribute     13 value+    put (FramedInterfaceIdAttribute value)      = putAttribute     96 value+    put (LoginIPHostAttribute value)            = putAttribute     14 value+    put (LoginIPv6HostAttribute value)          = putAttribute     98 value+    put (LoginServiceAttribute value)           = putAttribute     15 value+    put (TerminationActionAttribute value)      = putAttribute     29 value+    put (NASPortTypeAttribute value)            = putAttribute     61 value+    put (AccountInputGigawordsAttribute value)  = putAttribute     52 value+    put (AccountOutputGigawordsAttribute value) = putAttribute     53 value+    put (EventTimeStampAttribute value)         = putAttribute     55 value+    put (ARAPZoneAccessAttribute value)         = putAttribute     72 value+    put (ARAPSecurityAttribute value)           = putAttribute     73 value+    put (PasswordRetryAttribute value)          = putAttribute     75 value+    put (PromptAttribute value)                 = putAttribute     76 value+    put (AcctInterimIntervalAttribute value)    = putAttribute     85 value+    put (FramedIPv6Prefix prefixLength prefix) = do+      let attr    = encode prefix+          attrLen = 4 + (fromIntegral . B.length $ attr)+      putWord8 97 -- Attribute type+      putWord8 attrLen+      putWord8 0  -- reserved+      putWord8 $ fromIntegral prefixLength+      putLazyByteString attr+    put (VendorSpecificAttribute iD str) = do+      let attrLen = (fromIntegral . B.length $ str) + 6 -- Attribute header length + string+      putWord8 26 -- Attribute Type+      putWord8 attrLen+      put iD+      putLazyByteString str+    put (CHAPPassword identity str)           = do+      let attrLen = (fromIntegral . B.length $ str) + 3 -- Attribute header plus string+      when (attrLen /= 19) $ fail $ "Invalid RADIUS CHAP Password length " ++ show attrLen+      putWord8 3 -- Attribute Type+      putWord8 attrLen+      putWord8 identity+      putLazyByteString str++    get = do+      code <- getWord8+      traceM $ "decode attr " ++ show code+      getAttribute code++-- | For internal use+putAttributeStr :: Word8 -> ByteString -> Put+putAttributeStr code str = do+    putWord8 code+    putWord8 $ (fromIntegral . B.length $ str) + 2 -- attr length + code + len octets+    putLazyByteString str++-- | For internal use+putAttribute :: (Binary a) => Word8 -> a -> Put+putAttribute code attribute = do+    let attrData = encode attribute+        attrLen  = (fromIntegral . B.length $ attrData) + 2 -- attr length + code + len octets+    putWord8 code+    putWord8 attrLen+    putLazyByteString attrData++getAttribute :: Word8 -> Get PacketAttribute+getAttribute   1 = getAttributeStr >>= return . UserNameAttribute+getAttribute   2 = getAttributeStr >>= return . UserPasswordAttribute+getAttribute  99 = getAttributeStr >>= return . FramedIPv6Route+getAttribute 100 = getAttributeStr >>= return . FramedIPv6Pool+getAttribute  11 = getAttributeStr >>= return . FilterIdAttribute+getAttribute  18 = getAttributeStr >>= return . ReplyMessageAttribute+getAttribute  19 = getAttributeStr >>= return . CallbackNumberAttribute+getAttribute  20 = getAttributeStr >>= return . CallbackIdAttribute+getAttribute  22 = getAttributeStr >>= return . FramedRouteAttribute+getAttribute  24 = getAttributeStr >>= return . StateAttribute+getAttribute  25 = getAttributeStr >>= return . ClassAttribute+getAttribute  30 = getAttributeStr >>= return . CalledStationIdAttribute+getAttribute  31 = getAttributeStr >>= return . CallingStationIdAttribute+getAttribute  32 = getAttributeStr >>= return . NASIdentifierAttribute+getAttribute  33 = getAttributeStr >>= return . ProxyStateAttribute+getAttribute  34 = getAttributeStr >>= return . LoginLATServiceAttribute+getAttribute  35 = getAttributeStr >>= return . LoginLATNodeAttribute+getAttribute  36 = getAttributeStr >>= return . LoginLATGroupAttribute+getAttribute  39 = getAttributeStr >>= return . FramedAppleTalkZoneAttribute+getAttribute  60 = getAttributeStr >>= return . CHAPChallengeAttribute+getAttribute  63 = getAttributeStr >>= return . LoginLATPortAttribute+getAttribute  70 = getAttributeStr >>= return . ARAPPasswordAttribute+getAttribute  71 = getAttributeStr >>= return . ARAPFeaturesAttribute+getAttribute  74 = getAttributeStr >>= return . ARAPSecurityDataAttribute+getAttribute  77 = getAttributeStr >>= return . ConnectInfoAttribute+getAttribute  78 = getAttributeStr >>= return . ConfigurationTokenAttribute+getAttribute  79 = getAttributeStr >>= return . EAPMessageAttribute+getAttribute  80 = getAttributeStr >>= return . MessageAuthenticatorAttribute+getAttribute  84 = getAttributeStr >>= return . ARAPChallengeResponseAttribute+getAttribute  87 = getAttributeStr >>= return . NASPortIdAttribute+getAttribute  88 = getAttributeStr >>= return . FramedPoolAttribute+getAttribute 5  = getAttributeValue >>= return . NASPortAttribute+getAttribute 12 = getAttributeValue >>= return . FramedMTUAttribute+getAttribute 16 = getAttributeValue >>= return . LoginTCPPortAttribute+getAttribute 23 = getAttributeValue >>= return . FramedIPXNetworkAttribute+getAttribute 27 = getAttributeValue >>= return . SessionTimeoutAttribute+getAttribute 28 = getAttributeValue >>= return . IdleTimeoutAttribute+getAttribute 37 = getAttributeValue >>= return . FramedAppleTalkLinkAttribute+getAttribute 38 = getAttributeValue >>= return . FramedAppleTalkNetworkAttribute+getAttribute 62 = getAttributeValue >>= return . PortLimitAttribute+getAttribute 4  = getAttributeValue >>= return . NASIPAddress+getAttribute 95 = getAttributeValue >>= return . NASIPv6Address+getAttribute 6  = getAttributeValue >>= return . ServiceTypeAttribute . fromEnum32+getAttribute 7  = getAttributeValue >>= return . FramedProtocolAttribute . fromEnum32+getAttribute 8  = getAttributeValue >>= return . FramedIPAddressAttribute+getAttribute 9  = getAttributeValue >>= return . FramedIPNetmaskAttribute+getAttribute 10 = getAttributeValue >>= return . FramedRoutingAttribute . fromEnum32+getAttribute 13 = getAttributeValue >>= return . FramedCompressionAttribute . fromEnum32+getAttribute 96 = getAttributeValue >>= return . FramedInterfaceIdAttribute+getAttribute 14 = getAttributeValue >>= return . LoginIPHostAttribute+getAttribute 98 = getAttributeValue >>= return . LoginIPv6HostAttribute+getAttribute 15 = getAttributeValue >>= return . LoginServiceAttribute . fromEnum32+getAttribute 29 = getAttributeValue >>= return . TerminationActionAttribute . fromEnum32+getAttribute 61 = getAttributeValue >>= return . NASPortTypeAttribute . fromEnum32+getAttribute 52 = getAttributeValue >>= return . AccountInputGigawordsAttribute+getAttribute 53 = getAttributeValue >>= return . AccountOutputGigawordsAttribute+getAttribute 55 = getAttributeValue >>= return . EventTimeStampAttribute+getAttribute 72 = getAttributeValue >>= return . ARAPZoneAccessAttribute . fromEnum32+getAttribute 73 = getAttributeValue >>= return . ARAPSecurityAttribute+getAttribute 75 = getAttributeValue >>= return . PasswordRetryAttribute+getAttribute 76 = getAttributeValue >>= return . PromptAttribute+getAttribute 85 = getAttributeValue >>= return . AcctInterimIntervalAttribute+getAttribute 97 = do+  attrLen      <- getWord8+  _reserved    <- getWord8+  prefixLength <- getWord8+  when (attrLen /= 20) $ fail $ "Unsupported RADIUS Framed IPv6 Prefix attribute length "+           ++ show attrLen+  prefix <- get+  return $ FramedIPv6Prefix (fromIntegral prefixLength) prefix+getAttribute 26 = do+  attrLen  <- getWord8+  iD       <- get+  attrData <- getLazyByteString . fromIntegral $ attrLen - 6+  return $ VendorSpecificAttribute iD attrData+getAttribute 3 = do+  attrLen  <- getWord8+  when (attrLen /= 19) $ fail $ "Invalid RADIUS CHAP Password length " ++ show attrLen+  identity <- getWord8+  attrData <- getLazyByteString 16 -- CHAP response is always 16 octets+  return $ CHAPPassword identity attrData+getAttribute n  = fail $ "Unknown RADIUS attribute type " ++ show n++-- | For internal use.+getAttributeStr :: Get ByteString+getAttributeStr = getWord8 >>= getLazyByteString . fromIntegral . (subtract 2) -- minus type + len++-- | For internal use.+getAttributeValue :: (Binary a) => Get a+getAttributeValue = getWord8 >> get++instance Binary ServiceType where+    put = putEnum+    get = getEnum++instance Binary FramedProtocol where+    put = putEnum+    get = getEnum++instance Binary FramedRouting where+    put = putEnum+    get = getEnum++instance Binary FramedCompression where+    put = putEnum+    get = getEnum++instance Binary LoginService where+    put = putEnum+    get = getEnum++instance Binary TerminationAction where+    put = putEnum+    get = getEnum++instance Binary NASPortType where+    put = putEnum+    get = getEnum++instance Binary ARAPZoneAccess where+    put = putEnum+    get = getEnum++-- | For internal use.+putEnum :: (Enum a) => a -> Put+putEnum = putWord32be . fromIntegral . fromEnum++-- | For internal use.+getEnum :: (Enum a) => Get a+getEnum = getWord8 >>= return . toEnum . fromIntegral++-- | For internal use.+fromEnum32 :: (Enum a) => Word32 -> a+fromEnum32 = toEnum . fromIntegral
+ src/Network/RADIUS/Types.hs view
@@ -0,0 +1,258 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-|+Module      : Network.RADIUS.Types+Description : Provides types and definitions for RADIUS as per RFC 2865+Copyright   : (c) Erick Gonzalez, 2017+License     : BSD3+Maintainer  : erick@codemonkeylabs.de+Stability   : experimental+Portability : POSIX++This module compiles the RADIUS packet definitions and different attributes as specified in+RFC 2865. The naming conventions from the RFC have been preserved as much as possible, so+it should be straightforward to look up a particular element and understand what it means etc.++RADIUS extensions in RFC 2869 are also supported, as well as RFC 3162 for IPv6 related attributes++-}+module Network.RADIUS.Types where++import Data.ByteString.Lazy.Char8    (ByteString)+import Data.Data                     (Data)+import Data.Word                     (Word8, Word16, Word32, Word64)+import Data.IP                       (IPv4, IPv6)+import Data.Int                      (Int8)++data Header = Header { getPacketType          :: PacketType,+                       getPacketId            :: Word8,+                       getPacketLength        :: Word16,+                       getPacketAuthenticator :: ByteString }+              deriving (Show, Eq)++data Packet = Packet { getHeader           :: Header,+                       getPacketAttributes :: [PacketAttribute] }+              deriving (Show, Eq)++data PacketType = AccessRequest+                | AccessAccept+                | AccessReject+                | AccountingRequest+                | AccountingResponse+                | AccessChallenge+                | StatusServer+                | StatusClient+                  deriving (Show, Eq)+++instance Enum PacketType where+    fromEnum AccessRequest      = 1+    fromEnum AccessAccept       = 2+    fromEnum AccessReject       = 3+    fromEnum AccountingRequest  = 4+    fromEnum AccountingResponse = 5+    fromEnum AccessChallenge    = 11+    fromEnum StatusServer       = 12+    fromEnum StatusClient       = 13+    toEnum 1  = AccessRequest+    toEnum 2  = AccessAccept+    toEnum 3  = AccessReject+    toEnum 4  = AccountingRequest+    toEnum 5  = AccountingResponse+    toEnum 11 = AccessChallenge+    toEnum 12 = StatusServer+    toEnum 13 = StatusClient+    toEnum x  = error $ "Invalid RADIUS packet type " ++ show x++data PacketAttribute =+    UserNameAttribute               { getUserNameAttribute               :: ByteString        }+  | UserPasswordAttribute           { getUserPasswordAttribute           :: ByteString        }+  | CHAPPassword                    { getCHAPIdentity                    :: Word8,+                                      getCHAPPasswordAttribute           :: ByteString        }+  | NASIPAddress                    { getNASIPAddress                    :: IPv4              }+  | NASIPv6Address                  { getNASIPv6Address                  :: IPv6              }+  | NASPortAttribute                { getNASPortAttribute                :: Word32            }+  | ServiceTypeAttribute            { getServiceTypeAttribute            :: ServiceType       }+  | FramedProtocolAttribute         { getFramedProtocolAttribute         :: FramedProtocol    }+  | FramedIPAddressAttribute        { getFramedIPAddressAttribute        :: IPv4              }+  | FramedIPNetmaskAttribute        { getFramedIPNetmaskAttribute        :: IPv4              }+  | FramedRoutingAttribute          { getFramedRoutingAttribute          :: FramedRouting     }+  | FramedInterfaceIdAttribute      { getFramedInterfaceIdAttribute      :: Word64            }+  | FramedIPv6Prefix                { getFramedIPv6PrefixLength          :: Int8,+                                      getFramedIPv6Prefix                :: IPv6              }+  | FramedIPv6Route                 { getFramedIPv6RouteAttribute        :: ByteString        }+  | FramedIPv6Pool                  { getFramedIPv6PoolAttribute         :: ByteString        }+  | FilterIdAttribute               { getFilterIdAttribute               :: ByteString        }+  | FramedMTUAttribute              { getFramedMTUAttribute              :: Word32            }+  | FramedCompressionAttribute      { getFramedCompressionAttribute      :: FramedCompression }+  | LoginIPHostAttribute            { getLoginIPHostAttribute            :: IPv4              }+  | LoginIPv6HostAttribute          { getLoginIPv6HostAttribute          :: IPv6              }+  | LoginServiceAttribute           { getLoginServiceAttribute           :: LoginService      }+  | LoginTCPPortAttribute           { getLoginTCPPortAttribute           :: Word32            }+  | ReplyMessageAttribute           { getReplyMessageAttribute           :: ByteString        }+  | CallbackNumberAttribute         { getCallbackNumberAttribute         :: ByteString        }+  | CallbackIdAttribute             { getCallbackIdAttribute             :: ByteString        }+  | FramedRouteAttribute            { getFramedRouteAttribute            :: ByteString        }+  | FramedIPXNetworkAttribute       { getFramedIPXNetworkAttribute       :: Word32            }+  | StateAttribute                  { getStateAttribute                  :: ByteString        }+  | ClassAttribute                  { getClassAttribute                  :: ByteString        }+  | VendorSpecificAttribute         { getVendorSpecificAttributeId       :: Word32,+                                      getVendorSpecificAttribute         :: ByteString        }+  | SessionTimeoutAttribute         { getSessionTimeoutAttribute         :: Word32            }+  | IdleTimeoutAttribute            { getIdleTimeoutAttribute            :: Word32            }+  | TerminationActionAttribute      { getTerminationActionAttribute      :: TerminationAction }+  | CalledStationIdAttribute        { getCalledStationIdAttribute        :: ByteString        }+  | CallingStationIdAttribute       { getCallingStationIdAttribute       :: ByteString        }+  | NASIdentifierAttribute          { getNASIdentifierAttribute          :: ByteString        }+  | ProxyStateAttribute             { getProxyStateAttribute             :: ByteString        }+  | LoginLATServiceAttribute        { getLoginLATServiceAttribute        :: ByteString        }+  | LoginLATNodeAttribute           { getLoginLATNodeAttribute           :: ByteString        }+  | LoginLATGroupAttribute          { getLoginLATGroupAttribute          :: ByteString        }+  | FramedAppleTalkLinkAttribute    { getFramedAppleTalkLinkAttribute    :: Word32            }+  | FramedAppleTalkNetworkAttribute { getFramedAppleTalkNetworkAttribute :: Word32            }+  | FramedAppleTalkZoneAttribute    { getFramedAppleTalkZoneAttribute    :: ByteString        }+  | CHAPChallengeAttribute          { getCHAPChallengeAttribute          :: ByteString        }+  | NASPortTypeAttribute            { getNASPortTypeAttribute            :: NASPortType       }+  | PortLimitAttribute              { getPortLimitAttribute              :: Word32            }+  | LoginLATPortAttribute           { getLoginLATPortAttribute           :: ByteString        }+  | AccountInputGigawordsAttribute  { getAccountInputGigawordsAttribute  :: Word32            }+  | AccountOutputGigawordsAttribute { getAccountOutputGigawordsAttribute :: Word32            }+  | EventTimeStampAttribute         { getEventTimeStampAttribute         :: Word32            }+  | ARAPPasswordAttribute           { getARAPPasswordAttribute           :: ByteString        }+  | ARAPFeaturesAttribute           { getARAPFeaturesAttribute           :: ByteString        }+  | ARAPZoneAccessAttribute         { getARAPZoneAccessAttribute         :: ARAPZoneAccess    }+  | ARAPSecurityAttribute           { getARAPSecurityAttribute           :: Word32            }+  | ARAPSecurityDataAttribute       { getARAPSecurityDataAttribute       :: ByteString        }+  | PasswordRetryAttribute          { getPasswordRetryAttribute          :: Word32            }+  | PromptAttribute                 { getPromptAttribute                 :: Word32            }+  | ConnectInfoAttribute            { getConnectInfoAttribute            :: ByteString        }+  | ConfigurationTokenAttribute     { getConfigurationTokenAttribute     :: ByteString        }+  | EAPMessageAttribute             { getEAPMessageAttribute             :: ByteString        }+  | MessageAuthenticatorAttribute   { getMessageAuthenticatorAttribute   :: ByteString        }+  | ARAPChallengeResponseAttribute  { getARAPChallengeResponseAttribute  :: ByteString        }+  | AcctInterimIntervalAttribute    { getAcctInterimIntervalAttribute    :: Word32            }+  | NASPortIdAttribute              { getNASPortIdAttribute              :: ByteString        }+  | FramedPoolAttribute             { getFramedPoolAttribute             :: ByteString        }+  deriving (Show, Eq, Data)+++data ServiceType = LoginService+                 | FramedService+                 | CallbackLoginService+                 | CallbackFramedService+                 | OutboundService+                 | AdministrativeService+                 | NASPromptService+                 | AuthenticateOnlyService+                 | CallbackNASPrompt+                 | CallCheckService+                 | CallbackAdministrativeService+                   deriving (Show, Eq, Data)++instance Enum ServiceType where+    fromEnum LoginService                  = 1+    fromEnum FramedService                 = 2+    fromEnum CallbackLoginService          = 3+    fromEnum CallbackFramedService         = 4+    fromEnum OutboundService               = 5+    fromEnum AdministrativeService         = 6+    fromEnum NASPromptService              = 7+    fromEnum AuthenticateOnlyService       = 8+    fromEnum CallbackNASPrompt             = 9+    fromEnum CallCheckService              = 10+    fromEnum CallbackAdministrativeService = 11+    toEnum 1  = LoginService+    toEnum 2  = FramedService+    toEnum 3  = CallbackLoginService+    toEnum 4  = CallbackFramedService+    toEnum 5  = OutboundService+    toEnum 6  = AdministrativeService+    toEnum 7  = NASPromptService+    toEnum 8  = AuthenticateOnlyService+    toEnum 9  = CallbackNASPrompt+    toEnum 10 = CallCheckService+    toEnum 11 = CallbackAdministrativeService+    toEnum x  = error $ "Invalid RADIUS service type " ++ show x++data FramedProtocol = PPPFramedProtocol+                    | SLIPFramedProtocol+                    | ARAPFramedProtocol+                    | GandalfFramedProtocol+                    | XylogicsFramedProtocol+                    | X75FramedProtocol+                      deriving (Show, Eq, Data)++instance Enum FramedProtocol where+    fromEnum PPPFramedProtocol      = 1+    fromEnum SLIPFramedProtocol     = 2+    fromEnum ARAPFramedProtocol     = 3+    fromEnum GandalfFramedProtocol  = 4+    fromEnum XylogicsFramedProtocol = 5+    fromEnum X75FramedProtocol      = 6+    toEnum 1 = PPPFramedProtocol+    toEnum 2 = SLIPFramedProtocol+    toEnum 3 = ARAPFramedProtocol+    toEnum 4 = GandalfFramedProtocol+    toEnum 5 = XylogicsFramedProtocol+    toEnum 6 = X75FramedProtocol+    toEnum x = error $ "Invalid framed protocol " ++ show x++data FramedRouting = NoneFramedRouting+                   | SendFramedRouting+                   | ListenFramedRouting+                   | SendAndListenFramedRouting+                     deriving (Show, Eq, Enum, Data)++data FramedCompression = NoCompression+                       | VJTCPIPHeaderCompression+                       | IPXHeaderCompression+                       | StacLZSCompression+                         deriving (Show, Eq, Enum, Data)++data LoginService = TelnetService+                  | RloginService+                  | TCPClearService+                  | PortMasterService+                  | LATService+                  | X25PADService+                  | X25T3POSService+                  | UnusedService+                  | TCPClearQuietService+                    deriving (Show, Eq, Enum, Data)++data TerminationAction = DefaultTerminationAction | RADIUSRequestTerminationAction+                       deriving (Show, Eq, Enum, Data)++data NASPortType = AsyncNASPort+                 | SyncNASPort+                 | ISDNSyncPort+                 | ISDNAsyncV120Port+                 | VirtualNASPort+                 | PIAFSNASPort+                 | HDLCClearChannelNASPort+                 | X25NASPort+                 | X75NASPort+                 | G3FaxNASPort+                 | SDSLNASPort+                 | ADSLCAPNASPort+                 | ADSLDMTNASPort+                 | IDSLNASPort+                 | EthernetNASPort+                 | XDSLNASPort+                 | CableNASPort+                 | WirelessOtherNASPort+                 | WirelessIEEE80211NASPort+                   deriving (Show, Eq, Enum, Data)++data ARAPZoneAccess = DefaultZoneOnlyARAPAccess+                    | UseZoneFilterInclusivelyARAPAccess+                    | UseZoneFilterExclusivelyARAPAccess+                    deriving (Show, Eq, Data)++instance Enum ARAPZoneAccess where+    toEnum 1 = DefaultZoneOnlyARAPAccess+    toEnum 2 = UseZoneFilterInclusivelyARAPAccess+    toEnum 4 = UseZoneFilterExclusivelyARAPAccess+    toEnum n = error $ "Invalid RADIUS ARAP Zone Access " ++ show n+    fromEnum DefaultZoneOnlyARAPAccess = 1+    fromEnum UseZoneFilterInclusivelyARAPAccess = 2+    fromEnum UseZoneFilterExclusivelyARAPAccess = 4