Patch NBPLookupName to map IP address or domain name to AppleTalk-style address.

This commit is contained in:
Stephen Heumann 2017-04-08 23:40:41 -05:00
parent f0dee6d55c
commit 7dd2be9ae2
7 changed files with 174 additions and 0 deletions

View File

@ -1,5 +1,157 @@
#pragma noroot
#include <stddef.h>
#include <ctype.h>
#include <appletalk.h>
#include <tcpip.h>
#include <orca.h>
#include <misctool.h>
#include "atipmapping.h"
#include "asmglue.h"
#include "aspinterface.h"
struct ATIPMapping atipMapping;
#define DEFAULT_DSI_PORT 548
static char ATIPTypeName[] = "\pAFPServer";
static char ATIPZoneName[] = "\pAFP over TCP";
// Next numbers to use for new mappings
static int nextNode = 1;
static int nextSocket = 1;
#define return_error(x) do { \
commandRec->result = (x); \
commandRec->actualMatch = 0; \
RestoreStateReg(stateReg); \
return; \
} while (0)
#pragma databank 1
void DoLookupName(NBPLookupNameRec *commandRec) {
cvtRec hostInfo;
dnrBuffer dnrInfo;
Byte *curr, *dest;
unsigned int count, nameLen;
NBPLUNameBufferRec *resultBuf;
LongWord initialTime;
Word stateReg;
stateReg = ForceRomIn();
// TODO support async calls
if (commandRec->async)
return_error(atSyncErr);
// Length needed for result, assuming the request is for our type/zone
count = offsetof(NBPLUNameBufferRec, entityName)
+ ((EntName*)commandRec->entityPtr)->buffer[0]
+ ATIPTypeName[0] + ATIPZoneName[0];
if (count > commandRec->bufferLength)
return_error(nbpBufferErr);
resultBuf = (NBPLUNameBufferRec *)commandRec->bufferPtr;
curr = &((EntName*)commandRec->entityPtr)->buffer[0];
dest = &resultBuf->entityName.buffer[0];
// Copy object name into result buffer
nameLen = *curr;
for (count = 0; count <= nameLen; count++) {
*dest++ = *curr++;
}
// Check that entity type and zone are what we want,
// and copy names to result buffer.
nameLen = *curr;
for (count = 0; count <= nameLen; count++) {
if (toupper(*curr++) != toupper(ATIPTypeName[count]))
goto passThrough;
*dest++ = ATIPTypeName[count];
}
nameLen = *curr;
for (count = 0; count <= nameLen; count++) {
if (toupper(*curr++) != toupper(ATIPZoneName[count]))
goto passThrough;
*dest++ = ATIPTypeName[count];
}
if (TCPIPValidateIPString(&resultBuf->entityName.buffer[0])) {
TCPIPConvertIPToHex(&hostInfo, &resultBuf->entityName.buffer[0]);
resultBuf->enumerator = 0;
// TCPIPConvertIPToHex seems not to give port, so get it this way
hostInfo.cvtPort =
TCPIPMangleDomainName(0, &resultBuf->entityName.buffer[0]);
} else {
hostInfo.cvtPort =
TCPIPMangleDomainName(0xE000, &resultBuf->entityName.buffer[0]);
TCPIPDNRNameToIP(&resultBuf->entityName.buffer[0], &dnrInfo);
if (toolerror())
return_error(nbpNameErr);
initialTime = GetTick();
while (dnrInfo.DNRstatus == DNR_Pending) {
if (GetTick() - initialTime >= 15*60)
break;
TCPIPPoll();
}
// Re-copy object name into result buffer to undo mangling
curr = &((EntName*)commandRec->entityPtr)->buffer[0];
dest = &resultBuf->entityName.buffer[0];
nameLen = *curr;
for (count = 0; count <= nameLen; count++) {
*dest++ = *curr++;
}
if (dnrInfo.DNRstatus == DNR_OK) {
hostInfo.cvtIPAddress = dnrInfo.DNRIPaddress;
resultBuf->enumerator = 1;
} else if (dnrInfo.DNRstatus == DNR_NoDNSEntry) {
return_error(0); // not really an error, but 0 results
} else {
TCPIPCancelDNR(&dnrInfo);
return_error(nbpNameErr);
}
}
if (hostInfo.cvtPort == 0)
hostInfo.cvtPort = DEFAULT_DSI_PORT;
for (count = 0; count < MAX_SESSIONS; count++) {
if (sessionTbl[count].atipMapping.ipAddr == hostInfo.cvtIPAddress
&& sessionTbl[count].atipMapping.port == hostInfo.cvtPort)
{
atipMapping = sessionTbl[count].atipMapping;
goto haveMapping;
}
}
atipMapping.ipAddr = hostInfo.cvtIPAddress;
atipMapping.port = hostInfo.cvtPort;
atipMapping.networkNumber = 0xFFFF; /* invalid/reserved */
atipMapping.node = nextNode++;
atipMapping.socket = nextSocket++;
if (nextNode == 254)
nextNode = 1;
if (nextSocket == 255)
nextSocket = 1;
haveMapping:
resultBuf->netNum = atipMapping.networkNumber;
resultBuf->nodeNum = atipMapping.node;
resultBuf->socketNum = atipMapping.socket;
commandRec->actualMatch = 1;
commandRec->result = 0;
RestoreStateReg(stateReg);
return;
passThrough:
// TODO pass through to actual NBP
return_error(nbpNameErr);
}
#pragma databank 0
#undef return_error

View File

@ -2,6 +2,7 @@
#define ATIPMAPPING_H
#include <types.h>
#include <appletalk.h>
typedef struct ATIPMapping {
/* AppleTalk address/socket */
@ -16,4 +17,6 @@ typedef struct ATIPMapping {
extern struct ATIPMapping atipMapping;
void DoLookupName(NBPLookupNameRec *commandRec);
#endif

View File

@ -25,6 +25,17 @@ cmdProc start
jml DispatchASPCommand
end
nbpCmdProc start
lda 3,s
pha
lda 3,s
pha
lda cmdRecPtr
sta 4,s
lda cmdRecPtr+2
sta 6,s
jml DoLookupName
end
CallCompletionRoutine start
phb

View File

@ -2,6 +2,7 @@
#define CMDPROC_H
void cmdProc(void);
void nbpCmdProc(void);
void CallCompletionRoutine(void *);
#endif

View File

@ -16,6 +16,7 @@ NewCmd newCmds[] = {
{aspCloseSessionCommand, cmdProc},
{aspCommandCommand, cmdProc},
{aspWriteCommand, cmdProc},
{nbpLookupNameCommand, nbpCmdProc},
{0, 0}
};

View File

@ -3,6 +3,7 @@
#include <types.h>
#include "dsiproto.h"
#include "atipmapping.h"
/* Common portion of records for the various SP... commands */
typedef struct SPCommandRec {
@ -54,6 +55,9 @@ typedef struct Session {
/* Marinetti error codes, both the tcperr* value and any tool error */
Word tcperr;
Word toolerr;
/* AppleTalk<->IP address mapping used for this session */
ATIPMapping atipMapping;
} Session;
#endif

View File

@ -28,6 +28,8 @@ BOOLEAN StartTCPConnection(Session *sess) {
return FALSE;
}
sess->atipMapping = atipMapping;
if (TCPIPGetConnectStatus() == FALSE) {
TCPIPConnect(NULL);
if (toolerror()) {