/* * Copyright (c) 1998-2001 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ #ifndef _IOKIT_IOFWIPDEFINITIONS_H #define _IOKIT_IOFWIPDEFINITIONS_H #include "IOFWController.h" struct FWUnsignedWideStruct{ UInt32 hi; UInt32 lo; }; typedef struct FWUnsignedWideStruct FWUnsignedWide; /* All the different platforms (and their development environments) have slightly different type definition capitalization conventions, etc. This section regularizes all that so that our source code may use uniform names */ #define UNSIGNED unsigned #define UWIDE FWUnsignedWide /* Macros for convenience */ #undef LAST #define LAST(array) ((sizeof(array) / sizeof(array[0])) - 1) #define BIT_SET(x) (1 << x) /* Well known IPv4 & IPv6 multicast addresses */ const UInt8 IPv4KnownMcastAddresses[5] = {0x01, 0x00, 0x5E, 0x00, 0xE0}; /* IPv6 well know multicast addresses Scope ID 0xFF 1, 2, 4, 5, 8, D */ /* Solicited Multicast address FF 02::0:01:FFXX:XXXX */ /* * Miscellanaeous constants from IEEE Std 1394a-2000, ISO/IEC 13213:1994 * and RFC 2734. */ #define DEFAULT_BROADCAST_CHANNEL 31 #define GASP_TAG 3 #define LOCAL_BUS_ID 0x3FF #define ETHER_TYPE_MCAP 0x8861 #define IP1394_SPEC_ID 0x00005E /* Specifier_ID and ... */ #define IP1394_VERSION 0x000001 /* ... Version values for unit directory */ #define IP1394v6_VERSION 0x000002 /* ... Version values for unit directory */ #define IPV4_ADDR_SIZE 4 /* Four octets (xxx.xxx.xxx.xxx) */ #define IPV4_HDR_SIZE 20 /* Minimum size from RFC 791 */ #define FW_M_BCAST 0x10 #define FW_M_MCAST 0x20 #define FW_M_UCAST 0x40 #define FW_M_PKTHDR 0x02 /* Encapsulation headers defined by RFC 2734. Unfragmented datagrams use a short (one quadlet) encapsulation header that specifies the Ether type while the headers for datagram fragments are two quadlets and contain total datagram size and the position of the fragment within the datagram. When a datagram is fragmented, the Ether type is present in the first fragment, only */ typedef struct { /* Unfragmented encapsulation header*/ UInt16 reserved; /* Always zero for unfragmented datagram */ UInt16 etherType; /* See RFC 1700 */ } IP1394_UNFRAG_HDR; typedef struct { /* IP1394 encapsulation header */ UInt16 datagramSize; /* Total size of the datagram, less one */ UInt16 fragmentOffset; /* Second and subsequent fragments */ UInt16 dgl; /* Datagram label */ UInt16 reserved; } IP1394_FRAG_HDR; typedef union { IP1394_UNFRAG_HDR singleFragment; IP1394_FRAG_HDR fragment; } IP1394_ENCAP_HDR; /* NOTE: The link fragment type (lf) field is not shown above. It is the most significant two bits of the encapsulation header, with values as follows. */ typedef enum { UNFRAGMENTED = 0, FIRST_FRAGMENT, LAST_FRAGMENT, INTERIOR_FRAGMENT } FragmentType; /* IEEE Std 1394a-2000 defines a global asynchronous stream packet (GASP) format that is used by RFC 2734 for the broadcast and multicast datagrams and also for ARP and MCAP. The two-quadlet GASP header and its components are specified below, along with an entire packet structure (as specified by RFC 2734). */ typedef struct { UInt8 specifierID[3]; /* 24-bit RID (0x 00 005E) */ UInt8 version[3]; /* 24-bit version (0x00 00001) */ } GASP_ID; typedef struct { UInt16 sourceID; /* 16-bit node ID of sender */ GASP_ID gaspID; } GASP_HDR; /* In those cases where the entire GASP is sent or received, firewire services automatically alters the endian-ness of the first quadlet (packet header) while leaving the data payload as is. This means that code that interprets that quadlet has to account for the endian orientation of the CPU on which it executes. Hence there are two flavors of the GASP type, one for big- and the other for little-endian. */ #if (BYTE_ORDER == BIG_ENDIAN) typedef struct { UInt16 dataLength; UInt8 channel; /* Plus tag (in two most significant bits) */ UInt8 tCode; /* Plus sy (in four least significant bits) */ GASP_HDR gaspHdr; /* Two-quadlet GASP header */ IP1394_UNFRAG_HDR ip1394Hdr; /* Fragmentation not permitted! */ } GASP; #else typedef struct { UInt8 tCode; /* Plus sy (in four least significant bits) */ UInt8 channel; /* Plus tag (in two most significant bits) */ UInt16 dataLength; GASP_HDR gaspHdr; /* Two-quadlet GASP header */ IP1394_UNFRAG_HDR ip1394Hdr; /* Fragmentation not permitted! */ } GASP; #endif /* ARP message format defined by RFC 2734. When transmitted, it is preceded by an encapsulation header (one quadlet), whichis itself preceded by a GASP header (two quadlets). */ typedef struct { UInt16 hardwareType; /* Constant 0x0018 for Serial Bus */ UInt16 protocolType; /* Constant 0x0800 for Serial Bus ARP */ UInt8 hwAddrLen; /* "Hardware address" length */ UInt8 ipAddrLen; /* IPv4 address length */ UInt16 opcode; /* ARP request or response */ UWIDE senderUniqueID; /* EUI-64 from sender's bus information block */ UInt8 senderMaxRec; /* Maximum payload (2 ** senderMaxRec) */ UInt8 sspd; /* Maximum speed */ UInt16 senderUnicastFifoHi; /* Most significant 16 bits of FIFO address */ UInt32 senderUnicastFifoLo; /* Least significant 32 bits of FIFO address */ UInt32 senderIpAddress; /* Sender's IPv4 address */ UInt32 targetIpAddress; /* In ARP request, sought-after IPv4 address */ } IP1394_ARP; /* NDP message format defined by RFC 3146. */ struct ip1394_ndp { UInt8 type; /* type = 1 or 2 */ UInt8 len; /* len in units of 8 octets */ UInt8 lladdr[kIOFWAddressSize]; /* EUI-64 from sender's bus information block */ UInt8 senderMaxRec; /* Maximum payload (2 ** senderMaxRec) */ UInt8 sspd; /* Maximum speed */ UInt16 senderUnicastFifoHi; /* Most significant 16 bits of FIFO address */ UInt32 senderUnicastFifoLo; /* Least significant 32 bits of FIFO address */ UInt8 reserved[6]; /* reserved by the RFC 3146 */ } __attribute__((__packed__)); typedef struct ip1394_ndp IP1394_NDP; #define ARP_HDW_TYPE 24 /* ARP hrd type assigned by IANA */ /* The senderUniqueID, senderMaxRec, sspd and senderUnicastFifo fields in the ARP message collectively make a link-level "hardware" aaddress for IP394. This address is used in other contexts and its structure is given below. */ typedef struct { /* IP1394 "hardware" address */ UWIDE eui64; /* Node's EUI-64 (from bus information block) */ UInt8 maxRec; /* Maximum asynchronous payload */ UInt8 spd; /* Maximum speed */ UInt16 unicastFifoHi; /* Most significant bits of unicast FIFO address */ UInt32 unicastFifoLo; /* Least significant bits of unicast FIFO address */ } IP1394_HDW_ADDR; /* Multicast channel allocation protocol (MCAP) message format defined by RFC 2734. When transmitted, it is preceded by an encapsulation header (one quadlet), whichis itself preceded by a GASP header (two quadlets). */ typedef struct { UInt8 length; /* Total size of descriptor (bytes) */ UInt8 type; /* Constant one (1) for MCAST_DESCR */ UInt16 reserved1; UInt8 expiration; /* For advertisements, lifespan remaining */ UInt8 channel; /* Channel number for the group */ UInt8 speed; /* Transmission speed for the group */ UInt8 reserved2; UInt32 bandwidth; /* Not yet utilized */ UInt32 groupAddress; /* IPv4 multicast address */ } MCAST_DESCR; #define MCAST_TYPE 1 /* IPv4 MCAST type */ typedef struct { UInt16 length; /* Total length of MCAP message, in bytes */ UInt8 reserved; UInt8 opcode; /* Advertise or solicit */ MCAST_DESCR groupDescr[0]; /* Zero or more instances of MCAST_DESCR */ } IP1394_MCAP; #define MCAP_ADVERTISE 0 #define MCAP_SOLICIT 1 /* The IP1394 code requires a stable "handle" to represent an internal address (used analogously to Ethernet MAC addresses) for each IP address in the ARP cache. The handle is twelve bytes long and has a different form for unicast addresses (reachable via Serial Bus block write requests) and multi- cast addresses (reachable via asynchronous stream packets) */ typedef struct { /* IP1394 "hardware" address */ UInt32 deviceID; /* Stable reference to unit architecture */ UInt8 maxRec; /* Maximum asynchronous payload */ UInt8 spd; /* Maximum speed */ UInt16 unicastFifoHi; /* Upper 16 bits of unicast FIFO address */ UInt32 unicastFifoLo; /* Lower 32 bits of unicast FIFO address */ } TNF_UNICAST_HANDLE; typedef struct { /* IP1394 "hardware" address */ UInt32 deviceID; /* Always zero */ UInt8 maxRec; /* Maximum asynchronous payload */ UInt8 spd; /* Maximum speed */ UInt8 reserved; UInt8 channel; /* Channel number for GASP transmit / receive */ UInt32 groupAddress; /* Distinguish groups that share channel */ } TNF_MULTICAST_HANDLE; typedef union { TNF_UNICAST_HANDLE unicast; TNF_MULTICAST_HANDLE multicast; } TNF_HANDLE; struct arp_packet { GASP_HDR gaspHdr; IP1394_UNFRAG_HDR ip1394Hdr; IP1394_ARP arp; }; struct mcap_packet { GASP_HDR gaspHdr; IP1394_UNFRAG_HDR ip1394Hdr; IP1394_MCAP mcap; }; #if defined(__BIG_ENDIAN__) typedef struct { UInt16 size; UInt8 tag:2; UInt8 chan:6; UInt8 tcode:4; UInt8 sy:4; } ISOC_DATA_PKT; #elif defined(__LITTLE_ENDIAN__) typedef struct { UInt8 sy:4; UInt8 tcode:4; UInt8 chan:6; UInt8 tag:2; UInt16 size; } ISOC_DATA_PKT; #else #error host endian unknown #endif /* Multicast Address resolution block (ARB) contains all of the information necessary to map, in either direction, between an IPv4 address and a link-level "hardware" address rfc2373 - section 2.7.2 notes that 32 bits are enough to identify unique IPv6 multicast addresses. */ class MARB : public OSObject /* Used by both ARP 1394 and MCAP */ { OSDeclareDefaultStructors(MARB); public: TNF_HANDLE handle; /* Pseudo "hardware" address used internally */ }; /* Address resolution block (ARB) contains all of the information necessary to map, in either direction, between an IPv4 address and a link-level "hardware" address */ class ARB : public OSObject /* Used by both ARP 1394 and MCAP */ { OSDeclareDefaultStructors(ARB); public: UWIDE eui64; /* EUI-64 obtained from ARP response */ UInt8 fwaddr[kIOFWAddressSize]; TNF_HANDLE handle; /* Pseudo "hardware" address used internally */ bool itsMac; /* Indicates whether the destination Macintosh or not */ }; /* Device reference block (DRB) correlates an EUI-64 with a IOFireWireNub reference ID acquired with a kGUIDType parameter. A pointer to the LCB is also part of the structure---because the address of a DRB is passed to a bus reset notification procedure which in turn needs to reference the relevant LCB. Note also the inclusion of a timer field; because node removals may be temporary, the IP1394 code does NOT dispose of the device reference as soon as the node disappears. Instead, an expiration timer is started. If the device has not reappeared within the specified number of seconds, then the device reference ID is released. */ class DRB : public OSObject { OSDeclareDefaultStructors(DRB); public: UWIDE eui64; /* EUI-64 of the IP-capable device */ UInt8 fwaddr[kIOFWAddressSize]; UInt32 deviceID; /* Stable "handle" for the IP-capable device */ UInt16 maxPayload; /* Maximum payload and... */ IOFWSpeed maxSpeed; /* ...speed to device in current topology */ bool itsMac; /* Indicates whether the destination Macintosh or not */ }; /* Multicast control block (MCB) permits the management of multicast channel assignments, whether we are the owner or simply one of the participants in the multicast group. */ class MCB : public OSObject { OSDeclareDefaultStructors(MCB); public: UInt32 ownerNodeID; /* Channel owner (it may be us!) */ UInt32 groupCount; /* IP address groups active (this channel )*/ OSObject *asyncStreamID; UInt8 channel; /* Redundant (but makes debug easier) */ UInt8 expiration; /* Seconds remaining in valid channel mapping */ UInt8 nextTransmit; /* Seconds 'til MCAP advertisement transmitted */ UInt8 finalWarning; /* Channel deallocation warning messages */ }; #define MCAP_UNOWNED 0 /* No channel owner */ /* Reassembly control block (RCB) tracks the progress of the entire datagram as fragments arrive. The algorithm is simple---primitive even---but adequate for the unconfirmed nature of IP datagrams. When one of the fragments first arrives, an MBUF adequate to hold the entire datagram is allocated and the fragment is copied to its correct location; the residual count is decremented. This process repeats with successive fragments until residual is zero. */ class RCB : public IOCommand { OSDeclareDefaultStructors(RCB); private: void free(); public: UInt16 sourceID; /* Saved from LK_DATA.indication */ UInt16 dgl; /* Obtained from the fragment header */ UInt16 etherType; /* Saved from first fraagment header */ UInt16 datagramSize; /* Total size of the reassembled datagram */ UInt16 residual; /* Bytes still outstanding */ UInt32 timer; /* If nonzero, decrement and release upon zero */ mbuf_t mBuf; /* MBUF eventually passed to OS code */ void reinit(UInt16 id, UInt16 label, UInt16 etherType, UInt16 size, mbuf_t m); }; /* End of the type definitions for the miscellaneous control structures */ /* Link control block (LCB) used to maintain context for IOFireWireIP routines for a single link instance. The ARP and MCAP caches are also referenced by this structure. */ typedef struct lcb /* Link Control Block (LCB) for each link */ { IP1394_HDW_ADDR ownHardwareAddress; /* Our external address on Serial Bus */ UInt16 ownMaxPayload; /* From this link's bus information block */ UInt16 ownMaxSpeed; /* Link/PHY hardware capability */ UInt16 ownNodeID; /* Management information, only */ UInt16 maxBroadcastPayload;/* Updated when topology changes */ IOFWSpeed maxBroadcastSpeed; /* Ditto */ UInt16 datagramLabel; UInt32 busGeneration; /* Current as of most recent bus reset */ } LCB; #endif /* _IOKIT_IOFWIPDEFINITIONS_H */