From dfc67049be2be4e4f5e6cbcf2e7d4a0096a4f1d0 Mon Sep 17 00:00:00 2001 From: OpenAI Date: Wed, 17 Jun 2026 05:10:11 +0000 Subject: [PATCH] 0677 nwnss: wrap NDP shared idbroker providers --- include/nwnss/include/ndp_app.h | 29 + include/nwnss/include/ndp_comn.h | 725 ++++++++ include/nwnss/include/ndp_guids.h | 69 + include/nwnss/include/ndp_messagehandler.h | 71 + include/nwnss/include/ndp_msg.h | 218 +++ src/nwnss/CMakeLists.txt | 4 + src/nwnss/comn/common/ndpComnShared.c | 18 + src/nwnss/comn/common/ndpGuidsShared.c | 5 + src/nwnss/comn/common/ndpIdBrokerShared.c | 16 + .../comn/common/ndpMessageHandlerShared.c | 5 + .../comn/common/ndpNcpUserlandBoundary.c | 130 ++ src/nwnss/sharedsrc/ndp_comn.c.h | 1603 +++++++++++++++++ src/nwnss/sharedsrc/ndp_guids.c.h | 50 + src/nwnss/sharedsrc/ndp_idbroker.c.h | 34 +- src/nwnss/sharedsrc/ndp_messagehandler.c.h | 356 ++++ 15 files changed, 3316 insertions(+), 17 deletions(-) create mode 100644 include/nwnss/include/ndp_app.h create mode 100644 include/nwnss/include/ndp_comn.h create mode 100644 include/nwnss/include/ndp_guids.h create mode 100644 include/nwnss/include/ndp_messagehandler.h create mode 100644 include/nwnss/include/ndp_msg.h create mode 100644 src/nwnss/comn/common/ndpComnShared.c create mode 100644 src/nwnss/comn/common/ndpGuidsShared.c create mode 100644 src/nwnss/comn/common/ndpMessageHandlerShared.c create mode 100644 src/nwnss/comn/common/ndpNcpUserlandBoundary.c create mode 100644 src/nwnss/sharedsrc/ndp_comn.c.h create mode 100644 src/nwnss/sharedsrc/ndp_guids.c.h create mode 100644 src/nwnss/sharedsrc/ndp_messagehandler.c.h diff --git a/include/nwnss/include/ndp_app.h b/include/nwnss/include/ndp_app.h new file mode 100644 index 0000000..458899d --- /dev/null +++ b/include/nwnss/include/ndp_app.h @@ -0,0 +1,29 @@ +/**************************************************************************** + | MARS-NWE libnwnss userspace NDP application context compatibility. + | + | The original NDP shared sources include on the application side, + | but the delivered source snapshot only carries the equivalent ndpmod context + | layout. Keep this header limited to the context fields used by the shared + | NDP sources so the Novell shared *.c.h files can be wrapped unchanged. + +-------------------------------------------------------------------------*/ + +#ifndef NDP_APP_H +#define NDP_APP_H + +#include + +typedef struct ndpAppOptions_t { + /* Use the shared ndp_debug global instead of per-context debug state. */ + int unused; +} ndpAppOptions_t; + +typedef struct ndpContext_t { + char *appName; + GUID_t appGuid; + GUID_t appGuidPrime; + ndpAppOptions_t options; + ndp_guidmsgcontext_t *ndpMsgQueueContext; + ndp_guidlistcontext_t *guidListContext; +} ndpContext_t; + +#endif /* NDP_APP_H */ diff --git a/include/nwnss/include/ndp_comn.h b/include/nwnss/include/ndp_comn.h new file mode 100644 index 0000000..580419b --- /dev/null +++ b/include/nwnss/include/ndp_comn.h @@ -0,0 +1,725 @@ +/**************************************************************************** + | + | (C) Copyright 2004 Novell, Inc. + | All Rights Reserved. + | + | This program is free software; you can redistribute it and/or + | modify it under the terms of version 2 of the GNU General Public + | License as published by the Free Software Foundation. + | + | This program is distributed in the hope that it will be useful, + | but WITHOUT ANY WARRANTY; without even the implied warranty of + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + | GNU General Public License for more details. + | + | You should have received a copy of the GNU General Public License + | along with this program; if not, contact Novell, Inc. + | + | To contact Novell about this file by physical or electronic mail, + | you may find current contact information at www.novell.com + | + |*************************************************************************** + | + | Novell's User/Kernel Data Portal (NDP) Common include file. + | + |--------------------------------------------------------------------------- + | + | $Author: blarsen $ + | $Date: 2006-02-09 05:04:41 +0530 (Thu, 09 Feb 2006) $ + | + | $RCSfile$ + | $Revision: 1325 $ + | + |--------------------------------------------------------------------------- + | This file is used to: + | ... + +-------------------------------------------------------------------------*/ + +#ifndef NDP_COMN_H +#define NDP_COMN_H + +/******************************************** +** The following defines are for debugging ** +#define NO_MOD_LOCKING +#define NO_APP_LOCKING +********************************************/ + +#if (defined(__KERNEL__) && ! defined(NO_MOD_LOCKING)) +/*************************************** +*** Module Space LOCK/UNLOCK defines *** +***************************************/ +#include +#include +#include +#include +#include +//#include + +#define DECLARE_NDPLOCK(lockvar) \ + struct rw_semaphore lockvar + +#define INITLOCK_MSGQUEUE(guidmsgcontext) \ + init_rwsem(&guidmsgcontext->msgQueueLock) +#define DESTROYLOCK_MSGQUEUE(guidmsgcontext) + +#define RDLOCK_MSGQUEUE(guidmsgcontext) \ + down_read(&guidmsgcontext->msgQueueLock) +#define WRLOCK_MSGQUEUE(guidmsgcontext) \ + down_write(&guidmsgcontext->msgQueueLock) +#define RDUNLOCK_MSGQUEUE(guidmsgcontext) \ + up_read(&guidmsgcontext->msgQueueLock) +#define WRUNLOCK_MSGQUEUE(guidmsgcontext) \ + up_write(&guidmsgcontext->msgQueueLock) + +#define INITLOCK_GUIDLIST(guidlistcontext) \ + init_rwsem(&guidlistcontext->guidListLock) +#define DESTROYLOCK_GUIDLIST(guidlistcontext) + +#define RDLOCK_GUIDLIST(guidlistcontext) \ + down_read(&guidlistcontext->guidListLock) +#define WRLOCK_GUIDLIST(guidlistcontext) \ + down_write(&guidlistcontext->guidListLock) +#define RDUNLOCK_GUIDLIST(guidlistcontext) \ + up_read(&guidlistcontext->guidListLock) +#define WRUNLOCK_GUIDLIST(guidlistcontext) \ + up_write(&guidlistcontext->guidListLock) + +#endif /* (defined(__KERNEL__) && ! defined(NO_MOD_LOCKING)) */ + +#if (! defined(__KERNEL__) && ! defined(NO_APP_LOCKING)) +/******************************************** +*** Application Space LOCK/UNLOCK defines *** +*********************************************/ +/* NOTE: The following two defines MUST be done before including sys/types.h */ +#define __USE_UNIX98 1 +#define _XOPEN_SOURCE 600 +#include +#include +#include +#include +#include +#include + +#define __USE_BSD +#include +#include + +#define DECLARE_NDPLOCK(lockvar) \ + pthread_rwlock_t lockvar + +#define INITLOCK_MSGQUEUE(guidmsgcontext) \ + pthread_rwlock_init(&guidmsgcontext->msgQueueLock, NULL) +#define DESTROYLOCK_MSGQUEUE(guidmsgcontext) \ + pthread_rwlock_destroy(&guidmsgcontext->msgQueueLock) + +#define RDLOCK_MSGQUEUE(guidmsgcontext) \ + pthread_rwlock_rdlock(&guidmsgcontext->msgQueueLock) +#define WRLOCK_MSGQUEUE(guidmsgcontext) \ + pthread_rwlock_wrlock(&guidmsgcontext->msgQueueLock) +#define RDUNLOCK_MSGQUEUE(guidmsgcontext) \ + pthread_rwlock_unlock(&guidmsgcontext->msgQueueLock) +#define WRUNLOCK_MSGQUEUE(guidmsgcontext) \ + pthread_rwlock_unlock(&guidmsgcontext->msgQueueLock) + +#define INITLOCK_GUIDLIST(guidlistcontext) \ + pthread_rwlock_init(&guidlistcontext->guidListLock, NULL) +#define DESTROYLOCK_GUIDLIST(guidlistcontext) \ + pthread_rwlock_destroy(&guidlistcontext->guidListLock) + +#define RDLOCK_GUIDLIST(guidlistcontext) \ + pthread_rwlock_rdlock(&guidlistcontext->guidListLock) +#define WRLOCK_GUIDLIST(guidlistcontext) \ + pthread_rwlock_wrlock(&guidlistcontext->guidListLock) +#define RDUNLOCK_GUIDLIST(guidlistcontext) \ + pthread_rwlock_unlock(&guidlistcontext->guidListLock) +#define WRUNLOCK_GUIDLIST(guidlistcontext) \ + pthread_rwlock_unlock(&guidlistcontext->guidListLock) +#endif /* (! defined(__KERNEL__) && ! defined(NO_APP_LOCKING)) */ + +#if ((defined(__KERNEL__) && defined(NO_MOD_LOCKING)) \ + || (! defined(__KERNEL__) && defined(NO_APP_LOCKING))) +/*********************************************************** +*** Module | Application Space LOCK/UNLOCK defines (NOT) *** +***********************************************************/ +#define DECLARE_NDPLOCK(var) + +#define INITLOCK_MSGQUEUE(guidmsgcontext) +#define DESTROYLOCK_MSGQUEUE(guidmsgcontext) + +#define RDLOCK_MSGQUEUE(guidmsgcontext) +#define WRLOCK_MSGQUEUE(guidmsgcontext) +#define RDUNLOCK_MSGQUEUE(guidmsgcontext) +#define WRUNLOCK_MSGQUEUE(guidmsgcontext) + +#define INITLOCK_GUIDLIST(guidlistcontext) +#define DESTROYLOCK_GUIDLIST(guidlistcontext) + +#define RDLOCK_GUIDLIST(guidlistcontext) +#define WRLOCK_GUIDLIST(guidlistcontext) +#define RDUNLOCK_GUIDLIST(guidlistcontext) +#define WRUNLOCK_GUIDLIST(guidlistcontext) +#endif /* ((defined(__KERNEL__) && defined(NO_MOD_LOCKING)) \ + || (! defined(__KERNEL__) && defined(NO_APP_LOCKING))) */ + +#include /* for "GUID_t" --- DO NOT USE zOmni.h !!! */ + +#undef QUE_MACRO +#define QUE_MACRO ENABLE +#undef QUE_CHECK +#define QUE_CHECK DISABLE +#include /* for queue NSS definitions/macros */ + +/****************************************************************************** +******************************************************************************* +* NDP Device Name and MAJOR/MINOR Values & Macros +******************************************************************************* +******************************************************************************/ +#define DEFAULT_ndpDevice "/dev/ndp" + +#define ndpMAJOR 10 +#define ndpMINOR 123 + +#ifndef MAJOR +#define MAJOR(device) ((device) >> 8) +#endif +#ifndef MINOR +#define MINOR(device) ((device) & 0x00FF) +#endif + +extern QUAD NdpWriteCount; +extern QUAD NdpPrintfCount; + +/****************************************************************************** +******************************************************************************* +* NDP GUID Values +******************************************************************************* +******************************************************************************/ +extern GUID_t ndpAppGuid; +extern GUID_t ndpAppGuidPrime; +extern GUID_t ndpModGuid; +extern GUID_t ndpModGuidPrime; + +/****************************************************************************** +******************************************************************************* +* Data Type Definitions +******************************************************************************* +******************************************************************************/ + +/************************ +* Message type definition +************************/ +typedef struct ndp_msg_t ndp_msg_t; +struct ndp_msg_t { + GUID_t srcGuid; + GUID_t dstGuid; + LONG length; /* 32 bit unsigned value */ + unsigned char data[0]; /* !!! Data starts here !!! */ + /* NOTE: "data" currently allocated at end of this struct. */ +}; + +/************************************ +* Message Queue Entry type definition +************************************/ +typedef struct ndp_msgqueue_t ndp_msgqueue_t; +struct ndp_msgqueue_t { + ndp_msg_t *msg; + SQlink_t sqLink; + /* NOTE: "msg" currently allocated at end of this struct. */ +}; + +/************************************* +* GUID Message Context type definition +*************************************/ +typedef struct ndp_guidmsgcontext_t ndp_guidmsgcontext_t; +struct ndp_guidmsgcontext_t { + SQhead_t sqHead; + int msgCount; + DECLARE_NDPLOCK(msgQueueLock); + /* + * The following waitqueue data + * is to enable a read to sleep + * until a message is present + */ +#ifdef __KERNEL__ + wait_queue_head_t *msgwaitqueue; + wait_queue_head_t _msgwaitqueue; +#else + sem_t *msgwaitqueue; + sem_t _msgwaitqueue; +#endif /* __KERNEL__ */ + /* + * The following information is connection specific, + * and needs filled in by the connecting routine. + * Everything will be zeroed out upon creation. + * (NOTE: This is here instead of in ndp_guidlist_t for ease of access only) + */ + int connection; /* Connection Types - See NDPCONN_xxx values */ + pid_t pid; /* For NDPCONN_msgop */ + long ndpMsgQueueID; /* For NDPCONN_msgop */ +}; + +/**************************/ +/* Known Connection Types */ +/**************************/ + +#define NDPCONN_unknown -1 + +#define NDPCONNSTR_linked "linked" +#define NDPCONN_linked 0 + +#define NDPCONNSTR_msgop "msgop" +#define NDPCONN_msgop 1 + +/************************** +* GUID List type definition +**************************/ +typedef struct ndp_guidlist_t ndp_guidlist_t; +struct ndp_guidlist_t { + GUID_t guid; + GUID_t guidPrime; + unsigned char *name; /* Optional - Mainly for debugging */ + ndp_guidmsgcontext_t *guidmsgcontext; + DQlink_t dqLink; + /* NOTE: "name" currently allocated at end of this struct. */ +}; + +/********************************** +* GUID List Context type definition +**********************************/ +typedef struct ndp_guidlistcontext_t ndp_guidlistcontext_t; +struct ndp_guidlistcontext_t { + DQhead_t dqHead; + int guidCount; + DECLARE_NDPLOCK(guidListLock); +}; + +/****************************************************************************** +******************************************************************************* +* Define some NDP specific data values +******************************************************************************* +******************************************************************************/ +//#define MIN_MSG_SIZE (sizeof(GUID_t) + sizeof(GUID_t) + sizeof(LONG)) +#define MIN_MSG_SIZE (sizeof(ndp_msg_t)) + +/****************************************************************************** +******************************************************************************* +* Kernel Module / User Application Bridging Macros +******************************************************************************* +******************************************************************************/ + +#ifdef __KERNEL__ +# define THISGUID ndpModGuid +# define THISGUIDPRIME ndpModGuidPrime +# define OTHERGUID ndpAppGuid +# define OTHERGUIDPRIME ndpAppGuidPrime +# define ndpPrintf printk +# define ndpMalloc(size,type) kmalloc(size,type) +# define ndpFree kfree +#else +# define EXPORT_SYMBOL(sym) +# define THISGUID ndpAppGuid +# define THISGUIDPRIME ndpAppGuidPrime +# define OTHERGUID ndpModGuid +# define OTHERGUIDPRIME ndpModGuidPrime +# define ndpPrintf printf +# define ndpMalloc(size,type) malloc(size) +# define ndpFree free +#endif + +#define ndpDbgDumpDataInHex(dbgLevel,msg,cnt,buf) \ + if (ndp_debug >= dbgLevel) ndp_dumpDataInHex(dbgLevel,msg,cnt,buf) + +extern int ndp_debug; + +/****************************************************************************** +******************************************************************************* +* Function Pre-Declarations +******************************************************************************* +******************************************************************************/ + +/****************************************************************************** +* An ERROR message routine for NDP +******************************************************************************/ +#ifdef __KERNEL__ +#define ndpErrPrintf(fmt,args...) \ + ndpPrintf(KERN_ERR fmt, ##args) +#else +void ndpErrPrintf( + char *fmt, + ...); +#endif + +/****************************************************************************** +* A WARNING message routine for NDP +******************************************************************************/ +#ifdef __KERNEL__ +#define ndpWrnPrintf(fmt,args...) \ + ndpPrintf(KERN_WARNING fmt, ##args) +#else +void ndpWrnPrintf( + char *fmt, + ...); +#endif + +/****************************************************************************** +* A debug message routine for NDP +******************************************************************************/ +#ifdef __KERNEL__ +#define __ndpDbgPrintf(fmt,args...) \ + ndpPrintf(KERN_DEBUG fmt, ##args) +#else +void __ndpDbgPrintf( + char *fmt, + ...); +#endif + +#define ndpDbgPrintf(dbgLevel,fmt,arg...) \ + if (ndp_debug >= dbgLevel) __ndpDbgPrintf(fmt, ##arg) + +/****************************************************************************** +* Hex Data Dump routine +******************************************************************************/ +void ndp_dumpDataInHex( + int dbgLevel, + char *msg, + LONG length, + unsigned char *data); + +/***************************************************************************** +* Convert a "hex GUID" to a "binary GUID" +*****************************************************************************/ +void ndp_hex2guid( + unsigned char hexguid[(2*sizeof(GUID_t))+1], + GUID_t *_guid); + +/***************************************************************************** +* Convert a "binary GUID" to a "hex GUID" +*****************************************************************************/ +void ndp_guid2hex( + GUID_t *_guid, + unsigned char hexguid[(2*sizeof(GUID_t))+1]); + +/***************************************************************************** +* Convert a "hex buffer" to a "binary buffer" +* NOTE - datalen is the number of output bytes expected in the _bindata. +*****************************************************************************/ +void ndp_hex2buf( + unsigned char *hexdata, + int datalen, + unsigned char *_bindata); /* Big enough to receive "datalen" bytes of data */ + +/***************************************************************************** +* Convert a "binary buffer" to a "hex buffer" +* NOTE - datalen is number of input bytes. Output must be big enough to +* receive two bytes for every input byte, plus a trailing NULL byte. +*****************************************************************************/ +void ndp_buf2hex( + unsigned char *_bindata, + int datalen, + unsigned char *hexdata); /* Big enough to receive "(datalen*2)+1" bytes of hex data */ + +/***************************************************************************** +* Extract a string value (or NULL) from an XML tagged data buffer +* Return value == 0 if tag found and data is OK, else ERROR Status +* Note: We assume zOK == 0 +*****************************************************************************/ +int ndp_getXmlTagValueString( + utf8_t *tag, + utf8_t *data, + int length, + unsigned char **retString); + +/***************************************************************************** +* Extract a LONG value (or -1) from an XML tagged data buffer +* Return value == 0 if tag found and data is OK, else ERROR Status +* Note: We assume zOK == 0 +*****************************************************************************/ +int ndp_getXmlTagValueLong( + utf8_t *tag, + utf8_t *data, + int length, + LONG *retLong); + +/****************************************************************************** +* Emulate strdup only for generic data +* Return a pointer to a new data chunck which is a duplicate of the original. +******************************************************************************/ +unsigned char *ndp_memdup( + unsigned char *data, + int length); + +/****************************************************************************** +* Emulate atoi +* Convert an ascii string to an integer value (base 10) +******************************************************************************/ +int ndp_atoi( + char *a); + +/****************************************************************************** +* Emulate atol +* Convert an ascii string to a LONG (long integer) value (base 10) +******************************************************************************/ +LONG ndp_atol( + char *a); + +/****************************************************************************** +* Compares the character to any White Space character +* Returns 1 if it is whitespace, else it returns 0 +******************************************************************************/ +int ndp_CharIsWhiteSpace( + unsigned char c); + +/****************************************************************************** +* Skip past any White Space characters +* Returns the new pointer, and a modified length +******************************************************************************/ +unsigned char *ndp_SkipWhitespace( + unsigned char *_data, + LONG *_length); + +/****************************************************************************** +* Emulate strncasecmp +* Returns +* an integer less than, equal to, or greater than zero +* if s1 is found, respectively, to be less than, +* to match, or be greater than s2. +******************************************************************************/ +int ndp_strncasecmp( + unsigned char *s1, + unsigned char *s2, + int n); + +/****************************************************************************** +* Allocate and fill in a new NDP Message Queue Entry +******************************************************************************/ +ndp_msgqueue_t *new_ndp_msgqueue_entry( + GUID_t *srcGuid, + GUID_t *dstGuid, + LONG length, /* 32 bit unsigned value */ + unsigned char *data); + +/****************************************************************************** +* Free a previously allocated NDP Message Queue Entry +******************************************************************************/ +void free_ndp_msgqueue_entry( + ndp_msgqueue_t *entry); + +/****************************************************************************** +* Free a previously allocated NDP Message Queue +******************************************************************************/ +void free_ndp_msgqueue( + ndp_guidmsgcontext_t *context); + +/****************************************************************************** +* Specify a wait queue to use instead of +* the msgwaitqueue provided with each msg queue +******************************************************************************/ +#ifdef __KERNEL__ +wait_queue_head_t *substituteMsgWaitQueue( + GUID_t *guidPrime, + wait_queue_head_t *msgWaitQueue); +#else +sem_t *substituteMsgWaitQueue( + GUID_t *guidPrime, + sem_t *msgWaitQueue); +#endif + +/****************************************************************************** +* Allocate and fill in a new NDP GUID Message Context +******************************************************************************/ +ndp_guidmsgcontext_t *new_ndp_guidmsgcontext( + void); + +/****************************************************************************** +* Free a previously allocated NDP GUID Message Context +******************************************************************************/ +void free_ndp_guidmsgcontext( + ndp_guidmsgcontext_t *context); + +/****************************************************************************** +* Allocate and fill in a new NDP GUID List Entry +******************************************************************************/ +ndp_guidlist_t *new_ndp_guidlist_entry( + GUID_t *guid, + GUID_t *guidPrime, + char *name); + +/****************************************************************************** +* Free a previously allocated NDP GUID List Entry +******************************************************************************/ +void free_ndp_guidlist_entry( + ndp_guidlist_t *entry); + +/****************************************************************************** +* Free a previously allocated NDP GUID List +******************************************************************************/ +void free_ndp_guidlist( + ndp_guidlistcontext_t *context); + +/****************************************************************************** +* Allocate and fill in a new NDP GUID List Context +******************************************************************************/ +ndp_guidlistcontext_t *new_ndp_guidlistcontext( + void); + +/****************************************************************************** +* Free a previously allocated NDP GUID List Context +******************************************************************************/ +void free_ndp_guidlistcontext( + ndp_guidlistcontext_t *context); + +/****************************************************************************** +* Extract NDP Message Queue Entry from Queue +* (Message Queue is maintained as a FIFO) +* (Extract from head of queue) +******************************************************************************/ +ndp_msgqueue_t *extract_ndp_msgqueue_entry( + ndp_guidmsgcontext_t *context); + +/****************************************************************************** +* Insert NDP Message Queue Entry into Queue +* (Message Queue is maintained as a FIFO) +* (Insert at tail of queue) +******************************************************************************/ +int insert_ndp_msgqueue_entry( + ndp_guidmsgcontext_t *context, + ndp_msgqueue_t *entry); + +/****************************************************************************** +* Exchange NDP GUID Prime for NDP Guid from NDP GUID List +******************************************************************************/ +int ndp_exchangeGuidPrimeForGuid( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guidPrime, + GUID_t *guid); + +/****************************************************************************** +* Exchange NDP GUID for NDP Guid Prime from NDP GUID List +******************************************************************************/ +int ndp_exchangeGuidForGuidPrime( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guid, + GUID_t *guidPrime); + +/****************************************************************************** +* Find NDP GUID List Entry +******************************************************************************/ +ndp_guidmsgcontext_t *find_ndp_guidmsgcontext( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guid); + +/****************************************************************************** +* Find NDP GUID Prime List Entry +******************************************************************************/ +ndp_guidmsgcontext_t *find_ndp_guidprimemsgcontext( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guidPrime); + +/****************************************************************************** +* Extract NDP GUID List Entry from List +* (GUID list is maintained in sorting order) +******************************************************************************/ +ndp_guidlist_t *extract_ndp_guidlist_entryByGuidPrime( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guidPrime); + +/****************************************************************************** +* Insert NDP GUID List Entry into List +* (GUID list is maintained in sorting order) +******************************************************************************/ +int insert_ndp_guidlist_entry( + ndp_guidlistcontext_t *guidlsitcontext, + ndp_guidlist_t *entry); + +/****************************************************************************** +* Read data sent to a specified guid (reader verified with guidPrime) +* (Note: This routine is available to other kernel modules) +******************************************************************************/ +int ndp_readFromGuid( + int dumpDataDebugLevel, + GUID_t *guidPrime, + GUID_t *srcGuid, /* A GUID value is returned */ + LONG *length, /* A 32 bit unsigned value is returned */ + unsigned char **data); /* An allocated data chunk is returned */ + /* (if length > 0) */ + +/****************************************************************************** +* Read data sent to a specified guid (reader verified with guidPrime) +* Don't return unless data has been received (and read) +* or until the specified timeout has occurred. +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +int ndp_readFromGuidUntilTimeout( + int dumpDataDebugLevel, + GUID_t *guidPrime, + GUID_t *srcGuid, /* A GUID value is returned */ + LONG *length, /* A 32 bit unsigned value is returned */ + unsigned char **data, /* An allocated data chunk is returned */ + /* (if length > 0) */ + int timeoutInSeconds); /* Maximum number of seconds to wait */ + +/****************************************************************************** +* Write data sent to a specified guid (writer verified with guidPrime) +* (Note: This routine is available to other kernel modules) +******************************************************************************/ +int ndp_writeToGuid( + int dumpDataDebugLevel, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + LONG length, /* 32 bit unsigned value */ + unsigned char *data); + +/****************************************************************************** +* Printf data sent to a specified guid (writer verified with guidPrime) +* (Note: This routine is available to other kernel modules) +******************************************************************************/ +int ndp_printfToGuid( + int dumpDataDebugLevel, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + char *fmt, + ...); + +#ifndef __KERNEL__ +/****************************************************************************** +* Printf data sent via msgsnd to a specified guid +* (writer verified with guidPrime) +* --- Application space only (not in kernel) --- +******************************************************************************/ +int ndpmsgsnd_printfToGuid( + int dumpDataDebugLevel, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + char *fmt, + ...); +#endif + +/****************************************************************************** +* Register a guid for data transfers (read & write) +* A guidPrime will be returned for use hereafter with these routines +* (Note: This routine is available to other kernel modules) +******************************************************************************/ +int ndp_registerGuid( + GUID_t *guid, + GUID_t *guidPrime, /* Space must be provided by the caller !!! */ + char *name); + +/****************************************************************************** +* Generate a new random Guid -AND- +* Register a this guid for data transfers (read & write) +* The guid & guidPrime will be returned for use hereafter with these routines +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +int ndp_registerRandomGuid( + GUID_t *guid, /* Space must be provided by the caller !!! */ + GUID_t *guidPrime, /* Space must be provided by the caller !!! */ + char *name); + +/****************************************************************************** +* De-Register a previously register guid (guid verified with guidPrime) +* (Note: This routine is available to other kernel modules) +******************************************************************************/ +void ndp_deregisterGuid( + GUID_t *guidPrime); + +#endif /* NDP_COMN_H */ diff --git a/include/nwnss/include/ndp_guids.h b/include/nwnss/include/ndp_guids.h new file mode 100644 index 0000000..06f02f8 --- /dev/null +++ b/include/nwnss/include/ndp_guids.h @@ -0,0 +1,69 @@ +/**************************************************************************** + | + | (C) Copyright 2004 Novell, Inc. + | All Rights Reserved. + | + | This program is free software; you can redistribute it and/or + | modify it under the terms of version 2 of the GNU General Public + | License as published by the Free Software Foundation. + | + | This program is distributed in the hope that it will be useful, + | but WITHOUT ANY WARRANTY; without even the implied warranty of + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + | GNU General Public License for more details. + | + | You should have received a copy of the GNU General Public License + | along with this program; if not, contact Novell, Inc. + | + | To contact Novell about this file by physical or electronic mail, + | you may find current contact information at www.novell.com + | + |*************************************************************************** + | + | Novell's User/Kernel Data Portal (NDP) GUIDs file. + | + |--------------------------------------------------------------------------- + | + | $Author: vandana $ + | $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $ + | + | $RCSfile$ + | $Revision: 1177 $ + | + |--------------------------------------------------------------------------- + | This file is used to: + | ... + +-------------------------------------------------------------------------*/ + +#ifndef NDP_GUIDS_H +#define NDP_GUIDS_H + +#ifdef NON_NSS + typedef unsigned int LONG; /* 32 bits */ + typedef unsigned short WORD; /* 16 bits */ + typedef unsigned char BYTE; /* 8 bits */ + + /* 16 unsigned bytes */ + typedef struct GUID_t GUID_t; + struct GUID_t { + LONG timeLow; + WORD timeMid; + WORD timeHighAndVersion; + BYTE clockSeqHighAndReserved; + BYTE clockSeqLow; + BYTE node[6]; + }; +#else +# include /* for "GUID_t" --- DO NOT USE zOmni.h !!! */ +#endif + +/****************************************************************************** +******************************************************************************* +* Declare Extern the NDP Application & Module GUID Variables +******************************************************************************* +******************************************************************************/ + +extern GUID_t ndpAppGuid; +extern GUID_t ndpModGuid; + +#endif /* NDP_GUIDS_H */ diff --git a/include/nwnss/include/ndp_messagehandler.h b/include/nwnss/include/ndp_messagehandler.h new file mode 100644 index 0000000..ffb5dc4 --- /dev/null +++ b/include/nwnss/include/ndp_messagehandler.h @@ -0,0 +1,71 @@ +/**************************************************************************** + | + | (C) Copyright 2004 Novell, Inc. + | All Rights Reserved. + | + | This program is free software; you can redistribute it and/or + | modify it under the terms of version 2 of the GNU General Public + | License as published by the Free Software Foundation. + | + | This program is distributed in the hope that it will be useful, + | but WITHOUT ANY WARRANTY; without even the implied warranty of + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + | GNU General Public License for more details. + | + | You should have received a copy of the GNU General Public License + | along with this program; if not, contact Novell, Inc. + | + | To contact Novell about this file by physical or electronic mail, + | you may find current contact information at www.novell.com + | + |*************************************************************************** + | + | Novell's User/Kernel Data Portal (NDP) Common Message Handling include file. + | + |--------------------------------------------------------------------------- + | + | $Author: taysom $ + | $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $ + | + | $RCSfile$ + | $Revision: 465 $ + | + |--------------------------------------------------------------------------- + | This file is used to: + | ... + +-------------------------------------------------------------------------*/ + +#ifndef NDP_MESSAGEHANDLER_H +#define NDP_MESSAGEHANDLER_H + + +#ifdef __KERNEL__ +# include +# include +#else +/* NOTE: ndp_comn.h needs included before anything else in application land */ +# include +# include +# include +#endif + +#include + +/****************************************************************************** +******************************************************************************* +* Function Pre-Declarations +******************************************************************************* +******************************************************************************/ + +/****************************************************************************** +* The NDP Application Message Handling Routine +* This routine is called whenever a message is received for the NDP Application +******************************************************************************/ +void ndp_messagehandler( + ndpContext_t *ndpContext, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + LONG length, /* 32 bit unsigned value */ + unsigned char *data); + +#endif /* NDP_MESSAGEHANDLER_H */ diff --git a/include/nwnss/include/ndp_msg.h b/include/nwnss/include/ndp_msg.h new file mode 100644 index 0000000..5c94f1e --- /dev/null +++ b/include/nwnss/include/ndp_msg.h @@ -0,0 +1,218 @@ +/**************************************************************************** + | + | (C) Copyright 2004 Novell, Inc. + | All Rights Reserved. + | + | This program is free software; you can redistribute it and/or + | modify it under the terms of version 2 of the GNU General Public + | License as published by the Free Software Foundation. + | + | This program is distributed in the hope that it will be useful, + | but WITHOUT ANY WARRANTY; without even the implied warranty of + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + | GNU General Public License for more details. + | + | You should have received a copy of the GNU General Public License + | along with this program; if not, contact Novell, Inc. + | + | To contact Novell about this file by physical or electronic mail, + | you may find current contact information at www.novell.com + | + |*************************************************************************** + | + | Novell's User/Kernel Data Portal (NDP) msgsnd/msgrcv include file. + | + |--------------------------------------------------------------------------- + | + | $Author: blarsen $ + | $Date: 2006-01-19 23:42:21 +0530 (Thu, 19 Jan 2006) $ + | + | $RCSfile$ + | $Revision: 1309 $ + | + |--------------------------------------------------------------------------- + | This file is used to: + | ... + +-------------------------------------------------------------------------*/ + +#ifndef NDP_MSG_H +#define NDP_MSG_H + +#include +// Not in Here // #include + +#include +#include +#include + +/****************************************************************************** +* Provide a way for applications using this library top debug it +******************************************************************************/ +extern int ndplibdebug; + +/****************************************************************************** +* Define the message_type (src/dst identifier for the message) for the NDP +* Application. Applications communicating with the NDP Application should: +* Specify NDP_APP_MTYPE when using msgsnd() +* Specify their PID (process ID) when using msgrcv() +******************************************************************************/ +#define NDP_APP_MSG_DST 1L + +/****************************************************************************** +* Define the maximum NDP message size to be associated with msgsnd/msgrcv +******************************************************************************/ +#define NDP_MAX_MSG_SIZE 4096 + +/****************************************************************************** +* Define the method of getting the NDP Message Key +******************************************************************************/ +#define GetNdpMsgKey() ftok("/dev/ndp", 0x75) + +/****************************************************************************** +******************************************************************************* +* Define the NDP Message Structure Type(s) +******************************************************************************* +******************************************************************************/ + +#define NDP_FIRST_MULT_MSG 0x1 +#define NDP_LAST_MULT_MSG 0x2 + +typedef struct ndpmsg_data_t ndpmsg_data_t; +struct ndpmsg_data_t { + GUID_t srcGuidPrime; + GUID_t dstGuid; + unsigned long dataLength; /* Length of data in this packet */ + unsigned long totalLength; /* Total length of all data in all packets */ + unsigned long msgsRemaining; /* Total number of messages to be sent. */ + unsigned long multipleID; /* Unique number used to associate multiple packets + * with each other. */ + int flags; /* Defines above ... */ + unsigned char data[0]; +}; + +typedef struct ndpmsg_t ndpmsg_t; +struct ndpmsg_t { + LONG dstID; + union { + unsigned char raw[NDP_MAX_MSG_SIZE]; + ndpmsg_data_t msg; + } u; +}; + +/****************************************************************************** +******************************************************************************* +* Define some useful interface macros (inline functions) +******************************************************************************* +******************************************************************************/ + +/****************************************************************************** +* The NDP msgop Context Structure Definition +* NOTE: All the ndpmsgop_XXX() operations require +* 1) an ndpmsgopContext pointer. +* 2) an integer sts value. +* A sts value of 0 upon completion is GOOD, else, BAD! +/*****************************************************************************/ +typedef struct ndpmsgopContext_t ndpmsgopContext_t; +struct ndpmsgopContext_t { + GUID_t guid; + GUID_t guidPrime; /* Will/needs to be set to guid at init time */ + pid_t pid; + unsigned char *name; /* Allocated & Freed */ + key_t ndpMsgKey; + long ndpMsgQueueID; + int initialized; + int registered; +}; + +/****************************************************************************** +* ndpmsgop_printXXX(s) for debugging ... +******************************************************************************/ +void ndpmsgop_printGuid( + char *label, + GUID_t *guid); + +void ndpmsgop_printContext( + char *label, + ndpmsgopContext_t *context); + +void ndpmsgop_printRawData( + unsigned char *cp, + int length); + +void ndpmsgop_printNdpmsg( + char *label, + ndpmsg_t *ndpmsg); + +/****************************************************************************** +* Prepare for NDP msgop communications(s) +******************************************************************************/ +int ndpmsgop_init( + ndpmsgopContext_t *context, + GUID_t *guid, + unsigned char *name); + +/****************************************************************************** +* Cleanup from NDP msgop communications(s) +******************************************************************************/ +int ndpmsgop_cleanup( + ndpmsgopContext_t *context); + +/****************************************************************************** +* Do an NDP Register of a GUID using msgop communication +******************************************************************************/ +int ndpmsgop_registerGuid( + ndpmsgopContext_t *context); + +/****************************************************************************** +* Do an NDP Deregister of a GUID using msgop communication +******************************************************************************/ +int ndpmsgop_deregisterGuid( + ndpmsgopContext_t *context); + +/****************************************************************************** +* Do an NDP writeToGuid() using msgop communication +******************************************************************************/ +int ndpmsgop_writeToGuid( + ndpmsgopContext_t *context, + GUID_t *guid, + unsigned char *data, + LONG length); +/****************************************************************************** +* Do an NDP printToGuid() using msgop communication +******************************************************************************/ +int ndpmsgop_printfToGuid( + ndpmsgopContext_t *context, + GUID_t *guid, + char *fmt, + ...); + +/****************************************************************************** +* Do an NDP read from a GUID using msgop communication +******************************************************************************/ +int ndpmsgop_readFromGuid( + ndpmsgopContext_t *context, + ndpmsg_t *ndpmsg); + +/***************************************************************************** +* Notification If DN Has Been Renamed Or Deleted +* If newDN is 0, the object has been deleted +* K2U ... N/A (no return value) ... +* U2K cccccc +* Returns 0 if successful, else an error occurred sending the message +*****************************************************************************/ +int ndpmsgop_NCPNotifyDNChange( + ndpmsgopContext_t *context, + unicode_t *oldDN, + unicode_t *newDN); + +/***************************************************************************** +* Notification If SEV Has Been Changed +* K2U ... N/A (no return value) ... +* U2K hex +* Returns 0 if successful, else an error occurred sending the message +*****************************************************************************/ +int ndpmsgop_NCPNotifySEVChange( + ndpmsgopContext_t *context, + GUID_t *guid); + +#endif /* NDP_MSG_H */ diff --git a/src/nwnss/CMakeLists.txt b/src/nwnss/CMakeLists.txt index 676bab7..79a540f 100644 --- a/src/nwnss/CMakeLists.txt +++ b/src/nwnss/CMakeLists.txt @@ -213,7 +213,11 @@ add_library(nwnss SHARED library/misc/dbginit.c library/misc/nssErrorTable.c library/debug/otherErrorTables.c + comn/common/ndpComnShared.c + comn/common/ndpGuidsShared.c + comn/common/ndpMessageHandlerShared.c comn/common/ndpIdBrokerShared.c + comn/common/ndpNcpUserlandBoundary.c library/misc/sysimp.c comn/main/comnCmdline.c comn/authsys/authorize.c diff --git a/src/nwnss/comn/common/ndpComnShared.c b/src/nwnss/comn/common/ndpComnShared.c new file mode 100644 index 0000000..3e25027 --- /dev/null +++ b/src/nwnss/comn/common/ndpComnShared.c @@ -0,0 +1,18 @@ +/**************************************************************************** + | MARS-NWE libnwnss import wrapper for NSS shared NDP common source. + +-------------------------------------------------------------------------*/ + +#include +#include + +#include + +ndpContext_t *ndpContext = NULL; +int ndpSyslogFacility = LOG_USER; +int ndp_debug = 0; +long ndpMsgQueueID = -1; +long ndpmsg_multipleID = 0; +int daemonize = 0; +sem_t ndpmsg_multipleIDsem; + +#include diff --git a/src/nwnss/comn/common/ndpGuidsShared.c b/src/nwnss/comn/common/ndpGuidsShared.c new file mode 100644 index 0000000..57aa560 --- /dev/null +++ b/src/nwnss/comn/common/ndpGuidsShared.c @@ -0,0 +1,5 @@ +/**************************************************************************** + | MARS-NWE libnwnss import wrapper for NSS shared NDP GUID source. + +-------------------------------------------------------------------------*/ + +#include diff --git a/src/nwnss/comn/common/ndpIdBrokerShared.c b/src/nwnss/comn/common/ndpIdBrokerShared.c index e36e23e..0ac5502 100644 --- a/src/nwnss/comn/common/ndpIdBrokerShared.c +++ b/src/nwnss/comn/common/ndpIdBrokerShared.c @@ -2,4 +2,20 @@ | MARS-NWE libnwnss import wrapper for NSS shared NDP idbroker source. +-------------------------------------------------------------------------*/ +#include + +#include +#include +#include +#include +#include + +extern long ndpmsg_multipleID; +extern sem_t ndpmsg_multipleIDsem; +extern int daemonize; + +STATUS COMN_GenerateVolumeCrypto(VolumeKey_s *key, unicode_t *password); +STATUS COMN_ProcessVolumeCrypto(VolumeKey_s *key, unicode_t *password); + +#define BUILD_NDP_IDBROKER 1 #include diff --git a/src/nwnss/comn/common/ndpMessageHandlerShared.c b/src/nwnss/comn/common/ndpMessageHandlerShared.c new file mode 100644 index 0000000..3b0a2d4 --- /dev/null +++ b/src/nwnss/comn/common/ndpMessageHandlerShared.c @@ -0,0 +1,5 @@ +/**************************************************************************** + | MARS-NWE libnwnss import wrapper for NSS shared NDP message handler source. + +-------------------------------------------------------------------------*/ + +#include diff --git a/src/nwnss/comn/common/ndpNcpUserlandBoundary.c b/src/nwnss/comn/common/ndpNcpUserlandBoundary.c new file mode 100644 index 0000000..d5e1916 --- /dev/null +++ b/src/nwnss/comn/common/ndpNcpUserlandBoundary.c @@ -0,0 +1,130 @@ +/**************************************************************************** + | MARS-NWE libnwnss userspace NDP/NCP dynamic boundary. + | + | The NSS shared management sources call a small NCP/NSSAdmin surface directly. + | Novell's NDP idbroker side binds these providers dynamically instead of + | linking the module hard to libncpid/libnssadmin. Keep the same boundary for + | libnwnss: resolve the optional providers at runtime and return an error when + | the external service is unavailable. + +-------------------------------------------------------------------------*/ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static void *mars_nwnss_ncpid_handle; +static void *mars_nwnss_nssadmin_handle; + +static void *mars_nwnss_open_optional_library(void **handle, const char *name) +{ + if (*handle == NULL) { + *handle = dlopen(name, RTLD_NOW | RTLD_LOCAL); + } + return *handle; +} + +static void *mars_nwnss_ncpid_symbol(const char *name) +{ + void *handle = mars_nwnss_open_optional_library(&mars_nwnss_ncpid_handle, + "libncpid.so"); + return handle ? dlsym(handle, name) : NULL; +} + +static void *mars_nwnss_nssadmin_symbol(const char *name) +{ + void *handle = mars_nwnss_open_optional_library(&mars_nwnss_nssadmin_handle, + "libnssadmin.so"); + return handle ? dlsym(handle, name) : NULL; +} + +int OpenNCPServLib(void) +{ + int (*fn)(void) = (int (*)(void))mars_nwnss_ncpid_symbol("OpenNCPServLib"); + return fn ? fn() : -1; +} + +void CloseNCPServLib(void) +{ + void (*fn)(void) = (void (*)(void))mars_nwnss_ncpid_symbol("CloseNCPServLib"); + if (fn) { + fn(); + } +} + +int NCPMapGUIDToDN(const char *guid, const size_t dnSize, unsigned short *dn) +{ + int (*fn)(const char *, const size_t, unsigned short *) = + (int (*)(const char *, const size_t, unsigned short *)) + mars_nwnss_ncpid_symbol("NCPMapGUIDToDN"); + return fn ? fn(guid, dnSize, dn) : -1; +} + +int OpenNSSAdminLib(void) +{ + int (*fn)(void) = (int (*)(void))mars_nwnss_nssadmin_symbol("OpenNSSAdminLib"); + return fn ? fn() : -1; +} + +void CloseNSSAdminLib(void) +{ + void (*fn)(void) = (void (*)(void))mars_nwnss_nssadmin_symbol("CloseNSSAdminLib"); + if (fn) { + fn(); + } +} + +int NCPLoginAsNSSAdmin(int context) +{ + int (*fn)(int) = (int (*)(int))mars_nwnss_nssadmin_symbol("NCPLoginAsNSSAdmin"); + return fn ? fn(context) : -1; +} + +int NCPCloseAdminIdentity(int context) +{ + int (*fn)(int) = (int (*)(int))mars_nwnss_nssadmin_symbol("NCPCloseAdminIdentity"); + return fn ? fn(context) : -1; +} + +STATUS MNSS_FindUserIDByDN(unsigned char *context, unsigned char *dn, + UserID_t *userID) +{ + STATUS status; + NINT offset = 0; + unicode_t uniName[MAX_DN_CHARS]; + utf8_t tempName[MAX_DN_CHARS]; + + if ((dn == NULL) || (userID == NULL)) { + return -1; + } + + if (dn[0] != '.') { + tempName[0] = '.'; + offset = 1; + } + if (context != NULL) { + strcpy(&tempName[offset], dn); + strcat(tempName, "."); + strcat(tempName, context); + } else { + strcpy(&tempName[offset], dn); + } + + utf2uni(tempName, uniName, sizeof(uniName)); + status = ndp_NCPMapDNToGUID(1, uniName, userID); + if ((status == ERR_ILLEGAL_DS_NAME) && + (tempName[strlen(tempName) - 1] != '.')) { + strcat(tempName, "."); + utf2uni(tempName, uniName, sizeof(uniName)); + status = ndp_NCPMapDNToGUID(1, uniName, userID); + } + return status; +} diff --git a/src/nwnss/sharedsrc/ndp_comn.c.h b/src/nwnss/sharedsrc/ndp_comn.c.h new file mode 100644 index 0000000..27036a0 --- /dev/null +++ b/src/nwnss/sharedsrc/ndp_comn.c.h @@ -0,0 +1,1603 @@ +/**************************************************************************** + | + | (C) Copyright 2004 Novell, Inc. + | All Rights Reserved. + | + | This program is free software; you can redistribute it and/or + | modify it under the terms of version 2 of the GNU General Public + | License as published by the Free Software Foundation. + | + | This program is distributed in the hope that it will be useful, + | but WITHOUT ANY WARRANTY; without even the implied warranty of + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + | GNU General Public License for more details. + | + | You should have received a copy of the GNU General Public License + | along with this program; if not, contact Novell, Inc. + | + | To contact Novell about this file by physical or electronic mail, + | you may find current contact information at www.novell.com + | + |*************************************************************************** + | + | Novell's User/Kernel Data Portal (NDP) Common program file. + | + |--------------------------------------------------------------------------- + | + | $Author: blarsen $ + | $Date: 2006-02-09 05:04:41 +0530 (Thu, 09 Feb 2006) $ + | + | $RCSfile$ + | $Revision: 1325 $ + | + |--------------------------------------------------------------------------- + | This file is used to: + | ... + +-------------------------------------------------------------------------*/ + +#ifdef __KERNEL__ +# include +# include +# include +# include +# include +# include +#else +/* NOTE: ndp_comn.h needs included before anything else in application land */ +# include +# include +# include +# include +# include +# include +# include +#include +#endif + +#include +#include +#include +#include + +extern ndpContext_t *ndpContext; + +extern int ndpSyslogFacility; + +#ifndef __KERNEL__ +extern long ndpMsgQueueID; +#endif + +QUAD NdpWriteCount = 0; +QUAD NdpPrintfCount = 0; +#ifdef __KERNEL__ +EXPORT_SYMBOL(NdpWriteCount); +EXPORT_SYMBOL(NdpPrintfCount); +#endif + +/****************************************************************************** +* Function Pre-Declarations (not in ndp_comn.h) +******************************************************************************/ + +/****************************************************************************** +* Declare and initialize the NDP wait queue +******************************************************************************/ + +/****************************************************************************** +* NDP GUID Values (Also see ndp_guids.c) +/*****************************************************************************/ + +GUID_t ndpAppGuidPrime; /* Filled in at runtime as needed */ +GUID_t ndpModGuidPrime; /* Filled in at runtime as needed */ + +/****************************************************************************** +* An ERROR message routine for NDP +******************************************************************************/ +#ifndef __KERNEL__ +void ndpErrPrintf( + char *fmt, + ...) +{ + va_list vargp; + + if (fmt) { + va_start(vargp, fmt); + vsyslog(ndpSyslogFacility | LOG_ERR, fmt, vargp); + //JMG//ndpPrintf("%s:ERR: ", ndp_appname); + //JMG//vfprintf(stderr, fmt, vargp); + //JMG//ndpPrintf("\n"); + va_end(vargp); + } + return; +} /* ndpErrPrintf() */ +#endif + +/****************************************************************************** +* A WARNING message routine for NDP +******************************************************************************/ +#ifndef __KERNEL__ +void ndpWrnPrintf( + char *fmt, + ...) +{ + va_list vargp; + + if (fmt) { + va_start(vargp, fmt); + vsyslog(ndpSyslogFacility | LOG_WARNING, fmt, vargp); + //JMG//ndpPrintf("%s:WRN: ", ndp_appname); + //JMG//vfprintf(stderr, fmt, vargp); + //JMG//ndpPrintf("\n"); + va_end(vargp); + } + return; +} /* ndpWrnPrintf() */ +#endif + +/****************************************************************************** +* A debug message routine for NDP +* (NOT MEANT TO BE CALLED DIRECTLY --- See ndpDbgPrintf Macro in ndp_comn.h) +******************************************************************************/ +#ifndef __KERNEL__ +void __ndpDbgPrintf( + char *fmt, + ...) +{ + va_list vargp; + + if (fmt) { + va_start(vargp, fmt); + vsyslog(ndpSyslogFacility | LOG_DEBUG, fmt, vargp); + //JMG//printf("%s:DBG: ", ndp_appname); + //JMG//vprintf(fmt, vargp); + va_end(vargp); + } + return; +} /* __ndpDbgPrintf() */ +#endif + +/****************************************************************************** +* Hex Data Dump routine +******************************************************************************/ +void ndp_dumpDataInHex( + int dbgLevel, + char *msg, + LONG length, + unsigned char *data) +{ + char hexBuf[80]; + NINT bytesThisLine; + unsigned char *bPtr; + NINT idx; + char ch; + + if (ndp_debug >= dbgLevel) { + ndpDbgPrintf(dbgLevel, "%s:%d:%X:\n", msg, length, data); + + bPtr = data; + + /* While there are more lines to print... */ + while (length > 0) + { + if (length > 16) { + bytesThisLine = 16; + } else { + bytesThisLine = length; + } + + /* Print address */ + sprintf(hexBuf, "%08x ", bPtr); + + /* Print hex portion of the line */ + for (idx=0; idx < 16; idx++) + { + if (idx < bytesThisLine) { + sprintf(hexBuf, "%s%02x ", hexBuf, bPtr[idx]); + } else { + sprintf(hexBuf, "%s ", hexBuf); + } + } + + sprintf(hexBuf, "%s ", hexBuf); + + /* Print Alpha portion of the line */ + for (idx=0; idx < bytesThisLine; idx++) + { + ch = bPtr[idx]; + if ((ch >= ' ') && (ch <= '~')) { + sprintf(hexBuf, "%s%c", hexBuf, ch); + } else { + sprintf(hexBuf, "%s.", hexBuf); + } + } + + /* Go on to the next line */ + ndpDbgPrintf(dbgLevel, "%s\n", hexBuf); + bPtr += bytesThisLine; + length -= bytesThisLine; + } + } + return; +} /* ndp_dumpDataInHex() */ + +/***************************************************************************** +* Convert a "hex GUID" to a "binary GUID" +*****************************************************************************/ +void ndp_hex2guid( + unsigned char hexguid[(2*sizeof(GUID_t))+1], + GUID_t *_guid) +{ + int i; + int n = 0; + unsigned char c; + if ((_guid) && (hexguid)) { + unsigned char *guid = (unsigned char *)_guid; + for (i = 0; i < sizeof(GUID_t); i++) { + c = hexguid[n++]; + guid[i] = ((c <= '9')?(c-'0'):(c-'0'-7)) << 4; + c = hexguid[n++]; + guid[i] |= (c <= '9')?(c-'0'):(c-'0'-7); + } + } + return; +} /* ndp_hex2guid() */ + +/***************************************************************************** +* Convert a "binary GUID" to a "hex GUID" +*****************************************************************************/ +void ndp_guid2hex( + GUID_t *_guid, + unsigned char hexguid[(2*sizeof(GUID_t))+1]) +{ + int i; + int n = 0; + unsigned char c; + if ((_guid) && (hexguid)) { + unsigned char *guid = (unsigned char *)_guid; + for (i = 0; i < sizeof(GUID_t); i++) { + c = ((guid[i] >> 4) & 0x0F); + hexguid[n++] = (c <= 9)?(c+'0'):(c+'0'+7); + c = ((guid[i]) & 0x0F); + hexguid[n++] = (c <= 9)?(c+'0'):(c+'0'+7); + } + hexguid[n] = '\0'; + } + return; +} /* ndp_guid2hex() */ + +/***************************************************************************** +* Convert a "hex buffer" to a "binary buffer" +* NOTE - datalen is the number of output bytes expected in the _bindata. +*****************************************************************************/ +void ndp_hex2buf( + unsigned char *hexdata, + int datalen, + unsigned char *_bindata) /* Big enough to receive "datalen" bytes of data */ +{ + int i; + int n = 0; + unsigned char c; + if ((hexdata) && (_bindata)) { + unsigned char *bindata = (unsigned char *)_bindata; + for (i = 0; i < datalen; i++) { + c = hexdata[n++]; + bindata[i] = ((c <= '9')?(c-'0'):(c-'0'-7)) << 4; + c = hexdata[n++]; + bindata[i] |= (c <= '9')?(c-'0'):(c-'0'-7); + } + } + return; +} /* ndp_hex2buf() */ + +/***************************************************************************** +* Convert a "binary buffer" to a "hex buffer" +* NOTE - datalen is number of input bytes. Output must be big enough to +* receive two bytes for every input byte, plus a trailing NULL byte. +*****************************************************************************/ +void ndp_buf2hex( + unsigned char *_bindata, + int datalen, + unsigned char *hexdata) /* Big enough to receive "(datalen*2)+1" bytes of hex data */ +{ + int i; + int n = 0; + unsigned char c; + if ((_bindata) && (hexdata)) { + unsigned char *bindata = (unsigned char *)_bindata; + for (i = 0; i < datalen; i++) { + c = ((bindata[i] >> 4) & 0x0F); + hexdata[n++] = (c <= 9)?(c+'0'):(c+'0'+7); + c = ((bindata[i]) & 0x0F); + hexdata[n++] = (c <= 9)?(c+'0'):(c+'0'+7); + } + hexdata[n] = '\0'; + } + return; +} /* ndp_buf2hex() */ + +/***************************************************************************** +* Extract a string value (or NULL) from an XML tagged data buffer +* Return value == 0 if tag found and data is OK, else ERROR Status +* Note: We assume zOK == 0 +*****************************************************************************/ +int ndp_getXmlTagValueString( + utf8_t *tag, + utf8_t *data, + int length, + unsigned char **retString) +{ + int retval; + XML_ElementInfo_s xmlInfo; + + ndpDbgPrintf(5, "ndp_getXmlTagValueString(Enter)\n"); + retval = XML_GetTagElement(tag, &data[0], &data[length-1], &xmlInfo); + if (retval == zOK) { + unsigned char tmpC; + int length; + tmpC = *(xmlInfo.dataEnd + 1); + *(xmlInfo.dataEnd + 1) = '\0'; + /* When copying, count the '\0' character */ + length = (xmlInfo.dataEnd - xmlInfo.dataStart) + 2; + *retString = ndp_memdup((unsigned char *)xmlInfo.dataStart, length); + *(xmlInfo.dataEnd + 1) = tmpC; + } else { + *retString = NULL; + } + ndpDbgPrintf(5, "ndp_getXmlTagValueString(Leave:%d:%s)\n",retval,*retString?*retString:(unsigned char *)"NULL"); + return(retval); +} /* ndp_getXmlTagValueString() */ + +/***************************************************************************** +* Extract a LONG value (or -1) from an XML tagged data buffer +* Return value == 0 if tag found and data is OK, else ERROR Status +*****************************************************************************/ +int ndp_getXmlTagValueLong( + utf8_t *tag, + utf8_t *data, + int length, + LONG *retLong) +{ + int retval; + XML_ElementInfo_s xmlInfo; + + ndpDbgPrintf(5, "ndp_getXmlTagValueLong(Enter)\n"); + retval = XML_GetTagElement(tag, &data[0], &data[length-1], &xmlInfo); + if (retval == zOK) { + unsigned char tmpC; + tmpC = *(xmlInfo.dataEnd + 1); + *(xmlInfo.dataEnd + 1) = '\0'; + ndpDbgPrintf(13, "ndp_getXmlTagValueLong(tag:%s)\n", xmlInfo.dataStart); + *retLong = ndp_atol(xmlInfo.dataStart); + ndpDbgPrintf(13, "ndp_getXmlTagValueLong(retLong:%d)\n", *retLong); + *(xmlInfo.dataEnd + 1) = tmpC; + } else { + *retLong = -1; + } + ndpDbgPrintf(5, "ndp_getXmlTagValueLong(Leave:%d:%d)\n",retval,*retLong); + return(retval); +} /* ndp_getXmlTagValueLong() */ + +/****************************************************************************** +* Emulate strdup only for generic data +* Return a pointer to a new data chunck which is a duplicate of the original. +******************************************************************************/ +unsigned char *ndp_memdup( + unsigned char *data, + int length) +{ + unsigned char *newmem; + + newmem = (unsigned char *)ndpMalloc(length, GFP_KERNEL); + if (newmem){ + memcpy(newmem, data, length); + } + + return(newmem); +} /* ndp_memdup() */ + +/****************************************************************************** +* Emulate atoi +* Convert an ascii string to an integer value (base 10) +******************************************************************************/ +int ndp_atoi( + char *a) +{ + register int value; + char sign; + + while( ndp_CharIsWhiteSpace( *a ) ) ++a; + sign = *a; + if( sign == '+' || sign == '-' ) ++a; + value = 0; + while( (*a >= '0') && (*a <= '9') ) { + value = value * 10 + *a - '0'; + ++a; + } + if( sign == '-' ) value = - value; + return( value ); +} /* ndp_atoi() */ + +/****************************************************************************** +* Emulate atol +* Convert an ascii string to a LONG (long integer) value (base 10) +******************************************************************************/ +LONG ndp_atol( + char *a) +{ + register long int value; + char sign; + + /* Skip white space */ + while( ndp_CharIsWhiteSpace( *a ) ) ++a; + sign = *a; + if( sign == '+' || sign == '-' ) ++a; + value = 0; + while( (*a >= '0') && (*a <= '9') ) { + value = value * 10 + *a - '0'; + ++a; + } + if( sign == '-' ) value = - value; + return( value ); +} /* ndp_atol() */ + +/****************************************************************************** +* Compares the character to any White Space character +* Returns 1 if it is whitespace, else it returns 0 +******************************************************************************/ +int ndp_CharIsWhiteSpace( + unsigned char c) +{ + if ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')) { + return(1); + } else { + return(0); + } +} /* ndp_CharIsWhiteSpace() */ + +/****************************************************************************** +* Skip past any White Space characters +* Returns the new pointer, and a modified length +******************************************************************************/ +unsigned char *ndp_SkipWhitespace( + unsigned char *_data, + LONG *_length) +{ + unsigned char *data; + LONG length; + + data = _data; + length = *_length; + if ((data) && (length > 0)) { + while ((length > 0) && (ndp_CharIsWhiteSpace(*data))) { + data++; + length--; + } + } + *_length = length; + return(data); +} /* ndp_SkipWhitespace() */ + +/****************************************************************************** +* Emulate strncasecmp +* Returns +* an integer less than, equal to, or greater than zero +* if s1 is found, respectively, to be less than, +* to match, or be greater than s2. +******************************************************************************/ +int ndp_strncasecmp( + unsigned char *s1, + unsigned char *s2, + int n) +{ + int retval = 0; + unsigned char c1, c2; + + if ((s1) && (s2)) { + for ( ; n > 0; n--) { + /* Only compare lowercase characters */ + c1 = (*s1++) | 0x20; /* Get and convert to LC */ + c2 = (*s2++) | 0x20; /* Get and convert to LC */ + if (c1 != c2) { + if (c1 < c2) { + retval = 1; + } else /* (c1 > c2) */ { + retval = -1; + } + break; + } + } + } else { + if (s1) { + retval = 1; + } else if (s2) { + retval = -1; + } + } + return(retval); +} /* ndp_strncasecmp() */ + +/****************************************************************************** +* Generate a new guid (128 bit) value +* for use as a guidPrime value or as a session ID +******************************************************************************/ +static void ndp_generateGuid( + GUID_t *guidPrime) +{ + ndpDbgPrintf(15, "ndp_generateGuid(Enter)\n"); +#ifdef __KERNEL__ + if (guidPrime) { + generate_random_uuid((unsigned char *)guidPrime); + } +#else + extern void uuid_generate(GUID_t *guid); /* See /lib/libuuid* */ + if (guidPrime) { + uuid_generate(guidPrime); + } +#endif + ndpDbgPrintf(15, "ndp_generateGuid(Leave)\n"); + return; +} /* ndp_generateGuid() */ + +/****************************************************************************** +* Allocate and fill in a new NDP Message Queue Entry +******************************************************************************/ +ndp_msgqueue_t *new_ndp_msgqueue_entry( + GUID_t *srcGuid, + GUID_t *dstGuid, + LONG length, /* 32 bit unsigned value */ + unsigned char *data) +{ + size_t size; + ndp_msgqueue_t *new_entry = NULL; + + ndpDbgPrintf(20, "new_ndp_msgqueue_entry(Enter)\n"); + if ((srcGuid) && (((length > 0) && (data)) || (length == 0))) { + size = sizeof(ndp_msgqueue_t) + sizeof(ndp_msg_t) + length; + new_entry = (ndp_msgqueue_t *)ndpMalloc(size, GFP_KERNEL); + if (new_entry) { + memset(new_entry, 0, size); + new_entry->msg = (ndp_msg_t *)&new_entry[1]; + memcpy(&new_entry->msg->srcGuid, srcGuid, sizeof(GUID_t)); + memcpy(&new_entry->msg->dstGuid, dstGuid, sizeof(GUID_t)); + new_entry->msg->length = length; + if (length > 0) { + memcpy(&new_entry->msg->data[0], data, length); + } + } + } + ndpDbgPrintf(20, "new_ndp_msgqueue_entry(Leave:%X)\n", new_entry); + + return(new_entry); +} /* new_ndp_msgqueue_entry() */ + +/****************************************************************************** +* Free a previously allocated NDP Message Queue Entry +******************************************************************************/ +void free_ndp_msgqueue_entry( + ndp_msgqueue_t *entry) +{ + ndpDbgPrintf(20, "free_ndp_msgqueue_entry(Enter:%X)\n", entry); + if (entry) { + ndpFree(entry); + } + ndpDbgPrintf(20, "free_ndp_msgqueue_entry(Leave)\n"); + return; +} /* free_ndp_msgqueue_entry() */ + +/****************************************************************************** +* Free a previously allocated NDP Message Queue +******************************************************************************/ +void free_ndp_msgqueue( + ndp_guidmsgcontext_t *context) +{ + ndp_msgqueue_t *entry; + + ndpDbgPrintf(20, "free_ndp_msgqueue(Enter:%X)\n", context); + entry = extract_ndp_msgqueue_entry(context); + while (entry) { + free_ndp_msgqueue_entry(entry); + entry = extract_ndp_msgqueue_entry(context); + } + ndpDbgPrintf(20, "free_ndp_msgqueue(Leave)\n"); + return; +} /* free_ndp_msgqueue_entry() */ + +/****************************************************************************** +* Specify a wait queue to use instead of +* the msgwaitqueue provided with each msg queue +******************************************************************************/ +#ifdef __KERNEL__ +wait_queue_head_t *substituteMsgWaitQueue( + GUID_t *guidPrime, + wait_queue_head_t *newmsgwaitqueue) +#else +sem_t *substituteMsgWaitQueue( + GUID_t *guidPrime, + sem_t *newmsgwaitqueue) +#endif +{ +#ifdef __KERNEL__ + wait_queue_head_t *oldmsgwaitqueue = NULL; +#else + sem_t *oldmsgwaitqueue = NULL; +#endif + ndp_guidmsgcontext_t *context = NULL; + + context = find_ndp_guidprimemsgcontext( + ndpContext->guidListContext, guidPrime); + if (context) { + oldmsgwaitqueue = context->msgwaitqueue; + context->msgwaitqueue = newmsgwaitqueue; + } + return(oldmsgwaitqueue); +} /* substituteMsgWaitQueue() */ + +/****************************************************************************** +* Allocate and fill in a new NDP GUID Message Context +******************************************************************************/ +ndp_guidmsgcontext_t *new_ndp_guidmsgcontext( + void) +{ + size_t size; + ndp_guidmsgcontext_t *new_context = NULL; + + ndpDbgPrintf(20, "new_ndp_guidmsgcontext(Enter)\n"); + size = sizeof(ndp_guidmsgcontext_t); + new_context = (ndp_guidmsgcontext_t *)ndpMalloc(size, GFP_KERNEL); + if (new_context) { + memset(new_context, 0, size); + SQ_INIT(&new_context->sqHead); + INITLOCK_MSGQUEUE(new_context); + /* + * Initialize the msgwaitqueue + * We use a pointer to it so it can be overridden & customized. + */ + new_context->msgwaitqueue = &new_context->_msgwaitqueue; +#ifdef __KERNEL__ + init_waitqueue_head(new_context->msgwaitqueue); +#else + sem_init(new_context->msgwaitqueue, 0, 1); +#endif /* __KERNEL__ */ + } + ndpDbgPrintf(20, "new_ndp_guidmsgcontext(Leave:%X)\n", new_context); + return(new_context); +} /* new_ndp_guidmsgcontext() */ + +/****************************************************************************** +* Free a previously allocated NDP GUID Message Context +******************************************************************************/ +void free_ndp_guidmsgcontext( + ndp_guidmsgcontext_t *context) +{ + ndpDbgPrintf(20, "free_ndp_guidmsgcontext(Enter:%X)\n", context); + if (context) { + free_ndp_msgqueue(context); + //NOT NEEDED//context->msgCount = 0; + /* + * Destroy the (ORIGINAL not substituted) msgwaitqueue + */ +#ifdef __KERNEL__ + /* destroy_waitqueue_head() appears not to exist & not needed */ + //destroy_waitqueue_head(&context->_msgwaitqueue); +#else + sem_destroy(&context->_msgwaitqueue); +#endif /* __KERNEL__ */ + ndpFree(context); + } + ndpDbgPrintf(20, "free_ndp_guidmsgcontext(Leave)\n"); + return; +} /* free_ndp_guidmsgcontext() */ + +/****************************************************************************** +* Allocate and fill in a new NDP GUID List Entry +******************************************************************************/ +ndp_guidlist_t *new_ndp_guidlist_entry( + GUID_t *guid, + GUID_t *guidPrime, + char *name) +{ + size_t size; + ndp_guidlist_t *new_entry = NULL; + static char *unknown = "unknown"; + int namelen; + + ndpDbgPrintf(20, "new_ndp_guidlist_entry(Enter)\n"); + if ((guid) && (guidPrime)) { + if ((name == NULL) || (*name == '\0')) { + name = unknown; + } + namelen = strlen(name); + namelen++; /* Account for NULL terminator */ + size = sizeof(ndp_guidlist_t) + namelen; + new_entry = (ndp_guidlist_t *)ndpMalloc(size, GFP_KERNEL); + if (new_entry) { + ndpDbgPrintf(20, "new_ndp_guidlist_entry: name=%s\n", name); + memset(new_entry, 0, size); + memcpy(&new_entry->guid, guid, sizeof(GUID_t)); + ndp_generateGuid(guidPrime); /* Generate a new GUID (Prime) */ + memcpy(&new_entry->guidPrime, guidPrime, sizeof(GUID_t)); + new_entry->name = (unsigned char *)&new_entry[1]; + memcpy(new_entry->name, name, namelen); + new_entry->guidmsgcontext = new_ndp_guidmsgcontext(); + if (new_entry->guidmsgcontext == NULL) { + free_ndp_guidlist_entry(new_entry); + new_entry = NULL; + } + } + } + ndpDbgPrintf(20, "new_ndp_guidlist_entry(Leave:%X)\n", new_entry); + return(new_entry); +} /* new_ndp_guidlist_entry() */ + +/****************************************************************************** +* Free a previously allocated NDP GUID List Entry +******************************************************************************/ +void free_ndp_guidlist_entry( + ndp_guidlist_t *entry) +{ + ndpDbgPrintf(20, "free_ndp_guidlist_entry(Enter:%X)\n", entry); + if (entry) { + if (entry->guidmsgcontext) { + free_ndp_guidmsgcontext(entry->guidmsgcontext); + //NOT NEEDED//entry->guidmsgcontext = NULL; + } + ndpFree(entry); + } + ndpDbgPrintf(20, "free_ndp_guidlist_entry(Leave)\n"); + return; +} /* free_ndp_guidlist_entry() */ + +/****************************************************************************** +* Free a previously allocated NDP GUID List +******************************************************************************/ +void free_ndp_guidlist( + ndp_guidlistcontext_t *context) +{ + ndp_guidlist_t *entry; + + ndpDbgPrintf(20, "free_ndp_guidlist(Enter:%X)\n", context); + WRLOCK_GUIDLIST(context); + DQ_DEQ(&context->dqHead, entry, ndp_guidlist_t, dqLink); + while (entry) { + free_ndp_guidlist_entry(entry); + DQ_DEQ(&context->dqHead, entry, ndp_guidlist_t, dqLink); + } + WRUNLOCK_GUIDLIST(context); /* Write Unlock RBD */ + ndpDbgPrintf(20, "free_ndp_guidlist(Leave)\n"); + return; +} /* free_ndp_guidlist() */ + +/****************************************************************************** +* Allocate and fill in a new NDP GUID List Context +******************************************************************************/ +ndp_guidlistcontext_t *new_ndp_guidlistcontext( + void) +{ + size_t size; + ndp_guidlistcontext_t *new_context = NULL; + + ndpDbgPrintf(20, "new_ndp_guidlistcontext(Enter)\n"); + size = sizeof(ndp_guidlistcontext_t); + new_context = (ndp_guidlistcontext_t *)ndpMalloc(size, GFP_KERNEL); + if (new_context) { + memset(new_context, 0, size); + DQ_INIT(&new_context->dqHead); + INITLOCK_GUIDLIST(new_context); + } + ndpDbgPrintf(20, "new_ndp_guidlistcontext(Leave:%X)\n", new_context); + return(new_context); +} /* new_ndp_guidlistcontext() */ + +/****************************************************************************** +* Free a previously allocated NDP GUID List Context +******************************************************************************/ +void free_ndp_guidlistcontext( + ndp_guidlistcontext_t *context) +{ + ndpDbgPrintf(20, "free_ndp_guidlistcontext(Enter:%X)\n", context); + if (context) { + free_ndp_guidlist(context); + //NOT NEEDED//context->guidCount = 0; + ndpFree(context); + } + ndpDbgPrintf(20, "free_ndp_guidlistcontext(Leave)\n"); + return; +} /* free_ndp_guidlistcontext() */ + +/****************************************************************************** +* Extract NDP Message Queue Entry from Queue +* (Message Queue is maintained as a FIFO) +* (Extract from head of queue) +******************************************************************************/ +ndp_msgqueue_t *extract_ndp_msgqueue_entry( + ndp_guidmsgcontext_t *context) +{ + ndp_msgqueue_t *entry = NULL; + + ndpDbgPrintf(17, "extract_ndp_msgqueue_entry(Enter:%X)\n", context); + WRLOCK_MSGQUEUE(context); + SQ_DEQ(&context->sqHead, entry, ndp_msgqueue_t, sqLink); + if (context->msgCount > 0) { + context->msgCount--; + } + WRUNLOCK_MSGQUEUE(context); + ndpDbgPrintf(17, "extract_ndp_msgqueue_entry(Leave:%X)\n", entry); + return(entry); +} /* extract_ndp_msgqueue_entry() */ + +/****************************************************************************** +* Insert NDP Message Queue Entry into Queue +* (Message Queue is maintained as a FIFO) +* (Insert at tail of queue) +* +* Signals ndp_read() that data is available when done +******************************************************************************/ +int insert_ndp_msgqueue_entry( + ndp_guidmsgcontext_t *context, + ndp_msgqueue_t *entry) +{ + int retval = 0; + + ndpDbgPrintf(17, "insert_ndp_msgqueue_entry(Enter:%X:%X)\n", context, entry); + if (entry) { +#ifndef __KERNEL__ + /* + * If the connection type is NDPCONN_msgop + * then send it now (put it on the msgop queue), + * else insert it into the NDP queue. + */ + if (context->connection == NDPCONN_msgop) { + size_t msgsndSize; + ndpmsg_t ndpmsg; + /* + * NOTE: the packet format on the ndp_msgqueue_t is of type + * ndp_msg_t which is different than the type used by msgsnd/msgrcv. + * We need to convert the packet to an ndpmsg_t type by copying + * the individual fields. + */ + ndpmsg.dstID = (LONG)context->pid; + memcpy(&ndpmsg.u.msg.srcGuidPrime, &entry->msg->srcGuid, sizeof(GUID_t)); + memcpy(&ndpmsg.u.msg.dstGuid, &entry->msg->dstGuid, sizeof(GUID_t)); + ndpmsg.u.msg.dataLength = entry->msg->length; + ndpmsg.u.msg.totalLength = entry->msg->length; + ndpmsg.u.msg.msgsRemaining = 0; + ndpmsg.u.msg.multipleID = 0; + ndpmsg.u.msg.flags = 0; + memcpy(&ndpmsg.u.msg.data[0], &entry->msg->data[0], entry->msg->length); + msgsndSize = sizeof(LONG) + sizeof(ndpmsg_data_t) + entry->msg->length; + retval = msgsnd( + context->ndpMsgQueueID, /* int msqid */ + &ndpmsg, /* ndpmsg_t *msgp */ + msgsndSize, /* size_t msgsz */ + 0); /* /* int msgflg */ + free_ndp_msgqueue_entry(entry); + } else +#endif /* ! __KERNEL__ */ + { + WRLOCK_MSGQUEUE(context); + context->msgCount++; + SQ_ENQ(&context->sqHead, entry, sqLink); + WRUNLOCK_MSGQUEUE(context); + } + } + /* + * Wake up anything waiting on the associated msgwaitqueue + */ +#ifdef __KERNEL__ + wake_up_interruptible(context->msgwaitqueue); +#else + sem_post(context->msgwaitqueue); +#endif /* __KERNEL__ */ + ndpDbgPrintf(17, "insert_ndp_msgqueue_entry(Leave:%d)\n", retval); + return(retval); +} /* insert_ndp_msgqueue_entry() */ + +/****************************************************************************** +* Exchange NDP GUID Prime for NDP Guid from NDP GUID List +******************************************************************************/ +int ndp_exchangeGuidPrimeForGuid( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guidPrime, + GUID_t *guid) +{ + int retval = 1; + ndp_guidlist_t *entry = NULL; + + ndpDbgPrintf(16, "ndp_exchangeGuidPrimeForGuid(Enter)\n"); + RDLOCK_GUIDLIST(guidlistcontext); + DQ_FOREACH(&guidlistcontext->dqHead, entry, ndp_guidlist_t, dqLink) { + if ((entry) && (memcmp(&entry->guidPrime, guidPrime, sizeof(GUID_t)) == 0)) { + memcpy(guid, &entry->guid, sizeof(GUID_t)); + retval = 0; + break; + } + } + RDUNLOCK_GUIDLIST(guidlistcontext); + ndpDbgPrintf(16, "ndp_exchangeGuidPrimeForGuid(Leave:%d)\n", retval); + return(retval); +} /* ndp_exchangeGuidPrimeForGuid() */ + +/****************************************************************************** +* Exchange NDP GUID for NDP Guid Prime from NDP GUID List +******************************************************************************/ +int ndp_exchangeGuidForGuidPrime( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guid, + GUID_t *guidPrime) +{ + int retval = 1; + ndp_guidlist_t *entry = NULL; + + ndpDbgPrintf(16, "ndp_exchangeGuidForGuidPrime(Enter)\n"); + RDLOCK_GUIDLIST(guidlistcontext); + DQ_FOREACH(&guidlistcontext->dqHead, entry, ndp_guidlist_t, dqLink) { + if ((entry) && (memcmp(&entry->guid, guid, sizeof(GUID_t)) == 0)) { + memcpy(guidPrime, &entry->guidPrime, sizeof(GUID_t)); + retval = 0; + break; + } + } + RDUNLOCK_GUIDLIST(guidlistcontext); + ndpDbgPrintf(16, "ndp_exchangeGuidForGuidPrime(Leave:%d)\n", retval); + return(retval); +} /* ndp_exchangeGuidPrimeForGuid() */ + +/****************************************************************************** +* Find NDP GUID List Entry +******************************************************************************/ +ndp_guidmsgcontext_t *find_ndp_guidmsgcontext( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guid) +{ + ndp_guidmsgcontext_t *guidmsgcontext = NULL; + ndp_guidlist_t *entry = NULL; + + ndpDbgPrintf(18, "find_ndp_guidmsgcontext(Enter)\n"); + RDLOCK_GUIDLIST(guidlistcontext); + DQ_FOREACH(&guidlistcontext->dqHead, entry, ndp_guidlist_t, dqLink) { + if (entry) { + ndpDbgPrintf(19, "find_ndp_guidmsgcontext: ? name=%s\n", entry->name); + if (memcmp(&entry->guid, guid, sizeof(GUID_t)) == 0) { + guidmsgcontext = entry->guidmsgcontext; + ndpDbgPrintf(18, "find_ndp_guidmsgcontext: Y name=%s\n", entry->name); + break; + } + } + } + RDUNLOCK_GUIDLIST(guidlistcontext); + ndpDbgPrintf(18, "find_ndp_guidmsgcontext(Leave:%X)\n", guidmsgcontext); + return(guidmsgcontext); +} /* find_ndp_guidmsgcontext() */ + +/****************************************************************************** +* Find NDP GUID Prime List Entry +******************************************************************************/ +ndp_guidmsgcontext_t *find_ndp_guidprimemsgcontext( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guidPrime) +{ + ndp_guidmsgcontext_t *guidmsgcontext = NULL; + ndp_guidlist_t *entry = NULL; + + ndpDbgPrintf(18, "find_ndp_guidprimemsgcontext(Enter)\n"); + RDLOCK_GUIDLIST(guidlistcontext); + DQ_FOREACH(&guidlistcontext->dqHead, entry, ndp_guidlist_t, dqLink) { + if (entry) { + ndpDbgPrintf(21, "find_ndp_guidprimemsgcontext: ? name=%s\n", entry->name); + if (memcmp(&entry->guidPrime, guidPrime, sizeof(GUID_t)) == 0) { + guidmsgcontext = entry->guidmsgcontext; + ndpDbgPrintf(18, "find_ndp_guidprimemsgcontext: Y name=%s\n", entry->name); + break; + } + } + } + RDUNLOCK_GUIDLIST(guidlistcontext); + ndpDbgPrintf(18, "find_ndp_guidprimemsgcontext(Leave:%X)\n", guidmsgcontext); + return(guidmsgcontext); +} /* find_ndp_guidmsgcontext() */ + +/****************************************************************************** +* Extract NDP GUID List Entry from List +* (GUID list is maintained in sorting order) +******************************************************************************/ +ndp_guidlist_t *extract_ndp_guidlist_entryByGuidPrime( + ndp_guidlistcontext_t *guidlistcontext, + GUID_t *guidPrime) +{ + ndp_guidlist_t *extractedEntry = NULL; + ndp_guidlist_t *entry = NULL; + + ndpDbgPrintf(16, "extract_ndp_guidlist_entryByGuidPrime(Enter)\n"); + WRLOCK_GUIDLIST(guidlistcontext); + DQ_FOREACH(&guidlistcontext->dqHead, entry, ndp_guidlist_t, dqLink) { + if ((entry) && (memcmp(&entry->guidPrime, guidPrime, sizeof(GUID_t)) == 0)) { + DQ_RMV(entry, dqLink); + if (guidlistcontext->guidCount > 0) { + guidlistcontext->guidCount--; + } + extractedEntry = entry; + break; + } + } + WRUNLOCK_GUIDLIST(guidlistcontext); + ndpDbgPrintf(16, "extract_ndp_guidlist_entryByGuidPrime(Leave:%X)\n", entry); + return(extractedEntry); +} /* extract_ndp_guidlist_entryByGuidPrime() */ + +/****************************************************************************** +* Insert NDP GUID List Entry into List +* (GUID list is maintained in sorting order) +******************************************************************************/ +int insert_ndp_guidlist_entry( + ndp_guidlistcontext_t *guidlistcontext, + ndp_guidlist_t *entry) +{ + int retval = 0; + + ndpDbgPrintf(17, "insert_ndp_guidlist_entry(Enter)\n"); + if (entry) { + WRLOCK_GUIDLIST(guidlistcontext); + DQ_ENQ(&guidlistcontext->dqHead, entry, dqLink); + guidlistcontext->guidCount++; + WRUNLOCK_GUIDLIST(guidlistcontext); + } + ndpDbgPrintf(17, "insert_ndp_guidlist_entry(Leave:%d)\n", retval); + return(retval); +} /* insert_ndp_guidlist_entry() */ + +/****************************************************************************** +* Read data sent to a specified guid (reader verified with guidPrime) +* Don't return unless data has been received (and read) +* or until the specified timeout has occurred. +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +int ndp_readFromGuidUntilTimeout( + int dumpDataDebugLevel, + GUID_t *guidPrime, + GUID_t *srcGuid, /* A GUID value is returned */ + LONG *length, /* A 32 bit unsigned value is returned */ + unsigned char **data, /* An allocated data chunk is returned */ + /* (if length > 0) */ + int timeoutInSeconds) /* Maximum number of seconds to wait */ +{ + int retval = -EFAULT; +// int loopCount = 0; + + ndpDbgPrintf(15, "ndp_readFromGuidUntilTimeout(Enter)\n"); + if ((guidPrime) && (length) && (data)) { + ndp_guidmsgcontext_t *guidmsgcontext; + *length = 0; + *data = NULL; + /* + * 1st verify that the guidPrime is valid (have they registered) + * Do this by doing the lookup with the guidPrime value. + */ + guidmsgcontext = find_ndp_guidprimemsgcontext( + ndpContext->guidListContext, + guidPrime); + if (guidmsgcontext) { + /************************ + *** Use Wait Queue(s) *** + ************************/ + /* Loop until we have data or timeout (if timeout specified) */ + for ( ; ; ) { + ndp_msgqueue_t *msgqueueentry; +// loopCount++; + if (guidmsgcontext->msgCount > 0) { + msgqueueentry = extract_ndp_msgqueue_entry(guidmsgcontext); + } else { + msgqueueentry = NULL; + } + if (msgqueueentry) { + *length = msgqueueentry->msg->length; + memcpy(srcGuid, &msgqueueentry->msg->srcGuid, sizeof(GUID_t)); + retval = 0; + if (msgqueueentry->msg->length > 0) { + *data = (unsigned char *)ndpMalloc(*length, GFP_KERNEL); + if (*data) { + memcpy(*data, &msgqueueentry->msg->data[0], *length); + ndpDbgDumpDataInHex(dumpDataDebugLevel, + "ndp_readFromGuidUntilTimeout", *length, *data); + } else { + retval = -ENOMEM; + break; /* Quit looping, ERROR */ + } + } + free_ndp_msgqueue_entry(msgqueueentry); + break; /* Quit looping, We have something */ + } else { + retval = -EAGAIN; + if (timeoutInSeconds > 0) { +#define ndpTIMEOUTINCREMENT 5 + int timeoutIncrement; + /* + * Wait on msgwaitqueue + * (associated with each specific message queue) + */ +#if (0) +/* Use 1 large wait increment */ + timeoutIncrement = timeoutInSeconds; +#else +/* Use N small wait increments */ +// if (loopCount < ndpTIMEOUTINCREMENT) { +// if (timeoutInSeconds > loopCount) { +// timeoutIncrement = loopCount; +// } else { +// timeoutIncrement = timeoutInSeconds; +// } +// } else { + if (timeoutInSeconds > ndpTIMEOUTINCREMENT) { + timeoutIncrement = ndpTIMEOUTINCREMENT; + } else { + timeoutIncrement = timeoutInSeconds; + } +// } +#endif +#ifdef __KERNEL__ + /* + * Call schedule() to give the system time to look + * at things just in case we are in a very tight read + * loop. This will give the user some response to + * kill the app. + */ +//Commented out because we are no longer in a tight loop, and this seems to make +//some threads hang. For example, a thread that calls ndp_namGetUserFDNfromUID +//eventually hangs, after successfully returning from this code. However, if +//we don't do the schedule here, the thread does not hang... +// schedule(); +// current->state = TASK_INTERRUPTIBLE; + wait_event_interruptible_timeout( + *(guidmsgcontext->msgwaitqueue), + (guidmsgcontext->msgCount > 0), + (timeoutIncrement * HZ)); + timeoutInSeconds -= timeoutIncrement; +#else /* __KERNEL__ */ + { + struct timespec tsTimeoutInSeconds; + tsTimeoutInSeconds.tv_sec = + time(NULL) + timeoutIncrement; + tsTimeoutInSeconds.tv_nsec = 0L; + (void) sem_timedwait(guidmsgcontext->msgwaitqueue, + &tsTimeoutInSeconds); + timeoutInSeconds -= timeoutIncrement; + } +#endif /* ! __KERNEL__ */ + } else { + break; /* Quit looping, Timed Out */ + } + } + } /* for(...) */ + } + } + ndpDbgPrintf(15, "ndp_readFromGuidUntilTimeout(Leave:%d:%ld)\n", retval, *length); + return(retval); +} /* ndp_readFromGuidUntilTimeout() */ +EXPORT_SYMBOL(ndp_readFromGuidUntilTimeout); + +/****************************************************************************** +* Read data sent to a specified guid (reader verified with guidPrime) +* Return immedietly (with or without data) +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +int ndp_readFromGuid( + int dumpDataDebugLevel, + GUID_t *guidPrime, + GUID_t *srcGuid, /* A GUID value is returned */ + LONG *length, /* A 32 bit unsigned value is returned */ + unsigned char **data) /* An allocated data chunk is returned */ + /* (if length > 0) */ +{ +#if (0) + int retval = -EFAULT; + + ndpDbgPrintf(15, "ndp_readFromGuid(Enter)\n"); + if ((guidPrime) && (length) && (data)) { + *length = 0; + *data = NULL; + /* + * 1st verify that the guidPrime is valid (have they registered) + * Do this by doing the lookup with the guidPrime value. + */ + ndp_guidmsgcontext_t *guidmsgcontext; + guidmsgcontext = find_ndp_guidprimemsgcontext( + ndpContext->guidListContext, + guidPrime); + if (guidmsgcontext) { + ndp_msgqueue_t *msgqueueentry; + msgqueueentry = extract_ndp_msgqueue_entry(guidmsgcontext); + if (msgqueueentry) { + *length = msgqueueentry->msg->length; + memcpy(srcGuid, &msgqueueentry->msg->srcGuid, sizeof(GUID_t)); + retval = 0; + if (msgqueueentry->msg->length > 0) { + *data = (unsigned char *)ndpMalloc(*length, GFP_KERNEL); + if (*data) { + memcpy(*data, &msgqueueentry->msg->data[0], *length); + } else { + retval = -ENOMEM; + } + } + free_ndp_msgqueue_entry(msgqueueentry); + } else { + retval = -EAGAIN; + } + } + } + ndpDbgPrintf(15, "ndp_readFromGuid(Leave:%d:%ld)\n", retval, *length); + return(retval); +#else + return(ndp_readFromGuidUntilTimeout(dumpDataDebugLevel, + guidPrime, srcGuid, length, data, 0)); +#endif +} /* ndp_readFromGuid() */ +EXPORT_SYMBOL(ndp_readFromGuid); + +/****************************************************************************** +* Write data sent to a specified guid (writer verified with guidPrime) +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +int ndp_writeToGuid( + int dumpDataDebugLevel, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + LONG length, /* 32 bit unsigned value */ + unsigned char *data) +{ + int retval = -EFAULT; + ndp_msgqueue_t *msgqueueentry; + GUID_t srcGuid; + int sts; + + ndpDbgPrintf(10, "ndp_writeToGuid(Enter)\n"); + NdpWriteCount++; + if ((srcGuidPrime) && (dstGuid)) { + if (ndp_debug >= dumpDataDebugLevel) { + ndp_dumpDataInHex(dumpDataDebugLevel, + "ndp_writeToGuid", length, data); + } + /* + * 1st verify that the srcGuidPrime is valid (have they registered) + * If so, replace the srcGuidPrime with the srcGuid registered. + */ + sts = ndp_exchangeGuidPrimeForGuid( + ndpContext->guidListContext, srcGuidPrime, &srcGuid); + if (sts == 0) { + msgqueueentry = new_ndp_msgqueue_entry( + &srcGuid, /* srcGuid */ + dstGuid, /* dstGuid */ + length, /* length */ + data); /* data */ + if (msgqueueentry) { + ndp_guidmsgcontext_t *guidmsgcontext; + guidmsgcontext = find_ndp_guidmsgcontext( + ndpContext->guidListContext, + dstGuid); + if (guidmsgcontext) { + /* Insert signals ndp_read() that data is available */ + sts = insert_ndp_msgqueue_entry( + guidmsgcontext, msgqueueentry); + if (memcmp(dstGuid, &THISGUID, sizeof(GUID_t)) == 0) { + ndp_messagehandler(ndpContext, + NULL, NULL, 0L, NULL); + } + } else { + /* Insert signals ndp_read() that data is available */ + sts = insert_ndp_msgqueue_entry( + ndpContext->ndpMsgQueueContext, msgqueueentry); + } + if (sts == 0) { + retval = 0; + } + } + } else { + /* + * The srcGuidPrime is not valid (they have not registered). + * See if the dstGuid is for the NDP message handler. + * If so, forward to the NDP Message Handler and let it + * check for the command and handle it accordingly. + */ + if (memcmp(dstGuid, &THISGUID, sizeof(GUID_t)) == 0) { + ndp_messagehandler(NULL, srcGuidPrime, dstGuid, length, data); + retval = 0; + } + } + } + ndpDbgPrintf(10, "ndp_writeToGuid(Leave:%d)\n", retval); + return(retval); +} /* ndp_writeToGuid() */ +EXPORT_SYMBOL(ndp_writeToGuid); + +/****************************************************************************** +* Printf data sent to a specified guid (writer verified with guidPrime) +* (Note: This routine is available to other kernel modules) +******************************************************************************/ +int ndp_printfToGuid( + int dumpDataDebugLevel, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + char *fmt, + ...) +{ + int retval = -EFAULT; + va_list vargp; + int length; + char shortdata[4]; + char *data; + + ndpDbgPrintf(10, "ndp_printfToGuid(Enter)\n"); + NdpPrintfCount++; + if ((srcGuidPrime) && (dstGuid) && (fmt)) { + va_start(vargp, fmt); + length = vsnprintf(shortdata, 0, fmt, vargp); + length += 4; /* Allow a little slop for '\0' terminator, ... */ + va_end(vargp); + data = (char *)ndpMalloc(length, GFP_KERNEL); + if (data) { + va_start(vargp, fmt); + length = vsnprintf(data, length, fmt, vargp); + va_end(vargp); + if (length >= 0) { +#if (0) +/* Now done in ndp_writeToGuid() */ + if (ndp_debug >= dumpDataDebugLevel) { + ndp_dumpDataInHex(dumpDataDebugLevel, + "ndp_printfToGuid", length, data); + } +#endif + retval = ndp_writeToGuid( + dumpDataDebugLevel, + srcGuidPrime, + dstGuid, + (LONG)length, + (unsigned char *)data); + } else { + retval = length; + } + ndpFree(data); + } else { + retval = -ENOMEM; + } + } + ndpDbgPrintf(10, "ndp_printfToGuid(Leave:%d)\n", retval); + return(retval); +} /* ndp_printfToGuid() */ +EXPORT_SYMBOL(ndp_printfToGuid); + +#ifndef __KERNEL__ +/****************************************************************************** +* Write a piece of formatted data in multiple msgsnd messages +******************************************************************************/ +int ndpmsgsnd_writeMsgMultiple( + int dumpDataDebugLevel, + ndpmsg_t *ndpmsg, + LONG length, + BYTE *formattedData) +{ + int retval = -EFAULT; + unsigned char *nextDataPtr; + int remainingSize; + int chunkSize; + int maxdatasize = (NDP_MAX_MSG_SIZE - sizeof(ndpmsg_data_t)) - sizeof(LONG); + int msgsRemaining; + int flags = NDP_FIRST_MULT_MSG; + size_t msgsndSize; + + ndpDbgPrintf(10, "ndpmsgsnd_writeMsgMultiple(Enter)\n"); + + /* Calculate the number of messages to be written, and init for looping */ + msgsRemaining = (length + (maxdatasize-1)) / maxdatasize; + remainingSize = length; + nextDataPtr = formattedData; + chunkSize = maxdatasize; + + ndpDbgPrintf(10, "ndpmsgsnd_writeMsgMultiple(Using multipleID %d)\n",ndpmsg_multipleID); + + while (msgsRemaining--) { + /* Copy the next chunk of data */ + if (chunkSize >= remainingSize) { + chunkSize = remainingSize; + flags = NDP_LAST_MULT_MSG; + } + memcpy(ndpmsg->u.msg.data, nextDataPtr, chunkSize); + + ndpmsg->u.msg.dataLength = chunkSize; + ndpmsg->u.msg.totalLength = length; + ndpmsg->u.msg.msgsRemaining = msgsRemaining; + ndpmsg->u.msg.multipleID = ndpmsg_multipleID; + ndpmsg->u.msg.flags = flags; + msgsndSize = sizeof(LONG) + sizeof(ndpmsg_data_t) + chunkSize; + ndpDbgDumpDataInHex(dumpDataDebugLevel, "ndpmsgsnd_writeMsgMultiple", + chunkSize, ndpmsg->u.msg.data); + ndpDbgPrintf(10, "ndpmsgsnd_writeMsgMultiple(msgsnd, remaining=%d, size=%d)\n", + msgsRemaining, msgsndSize); + retval = msgsnd(ndpMsgQueueID, ndpmsg, msgsndSize, 0); + if (retval != 0) { + ndpErrPrintf( + "ndpmsgsnd_writeMsgMultiple: msgsnd error: %d: %s", + errno, strerror(errno)); + /* Attempt to send an abort packet so the receiver will stop */ + ndpmsg->u.msg.dataLength = 0; + ndpmsg->u.msg.totalLength = 0; + ndpmsg->u.msg.msgsRemaining = -1; + ndpmsg->u.msg.multipleID = ndpmsg_multipleID; + ndpmsg->u.msg.flags = flags; + msgsndSize = sizeof(LONG) + sizeof(ndpmsg_data_t) + chunkSize; + /* Ignore return status on the abort */ + msgsnd(ndpMsgQueueID, ndpmsg, msgsndSize, 0); + break; + } + remainingSize -= chunkSize; + nextDataPtr += chunkSize; + flags = 0; + } + ndpDbgPrintf(10, "ndpmsgsnd_writeMsgMultiple(Leave:%d)\n", retval); + return(retval); +} + +/****************************************************************************** +* Printf data sent via msgsnd to a specified guid +* (writer verified with guidPrime) +* --- Application space only (not in kernel) --- +******************************************************************************/ +int ndpmsgsnd_printfToGuid( + int dumpDataDebugLevel, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + char *fmt, + ...) +{ + int retval = -EFAULT; + va_list vargp; + unsigned long length; + unsigned long length2; + char *formattedData = NULL; + int maxdatasize = (NDP_MAX_MSG_SIZE - sizeof(ndpmsg_data_t)) - sizeof(LONG); + + ndpDbgPrintf(10, "ndpmsgsnd_printfToGuid(Enter)\n"); + if ((srcGuidPrime) && (dstGuid) && (fmt)) { + size_t msgsndSize; + ndpmsg_t ndpmsg; + + ndpmsg.dstID = NDP_APP_MSG_DST; + + memcpy(&ndpmsg.u.msg.srcGuidPrime, + srcGuidPrime, + sizeof(GUID_t)); + memcpy(&ndpmsg.u.msg.dstGuid, dstGuid, sizeof(GUID_t)); + va_start(vargp, fmt); + length = (LONG)vsnprintf((char *)ndpmsg.u.msg.data, + maxdatasize, + fmt, + vargp); + va_end(vargp); + + /****************************************************************/ + /*** NOTE: The length returned by vsnprintf is the exact number**/ + /*** of data bytes put into the buffer. If a trailing NULL is **/ + /*** stripped, the length will be == maxdatasize, but it did ***/ + /*** truncate the NULL byte. We can only be sure that the ***/ + /*** whole packet fit if the returned length is < maxdatasize.***/ + /****************************************************************/ + + if (length < maxdatasize) { + /* The length fit in a single packet. Just write it out */ + ndpmsg.u.msg.dataLength = length; + ndpmsg.u.msg.totalLength = length; + ndpmsg.u.msg.msgsRemaining = 0; + ndpmsg.u.msg.multipleID = 0; + msgsndSize = sizeof(LONG) + sizeof(ndpmsg_data_t) + length; + ndpDbgDumpDataInHex(dumpDataDebugLevel, "ndpmsgsnd_printfToGuid", + length, ndpmsg.u.msg.data); + retval = msgsnd(ndpMsgQueueID, &ndpmsg, msgsndSize, 0); + } else { + /****************************************************************/ + /*** The length did not fit in a single packet. Get a bigger ***/ + /*** buffer to hold the entire formatted response, including ***/ + /*** space for a trailing NULL. ***/ + /****************************************************************/ + formattedData = (char *)ndpMalloc( length+1, GFP_KERNEL); + if (formattedData == NULL) { + ndpErrPrintf( + "ndpmsgsnd_printfToGuid unable to allocate memory: %d: %s", + errno, strerror(errno)); + } else { + /* Reformat into the bigger buffer */ + va_start(vargp, fmt); + length2 = (LONG)vsnprintf(formattedData, + length+1, + fmt, + vargp); + va_end(vargp); + /* Cross-check the two lengths */ + if (length2 != length) { + ndpErrPrintf( + "ndpmsgsnd_printfToGuid inconsistents message lengths: %d: %d", + length, length2); + } else { + /* Write msg in multiple chunks. Guids already filled in */ + retval = ndpmsgsnd_writeMsgMultiple( + dumpDataDebugLevel, + &ndpmsg, + length, + (unsigned char *)formattedData); + } + ndpFree(formattedData); + } + } + } + ndpDbgPrintf(10, "ndpmsgsnd_printfToGuid(Leave:%d)\n", retval); + return(retval); +} /* ndpmsgsnd_printfToGuid() */ +#endif + +/****************************************************************************** +* Register a guid for data transfers (read & write) +* A guidPrime will be returned for use hereafter with these routines +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +int ndp_registerGuid( + GUID_t *guid, + GUID_t *guidPrime, /* Space must be provided by the caller !!! */ + char *name) +{ + int retval = -EINVAL; + ndp_guidlist_t *entry; + + ndpDbgPrintf(14, "ndp_registerGuid(Enter)\n"); + if ((guid) && (guidPrime)) { /* name isn't required */ + /*******************************************************************/ + /*** Note: new_ndp_guidlist_entry() creates & fills in guidPrime ***/ + /*******************************************************************/ + entry = new_ndp_guidlist_entry(guid, guidPrime, name); + if (entry) { + ndpDbgDumpDataInHex(15, "ndp_registerGuid:Guid", sizeof(GUID_t), (unsigned char *)guid); + ndpDbgDumpDataInHex(15, "ndp_registerGuid:GuidPrime", sizeof(GUID_t), (unsigned char *)guidPrime); + retval = insert_ndp_guidlist_entry( + ndpContext->guidListContext, entry); + } + } + ndpDbgPrintf(14, "ndp_registerGuid(Leave:%d)\n", retval); + return(retval); +} /* ndp_registerGuid() */ +EXPORT_SYMBOL(ndp_registerGuid); + +/****************************************************************************** +* Generate a new random Guid -AND- +* Register a this guid for data transfers (read & write) +* The guid & guidPrime will be returned for use hereafter with these routines +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +int ndp_registerRandomGuid( + GUID_t *guid, /* Space must be provided by the caller !!! */ + GUID_t *guidPrime, /* Space must be provided by the caller !!! */ + char *name) +{ + int retval = -EINVAL; + + if (guid && guidPrime) { + ndp_generateGuid(guid); + retval = ndp_registerGuid(guid, guidPrime, name); + } + return(retval); +} /* ndp_registerRandomGuid() */ +EXPORT_SYMBOL(ndp_registerRandomGuid); + +/****************************************************************************** +* De-Register a previously register guid (guid verified with guidPrime) +* (Note: This routine has been exported for other kernel modules) +******************************************************************************/ +void ndp_deregisterGuid( + GUID_t *guidPrime) +{ + ndpDbgPrintf(14, "ndp_deregisterGuid(Enter)\n"); + if (guidPrime) { + ndp_guidlist_t *entry; + entry = extract_ndp_guidlist_entryByGuidPrime( + ndpContext->guidListContext, guidPrime); + if (entry) { + free_ndp_guidlist_entry(entry); + } + } + ndpDbgPrintf(14, "ndp_deregisterGuid(Leave)\n"); + return; +} /* ndp_deregisterGuid() */ +EXPORT_SYMBOL(ndp_deregisterGuid); diff --git a/src/nwnss/sharedsrc/ndp_guids.c.h b/src/nwnss/sharedsrc/ndp_guids.c.h new file mode 100644 index 0000000..be0e08e --- /dev/null +++ b/src/nwnss/sharedsrc/ndp_guids.c.h @@ -0,0 +1,50 @@ +/**************************************************************************** + | + | (C) Copyright 2004 Novell, Inc. + | All Rights Reserved. + | + | This program is free software; you can redistribute it and/or + | modify it under the terms of version 2 of the GNU General Public + | License as published by the Free Software Foundation. + | + | This program is distributed in the hope that it will be useful, + | but WITHOUT ANY WARRANTY; without even the implied warranty of + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + | GNU General Public License for more details. + | + | You should have received a copy of the GNU General Public License + | along with this program; if not, contact Novell, Inc. + | + | To contact Novell about this file by physical or electronic mail, + | you may find current contact information at www.novell.com + | + |*************************************************************************** + | + | Novell's User/Kernel Data Portal (NDP) GUIDs file. + | + |--------------------------------------------------------------------------- + | + | $Author: taysom $ + | $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $ + | + | $RCSfile$ + | $Revision: 465 $ + | + |--------------------------------------------------------------------------- + | This file is used to: + | ... + +-------------------------------------------------------------------------*/ + +#include + +/****************************************************************************** +******************************************************************************* +* Declare the NDP Application & Module GUID Values +******************************************************************************* +******************************************************************************/ + +/* DD698A15-9E44-4317-9195-5B0499873F26 */ +GUID_t ndpAppGuid = { 0xdd698a15, 0x9e44, 0x4317, 0x91, 0x95, { 0x5b, 0x04, 0x99, 0x87, 0x3f, 0x26 } }; + +/* 4B1F2770-DE5E-4482-8E52-70D86EFE990C */ +GUID_t ndpModGuid = { 0x4b1f2770, 0xde5e, 0x4482, 0x8e, 0x52, { 0x70, 0xd8, 0x6e, 0xfe, 0x99, 0x0c } }; diff --git a/src/nwnss/sharedsrc/ndp_idbroker.c.h b/src/nwnss/sharedsrc/ndp_idbroker.c.h index 7c20b66..ca4047c 100644 --- a/src/nwnss/sharedsrc/ndp_idbroker.c.h +++ b/src/nwnss/sharedsrc/ndp_idbroker.c.h @@ -299,7 +299,7 @@ static ndpIdBrokerInfo_t ndpIdBrokerInfo[] = * The NDP ID Broker Message Handling Routine * These routines run in their own threads... ******************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) void *ndp_idBroker_messagehandler( THREAD thread, void *_threadContext) @@ -840,7 +840,7 @@ int ndp_init_idBroker(void) sts = pthread_create( &ndpIdBrokerInfo[g].thread, NULL, - ndp_idBroker_messagehandler, + (void *(*)(void *))ndp_idBroker_messagehandler, &ndpIdBrokerInfo[g].threadContext); // if (sts) { // /* Thread Creation Error */ @@ -908,7 +908,7 @@ int ndp_cleanup_idBroker(void) * K2U nnn * U2K nnnnnnccc *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_namGetUserFDNfromUID( int uid, unicode_t **userFDN) @@ -1223,7 +1223,7 @@ int ndp_namGetUserFDNfromUID_handler( * K2U nnnccc * U2K nnnccchex *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPMapDNToGUID( int create, unicode_t *dn, @@ -1400,7 +1400,7 @@ SendResponse: * K2U nnn * U2K nnnccc *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPLocalTreeName( size_t treeNameSize, /* This is buffer size in bytes */ unicode_t *treeName) @@ -1579,7 +1579,7 @@ SendResponse: * U2K nnncccnnn * hex,... *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPMapDNToSEV( unicode_t *dn, size_t *_guidSEVCount, @@ -1848,7 +1848,7 @@ SendResult: * U2K nnnhex * nnn *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPMapGUIDToMgtLevel( size_t numAuthenticatedIDs, GUID_t *authenticatedIDs, @@ -2081,7 +2081,7 @@ SendResult: * K2U hexnnn * U2K nnnhexccc *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPMapGUIDToDN( GUID_t *guid, size_t dnSize, @@ -2274,7 +2274,7 @@ SendResult: * K2U hex * U2K nnnhexnnn *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPMapGUIDToUID( GUID_t *guid, LONG *uid) @@ -2417,7 +2417,7 @@ int ndp_NCPMapGUIDToUID_handler( * K2U nnn * U2K nnnnnnhex *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPMapUIDToGUID( LONG uid, GUID_t *guid) @@ -2551,7 +2551,7 @@ int ndp_NCPMapUIDToGUID_handler( * K2U ccc * U2K nnncccnnn *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_GetUIDFromName( unsigned char *name, LONG *uid) @@ -2788,7 +2788,7 @@ utf8_t *ndp_UnManglePassword( * U2K nnnccchex

