Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
OTGetDefaultEthernetAddress.c
/* |
File: OTGetDefaultEthernetAddress.c |
Contains: Demo of accessing OT from CodeWarrior 68K and |
Symantec for MPW 68K code resource. |
Written by: Quinn "The Eskimo!" |
Copyright: © 1996-8 by Apple Computer, Inc., all rights reserved. |
Change History (most recent first): |
*/ |
#define qDebug 1 |
///////////////////////////////////////////////////////////////////// |
// Standard OT Interfaces |
#include <OpenTransport.h> |
#include <OpenTptLinks.h> |
///////////////////////////////////////////////////////////////////// |
// Low-Level OT Interfaces |
#include <OTDebug.h> |
// OTDebugStr is not defined in any OT header files, but it is |
// exported by the libraries, so we define the prototype here. |
extern pascal void OTDebugStr(const char* str); |
///////////////////////////////////////////////////////////////////// |
// Other Toolbox Interfaces |
#include <HyperXCMD.h> |
#include <TextUtils.h> |
#include <Strings.h> |
///////////////////////////////////////////////////////////////////// |
// Specical Envirnoment Dependent Stuff |
#if defined(__MWERKS__) |
#include <A4Stuff.h> |
extern UInt32 ZZZApplParamsHack[8]; |
// Evil pseudo-LibraryManager stuff |
typedef long GlobalWorld; |
GlobalWorld GetCurrentGlobalWorld(void):__D0 |
= {0x200D}; /* move.l A5,D0 */ |
void SynchGlobalWorldFromA4(void) |
= {0x2A4C}; /* move.l A4,A5 */ |
void SynchA4FromGlobalWorld(void) |
= {0x284D}; /* move.l A5,A4 */ |
GlobalWorld SetCurrentGlobalWorld(GlobalWorld:__A0):__D0 |
= {0x200D, /* move.l A5,D0 */ |
0x2A48}; /* move.l A0,A5 */ |
#else |
#include <LibraryManagerUtilities.h> |
#include <LibraryManager.h> |
#endif |
///////////////////////////////////////////////////////////////////// |
// Forward definition for TrueMain |
static void TrueMain(XCmdPtr xpb); |
///////////////////////////////////////////////////////////////////// |
// Standard XCMD main entry point, one for each environment. |
#if defined(__MWERKS__) |
pascal void main(XCmdPtr xpb); |
pascal void main(XCmdPtr xpb) |
// Metrowerks main line. |
{ |
long oldA4; |
GlobalWorld oldWorld; |
UInt32 *junk; |
Debugger(); |
// Create a reference to our dummy AppParams globals and |
// assign it to a pointer. This prevents the linker |
// from dead-stripper the variable. |
junk = &ZZZApplParamsHack[1]; |
// Now save A5, setup A4, and then setup A4 from A5. |
oldWorld = GetCurrentGlobalWorld(); |
oldA4 = SetCurrentA4(); |
SynchGlobalWorldFromA4(); |
// Call the real code. |
TrueMain(xpb); |
// Clean up. |
(void) SetCurrentGlobalWorld(oldWorld); |
(void) SetA4(oldA4); |
// Debugger(); |
} |
#else |
pascal void MAIN(XCmdPtr xpb) |
// Symantec main line. |
{ |
OSStatus err; |
GlobalWorld oldWorld; |
Debugger(); |
// Save A5 and then init our code resource's A5 world. |
oldWorld = GetCurrentGlobalWorld(); |
err = InitCodeResource(); |
if (err != noErr) { |
// No point using a DebugStr because the string would A5 relative |
// and this failure indicates that A5 could not be setup! |
Debugger(); |
} else { |
// Call the real code. |
TrueMain(xpb); |
// Clean up. |
(void) SetCurrentGlobalWorld(oldWorld); |
FreeGlobalWorld(); |
} |
// Debugger(); |
} |
#endif |
///////////////////////////////////////////////////////////////////// |
// Generic OT Stuff |
struct EnetAddress { |
unsigned char bytes[6]; |
}; |
typedef struct EnetAddress EnetAddress, *EnetAddressPtr; |
typedef struct T8022Address T8022Address; |
static T8022Address gSimpleAddr = { |
AF_8022, // OTAddressType for 802 provider |
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // hardware address, use zeros for bind requests |
0x8888, // SAP / protocol type, value > 1500 implies ethernet protocol with no SNAP |
{0x00,0x00,0x00,0x00,0x00} |
}; |
static OSStatus GetDefaultEthernetAddress(EnetAddressPtr defEnetAddr) |
// This routine returns the default Ethernet address of the machine |
// in the (6 byte) buffer pointed to by defEnetAddr. |
{ |
OSStatus err; |
OSStatus junk; |
EndpointRef ep; |
TBind bindRequest; |
TBind bindResult; |
T8022Address resultAddr; |
ep = OTOpenEndpoint(OTCreateConfiguration(kEnetName), 0, 0, &err); |
if (err == kOTNoError) { |
// Setup bind request |
OTMemzero(&bindRequest, sizeof(TBind)); |
bindRequest.addr.buf = (UInt8 *) &gSimpleAddr; |
bindRequest.addr.len = k8022BasicAddressLength; // family type + Ethernet + type field |
// Setup bind result |
OTMemzero(&bindResult, sizeof(TBind)); |
bindResult.addr.buf = (UInt8 *) &resultAddr; |
bindResult.addr.maxlen = sizeof(resultAddr); |
// Call bind, which will return the MAC address |
// to which we're bound. |
err = OTBind(ep, &bindRequest, &bindResult); |
if (err == noErr) { |
BlockMoveData( resultAddr.fHWAddr, defEnetAddr->bytes, 6); |
} |
// Clean up. |
junk = OTCloseProvider(ep); |
OTAssert("GetDefaultEthernetAddress: Could not close endpoint", junk == noErr); |
} |
return err; |
} |
static char gHexDigits[16] = "0123456789ABCDEF"; |
static void HexB(UInt8 b, char *buffer) |
{ |
buffer[0] = gHexDigits[b >> 4]; |
buffer[1] = gHexDigits[b & 0x0F]; |
} |
static void TrueMain(XCmdPtr xpb) |
// Extra procedure wrapper to avoid horrible register caching problem |
// whereby the value of result was held in register A3 which was |
// setup from an A5 relative offset before our A5 had been set up |
// by InitCodeResource. Urgh! |
{ |
OSStatus err; |
EnetAddress defEnetAddr; |
char result[256]; |
short i; |
err = InitOpenTransport(); |
if (err == noErr) { |
// Call OT to get the Ethernet address. |
err = GetDefaultEthernetAddress(&defEnetAddr); |
// Construct a formatted string from the Ethernet address. |
if (err == noErr) { |
OTStrCopy(result, "xx:xx:xx:xx:xx:xx"); |
for (i = 0; i < 6; i++) { |
HexB(defEnetAddr.bytes[i], result + (3 * i)); |
} |
} |
if (err != noErr) { |
OTStrCopy(result, "Error"); |
} |
// Copy that string out to the returnValue handle. |
(void) PtrToHand((Ptr) result, &xpb->returnValue, OTStrLength(result) + 1); |
CloseOpenTransport(); |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22