-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | High level configuration and control of computer networks. -- -- This module provides a logical representation of the messages of the -- OpenFlow protocol (http://www.openflowswitch.org) and -- implements the binary formats for these messages. This module also -- provides TCP servers that accept connections from switches and provide -- methods to receive messages from and send messages to connected -- switches. The library is under active development and should still be -- considered experimental. @package nettle-openflow @version 0.1 module Nettle.OpenFlow.Error -- | When a switch encounters an error condition, it sends the controller a -- message containing the information in SwitchErrorRecord. data SwitchError HelloFailed :: HelloFailure -> String -> SwitchError BadRequest :: RequestError -> [Word8] -> SwitchError BadAction :: ActionError -> [Word8] -> SwitchError FlowModFailed :: FlowModError -> [Word8] -> SwitchError PortModFailed :: PortModError -> [Word8] -> SwitchError QueueOperationFailed :: QueueOpError -> [Word8] -> SwitchError data HelloFailure IncompatibleVersions :: HelloFailure HelloPermissionsError :: HelloFailure data RequestError VersionNotSupported :: RequestError MessageTypeNotSupported :: RequestError StatsRequestTypeNotSupported :: RequestError VendorNotSupported :: RequestError VendorSubtypeNotSupported :: RequestError RequestPermissionsError :: RequestError BadRequestLength :: RequestError BufferEmpty :: RequestError UnknownBuffer :: RequestError data ActionError UnknownActionType :: ActionError BadActionLength :: ActionError UnknownVendorID :: ActionError UnknownActionTypeForVendor :: ActionError BadOutPort :: ActionError BadActionArgument :: ActionError ActionPermissionsError :: ActionError TooManyActions :: ActionError InvalidQueue :: ActionError data FlowModError TablesFull :: FlowModError OverlappingFlow :: FlowModError FlowModPermissionsError :: FlowModError EmergencyModHasTimeouts :: FlowModError BadCommand :: FlowModError UnsupportedActionList :: FlowModError data PortModError BadPort :: PortModError BadHardwareAddress :: PortModError data QueueOpError QueueOpBadPort :: QueueOpError QueueDoesNotExist :: QueueOpError QueueOpPermissionsError :: QueueOpError instance Show QueueOpError instance Eq QueueOpError instance Ord QueueOpError instance Enum QueueOpError instance Show PortModError instance Eq PortModError instance Ord PortModError instance Enum PortModError instance Show FlowModError instance Eq FlowModError instance Ord FlowModError instance Enum FlowModError instance Show ActionError instance Eq ActionError instance Ord ActionError instance Enum ActionError instance Show RequestError instance Eq RequestError instance Ord RequestError instance Enum RequestError instance Show HelloFailure instance Eq HelloFailure instance Ord HelloFailure instance Enum HelloFailure instance Show SwitchError instance Eq SwitchError module Nettle.Servers.TwoWayChannel data Chan2 a b c whenDead :: Chan2 a b c -> IO c kill :: Chan2 a b c -> c -> IO () newChan2 :: IO (Chan2 a b c) readChan2 :: Chan2 a b c -> IO a writeChan2 :: Chan2 a b c -> b -> IO () getChanContents2 :: Chan2 a b c -> IO [a] writeList2Chan2 :: Chan2 a b c -> [b] -> IO () theOtherEnd2 :: Chan2 a b c -> Chan2 b a c -- | This module receives messages from external network components, such -- as, authentication portals, intrusion detection systems, vulnerability -- scanners, etc. These components are not necessarily written in Haskell -- or depend on Nettle; thus, the module acts an interface to the outside -- world. -- -- This module interacts with external components via a threaded TCP -- server. Users of this module are given a channel on which they can -- receive messages from external components. -- -- This module also assists in writing messenger clients that send -- messages to the server. Note that these clients need not be written in -- Haskell; it would be trivial to write a messenger client in another -- language. We provide a messenger client here for your reference and -- for convenience of integrating external Haskell components with -- Nettle. -- -- Messages are plain text; it is your responsibility to impose semantics -- for these strings and ensure that messages from different components -- don't clash. (For example, I recommend that all messages from a -- vulnerability scanner be prefixed with "Scanner", messages from a Web -- portal be prefixed with "Portal", etc.) module Nettle.Servers.MessengerServer type Message = String -- | Run a server that listens for connections from external messenger -- components. The server is run in a separate thread; the current thread -- returns a channel to the user where he can receive messages from the -- external components. Messages are annotated with the client's address -- information. messengerServer :: PortID -> IO (Chan (SockAddr, Message)) -- | Connect to a messenger server (i.e., a Nettle controller that runs -- messengerServer) and send messages. Note that although this function -- returns a bidirectional channel for both sending and receiving -- messages from the server, the server currently does not send any -- messages. messengerClient :: HostName -> PortID -> (Chan2 (Maybe Message) (Maybe Message) () -> IO ()) -> IO () instance Typeable DeadException instance Show DeadException instance Exception DeadException -- | Provides a generic TCP server, parameterized over the server's -- listening port and the types of messages received from and sent to -- clients. module Nettle.Servers.TCPServer -- | tcpServer starts a TCP server at the given port number, waiting for -- new connections. Whenever a new connection is established, new threads -- are created for reading and writing to the thread, using the given tcp -- message driver. The socket address of the other side of the -- connection, along with a pair of channels for the incoming messages -- and outgoing messages is placed on the result channel. This method -- returns immediately. tcpServer :: Show a => ServerPortNumber -> TCPMessageDriver a b -> IO ([Peer a b]) type ServerPortNumber = Word16 -- | A TCPMessageDriver a b is used by the tcpServer to -- read messages of type a from the underlying TCP sockets with -- peers as well as write messages of type b to the TCP sockets. data TCPMessageDriver a b TCPMessageDriver :: (Handle -> IO (Maybe a)) -> (b -> Handle -> IO ()) -> TCPMessageDriver a b -- | Method to read a value from the handle. Returns Nothing if -- the read failed. getMessage :: TCPMessageDriver a b -> Handle -> IO (Maybe a) -- | Method to write a value to a handle. putMessage :: TCPMessageDriver a b -> b -> Handle -> IO () -- | A Peer is a TCP peer. It consists of a SockAddr value giving -- the the socket address of the peer, as well as a Process -- value which provides methods to access messages received from the peer -- and send messages to a peer. type Peer a b = (SockAddr, Process a b IOException) -- | A Process a b c represents a process with an API that allows -- another IO computation to observe its outputs (of type a), to -- supply it with inputs (of type b), and to observe when it -- terminates. data Process a b c Process :: IO a -> (b -> IO ()) -> IO c -> Process a b c -- | interact with the process by receiving one of its outputs; should -- block until the process emits a value. readP :: Process a b c -> IO a -- | interact with the process by sending it an input; should be -- non-blocking. tellP :: Process a b c -> b -> IO () -- | should block until the process terminates, carrying an output value of -- type c. whenDeadP :: Process a b c -> IO c -- | Read all of the output from the process as a lazy stream. readAll :: Process a b c -> IO [a] -- | Write a list to the process; does not return until every element of -- the list has been sent to the process. writeAll :: Process a b c -> [b] -> IO () data SockAddr :: * instance Ord SockAddr -- | This module provides a TCP server that multiplexes incoming and -- outgoing messages from many connected peers onto a single pair of -- input and output channels. The socket address of the peer is used to -- identify the source and destination of messages. -- -- This interface introduces a new error condition: that a message on the -- outgoing channel has a socket address for which no socket exists. This -- may occur because of incorrect usage of this library, or because a -- peer disconnected after the client placed a message on the outgoing -- channel, but before that message was sent. Currently, the server does -- not notify its caller of the occurrence of this error. module Nettle.Servers.MultiplexedTCPServer -- | Runs a TCP server returning a process that outputs messages of type -- a from connected peers, tagged with their SockAddr, -- and accepts messages of type b for peers, again tagged with -- their SockAddr. muxedTCPServer :: Show a => ServerPortNumber -> TCPMessageDriver a b -> IO (MultiplexedProcess a b) -- | A multiplexed process has inputs and outputs that are tagged with the -- SockAddr of the sending or receiving peer, and carries -- connection start and connection end events. type MultiplexedProcess a b = Process (TCPMessage a) (SockAddr, b) IOException -- | The type of externally visible events that may occur for the -- multiplexed TCP server. data TCPMessage a -- | A connection to a peer with the given address is established. ConnectionEstablished :: SockAddr -> TCPMessage a -- | A connection with the given address is terminated, due to the given -- exception. ConnectionTerminated :: SockAddr -> IOException -> TCPMessage a -- | A message of type a has been received from the peer with the -- given address. PeerMessage :: SockAddr -> a -> TCPMessage a instance Show a => Show (TCPMessage a) instance Eq a => Eq (TCPMessage a) module Nettle.IPv4.IPAddress newtype IPAddress IPAddress :: Word32 -> IPAddress type IPAddressPrefix = (IPAddress, PrefixLength) type PrefixLength = Word8 ipAddressToWord32 :: IPAddress -> Word32 ipAddress :: Word8 -> Word8 -> Word8 -> Word8 -> IPAddress getIPAddress :: Get IPAddress putIPAddress :: IPAddress -> Put (//) :: IPAddress -> PrefixLength -> IPAddressPrefix addressPart :: IPAddressPrefix -> IPAddress prefixLength :: IPAddressPrefix -> PrefixLength maxPrefixLen :: Word8 prefixIsExact :: IPAddressPrefix -> Bool addressToOctets :: IPAddress -> (Word8, Word8, Word8, Word8) showOctets :: IPAddress -> String showPrefix :: IPAddressPrefix -> String prefixPlus :: IPAddressPrefix -> Word32 -> IPAddress prefixOverlaps :: IPAddressPrefix -> IPAddressPrefix -> Bool elemOfPrefix :: IPAddress -> IPAddressPrefix -> Bool intersect :: IPAddressPrefix -> IPAddressPrefix -> Maybe IPAddressPrefix intersects :: [IPAddressPrefix] -> Maybe IPAddressPrefix disjoint :: IPAddressPrefix -> IPAddressPrefix -> Bool disjoints :: [IPAddressPrefix] -> Bool isSubset :: IPAddressPrefix -> IPAddressPrefix -> Bool parseIPAddress :: String -> Maybe IPAddress ipAddressParser :: CharParser () IPAddress instance Read IPAddress instance Eq IPAddress instance Show IPAddress instance Ord IPAddress instance Binary IPAddress -- | This module provides Get values for parsing various IP -- packets and headers from ByteStrings into a byte-sequence-independent -- representation as Haskell datatypes. -- -- Warning: -- -- These are incomplete. The headers may not contain all the information -- that the protocols specify. For example, the Haskell representation of -- an IP Header only includes source and destination addresses and IP -- protocol number, even though an IP packet has many more header fields. -- More seriously, an IP header may have an optional extra headers -- section after the destination address. We assume this is not present. -- If it is present, then the transport protocol header will not be -- directly after the destination address, but will be after these -- options. Therefore functions that assume this, such as the -- getExactMatch function below, will give incorrect results when applied -- to such IP packets. -- -- The Haskell representations of the headers for the transport protocols -- are similarly incomplete. Again, the Get instances for the transport -- protocols may not parse through the end of the transport protocol -- header. module Nettle.IPv4.IPPacket -- | An IP packet consists of a header and a body. data IPPacket IPPacket :: IPHeader -> IPBody -> IPPacket -- | An IP Header includes various information about the packet, including -- the type of payload it contains. Warning: this definition does not -- include every header field included in an IP packet. data IPHeader IPHeader :: IPAddress -> IPAddress -> IPProtocol -> Int -> Int -> DifferentiatedServicesCodePoint -> IPHeader ipSrcAddress :: IPHeader -> IPAddress ipDstAddress :: IPHeader -> IPAddress ipProtocol :: IPHeader -> IPProtocol headerLength :: IPHeader -> Int totalLength :: IPHeader -> Int -- | differentiated services code point - 6 bit number dscp :: IPHeader -> DifferentiatedServicesCodePoint type DifferentiatedServicesCodePoint = Word8 type FragOffset = Word16 type IPProtocol = Word8 type IPTypeOfService = Word8 type TransportPort = Word16 ipTypeTcp :: IPProtocol ipTypeUdp :: IPProtocol ipTypeIcmp :: IPProtocol -- | The body of an IP packet can be either a TCP, UDP, ICMP or other -- packet. Packets other than TCP, UDP, ICMP are represented as unparsed -- ByteString values. data IPBody TCPInIP :: TCPHeader -> IPBody UDPInIP :: UDPHeader -> IPBody ICMPInIP :: ICMPHeader -> IPBody UninterpretedIPBody :: ByteString -> IPBody getIPPacket :: Get IPPacket getIPHeader :: Get IPHeader type ICMPHeader = (ICMPType, ICMPCode) type ICMPType = Word8 type ICMPCode = Word8 getICMPHeader :: Get ICMPHeader type TCPHeader = (TCPPortNumber, TCPPortNumber) type TCPPortNumber = Word16 getTCPHeader :: Get TCPHeader type UDPHeader = (UDPPortNumber, UDPPortNumber) type UDPPortNumber = Word16 getUDPHeader :: Get UDPHeader -- | The FramedMessage class defines the class of data types which -- represents messages having source and destination addresses and a -- message body. class FramedMessage m a b | m -> a, m -> b body :: FramedMessage m a b => m -> b sourceAddress :: FramedMessage m a b => m -> a destAddress :: FramedMessage m a b => m -> a instance Show IPBody instance Eq IPBody instance Read IPHeader instance Show IPHeader instance Eq IPHeader instance Show IPPacket instance Eq IPPacket instance FramedMessage IPPacket IPAddress IPBody module Nettle.Ethernet.EthernetAddress -- | An Ethernet address consists of 6 bytes. data EthernetAddress EthernetAddress :: Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> Word8 -> EthernetAddress isReserved :: EthernetAddress -> Bool -- | Parse an Ethernet address from a ByteString getEthernetAddress :: Get EthernetAddress -- | Unparse an Ethernet address to a ByteString putEthernetAddress :: EthernetAddress -> Put instance Show EthernetAddress instance Read EthernetAddress instance Eq EthernetAddress instance Ord EthernetAddress -- | This module provides data structures for Ethernet frames as well as -- parsers and unparsers for Ethernet frames. module Nettle.Ethernet.EthernetFrame -- | An Ethernet frame consists of an Ethernet header and an Ethernet body. data EthernetFrame EthernetFrame :: EthernetHeader -> EthernetBody -> EthernetFrame data EthernetHeader EthernetHeader :: EthernetAddress -> EthernetAddress -> EthernetTypeCode -> EthernetHeader destMACAddress :: EthernetHeader -> EthernetAddress sourceMACAddress :: EthernetHeader -> EthernetAddress typeCode :: EthernetHeader -> EthernetTypeCode Ethernet8021Q :: EthernetAddress -> EthernetAddress -> EthernetTypeCode -> VLANPriority -> Bool -> VLANID -> EthernetHeader destMACAddress :: EthernetHeader -> EthernetAddress sourceMACAddress :: EthernetHeader -> EthernetAddress typeCode :: EthernetHeader -> EthernetTypeCode priorityCodePoint :: EthernetHeader -> VLANPriority canonicalFormatIndicator :: EthernetHeader -> Bool vlanId :: EthernetHeader -> VLANID -- | Ethernet type code, determines the type of payload carried by an -- Ethernet frame. type EthernetTypeCode = Word16 ethTypeVLAN :: EthernetTypeCode ethTypeIP :: EthernetTypeCode ethTypeARP :: EthernetTypeCode ethTypeLLDP :: EthernetTypeCode typeEth2Cutoff :: EthernetTypeCode type VLANPriority = Word8 type VLANID = Word16 -- | The body of an Ethernet frame is either an IP packet, an ARP packet, -- or an uninterpreted ByteString data EthernetBody IPInEthernet :: IPPacket -> EthernetBody ARPInEthernet :: ARPPacket -> EthernetBody UninterpretedEthernetBody :: ByteString -> EthernetBody -- | An ARP packet data ARPPacket ARPPacket :: ARPOpCode -> EthernetAddress -> IPAddress -> EthernetAddress -> IPAddress -> ARPPacket arpOpCode :: ARPPacket -> ARPOpCode senderEthernetAddress :: ARPPacket -> EthernetAddress senderIPAddress :: ARPPacket -> IPAddress targetEthernetAddress :: ARPPacket -> EthernetAddress targetIPAddress :: ARPPacket -> IPAddress -- | Type of ARP message. data ARPOpCode ARPRequest :: ARPOpCode ARPReply :: ARPOpCode -- | Type of parsers that can fail with an error message type GetE a = ErrorT ErrorMessage Get a -- | When a GetE parser fails, it provides an error message as a -- string type ErrorMessage = String -- | Method to run a GetE parser runGetE :: GetE a -> ByteString -> Either ErrorMessage a -- | Parser for Ethernet frames. getEthernetFrame :: GetE EthernetFrame -- | Parser for Ethernet headers. getEthHeader :: GetE EthernetHeader -- | Unparser for Ethernet headers. putEthHeader :: EthernetHeader -> Put -- | Parser for ARP packets getARPPacket :: GetE ARPPacket instance Show ARPOpCode instance Eq ARPOpCode instance Show ARPPacket instance Eq ARPPacket instance Show EthernetBody instance Eq EthernetBody instance Read EthernetHeader instance Show EthernetHeader instance Eq EthernetHeader instance Show EthernetFrame instance Eq EthernetFrame instance FramedMessage EthernetFrame EthernetAddress EthernetBody module Nettle.OpenFlow.Port -- | A switch receives and sends packets on a port; The Port data type -- models attributes of a physical port. data Port Port :: PortID -> String -> EthernetAddress -> [PortConfigAttribute] -> Bool -> SpanningTreePortState -> Maybe PortFeatures -> Maybe PortFeatures -> Maybe PortFeatures -> Maybe PortFeatures -> Port -- | value datapath associates with a physical port portID :: Port -> PortID -- | human-readable interface name portName :: Port -> String -- | the Ethernet address of the port portAddress :: Port -> EthernetAddress -- | describes spanning tree and administrative settings portConfig :: Port -> [PortConfigAttribute] -- | describes whether the link is down portLinkDown :: Port -> Bool -- | describes spanning tree state portSTPState :: Port -> SpanningTreePortState -- | port's current features portCurrentFeatures :: Port -> Maybe PortFeatures -- | features advertised by port portAdvertisedFeatures :: Port -> Maybe PortFeatures -- | features supported by port portSupportedFeatures :: Port -> Maybe PortFeatures -- | features advertised by peer portPeerFeatures :: Port -> Maybe PortFeatures type PortID = Word16 data SpanningTreePortState STPListening :: SpanningTreePortState STPLearning :: SpanningTreePortState STPForwarding :: SpanningTreePortState STPBlocking :: SpanningTreePortState -- | Possible behaviors of a physical port. Specification: -- ofp_port_config. data PortConfigAttribute -- | port is administratively down PortDown :: PortConfigAttribute -- | disable 802.1D spanning tree on this port STPDisabled :: PortConfigAttribute -- | drop all packets except 802.1D spanning tree packets OnlySTPackets :: PortConfigAttribute -- | drop received 802.1D STP packets NoSTPackets :: PortConfigAttribute -- | do not include this port when flooding NoFlooding :: PortConfigAttribute -- | drop packets forwarded to port DropForwarded :: PortConfigAttribute -- | do not send packet-in messages for this port NoPacketInMsg :: PortConfigAttribute -- | Possible port features. Specification ofp_port_features. data PortFeature -- | 10 Mb half-duplex rate support Rate10MbHD :: PortFeature -- | 10 Mb full-duplex rate support Rate10MbFD :: PortFeature -- | 100 Mb half-duplex rate support Rate100MbHD :: PortFeature -- | 100 Mb full-duplex rate support Rate100MbFD :: PortFeature -- | 1 Gb half-duplex rate support Rate1GbHD :: PortFeature -- | 1 Gb full-duplex rate support Rate1GbFD :: PortFeature -- | 10 Gb full-duplex rate support Rate10GbFD :: PortFeature Copper :: PortFeature Fiber :: PortFeature AutoNegotiation :: PortFeature Pause :: PortFeature AsymmetricPause :: PortFeature -- | Set of PortFeatures. Specification: bitmap of members in -- enum ofp_port_features. type PortFeatures = [PortFeature] -- | A port can be configured with a PortMod message. data PortMod PortMod :: PortID -> EthernetAddress -> Map PortConfigAttribute Bool -> PortMod -- | port number of port to modify portNumber :: PortMod -> PortID -- | hardware address of the port (redundant with the port number above; -- both are required) hwAddr :: PortMod -> EthernetAddress -- | attributes mapped to true will be set on, attributes mapped to false -- will be turned off, and attributes missing will be unchanged attributesToSet :: PortMod -> Map PortConfigAttribute Bool -- | The PortStatus represents information regarding a change to a -- port state on a switch. type PortStatus = (PortStatusUpdateReason, Port) -- | The reason that a port status update message was sent. data PortStatusUpdateReason PortAdded :: PortStatusUpdateReason PortDeleted :: PortStatusUpdateReason PortModified :: PortStatusUpdateReason portAttributeOn :: PortID -> EthernetAddress -> PortConfigAttribute -> PortMod portAttributeOff :: PortID -> EthernetAddress -> PortConfigAttribute -> PortMod instance Show PortStatusUpdateReason instance Read PortStatusUpdateReason instance Eq PortStatusUpdateReason instance Ord PortStatusUpdateReason instance Enum PortStatusUpdateReason instance Show PortMod instance Read PortMod instance Eq PortMod instance Show PortFeature instance Read PortFeature instance Eq PortFeature instance Show PortConfigAttribute instance Read PortConfigAttribute instance Eq PortConfigAttribute instance Ord PortConfigAttribute instance Enum PortConfigAttribute instance Show SpanningTreePortState instance Read SpanningTreePortState instance Eq SpanningTreePortState instance Ord SpanningTreePortState instance Enum SpanningTreePortState instance Show Port instance Read Port instance Eq Port module Nettle.OpenFlow.Action -- | Each flow table entry contains a list of actions that will be executed -- when a packet matches the entry. Specification: -- ofp_action_header and all ofp_action_* structures. data Action -- | send out given port SendOutPort :: PseudoPort -> Action -- | set the 802.1q VLAN ID SetVlanVID :: VLANID -> Action -- | set the 802.1q priority SetVlanPriority :: VLANPriority -> Action -- | strip the 802.1q header StripVlanHeader :: Action -- | set ethernet source address SetEthSrcAddr :: EthernetAddress -> Action -- | set ethernet destination address SetEthDstAddr :: EthernetAddress -> Action -- | set IP source address SetIPSrcAddr :: IPAddress -> Action -- | set IP destination address SetIPDstAddr :: IPAddress -> Action -- | IP ToS (DSCP field) SetIPToS :: IPTypeOfService -> Action -- | set TCP/UDP source port SetTransportSrcPort :: TransportPort -> Action -- | set TCP/UDP destination port SetTransportDstPort :: TransportPort -> Action -- | output to queue Enqueue :: PortID -> QueueID -> Action -- | port the queue belongs to enqueuePort :: Action -> PortID -- | where to enqueue the packets queueID :: Action -> QueueID VendorAction :: VendorID -> [Word8] -> Action -- | The supported switch actions are denoted with these symbols. data ActionType OutputToPortType :: ActionType SetVlanVIDType :: ActionType SetVlanPriorityType :: ActionType StripVlanHeaderType :: ActionType SetEthSrcAddrType :: ActionType SetEthDstAddrType :: ActionType SetIPSrcAddrType :: ActionType SetIPDstAddrType :: ActionType SetIPTypeOfServiceType :: ActionType SetTransportSrcPortType :: ActionType SetTransportDstPortType :: ActionType EnqueueType :: ActionType VendorActionType :: ActionType -- | A PseudoPort denotes the target of a forwarding action. data PseudoPort -- | send out physical port with given id PhysicalPort :: PortID -> PseudoPort -- | send packet out the input port InPort :: PseudoPort -- | send out all physical ports except input port and those disabled by -- STP Flood :: PseudoPort -- | send out all physical ports except input port AllPhysicalPorts :: PseudoPort -- | send to controller ToController :: MaxLenToSendController -> PseudoPort -- | process with normal L2/L3 switching NormalSwitching :: PseudoPort -- | process packet with flow table WithTable :: PseudoPort -- | A send to controller action includes the maximum number of bytes that -- a switch will send to the controller. type MaxLenToSendController = Word16 type VendorID = Word32 type QueueID = Word32 -- | Sequence of actions, represented as finite lists. The Monoid instance -- of lists provides methods for denoting the do-nothing action -- (mempty) and for concatenating action sequences -- mconcat. type ActionSequence = [Action] sendOnPort :: PortID -> ActionSequence sendOnInPort :: ActionSequence flood :: ActionSequence drop :: ActionSequence allPhysicalPorts :: ActionSequence processNormally :: ActionSequence sendToController :: MaxLenToSendController -> ActionSequence processWithTable :: ActionSequence setVlanVID :: VLANID -> ActionSequence setVlanPriority :: VLANPriority -> ActionSequence stripVlanHeader :: ActionSequence setEthSrcAddr :: EthernetAddress -> ActionSequence setEthDstAddr :: EthernetAddress -> ActionSequence setIPSrcAddr :: IPAddress -> ActionSequence setIPDstAddr :: IPAddress -> ActionSequence setIPToS :: IPTypeOfService -> ActionSequence setTransportSrcPort :: TransportPort -> ActionSequence setTransportDstPort :: TransportPort -> ActionSequence enqueue :: PortID -> QueueID -> ActionSequence vendorAction :: VendorID -> [Word8] -> ActionSequence instance Show PseudoPort instance Read PseudoPort instance Eq PseudoPort instance Show Action instance Eq Action instance Show ActionType instance Read ActionType instance Eq ActionType instance Ord ActionType instance Enum ActionType module Nettle.OpenFlow.Packet -- | A switch can be remotely commanded to send a packet. The packet can -- either be a packet buffered at the switch, in which case the bufferID -- is provided, or it can be specified explicitly by giving the packet -- data. data PacketOut PacketOut :: Either BufferID ByteString -> Maybe PortID -> ActionSequence -> PacketOut -- | either a buffer ID or the data itself bufferIDData :: PacketOut -> Either BufferID ByteString -- | the port at which the packet received, for the purposes of processing -- this command inPort :: PacketOut -> Maybe PortID -- | actions to apply to the packet actions :: PacketOut -> ActionSequence -- | Constructs a PacketOut value for a packet buffered at a -- switch. bufferedPacketOut :: BufferID -> Maybe PortID -> ActionSequence -> PacketOut -- | Constructs a PacketOut value for an unbuffered packet, -- including the packet data. unbufferedPacketOut :: ByteString -> Maybe PortID -> ActionSequence -> PacketOut -- | Constructs a PacketOut value that processes the packet -- referred to by the PacketInfo value according to the -- specified actions. receivedPacketOut :: PacketInfo -> ActionSequence -> PacketOut -- | A switch may buffer a packet that it receives. When it does so, the -- packet is assigned a bufferID which can be used to refer to that -- packet. type BufferID = Word32 -- | A switch receives packets on its ports. If the packet matches some -- flow rules, the highest priority rule is executed. If no flow rule -- matches, the packet is sent to the controller. When packet is sent to -- the controller, the switch sends a message containing the following -- information. data PacketInfo PacketInfo :: Maybe BufferID -> NumBytes -> PortID -> PacketInReason -> ByteString -> PacketInfo -- | buffer ID if packet buffered bufferID :: PacketInfo -> Maybe BufferID -- | full length of frame packetLength :: PacketInfo -> NumBytes -- | port on which frame was received receivedOnPort :: PacketInfo -> PortID -- | reason packet is being sent reasonSent :: PacketInfo -> PacketInReason -- | ethernet frame, includes full packet only if no buffer ID packetData :: PacketInfo -> ByteString -- | A PacketInfo message includes the reason that the message was sent, -- namely either there was no match, or there was a match, and that -- match's actions included a Sent-To-Controller action. data PacketInReason NotMatched :: PacketInReason ExplicitSend :: PacketInReason -- | The number of bytes in a packet. type NumBytes = Integer bufferedAtSwitch :: PacketInfo -> Bool instance Show PacketInReason instance Read PacketInReason instance Eq PacketInReason instance Ord PacketInReason instance Enum PacketInReason instance Show PacketInfo instance Eq PacketInfo instance Ord PacketInfo instance Eq PacketOut instance Show PacketOut module Nettle.OpenFlow.Switch -- | The switch features record, summarizes information about a switch data SwitchFeatures SwitchFeatures :: SwitchID -> Integer -> Integer -> [SwitchCapability] -> [ActionType] -> [Port] -> SwitchFeatures -- | unique switch identifier switchID :: SwitchFeatures -> SwitchID -- | maximum number of packets buffered at the switch packetBufferSize :: SwitchFeatures -> Integer -- | number of flow tables numberFlowTables :: SwitchFeatures -> Integer -- | switch's capabilities capabilities :: SwitchFeatures -> [SwitchCapability] -- | switch's supported actions supportedActions :: SwitchFeatures -> [ActionType] -- | description of each port on switch ports :: SwitchFeatures -> [Port] -- | A unique identifier for a switch, also known as DataPathID. type SwitchID = Word64 -- | The switch capabilities are denoted with these symbols data SwitchCapability -- | can provide flow statistics HasFlowStats :: SwitchCapability -- | can provide table statistics HasTableStats :: SwitchCapability -- | can provide port statistics HasPortStats :: SwitchCapability -- | supports the 802.1d spanning tree protocol SpanningTree :: SwitchCapability -- | can provide queue statistics HasQueueStatistics :: SwitchCapability -- | match IP addresses in ARP packets CanMatchIPAddressesInARPPackets :: SwitchCapability -- | can reassemble IP fragments CanReassembleIPFragments :: SwitchCapability -- | Maximum number of ports on a switch maxNumberPorts :: PortID instance Show SwitchCapability instance Read SwitchCapability instance Eq SwitchCapability instance Ord SwitchCapability instance Enum SwitchCapability instance Show SwitchFeatures instance Read SwitchFeatures instance Eq SwitchFeatures module Nettle.OpenFlow.Match -- | Each flow entry includes a match, which essentially defines -- packet-matching condition. Fields that are left Nothing are -- wildcards. data Match Match :: Maybe PortID -> Maybe EthernetAddress -> Maybe EthernetAddress -> Maybe VLANID -> Maybe VLANPriority -> Maybe EthernetTypeCode -> Maybe IPTypeOfService -> Maybe IPProtocol -> IPAddressPrefix -> IPAddressPrefix -> Maybe TransportPort -> Maybe TransportPort -> Match inPort :: Match -> Maybe PortID srcEthAddress :: Match -> Maybe EthernetAddress dstEthAddress :: Match -> Maybe EthernetAddress vLANID :: Match -> Maybe VLANID vLANPriority :: Match -> Maybe VLANPriority ethFrameType :: Match -> Maybe EthernetTypeCode ipTypeOfService :: Match -> Maybe IPTypeOfService ipProtocol :: Match -> Maybe IPProtocol srcIPAddress :: Match -> IPAddressPrefix dstIPAddress :: Match -> IPAddressPrefix srcTransportPort :: Match -> Maybe TransportPort dstTransportPort :: Match -> Maybe TransportPort -- | A match that matches every packet. matchAny :: Match -- | Return True if given Match represents an exact match, i.e. no -- wildcards and the IP addresses' prefixes cover all bits. isExactMatch :: Match -> Bool -- | Utility function to get an exact match corresponding to a packet (as -- given by a byte sequence). getExactMatch :: PortID -> GetE Match frameToExactMatch :: PortID -> EthernetFrame -> Match ofpVlanNone :: Integer -- | Models the match semantics of an OpenFlow switch. matches :: (PortID, EthernetFrame) -> Match -> Bool instance Show Match instance Read Match instance Eq Match -- | A switch has some number of flow tables. Each flow table is a -- prioritized list of entries containing a Match, a list of -- Actions, and other options affecting the behavior of the -- switch. This module represents the OpenFlow messages that can be used -- to modify flow tables. module Nettle.OpenFlow.FlowTable type FlowTableID = Word8 data FlowMod AddFlow :: Match -> Priority -> ActionSequence -> Cookie -> TimeOut -> TimeOut -> Bool -> Maybe BufferID -> Bool -> FlowMod match :: FlowMod -> Match priority :: FlowMod -> Priority actions :: FlowMod -> ActionSequence cookie :: FlowMod -> Cookie idleTimeOut :: FlowMod -> TimeOut hardTimeOut :: FlowMod -> TimeOut notifyWhenRemoved :: FlowMod -> Bool applyToPacket :: FlowMod -> Maybe BufferID overlapAllowed :: FlowMod -> Bool AddEmergencyFlow :: Match -> Priority -> ActionSequence -> Cookie -> Bool -> FlowMod match :: FlowMod -> Match priority :: FlowMod -> Priority actions :: FlowMod -> ActionSequence cookie :: FlowMod -> Cookie overlapAllowed :: FlowMod -> Bool ModifyFlows :: Match -> ActionSequence -> Priority -> Cookie -> TimeOut -> TimeOut -> Bool -> Bool -> FlowMod match :: FlowMod -> Match newActions :: FlowMod -> ActionSequence ifMissingPriority :: FlowMod -> Priority ifMissingCookie :: FlowMod -> Cookie ifMissingIdleTimeOut :: FlowMod -> TimeOut ifMissingHardTimeOut :: FlowMod -> TimeOut ifMissingNotifyWhenRemoved :: FlowMod -> Bool ifMissingOverlapAllowed :: FlowMod -> Bool ModifyExactFlow :: Match -> Priority -> ActionSequence -> Cookie -> TimeOut -> TimeOut -> Bool -> Bool -> FlowMod match :: FlowMod -> Match priority :: FlowMod -> Priority newActions :: FlowMod -> ActionSequence ifMissingCookie :: FlowMod -> Cookie ifMissingIdleTimeOut :: FlowMod -> TimeOut ifMissingHardTimeOut :: FlowMod -> TimeOut ifMissingNotifyWhenRemoved :: FlowMod -> Bool ifMissingOverlapAllowed :: FlowMod -> Bool DeleteFlows :: Match -> Maybe PseudoPort -> FlowMod match :: FlowMod -> Match outPort :: FlowMod -> Maybe PseudoPort DeleteExactFlow :: Match -> Maybe PseudoPort -> Priority -> FlowMod match :: FlowMod -> Match outPort :: FlowMod -> Maybe PseudoPort priority :: FlowMod -> Priority type Cookie = Word64 -- | The priority of a flow entry is a 16-bit integer. Flow entries with -- higher numeric priorities match before lower ones. type Priority = Word16 -- | Each flow entry has idle and hard timeout values associated with it. data TimeOut Permanent :: TimeOut ExpireAfter :: Word16 -> TimeOut -- | When a switch removes a flow, it may send a message containing the -- information in FlowRemovedRecord to the controller. data FlowRemoved FlowRemoved :: Match -> Word64 -> Priority -> FlowRemovalReason -> Integer -> Integer -> Integer -> Integer -> Integer -> FlowRemoved flowRemovedMatch :: FlowRemoved -> Match flowRemovedCookie :: FlowRemoved -> Word64 flowRemovedPriority :: FlowRemoved -> Priority flowRemovedReason :: FlowRemoved -> FlowRemovalReason flowRemovedDuration :: FlowRemoved -> Integer flowRemovedDurationNSecs :: FlowRemoved -> Integer flowRemovedIdleTimeout :: FlowRemoved -> Integer flowRemovedPacketCount :: FlowRemoved -> Integer flowRemovedByteCount :: FlowRemoved -> Integer data FlowRemovalReason IdleTimerExpired :: FlowRemovalReason HardTimerExpired :: FlowRemovalReason DeletedByController :: FlowRemovalReason instance Show FlowRemovalReason instance Eq FlowRemovalReason instance Ord FlowRemovalReason instance Enum FlowRemovalReason instance Show FlowRemoved instance Eq FlowRemoved instance Show TimeOut instance Eq TimeOut instance Show FlowMod instance Eq FlowMod module Nettle.OpenFlow.Statistics data StatsRequest FlowStatsRequest :: Match -> TableQuery -> Maybe PseudoPort -> StatsRequest -- | fields to match statsRequestMatch :: StatsRequest -> Match -- | ID of table to read statsRequestTableID :: StatsRequest -> TableQuery -- | if present, require matching entries to include this as an output port statsRequestPort :: StatsRequest -> Maybe PseudoPort AggregateFlowStatsRequest :: Match -> TableQuery -> Maybe PseudoPort -> StatsRequest -- | fields to match statsRequestMatch :: StatsRequest -> Match -- | ID of table to read statsRequestTableID :: StatsRequest -> TableQuery -- | if present, require matching entries to include this as an output port statsRequestPort :: StatsRequest -> Maybe PseudoPort TableStatsRequest :: StatsRequest DescriptionRequest :: StatsRequest PortStatsRequest :: PortQuery -> StatsRequest portStatsQuery :: StatsRequest -> PortQuery QueueStatsRequest :: PortQuery -> QueueQuery -> StatsRequest queueStatsPort :: StatsRequest -> PortQuery queueStatsQuery :: StatsRequest -> QueueQuery data TableQuery AllTables :: TableQuery EmergencyTable :: TableQuery Table :: FlowTableID -> TableQuery data PortQuery AllPorts :: PortQuery SinglePort :: PortID -> PortQuery data QueueQuery AllQueues :: QueueQuery SingleQueue :: QueueID -> QueueQuery data StatsReply DescriptionReply :: Description -> StatsReply FlowStatsReply :: MoreToFollowFlag -> [FlowStats] -> StatsReply AggregateFlowStatsReply :: AggregateFlowStats -> StatsReply TableStatsReply :: MoreToFollowFlag -> [TableStats] -> StatsReply PortStatsReply :: MoreToFollowFlag -> [(PortID, PortStats)] -> StatsReply QueueStatsReply :: MoreToFollowFlag -> [QueueStats] -> StatsReply type MoreToFollowFlag = Bool data FlowStats FlowStats :: FlowTableID -> Match -> [Action] -> Priority -> Cookie -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> FlowStats -- | Table ID of the flow flowStatsTableID :: FlowStats -> FlowTableID -- | Match condition of the flow flowStatsMatch :: FlowStats -> Match -- | Actions for the flow flowStatsActions :: FlowStats -> [Action] -- | Priority of the flow entry (meaningful when the match is not exact). flowStatsPriority :: FlowStats -> Priority -- | Cookie associated with the flow. flowStatsCookie :: FlowStats -> Cookie flowStatsDurationSeconds :: FlowStats -> Integer flowStatsDurationNanoseconds :: FlowStats -> Integer flowStatsIdleTimeout :: FlowStats -> Integer flowStatsHardTimeout :: FlowStats -> Integer flowStatsPacketCount :: FlowStats -> Integer flowStatsByteCount :: FlowStats -> Integer data AggregateFlowStats AggregateFlowStats :: Integer -> Integer -> Integer -> AggregateFlowStats aggregateFlowStatsPacketCount :: AggregateFlowStats -> Integer aggregateFlowStatsByteCount :: AggregateFlowStats -> Integer aggregateFlowStatsFlowCount :: AggregateFlowStats -> Integer data TableStats TableStats :: FlowTableID -> String -> Integer -> Integer -> Integer -> Integer -> TableStats tableStatsTableID :: TableStats -> FlowTableID tableStatsTableName :: TableStats -> String tableStatsMaxEntries :: TableStats -> Integer tableStatsActiveCount :: TableStats -> Integer tableStatsLookupCount :: TableStats -> Integer tableStatsMatchedCount :: TableStats -> Integer data PortStats PortStats :: Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> Maybe Double -> PortStats portStatsReceivedPackets :: PortStats -> Maybe Double portStatsSentPackets :: PortStats -> Maybe Double portStatsReceivedBytes :: PortStats -> Maybe Double portStatsSentBytes :: PortStats -> Maybe Double portStatsReceiverDropped :: PortStats -> Maybe Double portStatsSenderDropped :: PortStats -> Maybe Double portStatsReceiveErrors :: PortStats -> Maybe Double portStatsTransmitError :: PortStats -> Maybe Double portStatsReceivedFrameErrors :: PortStats -> Maybe Double portStatsReceiverOverrunError :: PortStats -> Maybe Double portStatsReceiverCRCError :: PortStats -> Maybe Double portStatsCollisions :: PortStats -> Maybe Double -- | A port stats value with all fields missing. nullPortStats :: PortStats -- | A port stats value with all fields present, but set to 0. zeroPortStats :: PortStats -- | Lift a unary function and apply to every member of a PortStats record. liftIntoPortStats1 :: (Double -> Double) -> PortStats -> PortStats -- | Lift a binary function and apply to every member of a PortStats -- record. liftIntoPortStats2 :: (Double -> Double -> Double) -> PortStats -> PortStats -> PortStats data Description Description :: String -> String -> String -> String -> String -> Description manufacturerDesc :: Description -> String hardwareDesc :: Description -> String softwareDesc :: Description -> String serialNumber :: Description -> String datapathDesc :: Description -> String data QueueStats QueueStats :: PortID -> QueueID -> Integer -> Integer -> Integer -> QueueStats queueStatsPortID :: QueueStats -> PortID queueStatsQueueID :: QueueStats -> QueueID queueStatsTransmittedBytes :: QueueStats -> Integer queueStatsTransmittedPackets :: QueueStats -> Integer queueStatsTransmittedErrors :: QueueStats -> Integer instance Show QueueStats instance Eq QueueStats instance Show PortStats instance Eq PortStats instance Show TableStats instance Eq TableStats instance Show FlowStats instance Eq FlowStats instance Show AggregateFlowStats instance Eq AggregateFlowStats instance Show Description instance Eq Description instance Show StatsReply instance Eq StatsReply instance Show TableQuery instance Eq TableQuery instance Show QueueQuery instance Eq QueueQuery instance Ord QueueQuery instance Show PortQuery instance Eq PortQuery instance Ord PortQuery instance Show StatsRequest instance Eq StatsRequest -- | This module provides a logical representation of OpenFlow switches and -- protocol messages. An OpenFlow message is either a -- switch-to-controller message or controller-to-switch message. In -- either case, each message is tagged with a unique message identifier. module Nettle.OpenFlow.Messages -- | Every OpenFlow message is tagged with a MessageID value. type TransactionID = Word32 -- | The Switch can send the following messages to the controller. data SCMessage -- | Sent after a switch establishes a TCP connection to the controller SCHello :: SCMessage -- | Switch requests an echo reply SCEchoRequest :: [Word8] -> SCMessage -- | Switch responds to an echo request SCEchoReply :: [Word8] -> SCMessage -- | Switch reports its features Features :: SwitchFeatures -> SCMessage -- | Switch sends a packet to the controller PacketIn :: PacketInfo -> SCMessage -- | Switch sends port status PortStatus :: PortStatus -> SCMessage -- | Switch reports that a flow has been removed FlowRemoved :: FlowRemoved -> SCMessage -- | Switch reports statistics StatsReply :: StatsReply -> SCMessage -- | Switch reports an error Error :: SwitchError -> SCMessage -- | Switch responds that a barrier has been processed BarrierReply :: SCMessage -- | The controller can send these messages to the switch. data CSMessage -- | Controller must send hello before sending any other messages CSHello :: CSMessage -- | Controller requests a switch echo CSEchoRequest :: [Word8] -> CSMessage -- | Controller responds to a switch echo request CSEchoReply :: [Word8] -> CSMessage -- | Controller requests features information FeaturesRequest :: CSMessage -- | Controller commands switch to send a packet PacketOut :: PacketOut -> CSMessage -- | Controller modifies a switch flow table FlowMod :: FlowMod -> CSMessage -- | Controller configures a switch port PortMod :: PortMod -> CSMessage -- | Controller requests statistics StatsRequest :: StatsRequest -> CSMessage -- | Controller requests a barrier BarrierRequest :: CSMessage instance Show CSMessage instance Eq CSMessage instance Show SCMessage instance Eq SCMessage -- | This module implements parsing and unparsing functions for OpenFlow -- messages. It exports a driver that can be used to read messages from a -- file handle and write messages to a handle. module Nettle.OpenFlow.MessagesBinary -- | A message driver for use with TCP servers. messageDriver :: TCPMessageDriver (TransactionID, SCMessage) (TransactionID, CSMessage) -- | openFlowServer portNum starts a TCP server listening for new -- connections at portNum and returns a process that can be used -- to receive OpenFlow events and send OpenFlow messages. openFlowServer :: ServerPortNumber -> IO (Process (TCPMessage (TransactionID, SCMessage)) (SockAddr, (TransactionID, CSMessage)) IOException) -- | Parser for SCMessages getSCMessage :: Get (TransactionID, SCMessage) -- | Unparser for CSMessages putCSMessage :: (TransactionID, CSMessage) -> Put instance Show OFPMatch instance Eq OFPMatch instance Show FlowModFlag instance Eq FlowModFlag instance Ord FlowModFlag instance Enum FlowModFlag instance Show FlowModType instance Eq FlowModType instance Ord FlowModType instance Eq FlowModRecordInternal instance Show FlowModRecordInternal instance Show OFPHeader instance Eq OFPHeader