hex

*
*****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_GenerateVolumeKeyInfo( unicode_t *volumePassword, BYTE *retKey, /* ptr to 16 byte buffer to receive the new key */ @@ -2995,7 +2995,7 @@ SendResult: * K2U ccc

hex

* U2K nnnccchex *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_ExtractVolumeKeyInfo( unicode_t *volumePassword, BYTE *volP, /* ptr to 128 byte persistent portion of VolumeKey_s */ @@ -3215,7 +3215,7 @@ SendResult: * if already registered (-2) * if invalid function pointer (-1) *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) void (*ndp_NCPNotifyDNChange)(unicode_t *oldDN, unicode_t *newDN) = NULL; int ndp_register_NCPNotifyDNChange( @@ -3246,7 +3246,7 @@ EXPORT_SYMBOL(ndp_register_NCPNotifyDNChange); * K2U ... N/A (no return value) ... * U2K cccccc *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPNotifyDNChange_handler( GUID_t *srcGuid, LONG length, @@ -3313,7 +3313,7 @@ int ndp_NCPNotifyDNChange_handler( * if already registered (-2) * if invalid function pointer (-1) *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) void (*ndp_NCPNotifySEVChange)(GUID_t *changedGUID) = NULL; int ndp_register_NCPNotifySEVChange( @@ -3343,7 +3343,7 @@ EXPORT_SYMBOL(ndp_register_NCPNotifySEVChange); * K2U ... N/A (no return value) ... * U2K hex *****************************************************************************/ -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(MARS_NWE_NWNSS_USERSPACE) int ndp_NCPNotifySEVChange_handler( GUID_t *srcGuid, LONG length, diff --git a/src/nwnss/sharedsrc/ndp_messagehandler.c.h b/src/nwnss/sharedsrc/ndp_messagehandler.c.h new file mode 100644 index 0000000..27abd6b --- /dev/null +++ b/src/nwnss/sharedsrc/ndp_messagehandler.c.h @@ -0,0 +1,356 @@ +/**************************************************************************** + | + | (C) Copyright 2004 Novell, Inc. + | All Rights Reserved. + | + | This program is free software; you can redistribute it and/or + | modify it under the terms of version 2 of the GNU General Public + | License as published by the Free Software Foundation. + | + | This program is distributed in the hope that it will be useful, + | but WITHOUT ANY WARRANTY; without even the implied warranty of + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + | GNU General Public License for more details. + | + | You should have received a copy of the GNU General Public License + | along with this program; if not, contact Novell, Inc. + | + | To contact Novell about this file by physical or electronic mail, + | you may find current contact information at www.novell.com + | + |*************************************************************************** + | + | Novell's User/Kernel Data Portal (NDP) Common Message Handling program file. + | + |--------------------------------------------------------------------------- + | + | $Author: blarsen $ + | $Date: 2006-02-09 05:04:41 +0530 (Thu, 09 Feb 2006) $ + | + | $RCSfile$ + | $Revision: 1325 $ + | + |--------------------------------------------------------------------------- + | This file is used to: + | ... + +-------------------------------------------------------------------------*/ + +#include +#include + +#ifndef __KERNEL__ +#include +#endif /* __KERNEL__ */ + +extern ndpContext_t *ndpContext; + +/****************************************************************************** +* Declare and initialize NDP Application "Globals" +******************************************************************************/ +#ifndef __KERNEL__ +extern long ndpMsgQueueID; /* See ndp_app.c */ +#endif /* __KERNEL__ */ + +/****************************************************************************** +* Function Pre-Declarations (not in ndp_messagehandler.h, or static) +******************************************************************************/ + +static int ndp_messagehandler_echo( + GUID_t *ndpGuid, + GUID_t *ndpGuidPrime, + GUID_t *ndpOtherGuid, + GUID_t *msgSrcGuid, + LONG length, + unsigned char *data); + +static int ndp_messagehandler_register( + GUID_t *ndpGuid, + GUID_t *ndpGuidPrime, + GUID_t *ndpOtherGuid, + GUID_t *msgSrcGuid, + LONG length, + unsigned char *data); + +static int ndp_messagehandler_deregister( + GUID_t *ndpGuid, + GUID_t *ndpGuidPrime, + GUID_t *ndpOtherGuid, + GUID_t *msgSrcGuidPrime, + LONG length, + unsigned char *data); + +/****************************************************************************** +* Message Handler Action for the NDP Message Handler +* Returns 1 if handled by this handler +******************************************************************************* +* NOTE: As a saftey mechanism against an infinite loop, the echoed data +* is shortend by one character each time it is echoed... +******************************************************************************/ +static int ndp_messagehandler_echo( + GUID_t *ndpGuid, + GUID_t *ndpGuidPrime, + GUID_t *ndpOtherGuid, + GUID_t *msgSrcGuid, + LONG length, + unsigned char *data) +{ + int messageHandled = 0; + static unsigned char cmdString[] = ""; + int cmdStringLength = sizeof(cmdString) - 1; /* Don't count '\0' */ + + if ((length >= cmdStringLength) && (data)) { + if (ndp_strncasecmp(data, cmdString, cmdStringLength) == 0) { + unsigned char *dp = NULL; + ndpDbgPrintf(1, "ndp_messagehandler_echo(Start)\n"); + dp = ndpMalloc(((size_t)length+1), GFP_KERNEL); + if (dp) { + memcpy(dp, data, (size_t)length); + dp[(size_t)length] = '\0'; + ndpDbgPrintf(2, "ndp_messagehandler_echo:%ld=\"%s\"\n", + length, dp); + ndpFree(dp); + } + messageHandled = 1; + /* No need to get sts, we will just ignore the results */ + (void) ndp_writeToGuid(1, + ndpGuidPrime, /* *srcGuidPrime */ + msgSrcGuid, /* *dstGuid */ + length - 1, /* length shortened by a count of 1 */ + data); + ndpDbgPrintf(1, "ndp_messagehandler_echo(Stop)\n"); + } + } + return(messageHandled); +} /* ndp_messagehandler_echo() */ + +/****************************************************************************** +* Message Handler Action for the NDP Message Handler +* Returns 1 if handled by this handler +******************************************************************************/ +static int ndp_messagehandler_register( + GUID_t *ndpGuid, + GUID_t *ndpGuidPrime, + GUID_t *ndpOtherGuid, + GUID_t *msgSrcGuid, + LONG length, + unsigned char *data) +{ + int messageHandled = 0; +#ifndef __KERNEL__ +/* This is currently only allowed (useful) in the application world */ + static unsigned char cmdString[] = ""; + int cmdStringLength = sizeof(cmdString) - 1; /* Don't count '\0' */ + + if ((length >= cmdStringLength) && (data)) { + if (ndp_strncasecmp(data, cmdString, cmdStringLength) == 0) { + XML_ElementInfo_s xmlInfo; + ndp_guidmsgcontext_t *guidmsgcontext; + unsigned char msgReply[] = + "1234567890123456"; + + GUID_t *msgSrcGuidPrime = (GUID_t *)&msgReply[15]; + char *name = NULL; + pid_t pid = -1; + int connectionType = NDPCONN_unknown; + STATUS sts; + + ndpDbgPrintf(10, "ndp_messagehandler_register(Start): data=%s\n", data); + messageHandled = 1; + /* + * Parse the contents of the ... tag set + * Recognized tags: + * ... + * ... + * ... + * Recognized values: + * "link" - routines are linked in + * "msgop" - msgget, msgsnd, msgrcv, ... + */ + sts = XML_GetTagElement("name", + (utf8_t *)&data[0], (utf8_t *)&data[length-1], &xmlInfo); + if (sts == zOK) { + /* Get the value and add a '\0' terminator */ + *(xmlInfo.dataEnd + 1) = '\0'; + name = xmlInfo.dataStart; + } + sts = XML_GetTagElement("pid", + (utf8_t *)&data[0], (utf8_t *)&data[length-1], &xmlInfo); + if (sts == zOK) { + /* Get the value */ + *(xmlInfo.dataEnd + 1) = '\0'; + pid = (pid_t)ndp_atoi(xmlInfo.dataStart); + } + sts = XML_GetTagElement("connectiontype", + (utf8_t *)&data[0], (utf8_t *)&data[length-1], &xmlInfo); + if (sts == zOK) { + utf8_t *connectionTypeString; + /* Get the string value and convert it to a number */ + *(xmlInfo.dataEnd + 1) = '\0'; + connectionTypeString = xmlInfo.dataStart; + if (ndp_strncasecmp((unsigned char *)connectionTypeString, + (unsigned char *)NDPCONNSTR_linked, + strlen(NDPCONNSTR_linked)) == 0) { + connectionType = NDPCONN_linked; + } else if (ndp_strncasecmp((unsigned char *)connectionTypeString, + (unsigned char *)NDPCONNSTR_msgop, + strlen(NDPCONNSTR_msgop)) == 0) { + connectionType = NDPCONN_msgop; + } + } + /* Do the actual register */ + ndp_registerGuid(msgSrcGuid, msgSrcGuidPrime, name); + /* Fill in connection information */ + guidmsgcontext = find_ndp_guidmsgcontext( + ndpContext->guidListContext, msgSrcGuid); + guidmsgcontext->pid = pid; + guidmsgcontext->connection = connectionType; + guidmsgcontext->ndpMsgQueueID = ndpMsgQueueID; + /* Send the guidPrime back as a packet */ + (void) ndp_writeToGuid(10, + ndpGuidPrime, /* *srcGuidPrime */ + msgSrcGuid, /* *dstGuid */ + sizeof(msgReply), /* length */ + msgReply); + ndpDbgPrintf(10, "ndp_messagehandler_register(Stop)\n"); + } + } +#endif /* __KERNEL__ */ + return(messageHandled); +} /* ndp_messagehandler_register() */ + +/****************************************************************************** +* Message Handler Action for the NDP Message Handler +* Returns 1 if handled by this handler +******************************************************************************/ +static int ndp_messagehandler_deregister( + GUID_t *ndpGuid, + GUID_t *ndpGuidPrime, + GUID_t *ndpOtherGuid, + GUID_t *msgSrcGuidPrime, + LONG length, + unsigned char *data) +{ + int messageHandled = 0; + static unsigned char cmdString[] = ""; + int cmdStringLength = sizeof(cmdString) - 1; /* Don't count '\0' */ + + if ((length >= cmdStringLength) && (data)) { + if (ndp_strncasecmp(data, cmdString, cmdStringLength) == 0) { + ndpDbgPrintf(10, "ndp_messagehandler_deregister(Start)\n"); + messageHandled = 1; + ndp_deregisterGuid(msgSrcGuidPrime); + ndpDbgPrintf(10, "ndp_messagehandler_deregister(Stop)\n"); + } + } + return(messageHandled); +} /* ndp_messagehandler_deregister() */ + +/****************************************************************************** +* The NDP Application Message Handling Routine +* This routine is called whenever a message is received for the NDP Application +******************************************************************************* +* if (srcGuidPrime) { +* Use srcGuidPrime, dstGuid, length, and data values passed in. +* Try message handler. +* else if (ndpContext) { +* Call ndp_readFromGuid() to get the data. +* Try all message handlers except . +* } else { +* Error ... Ignore +* } +******************************************************************************* +* NOTE: is the ONLY case that comes here using (srcGuidPrime, +* dstGuid, length, data), all others ALWAYS come here * using (ndpContext). +******************************************************************************/ +void ndp_messagehandler( + ndpContext_t *ndpContext, + GUID_t *srcGuidPrime, + GUID_t *dstGuid, + LONG length, /* 32 bit unsigned value */ + unsigned char *data) +{ + int sts = 0; + GUID_t _srcGuid; + GUID_t *srcGuid = &_srcGuid; + GUID_t _srcGuidPrime; + + ndpDbgPrintf(13, "ndp_messagehandler(Enter)\n"); + if (srcGuidPrime) { + /* Skip past any white space */ + data = ndp_SkipWhitespace(data, &length); + if ((length > 0) && (*data == '<')) { + ndpDbgDumpDataInHex(13, "ndp_messagehandler(srcGuid)", + sizeof(GUID_t), (unsigned char *)srcGuidPrime); + ndpDbgDumpDataInHex(13, "ndp_messagehandler(data)", + length, data); + /* is the only message we allow to come in this way */ + /* No need to get sts, no other handlers will be tried */ + (void) ndp_messagehandler_register( + &THISGUID, + &THISGUIDPRIME, + &OTHERGUID, + srcGuidPrime, + length, + data); + } + } else if (ndpContext) { + sts = ndp_readFromGuid(13, &THISGUIDPRIME, srcGuid, &length, &data); + if (sts == 0) { + /* Skip past any white space */ + data = ndp_SkipWhitespace(data, &length); + if (length > 0) { + ndpDbgDumpDataInHex(13, "ndp_messagehandler(srcGuid)", + sizeof(GUID_t), (unsigned char *)srcGuid); + ndpDbgDumpDataInHex(13, "ndp_messagehandler(data)", + length, data); + /* get the srcGuidPrime using the guid */ + srcGuidPrime = &_srcGuidPrime; + sts = ndp_exchangeGuidForGuidPrime( + ndpContext->guidListContext, srcGuid, srcGuidPrime); + /* + * All message to the NDP message handler are in XML format. + * Thus, all messages start with '<' and the next character + * will be a quick indicator as to which handlers to try... + * All the handlers examine the data to see if they are + * supposed to deal with the data, and return 1 if they do + * and 0 if they don't. This way, we can try several + * handlers that start with the same character until one + * of them handles the message. Non-handled messages + * are ignored. + */ + if (data[0] == '<') switch (data[1]) { + case 'd': + case 'D': + { + /* (D) Possibly == DeRegister, ... */ + sts = ndp_messagehandler_deregister( + &THISGUID, + &THISGUIDPRIME, + &OTHERGUID, + srcGuidPrime, + length, + data); + } + case 'e': + case 'E': + { + /* (E) Possibly == Echo, ... */ + sts = ndp_messagehandler_echo( + &THISGUID, + &THISGUIDPRIME, + &OTHERGUID, + srcGuid, + length, + data); + } + } + } + } + if (data) { + ndpFree(data); + } + //IGNORE// } else { + } + ndpDbgPrintf(13, "ndp_messagehandler(Leave)\n"); + return; +} /* ndp_messagehandler() */