85dca984ba39e8c75b68482cd6ff757ca5f0dce6
[o-du/l2.git] / src / cm / cm_inet.c
1 /*******************************************************************************
2 ################################################################################
3 #   Copyright (c) [2017-2019] [Radisys]                                        #
4 #                                                                              #
5 #   Licensed under the Apache License, Version 2.0 (the "License");            #
6 #   you may not use this file except in compliance with the License.           #
7 #   You may obtain a copy of the License at                                    #
8 #                                                                              #
9 #       http://www.apache.org/licenses/LICENSE-2.0                             #
10 #                                                                              #
11 #   Unless required by applicable law or agreed to in writing, software        #
12 #   distributed under the License is distributed on an "AS IS" BASIS,          #
13 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
14 #   See the License for the specific language governing permissions and        #
15 #   limitations under the License.                                             #
16 ################################################################################
17 *******************************************************************************/
18
19 \f
20 /********************************************************************20**
21   
22         Name:     common Internet socket library
23     
24         Type:     C Source file 
25   
26         Desc:     common library for Internet sockets,
27                   always link this library with following libraries:
28                        Trillium's libos.a
29                        Solaris    nsl, socket 
30  
31         File:     cm_inet.c
32   
33 *********************************************************************21*/
34  
35 \f
36 /*
37  *      This software may be combined with the following TRILLIUM
38  *      software:
39  *
40  *      part no.                      description
41  *      --------    ----------------------------------------------
42  *      1000151     TCAP over TCP/IP   
43  */
44
45 \f  
46 /* header include files (.h) */
47   
48 #include "envopt.h"             /* environment options */  
49 #include "envdep.h"             /* environment dependent */
50 #include "envind.h"             /* environment independent */
51
52 #include "gen.h"                /* general */
53 #include "ssi.h"                /* system services interface */
54 #include "cm_inet.h"            /* socket library file */
55
56 /*cm_inet_c_001.main_35 : Updated for C++ compilation */
57 #ifdef __cplusplus
58 extern "C" {
59 #endif /* __cplusplus */
60
61 /* environment dependent include files */
62 #ifdef WIN32
63 #ifndef IN
64 #define IN
65 #endif
66 #include <winsock2.h>
67 #include <ws2tcpip.h>
68 #ifdef WIN2K
69 #include <Mswsock.h>
70 #endif /* WIN2K */
71 #else /* WIN32 */
72 #include <errno.h>
73 #if (!defined(SS_VW) && !defined(SS_PS))
74 #include <netdb.h>
75 #endif
76 #ifndef SS_PS
77 #include <unistd.h>
78 #endif
79 #include <string.h>
80 #include <sys/types.h>
81 #ifdef SS_PS
82 #include <pna.h>
83 #else
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
86 #endif /* SS_PS */
87 #ifdef SS_VW
88 #include <sys/times.h>
89 #include <ioLib.h>
90 #include <sockLib.h>
91 #include <selectLib.h>
92 #include <hostLib.h>
93 #else
94 #if (!defined (SS_PS) && !defined(HPOS))
95 #include <sys/select.h>
96 #include <sys/time.h>
97 #ifdef SS_LINUX
98 #include <sys/uio.h>
99 #else
100 #include <sys/filio.h>
101 #endif /* SS_LINUX */
102 #endif /* SS_PS && HPOS */
103 #ifdef HPOS
104 #include <sys/time.h>
105 #endif /* HPOS */
106 #endif /* SS_VW */
107 #ifndef SS_PS
108 #include <netinet/in.h>
109 #include <arpa/inet.h>
110 #include <netinet/tcp.h>
111 #ifdef IPV6_SUPPORTED 
112
113 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 adding the new header includes */
114 #if (defined(SS_VW) && defined(SS_VW6_7)) 
115 #include <ipcom_inet.h>
116 #include <ipcom_sock6.h>
117 #include <netinet/icmp6.h>
118 #else 
119 #include <netinet/icmp6.h>
120 #endif    
121
122 #endif /* IPV6_SUPPORTED */
123 #endif /* SS_PS */
124 #endif /* WIN32 */
125
126 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
127 #ifdef CM_LKSCTP
128 #include <netinet/sctp.h>
129 #endif
130
131    /* cm_inet_c_001.main_58: Added new header files to support filteration 
132     * of ICMP messages */
133 #ifdef SS_LINUX
134 #ifdef CM_ICMP_FILTER_SUPPORT
135 #include <asm/types.h>
136 #include <linux/icmp.h>
137 #endif
138 #endif
139  /* cm_inet_c_001.main_62:Warning fix */
140 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
141 #include <netdb.h>
142 #endif
143 #ifdef __cplusplus
144 }
145 #endif /* __cplusplus */
146 /* header/extern include files (.x) */
147
148 #include "gen.x"                /* general */
149 #include "ssi.x"                /* system services interface */
150 #include "cm_inet.x"            /* socket library file */
151 #include "cm_lib.x"             /* lib library file */
152 #ifdef NTL_LIB
153 #include "ntl_lib.h"
154 #endif 
155 #include "du_log.h"
156
157 \f  
158 /* local defines */
159
160 /* BSD and Winsock error handling is different */
161 #ifdef WIN32
162 #define INET_ERR             SOCKET_ERROR
163 #define INET_ERR_CODE        WSAGetLastError()
164 #define ERR_INPROGRESS       WSAEINPROGRESS  
165 #define ERR_ISCONN           WSAEISCONN
166 #define ERR_WOULDBLOCK       WSAEWOULDBLOCK
167 #define ERR_INADDRNONE       INADDR_NONE
168 #define ERR_NOTCONN          WSAENOTCONN
169 #define ERR_ALREADY          WSAEALREADY
170 #define ERR_AGAIN            WSAEWOULDBLOCK 
171 #define ERR_INVAL            WSAEINVAL
172 #define ERR_CONNREFUSED       WSAECONNREFUSED
173 #define ERR_PIPE             WSAENOTCONN
174 /* Changed ERR_TIMEOUT for pSos compilation */
175 #define ERR_TIMEDOUT         WSAETIMEDOUT
176 #define ERR_CONNRESET        WSAECONNRESET
177 #define ERR_CONNABORTED      WSAECONNABORTED
178 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
179 #define ERR_EINTR            WSAEINTR
180 /* cm_inet_c_001.main_37 network unreacheble error is added */
181 #define ERR_NETUNREACH       WSAENETUNREACH
182 /* cm_inet_c_001.main_61: host unreachable is added */
183 #define ERR_HOSTUNREACH      WSAEHOSTUNREACH
184 #else
185 #define INET_ERR             -1
186 #define INET_ERR_CODE        errno
187 #define ERR_INPROGRESS       EINPROGRESS
188 #define ERR_ISCONN           EISCONN
189 #define ERR_WOULDBLOCK       EWOULDBLOCK
190 #define ERR_INADDRNONE       -1
191 #define ERR_NOTCONN          ENOTCONN       
192 #define ERR_ALREADY          EALREADY
193 #define ERR_AGAIN            EAGAIN
194 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
195 #define ERR_EINTR            EINTR
196 /* EINVAL is not mapped because it is a valid error code here */
197 #define ERR_INVAL            0 
198 #define ERR_CONNREFUSED      ECONNREFUSED
199 #define ERR_PIPE             EPIPE 
200 /* Changed ERR_TIMEOUT for pSos compilation */
201 #define ERR_TIMEDOUT         ETIMEDOUT
202 #define ERR_CONNRESET        ECONNRESET
203 #define ERR_CONNABORTED      ECONNABORTED
204 /* cm_inet_c_001.main_37 network unreacheble error is added */
205 #define ERR_NETUNREACH       ENETUNREACH
206 /* cm_inet_c_001.main_61: host unreachable is added */
207 #define ERR_HOSTUNREACH      EHOSTUNREACH
208 #endif /* WIN32 */
209
210 /* back log range */
211 #define MIN_BACK_LOG  0
212
213 /* added a win2k specific defines in. */
214 #ifdef WIN32
215 #ifdef WIN2K
216 #ifndef SIO_UDP_CONNRESET
217 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
218 #endif 
219 #endif /* WIN2K */
220 #define MAX_BACK_LOG  1
221 #else
222 #define MAX_BACK_LOG  5
223 #endif /* WIN32 */
224
225 #ifdef IPV6_OPTS_SUPPORTED
226 #ifndef IPV6_SUPPORTED
227 #error "Enable IPV6_SUPPORTED flag if IPV6_OPTS_SUPPORTED is defined."
228 #endif 
229 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
230 #error "Enable _XPG4_2 or SS_LINUX if IPV6_OPTS_SUPPORTED is defined."
231 #endif /* SS_LINUX || _XPG4_2 */
232 #endif /* IPV6_OPTS_SUPPORTED */
233
234 #ifdef LOCAL_INTF
235 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
236 #error "Enable _XPG4_2 or SS_LINUX if LOCAL_INTF is defined."
237 #endif /* SS_LINUX || _XPG4_2 */
238 #endif /* LOCAL_INTF */
239
240 /* local typedefs */
241
242 /* local externs */
243   
244 /* forward references */
245
246 /* added !(defined(CMINETFLATBUF) */
247 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
248 /* Added another function parameter */
249 PRIVATE S16 buildRecvBuf ARGS((CmInetMemInfo *info, MsgLen len, 
250                                CmInetIovec rxArr[], Buffer *dBuf[], U16 maxSize,
251                                struct msghdr *msg, Bool isStrmMsg));
252 PRIVATE S16 buildRecvMsg ARGS((CmInetMemInfo *info, CmInetIovec rxArr[], 
253                                S16 numBduf, MsgLen msgLen, Buffer *dBufs[], 
254                                Buffer **mPtr));
255 /* cm_inet_c_001.main_50 - Added parameter to get length of dbufs packed for partial
256  *               send handling 
257  */
258 PRIVATE S16 buildSendIovec ARGS((Buffer *mBuf, MsgLen msgLen, 
259                                  CmInetIovec txArr[], S16 numDBuf, 
260                                  S16 *numIovElems, U32 *strtEndDBufNum,
261                                  MsgLen *ioLen)); 
262 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
263
264 /* prototypes of new functions needed to send and 
265  * process after receiving the extension headers through ancillary data */
266
267 #ifdef IPV6_SUPPORTED
268 #ifdef IPV6_OPTS_SUPPORTED
269 PRIVATE S16 cmInet6BuildSendHBHOpts    ARGS((CmInetIpv6HBHHdrArr *hbhOptsArr, 
270                                             U8 *cmsgBuf, U32 *curMsgIdx, 
271                                             U8 hdrId));
272 PRIVATE S16 cmInet6BuildSendRouteOpts  ARGS((CmInetIpv6RtHdr *rtOptsArr, 
273                                             U8 *cmsgBuf, U32 *curMsgIdx));
274
275 PRIVATE S16 cmInet6BuildRecvRtHdr      ARGS((U8 *cmsgData, U32 rtDataLen, 
276                                             CmInetIpv6RtHdr0 *rtHdr0, 
277                                             CmInetIpv6RtHdr *rtOptsArr,
278                                             CmInetMemInfo *info));
279 PRIVATE S16 cmInet6BuildRecvHopOptsArr ARGS((U8 *cmsgData, U32 hbhDataLen, 
280                                             CmInetIpv6HBHHdrArr *hbhOptsArr, 
281                                             U8 hdrId, CmInetMemInfo *info));
282 PRIVATE S16 cmInet6GetHopLimitValue    ARGS((U8 *cmsgData, U32 hopLimitDataLen,
283                                             CmInetIpv6HdrParm *ipv6HdrParam));
284
285 #ifdef SS_LINUX
286 PRIVATE S16 cmInetBuildSendHoplimit        ARGS((U32 hoplimit, U8 *cmsgBuf, 
287                                             U32 *curMsgIdx));
288 #endif /* SS_LINUX */
289 #ifdef LOCAL_INTF
290 PRIVATE S16 cmInet6BuildSendPktinfo         ARGS((CmInetIpAddr6 *srcAddr,
291                                             U8 *cmsgBuf, U32 *curMsgIdx,
292                                             U8 protType));
293 #endif /* LOCAL_INTF */
294 #endif /* IPV6_OPTS_SUPPORTED */
295 #endif /* IPV6_SUPPORTED */
296
297 /* public variable declarations */
298
299 /* private variable declarations */
300
301 #ifdef CMINETDBG
302 /* Global buffer for debug prints */
303 /*cm_inet_c_001.main_62:Warning fix*/
304 Txt   prntBuf[CMINET_PRNT_BUF_SIZE];
305 #endif /* CMINETDBG */
306
307 /* cm_inet_c_001.main_60 POLL Specific Functions defined */
308
309 /*
310 *
311 *      Fun:   cmInetPoll
312 *
313 *      Desc:  Poll on pollfdarr
314 *
315 *      Ret:   Number of File Descriptor Selected
316 *
317 *      Notes: None
318 *
319 *      File:  cm_inet.c
320 *
321 */
322
323 #ifdef ANSI
324 PUBLIC S16 cmInetPoll
325 (
326 CmInetPollFd  *pollFdArr,               /* poll FD Array */
327 U32               numFds,               /* Number of Fds to be monitored */
328 S16              *numRdyFds,            /* number of ready descriptors */
329 U32              timeout                /* timeout value for Poll */
330 )
331 #else
332 PUBLIC S16 cmInetPoll(pollFdArr,numFds,numRdyFds,timeout)
333 CmInetPollFd  *pollFdArr;               /* poll FD Array */
334 U32               numFds;               /* Number of Fds to be monitored */
335 S16              *numRdyFds;            /* number of ready descriptors */
336 U32               timeout;              /* timeout value for Poll */
337 #endif
338 {
339    S32  ret;
340
341    TRC2(cmInetPoll); 
342    ret = 0;
343    *numRdyFds = 0;
344
345    if(numFds > CM_INET_POLL_MAXFDSUPP)
346    {
347 #ifdef CMINETDBG
348 /* cm_inet_c_001.main_62:Warning fix */
349 #ifndef ALIGN_64BIT
350       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%lu) invalid \n",numFds);
351 #else
352       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%u) invalid \n",numFds);
353 #endif
354       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
355 #endif /* CMINETDBG */      
356       RETVALUE(RFAILED);
357    } 
358
359 #if (ERRCLASS & ERRCLS_INT_PAR)
360       /* error check on parameters */
361       if (pollFdArr == NULLP)
362       {
363 #ifdef CMINETDBG
364       /* cm_inet_c_001.main_62:Warning fix */
365       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : Invalid Parameter (pollFdArr is NULL)");
366       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
367 #endif /* CMINETDBG */      
368          RETVALUE(RFAILED);
369       }
370 #endif /* ERRCLASS & ERRCLS_INT_PAR */
371
372    ret = poll(pollFdArr,numFds,timeout);
373    if (ret == 0)
374    { 
375       RETVALUE(RTIMEOUT);
376    }
377    if (ret == INET_ERR)
378    {
379       switch(INET_ERR_CODE)
380       {
381          case ERR_EINTR:
382             RETVALUE(ROKDNA);
383
384          default:
385 #ifdef CMINETDBG
386             /* cm_inet_c_001.main_62:Warning fix */
387             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "File: %s, cmInetPoll() failed on line: %d \n\
388                     error(%d)\n", __FILE__, __LINE__, INET_ERR_CODE);
389             SPrint(prntBuf);
390 #endif /* CMINETDBG */
391             RETVALUE(RFAILED);
392
393       } /* end of switch */
394    }
395    
396    *numRdyFds = (S16)ret;
397   
398    RETVALUE(ROK);
399
400 }
401
402 /*
403 *
404 *      Fun:   cmInetPollSetFd
405 *
406 *      Desc:  Set the selected fd in pollFdArr with event eventMask
407 *
408 *      Ret:   RFAILED : if file descriptor is out of range
409 *             ROK     : if pollFdArr is set.
410 *
411 *      Notes: None
412 *
413 *      File:  cm_inet.c
414 *
415 */
416
417 #ifdef ANSI
418 PUBLIC S16 cmInetPollSetFd
419 (
420 CmInetFd         *sockFd,               /* socket file descriptor */
421 CmInetPollFd  *pollFdArr,               /* poll FD Array */
422 S16               idx,                  /* poll Fd Array Index */
423 U16               eventMask             /* Event Mask to be set */
424 )
425 #else
426 PUBLIC S16 cmInetPollSetFd(sockFd,pollFdArr,idx,eventMask)
427 CmInetFd         *sockFd;               /* socket file descriptor */
428 CmInetPollFd  *pollFdArr;               /* poll FD Array */
429 S16              idx;                   /* poll Fd Array Index */
430 U16              eventMask;             /* Event Mask to be set */
431 #endif
432 {
433    
434    TRC2(cmInetPollSetFd); 
435
436    if ((idx) >= CM_INET_POLL_MAXFDSUPP || (idx) < 0)
437    {
438 #ifdef CMINETDBG
439       /* cm_inet_c_001.main_62:Warning fix */
440       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid idx(%d) \n",idx);
441       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
442 #endif /* CMINETDBG */
443
444       RETVALUE(RFAILED);
445    }
446
447 #if (ERRCLASS & ERRCLS_INT_PAR)
448       /* error check on parameters */
449       if (pollFdArr == NULLP)
450       {
451 #ifdef CMINETDBG
452       /* cm_inet_c_001.main_62:Warning fix */
453       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid Parameter (pollFdArr is NULL)");
454       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
455 #endif /* CMINETDBG */      
456          RETVALUE(RFAILED);
457       }
458 #endif /* ERRCLASS & ERRCLS_INT_PAR */
459
460 #ifdef CMINETDBG
461 #ifndef ALIGN_64BIT
462       /* cm_inet_c_001.main_62:Warning fix */
463       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, 
464                "cmInetPollSetFd() Before Setting fd : sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set   fd(%ld) event(%d) \n",
465                pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
466       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf); 
467 #else
468       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,
469                "cmInetPollSetFd() Before Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set   fd(%d) event(%d) \n",
470                pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
471       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
472 #endif /*ALIGN_64BIT */
473 #endif /* CMINETDBG */
474
475 /* Setting fd and events with eventMask */
476    pollFdArr[idx].fd = sockFd->fd;
477    pollFdArr[idx].events |= eventMask;
478
479
480 #ifdef CMINETDBG
481 #ifndef ALIGN_64BIT
482       /* cm_inet_c_001.main_62:Warning fix */
483       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
484             pollFdArr[idx].fd,idx, pollFdArr[idx].events);
485       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
486 #else
487       /* cm_inet_c_001.main_62:Warning fix */
488       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
489             pollFdArr[idx].fd,idx, pollFdArr[idx].events);
490       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
491 #endif /*ALIGN_64BIT */
492 #endif /* CMINETDBG */
493
494    RETVALUE(ROK);
495
496 }
497
498
499 /*
500 *
501 *      Fun:   cmInetPollFdIsSet
502 *
503 *      Desc:  Checks whether fd is selected
504 *
505 *      Ret:   TRUE : If Fd is Selected
506 *             FALSE: If Fd is not Selected
507 *
508 *      Notes: None
509 *
510 *      File:  cm_inet.c
511 *
512 */
513
514 #ifdef ANSI
515 PUBLIC S16 cmInetPollFdIsSet
516 (
517 CmInetPollFd  *pollFdArr,            /* poll FD Array */
518 S16               idx,               /* poll Fd Array Index */
519 U16               eventMask          /* Event Mask to be set */
520 )
521 #else
522 PUBLIC S16 cmInetPollFdIsSet(pollFdArr,idx,eventMask)
523 CmInetPollFd  *pollFdArr;            /* poll FD Array */
524 S16               idx;               /* poll Fd Array Index */
525 U16               eventMask;         /* Event Mask to be set */
526 #endif
527 {
528    S16  ret;
529
530    TRC2(cmInetPollFdIsSet); 
531
532    if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
533    {
534 #ifdef CMINETDBG
535       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Index (%d) \n",idx);
536       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
537 #endif /* CMINETDBG */
538       RETVALUE(RFAILED);
539    }
540
541 #if (ERRCLASS & ERRCLS_INT_PAR)
542       /* error check on parameters */
543       if (pollFdArr == NULLP)
544       {
545 #ifdef CMINETDBG
546       /* cm_inet_c_001.main_62:Warning fix */
547       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Parameter (pollFdArr is NULL)");
548       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
549 #endif /* CMINETDBG */      
550          RETVALUE(RFAILED);
551       }
552 #endif /* ERRCLASS & ERRCLS_INT_PAR */
553
554    ret = (pollFdArr[idx].revents & eventMask);
555
556    RETVALUE(ret);
557 }
558
559 /*
560 *
561 *      Fun:   cmInetPollClearFdREvent
562 *
563 *      Desc:  clears the reventMask in revent of the givent FD.
564 *
565 *      Ret:   ROK
566 *             
567 *
568 *      Notes: None
569 *
570 *      File:  cm_inet.c
571 *
572 */
573
574 #ifdef ANSI
575 PUBLIC S16 cmInetPollClearFdREvent
576 (
577 CmInetPollFd  *pollFdArr,            /* poll FD Array */
578 S16               idx,               /* poll Fd Array Index */
579 U16               eventMask          /* Event Mask to be set */
580 )
581 #else
582 PUBLIC S16 cmInetPollClearFdREvent(sockFd,pollFdArr,eventMask)
583 CmInetPollFd  *pollFdArr;            /* poll FD Array */
584 S16               idx;               /* poll Fd Array Index */
585 U16               eventMask;         /* Event Mask to be set */
586 #endif
587 {
588
589    TRC2(cmInetPollClearFdREvent); 
590
591
592    if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
593    {
594 #ifdef CMINETDBG
595       /* cm_inet_c_001.main_62:Warning fix */
596       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Index (%d) \n",idx);
597       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
598 #endif /* CMINETDBG */
599       RETVALUE(RFAILED);
600    }
601
602 #if (ERRCLASS & ERRCLS_INT_PAR)
603       /* error check on parameters */
604       if (pollFdArr == NULLP)
605       {
606 #ifdef CMINETDBG
607       /* cm_inet_c_001.main_62:Warning fix */
608       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Parameter (pollFdArr is NULL)");
609       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
610 #endif /* CMINETDBG */      
611          RETVALUE(RFAILED);
612       }
613 #endif /* ERRCLASS & ERRCLS_INT_PAR */
614
615 #ifdef CMINETDBG
616 #ifndef ALIGN_64BIT
617       /* cm_inet_c_001.main_62:Warning fix */
618       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
619             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
620       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
621 #else
622       /* cm_inet_c_001.main_62:Warning fix */
623       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
624             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
625       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
626 #endif /*ALIGN_64BIT */
627 #endif /* CMINETDBG */
628
629 /* Clearing the events with eventMask */
630    pollFdArr[idx].revents = (pollFdArr[idx].revents & (~(eventMask)));
631
632 #ifdef CMINETDBG
633 #ifndef ALIGN_64BIT
634       /* cm_inet_c_001.main_62:Warning fix */
635       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
636             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
637       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
638 #else
639       /* cm_inet_c_001.main_62:Warning fix */
640       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
641             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
642       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
643 #endif /*ALIGN_64BIT */
644 #endif /* CMINETDBG */
645
646    RETVALUE(ROK);
647
648 }
649
650
651 /*
652 *
653 *      Fun:   cmInetPollClearFdEvent
654 *
655 *      Desc:  clears the eventMask in event of the givent FD.
656 *
657 *      Ret:   ROK
658 *             
659 *
660 *      Notes: None
661 *
662 *      File:  cm_inet.c
663 *
664 */
665
666 #ifdef ANSI
667 PUBLIC S16 cmInetPollClearFdEvent
668 (
669 CmInetPollFd  *pollFdArr,            /* poll FD Array */
670 S16               idx,               /* poll Fd Array Index */
671 U16               eventMask          /* Event Mask to be set */
672 )
673 #else
674 PUBLIC S16 cmInetPollClearFdEvent(sockFd,pollFdArr,eventMask)
675 CmInetPollFd   *pollFdArr;            /* poll FD Array */
676 S16             idx;                  /* poll Fd Array Index */
677 U16             eventMask;            /* Event Mask to be set */
678 #endif
679 {
680
681    TRC2(cmInetPollClearFdEvent); 
682
683
684    if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
685    {
686 #ifdef CMINETDBG
687       /* cm_inet_c_001.main_62:Warning fix */
688       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Index (%d) \n",idx);
689       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
690 #endif /* CMINETDBG */
691       RETVALUE(RFAILED);
692    }
693
694 #if (ERRCLASS & ERRCLS_INT_PAR)
695       /* error check on parameters */
696       if (pollFdArr == NULLP)
697       {
698 #ifdef CMINETDBG
699       /* cm_inet_c_001.main_62:Warning fix */
700       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Parameter (pollFdArr is NULL)");
701       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
702 #endif /* CMINETDBG */      
703          RETVALUE(RFAILED);
704       }
705 #endif /* ERRCLASS & ERRCLS_INT_PAR */
706
707 #ifdef CMINETDBG
708 #ifndef ALIGN_64BIT
709       /* cm_inet_c_001.main_62:Warning fix */
710       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask: \n sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
711             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
712       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
713 #else
714       /* cm_inet_c_001.main_62:Warning fix */
715       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask:\n  sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
716             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
717       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
718 #endif /*ALIGN_64BIT */
719 #endif /* CMINETDBG */
720
721 /* Clearing events with eventMask */
722    pollFdArr[idx].events = (pollFdArr[idx].events & (~(eventMask)));
723
724 #ifdef CMINETDBG
725 #ifndef ALIGN_64BIT
726       /* cm_inet_c_001.main_62:Warning fix */
727       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
728             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
729       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
730 #else
731       /* cm_inet_c_001.main_62:Warning fix */
732       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
733             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
734       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
735 #endif /*ALIGN_64BIT */
736 #endif /* CMINETDBG */
737
738    RETVALUE(ROK);
739
740 }
741
742
743 /*
744 *
745 *      Fun:   cmInetPollDelFd
746 *
747 *      Desc:  Delete the given FD from the pollFdArray
748 *             delIdx : Poll Fd Array Index at which fd has to be deleted.
749 *             lastIdx: Last index of poll fd array.
750 *
751 *             It deletes fd from array by swapping lastIdx pollFd
752 *             values to index to be deleted and deinitializes the 
753 *             lastIdx values.
754 *
755 *      Ret:   ROK
756 *             
757 *
758 *      Notes: It does not decrement the lastIdx and it has to be 
759 *             decremented by the caller of this function.
760 *
761 *      File:  cm_inet.c
762 *
763 */
764
765 #ifdef ANSI
766 PUBLIC S16 cmInetPollDelFd
767 (
768 CmInetPollFd  *pollFdArr,             /* poll FD Array */
769 S16               delIdx,             /* poll Fd Array Index for which fd has to be deleted*/
770 S16               lastIdx             /* Last index of poll Fd Array */
771 )
772 #else
773 PUBLIC S16 cmInetPollDelFd(pollFdArr, delIdx, lastIdx)
774 CmInetPollFd  *pollFdArr;            /* poll FD Array */
775 S16               delIdx;            /* poll Fd Array Index for which fd has to be deleted*/
776 S16               lastIdx;           /* Last index of poll Fd Array */
777 #endif
778 {
779
780    TRC2(cmInetPollDelFd); 
781
782    if(lastIdx < delIdx || lastIdx < 0 || delIdx < 0)
783    {
784 #ifdef CMINETDBG
785       /* cm_inet_c_001.main_62:Warning fix */
786       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Index \n Current Index (%d) Delete Index (%d) \n",lastIdx,delIdx);
787       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
788 #endif /* CMINETDBG */
789       RETVALUE(RFAILED);
790    }
791
792
793 #if (ERRCLASS & ERRCLS_INT_PAR)
794       /* error check on parameters */
795       if (pollFdArr == NULLP)
796       {
797 #ifdef CMINETDBG
798       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Parameter (pollFdArr is NULL)");
799       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
800 #endif /* CMINETDBG */      
801          RETVALUE(RFAILED);
802       }
803 #endif /* ERRCLASS & ERRCLS_INT_PAR */
804
805 #ifdef CMINETDBG
806 #ifndef ALIGN_64BIT
807       /* cm_inet_c_001.main_62:Warning fix */
808       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() Deleting the sockFd->fd(%d) Index(%d) Event(%d) revent(%d) \n",
809             pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
810       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
811 #else
812       /* cm_inet_c_001.main_62:Warning fix */
813       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
814             pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
815       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
816 #endif /*ALIGN_64BIT */
817 #endif /* CMINETDBG */
818
819    pollFdArr[delIdx].fd = pollFdArr[lastIdx].fd;
820    pollFdArr[delIdx].events = pollFdArr[lastIdx].events;
821    pollFdArr[delIdx].revents = pollFdArr[lastIdx].revents;
822
823    pollFdArr[lastIdx].fd = -1;
824    pollFdArr[lastIdx].events = 0;
825    pollFdArr[lastIdx].revents = 0;
826    
827    RETVALUE(ROK);
828
829 }
830
831 /*
832 *
833 *      Fun:   cmInetPollInitFdArr
834 *
835 *      Desc: Cleans all elements of fd array. 
836 *
837 *      Ret:   ROK
838 *             
839 *
840 *      Notes:  It does not allocates/deallocates memory for Poll Fd Array.
841 *              Caller of function has to allocate/deallocate memory for 
842 *              array.
843 *
844 *      File:  cm_inet.c
845 *
846 */
847
848 #ifdef ANSI
849 PUBLIC S16 cmInetPollInitFdArr
850 (
851 CmInetPollFd  *pollFdArr             /* poll FD Array */
852 )
853 #else
854 PUBLIC S16 cmInetPollInitFdArr(pollFdArr)
855 CmInetPollFd  *pollFdArr;            /* poll FD Array */
856 #endif
857 {
858    S16 idx;
859
860    TRC2(cmInetPollInitFdArr); 
861 /* Sets each element of pollFdArr to initial value
862    fd = -1
863    events = 0
864    revents = 0
865 */
866 #if (ERRCLASS & ERRCLS_INT_PAR)
867       /* error check on parameters */
868       if (pollFdArr == NULLP)
869       {
870 #ifdef CMINETDBG
871       /* cm_inet_c_001.main_62:Warning fix */
872       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollInitFdArr() : Invalid Parameter (pollFdArr is NULL)");
873       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
874 #endif /* CMINETDBG */      
875          RETVALUE(RFAILED);
876       }
877 #endif /* ERRCLASS & ERRCLS_INT_PAR */
878
879    for(idx=0; idx < CM_INET_POLL_MAXFDSUPP; idx++)
880    {
881       pollFdArr[idx].fd = -1;
882       pollFdArr[idx].events = 0;
883       pollFdArr[idx].revents = 0;
884    }
885    RETVALUE(ROK);
886 }
887
888 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
889 /*
890 *
891 *      Fun:   buildRecvBuf
892 *
893 *      Desc:  Allocates dBufs to receive an entire message.
894 *
895 *      Ret:   ROK     - successful
896 *             RFAILED - failed
897 *             ROUTRES - failed, out of resources
898 *
899 *      Notes: None
900 *
901 *      File:  cm_inet.c
902 *
903 */
904
905 #ifdef ANSI
906 PRIVATE S16 buildRecvBuf
907 (
908 CmInetMemInfo  *info,           /* buffer allocation info */
909 MsgLen          len,            /* message length */
910 CmInetIovec     rxArr[],        /* gather array */
911 Buffer         *dBuf[],         /* allocated dBufs */
912 U16             maxSize,        /* size of rxArr/dBuf array */       
913 struct msghdr  *msg,            /* message header for recvmsg() */           
914 Bool           isStrmMsg        /* Is a TCP message */
915 )
916 #else
917 PRIVATE S16 buildRecvBuf(info, len, rxArr, dBuf, maxSize, msg, isStrmMsg)
918    CmInetMemInfo   *info;          /* buffer allocation info */
919    MsgLen           len;           /* message length */        
920    CmInetIovec      rxArr[];       /* gather array */         
921    Buffer          *dBuf[];        /* allocated dBufs */
922    U16              maxSize;       /* size of rxArr/dBuf array */       
923    struct msghdr   *msg;           /* message header for recvmsg() */        
924    Bool            isStrmMsg;      /* Is a TCP message */
925 #endif
926 {
927    S16     ret;                 /* temporary return value */
928    U16     numBuf;              /* number of dBufs */
929    U16     i;                   /* dBuf index counter */
930    Data   *dPtr;                /* data pointer */
931    /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
932    MsgLen  bufLen;              /* entire receive buffer length, if S16 
933                                    could wrap to negative number */
934    MsgLen  dLen;                /* buffer length */ 
935
936    numBuf = 0;
937    bufLen = 0; 
938
939    /* Initialise ret and part of msg here */
940    ret = ROK;
941
942    /* added defined(_XPG4_2) */
943    /* Moved initialisation of msg here. */
944
945 #if (defined(SS_LINUX) || defined(_XPG4_2))
946    msg->msg_control    = NULLP;
947    msg->msg_controllen  = 0;
948 #else
949    msg->msg_accrights     = NULLP;
950    msg->msg_accrightslen  = 0;
951 #endif /* SS_LINUX */   
952
953    /* Check if maxSize if enough to hold the entire message length before 
954     * going into the loop. If the boolean isStrmMsg is TRUE then the recv 
955     * buf is built even if the whole message cannot be accomodated. */
956
957 #ifdef T2K_MEM_LEAK_DBG
958    char * file = __FILE__;
959    U32  line   = __LINE__;
960    ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]); 
961 #else
962    ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]); 
963 #endif
964    if (ret != ROK)
965       RETVALUE(ret);
966
967    /* Get the data part */
968    ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
969    if (ret != ROK)
970    {
971       numBuf++;           /* because of cleanup */
972       goto cleanup;
973    }
974
975    if (!isStrmMsg)
976    {
977       /* The assumption here is that all dBuf's from a given region and 
978        * pool have a constance size */
979       if (len > (maxSize * dLen))
980       {
981          ret = RNA;
982          numBuf++;           /* because of cleanup */
983          goto cleanup;
984       }
985    }
986
987 #ifdef SS_LINUX
988   rxArr[numBuf].iov_base = (Void*)dPtr;  
989   rxArr[numBuf].iov_len = (U32)dLen;    
990 #else
991   rxArr[numBuf].iov_base = (S8*)dPtr;
992   rxArr[numBuf].iov_len = dLen;
993 #endif /* SS_LINUX */
994
995   bufLen += dLen;
996   numBuf++;  
997
998    /* allocate buffer space for entire message length */
999    while (bufLen < len)
1000    {
1001       if (numBuf >= maxSize)
1002       {
1003          /* to big to fit in gather vector array */ 
1004          ret = RNA;
1005          break;
1006       }
1007       ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]); 
1008       if (ret != ROK)
1009       {
1010          goto cleanup;
1011       } 
1012       ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
1013       if (ret != ROK)
1014       {
1015          numBuf++;           /* because of cleanup */
1016          goto cleanup;
1017       }
1018 #ifdef SS_LINUX
1019       rxArr[numBuf].iov_base = (Void*)dPtr;  
1020       rxArr[numBuf].iov_len = (U32)dLen;    
1021 #else
1022       rxArr[numBuf].iov_base = (S8*)dPtr;
1023       rxArr[numBuf].iov_len = dLen;
1024 #endif /* SS_LINUX */
1025
1026       bufLen += dLen;
1027       numBuf++;  
1028    }
1029    /* adjust last buffer length */
1030    /*  check if we broke out because numBuf >= maxSize */
1031    if (bufLen < len)
1032       rxArr[numBuf - 1].iov_len = dLen;
1033    else
1034       rxArr[numBuf - 1].iov_len = dLen - (bufLen - len); 
1035
1036    /* setup recvmsg() message header */
1037    msg->msg_iov           = rxArr;
1038    msg->msg_iovlen        = numBuf;
1039
1040    RETVALUE(ret);
1041
1042 cleanup:
1043    /* cleanup */
1044    for (i = 0; i < numBuf; i++)
1045       SPutDBuf(info->region, info->pool, dBuf[i]);
1046
1047    msg->msg_iovlen = 0;
1048
1049    RETVALUE(ret);
1050 } /* end of buildRecvBuf */
1051
1052 /*
1053 *
1054 *      Fun:   buildRecvMsg
1055 *
1056 *      Desc:  Builds a message out of the received dBufs.
1057 *
1058 *      Ret:   ROK     - successful
1059 *             RFAILED - failed
1060 *             ROUTRES - failed, out of resources
1061 *
1062 *      Notes: None
1063 *
1064 *      File:  cm_inet.c
1065 *
1066 */
1067
1068 #ifdef ANSI
1069 PRIVATE S16 buildRecvMsg
1070 (
1071 CmInetMemInfo  *info,           /* buffer allocation info */
1072 CmInetIovec     rxArr[],        /* scatter array */  
1073 S16             numBuf,         /* number of allocated dBufs */
1074 MsgLen          msgLen,         /* message length */
1075 Buffer         *dBufs[],        /* dBufs */
1076 Buffer        **mPtr            /* message built from dBufs */     
1077 )
1078 #else
1079 PRIVATE S16 buildRecvMsg(info, rxArr, numBuf, msgLen, dBufs, mPtr)
1080 CmInetMemInfo  *info;           /* buffer allocation info */   
1081 CmInetIovec     rxArr[];        /* scatter array */            
1082 S16             numBuf;         /* number of allocated dBufs */
1083 MsgLen          msgLen;         /* length of one particular dBuf */          
1084 Buffer         *dBufs[];        /* dBufs */
1085 Buffer        **mPtr;           /* message built from dBufs */   
1086 #endif
1087 {
1088    S16      ret;                 /* return value */ 
1089    S16      i;                   /* dBuf index counter */
1090    MsgLen   bufLen;              /* length of one particular dBuf */
1091    /* cm_inet_c_001.main_54: Fix for Klockworks issue */
1092    Buffer  *mBuf = NULLP;        /* allocated message */  
1093
1094    ret = RFAILED;   
1095    i   = 0;
1096
1097    /* build message */
1098    ret = SGetMsg(info->region, info->pool, &mBuf);
1099    if (ret != ROK)
1100    {
1101       goto cleanup;
1102    }
1103
1104    /* link buffers to message */
1105    while (i < numBuf)
1106    {
1107       /* cm_inet_c_001.main_58: fix for klockwork issue */
1108       bufLen = (MsgLen)rxArr[i].iov_len; 
1109       if (msgLen < bufLen)
1110       {
1111          bufLen = msgLen;
1112       }
1113       ret = SUpdMsg(mBuf, dBufs[i], bufLen);
1114       if (ret != ROK)
1115       { 
1116          SPutMsg(mBuf);
1117          goto cleanup;
1118       }
1119       msgLen -= bufLen;
1120       i++;
1121       if (msgLen <= 0)
1122       {
1123          ret = ROK;      
1124          break;
1125       }
1126    }
1127
1128    *mPtr = mBuf;
1129
1130 cleanup:
1131    /* cleanup unused buffers */
1132    while (i < numBuf)
1133    {
1134 #ifdef T2K_MEM_LEAK_DBG
1135    char * file = __FILE__;
1136    U32  line   = __LINE__;
1137    SPutDBuf(info->region, info->pool, dBufs[i]);
1138 #else
1139    SPutDBuf(info->region, info->pool, dBufs[i]);
1140 #endif
1141     i++;
1142    }
1143
1144    RETVALUE(ret);
1145 } /* end of buildRecvMsg */
1146
1147 \f
1148
1149 /*
1150 *
1151 *      Fun:   buildSendIovec 
1152 *
1153 *      Desc:  Builds a io vector to send a message.
1154 *
1155 *      Ret:   ROK     - successful
1156 *             RFAILED - failed
1157 *             ROUTRES - failed, out of resources
1158 *             RNA     - failed, not available, indicates that the
1159 *                       maximum number of dBufs are not sufficient
1160 *                       to hold the entire message.
1161 *
1162 *      Notes: None
1163 *
1164 *      File:  cm_inet.c
1165 *
1166 */
1167 #ifdef ANSI
1168 PRIVATE S16 buildSendIovec
1169 (
1170 Buffer         *mBuf,           /* Message buffer */
1171 MsgLen         msgLen,          /* Length of mBuf */
1172 CmInetIovec    txArr[],         /* transmit scatter vector array */ 
1173 S16            numDBufs,        /* Maximum number of dBufs to use */
1174 S16            *numIovElems,    /* Number of iov elements in array */
1175 U32            *strtEndDBufNum, /* dBuf number to start and end */
1176 MsgLen         *ioLen           /* cm_inet_c_001.main_50 - Len of dbuf packed into IO-vector */ 
1177 )
1178 #else
1179 PRIVATE S16 buildSendIovec(mBuf, msgLen, txArr, numDBufs, numIovElems, 
1180                            strtEndDBufNum,ioLen) 
1181 Buffer         *mBuf;           /* Message buffer */
1182 MsgLen         msgLen;          /* Length of mBuf */
1183 CmInetIovec    txArr[];         /* transmit scatter vector array */ 
1184 S16            numDBufs;        /* Maximum number of dBufs to use */
1185 S16            *numIovElems;    /* Number of iov elements in array */
1186 U32            *strtEndDBufNum; /* dBuf number to start and end */
1187 MsgLen         *ioLen;          /* cm_inet_c_001.main_50 - Len of dbuf packed into IO-vector */ 
1188 #endif
1189 {
1190    S16         ret;
1191    MsgLen      dLen;
1192    S16         iovIdx;       
1193    Buffer      *dBuf;
1194    Data        *dPtr;
1195    MsgLen      allocLen;
1196    U32         dBufsToSkip;
1197
1198    /* Initialisations */
1199    (*numIovElems) = 0;
1200    iovIdx = 0;
1201    allocLen = 0;
1202
1203    /* cm_inet_c_001.main_50 - Intialize the newly added parameter */
1204    *ioLen = 0;
1205
1206    /* Set up vector for gathering send */
1207    ret = SInitNxtDBuf(mBuf);
1208    if (ret != ROK)
1209    {
1210       RETVALUE(RFAILED);
1211    }
1212
1213    iovIdx = 0;
1214    txArr[iovIdx].iov_len = 0;
1215
1216    if ((*strtEndDBufNum != 0))
1217    {
1218       /* Skip through the required number of dBufs */
1219       dBufsToSkip = *strtEndDBufNum;
1220
1221       while(dBufsToSkip)
1222       {
1223          ret = SGetNxtDBuf(mBuf, &dBuf);
1224          if (ret != ROK)
1225             RETVALUE(RFAILED);
1226          dBufsToSkip --;
1227       }
1228    }
1229
1230    for (;;)
1231    {
1232       ret = SGetNxtDBuf(mBuf, &dBuf);
1233       if (ret == ROK)
1234       {
1235          ret = SGetDataTx(dBuf, &dPtr, &dLen);
1236          if (ret != ROK)
1237          {  
1238             ret = RFAILED;
1239             break;
1240          }
1241
1242          txArr[iovIdx].iov_base = (S8 *)dPtr;
1243          txArr[iovIdx].iov_len = dLen;
1244
1245          allocLen += dLen;
1246       }
1247       else if  (ret == ROKDNA)
1248       {  
1249          ret = ROK;
1250          break;
1251       }
1252       else
1253       {
1254          ret = RFAILED;
1255          break;
1256       }
1257
1258       iovIdx += 1;
1259
1260       if (iovIdx >= numDBufs)
1261       {
1262          if (allocLen >= msgLen)
1263             ret = ROK;
1264          else
1265             ret = RNA;
1266          break;
1267       }
1268    }
1269
1270    (*numIovElems) = iovIdx;
1271    (*strtEndDBufNum) += iovIdx;
1272
1273    /* cm_inet_c_001.main_50 - Assign the value of dbufs packed in IO-vector */
1274    *ioLen = allocLen;
1275
1276    RETVALUE(ret);
1277
1278 } /* end of buildSendIovec */
1279 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
1280
1281 \f
1282 /*
1283 *
1284 *      Fun:   cmInetSocket
1285 *
1286 *      Desc:  Creates an Internet socket descriptor.
1287 *             On default the socket is non-blocking ( can be changed 
1288 *             with the function cmInetSetOpt()).
1289 *             Values for type:
1290 *
1291 *             CM_INET_STREAM   (TCP)
1292 *             CM_INET_DGRAM    (UDP)
1293 *
1294 *      Ret:   ROK     - successful
1295 *             RFAILED - failed
1296 *
1297 *      Notes: None
1298 *
1299 *      File:  cm_inet.c
1300 *
1301 */
1302 #ifdef ANSI
1303 #ifdef CM_INET2  
1304 #ifdef IPV6_SUPPORTED
1305 PUBLIC S16 cmInetSocket
1306 (
1307 U8        type,                 /* socket type */
1308 CmInetFd *sockFd,               /* socket file descriptor */
1309 U8       protocol,              /* protocol value */
1310 U8       domain                 /* domain */
1311 )
1312 #else
1313 PUBLIC S16 cmInetSocket
1314 (
1315 U8        type,                 /* socket type */
1316 CmInetFd *sockFd,               /* socket file descriptor */
1317 U8       protocol               /* protocol value */
1318 )
1319 #endif /* IPV6_SUPPORTED */
1320 #else   /* CM_INET2 */ 
1321 PUBLIC S16 cmInetSocket
1322 (
1323 U8        type,                 /* socket type */
1324 CmInetFd *sockFd                /* socket file descriptor */
1325 )
1326 #endif /* CM_INET2 */ 
1327 #else
1328 #ifdef CM_INET2  
1329 #ifdef IPV6_SUPPORTED
1330 PUBLIC S16 cmInetSocket(type, sockFd, protocol, domain)
1331 U8        type;                 /* socket type */
1332 CmInetFd *sockFd;               /* socket file descriptor */
1333 U8        protocol;             /* protocol value */
1334 U8        domain;               /* domain */
1335 #else
1336 PUBLIC S16 cmInetSocket(type, sockFd, protocol)
1337 U8        type;                 /* socket type */
1338 CmInetFd *sockFd;               /* socket file descriptor */
1339 U8        protocol;             /* protocol value */
1340 #endif /* IPV6_SUPPORTED */
1341 #else /* CM_INET2 */ 
1342 PUBLIC S16 cmInetSocket(type, sockFd)
1343 U8        type;                 /* socket type */
1344 CmInetFd *sockFd;               /* socket file descriptor */
1345 #endif /* CM_INET2 */ 
1346 #endif /* ANSI */
1347 {
1348    S32 ret;                     /* temporary return value */
1349
1350    U32 optVal;
1351
1352 #if (defined(WIN32) && defined(WIN2K))
1353    S32 bytesReturned;
1354    Bool bNewBehavior;
1355 #endif /* WIN2K && WIN32 */
1356
1357    TRC2(cmInetSocket);
1358
1359 #if (defined(WIN32) && defined(WIN2K))
1360    bytesReturned = 0;
1361    bNewBehavior = FALSE;
1362 #endif /* WIN32 && WIN2K */  
1363
1364    /* create socket */
1365 #ifdef CM_INET2  
1366 #ifdef IPV6_SUPPORTED
1367    sockFd->fd = socket(domain, type, protocol);
1368 #else
1369    sockFd->fd = socket(AF_INET, type, protocol);
1370 #endif /* IPV6_SUPPORTED */
1371 #else   /* CM_INET2 */ 
1372    sockFd->fd = socket(AF_INET, type, 0);
1373 #endif  /* CM_INET2 */ 
1374    if (CM_INET_INV_SOCK_FD(sockFd))
1375    {   
1376 #ifdef CMINETDBG
1377 #ifndef ALIGN_64BIT
1378       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1379       /* cm_inet_c_001.main_62:Warning fix */
1380       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%ld)\n", 
1381             INET_ERR_CODE, sockFd->fd);
1382       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1383 #else
1384       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%d)\n", 
1385             INET_ERR_CODE, sockFd->fd);
1386       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1387 #endif /*ALIGN_64BIT */
1388 #endif /* CMINETDBG */
1389       /* Set sockFd->fd to invalid socket */
1390       sockFd->fd = CM_INET_INV_SOCKFD;
1391       RETVALUE(RFAILED);   
1392    }
1393
1394    /* set socket type */
1395    sockFd->type = type;
1396
1397    /* set socket protocol type (IPv4/IPv6) */
1398 #ifdef IPV6_SUPPORTED   
1399    sockFd->protType = domain; 
1400 #endif /* IPV6_SUPPORTED */
1401
1402    /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1403 #ifdef CM_LKSCTP
1404    if (protocol != IPPROTO_SCTP)
1405    {
1406 #endif
1407    /* set default options */
1408    optVal = CM_INET_OPT_DISABLE;
1409    ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal); 
1410    if (ret != ROK) 
1411    {
1412       ret = cmInetClose(sockFd);
1413       RETVALUE(RFAILED);
1414    }
1415
1416 #ifdef SS_LINUX
1417 #ifndef CMINET_BSDCOMPAT
1418    optVal = CM_INET_OPT_ENABLE;
1419    ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BSD_COMPAT, (Ptr)&optVal);
1420    if (ret != ROK) 
1421    {
1422       ret = cmInetClose(sockFd);
1423       RETVALUE(RFAILED);
1424    }
1425 #endif /* CMINET_BSDCOMPAT */
1426 #endif /* SS_LINUX */
1427
1428 #if (defined(WIN32) && defined(WIN2K))   
1429    if(type == CM_INET_DGRAM)
1430       {
1431          ret = WSAIoctl(sockFd->fd, SIO_UDP_CONNRESET, &bNewBehavior,
1432                sizeof(bNewBehavior), NULLP, 0, &bytesReturned,
1433                NULLP, NULLP);
1434          if(ret == INET_ERR)
1435          {
1436 #ifdef CMINETDBG
1437 #ifndef ALIGN_64BIT
1438             /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1439             /* cm_inet_c_001.main_62:Warning fix */
1440             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%ld)\n", 
1441                   INET_ERR_CODE, sockFd->fd);
1442             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1443 #else
1444             /* cm_inet_c_001.main_62:Warning fix */
1445             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%d)\n", 
1446                   INET_ERR_CODE, sockFd->fd);
1447             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1448 #endif /*ALIGN_64BIT*/
1449 #endif /* CMINETDBG */      
1450             ret = cmInetClose(sockFd);
1451             RETVALUE(RFAILED);
1452          }
1453       }
1454 #endif /* WIN2K && WIN32 */   
1455       /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1456 #ifdef CM_LKSCTP
1457    }
1458 #ifdef CM_LKSCTP_NONBLOCK
1459    else
1460    {
1461       /* cm_inet_c_001.main_47:if non-blocking SCTP socket compile time
1462        *        * flag is set then even for kernel SCTP make the socket
1463        *               * non-blocking
1464        *                      */
1465       optVal = CM_INET_OPT_DISABLE;
1466       ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1467       if (ret != ROK)
1468       {
1469          ret = cmInetClose(sockFd);
1470          RETVALUE(RFAILED);
1471       }
1472    }
1473 #endif  /* CM_LKSCTP_NONBLOCK ends */
1474 #endif
1475    RETVALUE(ROK);
1476 } /* end of cmInetSocket */
1477
1478 \f
1479 /*
1480 *
1481 *      Fun:   cmInetBind 
1482 *
1483 *      Desc:  Binds a socket file descriptor to a local Internet 
1484 *             address/port.
1485 *
1486 *      Ret:   ROK     - successful
1487 *             RFAILED - failed
1488 *
1489 *      Notes: None.
1490 *
1491 *      File:  cm_inet.c
1492 *
1493 */
1494
1495 #ifdef ANSI
1496 PUBLIC S16 cmInetBind
1497 (
1498 CmInetFd   *sockFd,             /* socket file descriptor */ 
1499 CmInetAddr *myAddr              /* locale Internet address/port */
1500 )
1501 #else
1502 PUBLIC S16 cmInetBind(sockFd, myAddr)
1503 CmInetFd   *sockFd;             /* socket file descriptor */ 
1504 CmInetAddr *myAddr;             /* locale Internet address/port */
1505 #endif
1506 {
1507    S32 ret;                     /* temporary return value */
1508    struct sockaddr_in srcAddr;  /* local Internet address/port */
1509 #ifdef IPV6_SUPPORTED 
1510    struct sockaddr_in6 srcAddr6; /* local IPV6 address/port */
1511 #ifdef CMINETDBG
1512    U16    port;
1513 #endif /* CMINETDBG */
1514 #endif /* IPV6_SUPPORTED */
1515    U32    sizeOfAddr;            /* sizeof address passed to the bind call */
1516    CmInetSockAddr *sockAddrPtr; 
1517
1518    TRC2(cmInetBind);
1519
1520 #if (ERRCLASS & ERRCLS_INT_PAR)
1521    /* error check on parameters */
1522    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1523        (myAddr == NULLP))
1524    {
1525       RETVALUE(RFAILED);
1526    }
1527 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1528
1529 #ifdef IPV6_SUPPORTED 
1530    if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1531    {
1532       cmMemset((U8*)&srcAddr6, 0, sizeof(srcAddr6));
1533       srcAddr6.sin6_family      = AF_INET6;
1534       srcAddr6.sin6_port        = CM_INET_HTON_U16(myAddr->u.ipv6Addr.port);
1535       CM_INET_COPY_IPV6ADDR(&srcAddr6.sin6_addr, 
1536                             &myAddr->u.ipv6Addr.ipv6NetAddr);
1537       sizeOfAddr               = sizeof(struct sockaddr_in6);
1538       sockAddrPtr              = (CmInetSockAddr *)&srcAddr6;
1539    }
1540    else 
1541    {
1542       cmMemset((U8*)&srcAddr, 0, sizeof(srcAddr));
1543       srcAddr.sin_family      = AF_INET;
1544       srcAddr.sin_port        = CM_INET_HTON_U16(myAddr->u.ipv4Addr.port);
1545       srcAddr.sin_addr.s_addr = CM_INET_HTON_U32(myAddr->u.ipv4Addr.address);
1546       sizeOfAddr               = sizeof(struct sockaddr_in);
1547       sockAddrPtr              = (CmInetSockAddr *)&srcAddr;
1548    }
1549 #else 
1550    cmMemset((U8*)&srcAddr, 0, sizeof(srcAddr));
1551    srcAddr.sin_family      = AF_INET;
1552    srcAddr.sin_port        = CM_INET_HTON_U16(myAddr->port);
1553    srcAddr.sin_addr.s_addr = CM_INET_HTON_U32(myAddr->address);
1554    sizeOfAddr              = sizeof(struct sockaddr_in);
1555    sockAddrPtr             = (CmInetSockAddr *)&srcAddr;
1556 #endif /* IPV6_SUPPORTED */
1557
1558    ret = bind(sockFd->fd, sockAddrPtr, sizeOfAddr); 
1559    if (ret == INET_ERR)
1560    {
1561 #ifdef CMINETDBG
1562 #ifdef IPV6_SUPPORTED 
1563       if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1564          port = myAddr->u.ipv6Addr.port;
1565       else
1566          port = myAddr->u.ipv4Addr.port;
1567 #ifndef ALIGN_64BIT
1568       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1569       /* cm_inet_c_001.main_62:Warning fix */
1570       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d)," 
1571             " port(%d), sockFd->fd(%ld)\n", 
1572             INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1573       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1574 #else
1575       /* cm_inet_c_001.main_62:Warning fix */
1576       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d)," 
1577             " port(%d), sockFd->fd(%d)\n ", 
1578             INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1579       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1580 #endif /*ALIGN_64BIT*/
1581 #else
1582 #ifndef ALIGN_64BIT
1583       /* cm_inet_c_001.main_62:Warning fix */
1584       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%lx), port(%d),"
1585             "sockFd->fd(%ld)\n",
1586             INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1587       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1588 #else
1589       /* cm_inet_c_001.main_62:Warning fix */
1590       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%x), port(%d),"
1591             " sockFd->fd(%d)\n",
1592             INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1593       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1594 #endif /*ALIGN_64BIT*/
1595 #endif /* IPV6_SUPPORTED */
1596 #endif /* CMINETDBG */
1597       RETVALUE(RFAILED);
1598    }
1599
1600    RETVALUE(ROK); 
1601 } /* end of cmInetBind */
1602
1603 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1604 /* cm_inet_c_001.main_51 Added Ipv6 support to KSCtP implementation */
1605 #ifdef CM_LKSCTP
1606 /*
1607 *
1608 *      Fun:   cmInetSctpBindx 
1609 *
1610 *      Desc:  Binds a SCTP socket file descriptor to local Internet 
1611 *             address list
1612 *
1613 *      Ret:   ROK     - successful
1614 *             RFAILED - failed
1615 *
1616 *      Notes: None.
1617 *
1618 *      File:  cm_inet.c
1619 *
1620 */
1621 #ifdef ANSI
1622 PUBLIC S16 cmInetSctpBindx
1623 (
1624 CmInetFd          *sockFd,       /* socket file descriptor */ 
1625 CmInetNetAddrLst  *addrLst,      /* local Internet address list */
1626 U16                port          /* port number */
1627 )
1628 #else
1629 PUBLIC S16 cmInetSctpBindx(sockFd, addrLst, port)
1630 CmInetFd          *sockFd;       /* socket file descriptor */ 
1631 CmInetNetAddrLst  *addrLst;      /* locale Internet address list */
1632 U16                port;         /* port number */
1633 #endif
1634 {
1635    S32    ret;                     /* temporary return value */
1636    S32    idx;
1637    S32    idx4 = 0;
1638    U32    ipv4_array_size = 0;
1639    struct sockaddr_in  addrs[CM_INET_NUM_NET_ADDR];
1640 #ifndef IPV6_SUPPORTED
1641    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1642 #else
1643    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1644 #endif /* IPV6_SUPPORTED */
1645
1646 #ifdef SUN_KSCTP
1647    Data   *tempAddrPtr = NULLP;
1648 #endif 
1649    U32    addresses_array_size = 0;
1650 #ifdef IPV6_SUPPORTED 
1651 #ifdef SUN_KSCTP
1652    S8     *addrString = NULLP;
1653    U32    addrLen = 0;
1654    S8     ipv4Format[23] = "::ffff:";
1655 #endif /* SUN_KSCTP */
1656    S32    idx6 = 0;
1657    U32    ipv6_array_size = 0;
1658    struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1659 #endif /* IPV6_SUPPORTED */
1660    struct sockaddr *sockAddrPtr = NULLP;
1661    U32    sockAddrLen = 0;
1662
1663 #if (ERRCLASS & ERRCLS_INT_PAR)
1664    /* error check on parameters */
1665    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1666        (addrLst == NULLP))
1667    {
1668       RETVALUE(RFAILED);
1669    }
1670
1671    if(addrLst->count > CM_INET_NUM_NET_ADDR)
1672    {
1673 #ifdef CMINETDBG
1674 #ifndef ALIGN_64BIT
1675       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1676       /* cm_inet_c_001.main_62:Warning fix */
1677       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1678             " sockFd->fd(%ld)\n",
1679             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1680       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);   
1681 #else
1682       /* cm_inet_c_001.main_62:Warning fix */
1683       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1684             " sockFd->fd(%d)\n", 
1685             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1686       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);   
1687 #endif /*ALIGN_64BIT*/
1688 #endif /* CMINETDBG */
1689       RETVALUE(RFAILED);
1690    }
1691 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1692
1693    cmMemset((U8*)&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1694 #ifdef IPV6_SUPPORTED 
1695    cmMemset((U8*)&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1696 #endif /* IPV6_SUPPORTED */
1697
1698    for (idx = 0; idx < addrLst->count; idx++)
1699    {
1700 #ifdef IPV6_SUPPORTED 
1701       if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1702       {
1703          ipv6_array_size += sizeof(struct sockaddr_in6);
1704          addresses_array_size += sizeof(struct sockaddr_in6);
1705          if (sockFd->protType == AF_INET)
1706          {
1707 #ifdef CMINETDBG
1708 #ifndef ALIGN_64BIT
1709             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1710             /* cm_inet_c_001.main_62:Warning fix */
1711             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1712                   " sockFd->fd(%ld)\n", sockFd->fd);
1713             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1714 #else
1715            /* cm_inet_c_001.main_62:Warning fix */
1716             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket," 
1717                   " sockFd->fd(%d)\n", sockFd->fd);
1718             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1719 #endif /*ALIGN_64BIT*/
1720 #endif /* CMINETDBG */
1721             RETVALUE(RFAILED);
1722          }
1723
1724          addrs6[idx6].sin6_family      = AF_INET6;
1725          addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
1726          CM_INET_COPY_IPV6ADDR((addrs6[idx6].sin6_addr.s6_addr), &(addrLst->addrs[idx].u.ipv6NetAddr));
1727          idx6++;
1728       }
1729       else 
1730       {
1731 #ifdef SUN_KSCTP
1732
1733          ipv6_array_size += sizeof(struct sockaddr_in6);
1734          addresses_array_size += sizeof(struct sockaddr_in6);
1735          if (sockFd->protType == AF_INET)
1736          {
1737 #ifdef CMINETDBG
1738 #ifndef ALIGN_64BIT
1739             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1740             /* cm_inet_c_001.main_62:Warning fix */
1741             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1742                   " sockFd->fd(%ld)\n", sockFd->fd);
1743             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1744 #else
1745             /* cm_inet_c_001.main_62:Warning fix */
1746             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket," 
1747                   " sockFd->fd(%d)\n", sockFd->fd);
1748             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1749 #endif /*ALIGN_64BIT*/
1750 #endif /* CMINETDBG */
1751             RETVALUE(RFAILED);
1752          }
1753
1754          addrs6[idx6].sin6_family      = AF_INET6;
1755          addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
1756          addrLst->addrs[idx].u.ipv4NetAddr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
1757          cmInetNtoa(addrLst->addrs[idx].u.ipv4NetAddr, &addrString);
1758          addrLen = cmStrlen((U8*)addrString);
1759          cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
1760          ipv4Format[7+addrLen] = '\0';
1761          cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
1762          idx6++;
1763 #else
1764          ipv4_array_size += sizeof(struct sockaddr_in);
1765          addresses_array_size += sizeof(struct sockaddr_in);
1766          addrs[idx4].sin_family      = AF_INET;
1767          addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
1768          addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
1769          idx4++;
1770 #endif /* SUN_KSCTP */
1771       }
1772 #else 
1773       ipv4_array_size += sizeof(struct sockaddr_in);
1774       addresses_array_size += sizeof(struct sockaddr_in);
1775       addrs[idx4].sin_family      = AF_INET;
1776       addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
1777       addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
1778       idx4++;
1779 #endif /* IPV6_SUPPORTED */
1780    }
1781
1782
1783    if(ipv4_array_size > 0)
1784    {
1785        sockAddrPtr = (struct sockaddr*)address_array;
1786       sockAddrLen = sizeof(struct sockaddr_in);
1787       cmMemcpy((U8*)address_array, (U8*)addrs, ipv4_array_size); 
1788    }
1789 #ifdef IPV6_SUPPORTED
1790    else
1791    {
1792        sockAddrPtr = (struct sockaddr*)address_array;
1793       sockAddrLen = sizeof(struct sockaddr_in6);
1794    }
1795
1796    if(ipv6_array_size > 0)
1797    {
1798       cmMemcpy((U8*)(address_array + ipv4_array_size), (U8*)addrs6, ipv6_array_size); 
1799    }
1800 #endif /* IPV6_SUPPORTED */
1801
1802
1803 #ifdef SUN_KSCTP
1804    ret = bind(sockFd->fd, sockAddrPtr, sockAddrLen); 
1805    if (ret == INET_ERR)
1806    {
1807
1808 #ifdef CMINETDBG
1809 #ifndef ALIGN_64BIT
1810       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1811       /* cm_inet_c_001.main_62:Warning fix */
1812       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1813             " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1814       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1815 #else
1816       /* cm_inet_c_001.main_62:Warning fix */
1817       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1818             " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1819       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1820 #endif /*ALIGN_64BIT*/
1821 #endif /* CMINETDBG */
1822       RETVALUE(RFAILED);
1823    }
1824
1825    if (addrLst->count > 1)
1826    {
1827       if(((struct sockaddr*)address_array)->sa_family == AF_INET)
1828       {
1829          tempAddrPtr = address_array + (sizeof(struct sockaddr_in));
1830       }
1831       else if(((struct sockaddr*)address_array)->sa_family == AF_INET6)
1832       {
1833          tempAddrPtr = address_array + (sizeof(struct sockaddr_in6));
1834       }
1835       else
1836       {
1837 #ifdef CMINETDBG
1838 #ifndef ALIGN_64BIT
1839          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1840          /* cm_inet_c_001.main_62:Warning fix */
1841          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1842                " sockFd->fd(%ld),  error(%d), port(%d)\n ",
1843                INET_ERR_CODE, port, sockFd->fd);
1844          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1845 #else
1846          /* cm_inet_c_001.main_62:Warning fix */
1847          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1848                " sockFd->fd(%d), error(%d), port(%d)\n ", 
1849                INET_ERR_CODE, port, sockFd->fd);
1850          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1851 #endif /*ALIGN_64BIT*/
1852 #endif /* CMINETDBG */
1853          RETVALUE(RFAILED);
1854       }
1855
1856       ret = sctp_bindx(sockFd->fd, (Void*)tempAddrPtr, addrLst->count - 1, SCTP_BINDX_ADD_ADDR); 
1857    }
1858 #else
1859    /* linux */
1860    ret = sctp_bindx(sockFd->fd, (struct sockaddr*)address_array, addrLst->count, SCTP_BINDX_ADD_ADDR); 
1861         UNUSED(sockAddrPtr);
1862         UNUSED(sockAddrLen);
1863 #endif
1864    if (ret == INET_ERR)
1865    {
1866 #ifdef CMINETDBG
1867 #ifndef ALIGN_64BIT
1868       /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1869       /* cm_inet_c_001.main_62:Warning fix */
1870       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1871             " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1872       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1873 #else
1874       /* cm_inet_c_001.main_62:Warning fix */
1875       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1876             " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1877       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1878 #endif /*ALIGN_64BIT*/
1879 #endif /* CMINETDBG */
1880       RETVALUE(RFAILED);
1881    }
1882
1883    RETVALUE(ROK); 
1884 }
1885
1886 /*
1887 *
1888 *      Fun:   cmInetSctpConnectx 
1889 *
1890 *      Desc:  Establishes a sctp connection with remote addresses
1891 *
1892 *      Ret:   ROK     - successful
1893 *             RFAILED - failed
1894 *
1895 *      Notes: None.
1896 *
1897 *      File:  cm_inet.c
1898 *
1899 */
1900 #ifdef ANSI
1901 PUBLIC S16 cmInetSctpConnectx
1902 (
1903 CmInetFd          *sockFd,       /* socket file descriptor */ 
1904 CmInetNetAddr     *primAddr,     /* primary destination Internet address */
1905 CmInetNetAddrLst  *addrLst,      /* destination Internet address list */
1906 U16                port          /* port number */
1907 )
1908 #else
1909 PUBLIC S16 cmInetSctpConnectx(sockFd, primAddr, addrLst, port)
1910 CmInetFd          *sockFd;       /* socket file descriptor */ 
1911 CmInetNetAddr     *primAddr;     /* primary destination Internet address */
1912 CmInetNetAddrLst  *addrLst;      /* destination Internet address list */
1913 U16                port;         /* port number */
1914 #endif
1915 {
1916    S32   ret;   
1917    U32   cnt;
1918    /* cm_inet_c_001.main_46: Removed SS_LINUX flag */
1919    S32   idx;
1920
1921 /* cm_inet_c_001.main_64: New variable used as an argument for sctp_connectx */
1922 #ifdef SCTP_CONNECTX_NEW
1923    U32    assocId = 0;
1924 #endif   
1925    U32    addresses_array_size = 0;
1926    U32    idx4 = 0;
1927    struct sockaddr_in  addrs[CM_INET_NUM_NET_ADDR];
1928    U32    ipv4_array_size = 0;
1929
1930 #ifndef IPV6_SUPPORTED
1931    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1932 #else
1933    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1934 #endif /* IPV6_SUPPORTED */
1935
1936 #ifdef IPV6_SUPPORTED
1937 #ifdef SUN_KSCTP
1938    S8     *addrString = NULLP;
1939    U32    addrLen = 0;
1940    S8     ipv4Format[23] = "::ffff:";
1941    CmInetIpAddr ipv4NetAddr;
1942 #endif /* SUN_KSCTP */
1943    U32    idx6 = 0;
1944    struct sockaddr_in6  addrs6[CM_INET_NUM_NET_ADDR];
1945    U32    ipv6_array_size = 0;
1946 #endif /* IPV6_SUPPORTED */
1947 #ifndef SS_LINUX
1948    U32    sockAddrLen = 0;
1949 #endif /* sockAddrLen */
1950
1951 #ifndef SS_LINUX
1952    CmInetSockAddr *sockAddrPtr = NULLP;
1953 #endif /* SS_LINUX */
1954 #if (ERRCLASS & ERRCLS_INT_PAR)
1955    /* error check on parameters */
1956    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1957          (primAddr == NULLP))
1958    {
1959       RETVALUE(RFAILED);
1960    }
1961     /* cm_inet_c_001.main_58 : Added check for addrLst to fix klockwork issue */
1962    if (addrLst == NULLP)
1963    {
1964       RETVALUE(RFAILED);
1965    }
1966    /* cm_inet_c_001.main_46: Included check for no of address aginst max */
1967    if( addrLst->count > CM_INET_NUM_NET_ADDR )
1968    {
1969 #ifdef CMINETDBG
1970 #ifndef ALIGN_64BIT
1971       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1972       /* cm_inet_c_001.main_62:Warning fix */
1973       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1974             " sockFd->fd(%ld)\n", 
1975             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1976       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1977 #else
1978       /* cm_inet_c_001.main_62:Warning fix */
1979       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1980             " sockFd->fd(%d)\n", 
1981             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1982       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1983 #endif /*ALIGN_64BIT*/
1984 #endif /* CMINETDBG */
1985       RETVALUE(RFAILED);
1986    }
1987 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1988
1989
1990    cmMemset((U8*)&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1991 #ifdef IPV6_SUPPORTED
1992    cmMemset((U8*)&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1993 #endif /* IPV6_SUPPORTED */
1994
1995    cnt = 0;
1996
1997 #ifdef IPV6_SUPPORTED 
1998    if (primAddr->type == CM_INET_IPV6ADDR_TYPE)
1999    {
2000       if (sockFd->protType == AF_INET)
2001       {
2002 #ifdef CMINETDBG
2003 #ifndef ALIGN_64BIT
2004          /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2005          /* cm_inet_c_001.main_62:Warning fix */
2006          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2007                " sockFd->fd(%ld)\n", sockFd->fd);
2008          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
2009 #else
2010          /* cm_inet_c_001.main_62:Warning fix */
2011          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2012                " sockFd->fd(%d)\n",  sockFd->fd);
2013          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
2014 #endif /*ALIGN_64BIT*/
2015 #endif /* CMINETDBG */
2016          RETVALUE(RFAILED);
2017       }
2018
2019       addrs6[idx6].sin6_family      = AF_INET6;
2020       addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2021       CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr), &(primAddr->u.ipv6NetAddr));
2022       addresses_array_size += sizeof(struct sockaddr_in6);
2023       ipv6_array_size += sizeof(struct sockaddr_in6);
2024       idx6++;
2025    }
2026    else 
2027    {
2028 #ifdef SUN_KSCTP
2029       if (sockFd->protType == AF_INET)
2030       {
2031 #ifdef CMINETDBG
2032 #ifndef ALIGN_64BIT
2033          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2034          /* cm_inet_c_001.main_62:Warning fix */
2035          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2036                " sockFd->fd(%ld)\n", sockFd->fd);
2037          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
2038 #else
2039          /* cm_inet_c_001.main_62:Warning fix */
2040          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2041                " sockFd->fd(%d)\n", sockFd->fd);
2042          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
2043 #endif /*ALIGN_64BIT*/
2044 #endif /* CMINETDBG */
2045          RETVALUE(RFAILED);
2046       }
2047       addrs6[idx6].sin6_family      = AF_INET6;
2048       addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2049       ipv4NetAddr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2050       cmInetNtoa(ipv4NetAddr, &addrString);
2051       addrLen = cmStrlen((U8*)addrString);
2052       cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2053       ipv4Format[7+addrLen] = '\0';
2054       cmInetPton6((CmInetIpAddr6*)&(addrs6[idx6].sin6_addr), ipv4Format);
2055       addresses_array_size += sizeof(struct sockaddr_in6);
2056       ipv6_array_size += sizeof(struct sockaddr_in6);
2057       idx6++;
2058 #else
2059       addrs[idx4].sin_family      = AF_INET;
2060       addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2061       addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2062       addresses_array_size += sizeof(struct sockaddr_in);
2063       ipv4_array_size += sizeof(struct sockaddr_in);
2064       idx4++;
2065 #endif 
2066    }
2067 #else 
2068    addrs[idx4].sin_family      = AF_INET;
2069    addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2070    addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2071    addresses_array_size += sizeof(struct sockaddr_in);
2072    ipv4_array_size += sizeof(struct sockaddr_in);
2073    idx4++;
2074 #endif /* IPV6_SUPPORTED */
2075
2076    cnt++;
2077
2078    /* cm_inet_c_001.main_46: Moved the SS_LINUX flag down, 
2079     * copy addresses in Solaris also */
2080    if (addrLst != NULLP)
2081    {
2082       for (idx = 0; idx < addrLst->count; idx++)
2083       {
2084
2085          /* cm_inet_c_001.main_46: Don't include the primary address 
2086           * if its prersent in list */
2087          if ( addrLst->addrs[idx].type == CM_INET_IPV4ADDR_TYPE )
2088          {
2089             if ( addrLst->addrs[idx].u.ipv4NetAddr == primAddr->u.ipv4NetAddr )
2090             {
2091                continue;
2092             }
2093          }
2094 #ifdef IPV6_SUPPORTED
2095          else if ( addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE )
2096          {
2097             if (( cmMemcmp(addrLst->addrs[idx].u.ipv6NetAddr,
2098                    primAddr->u.ipv6NetAddr, sizeof(CmInetIpAddr6) )) == 0 )
2099             {
2100                continue;
2101             }
2102          }
2103
2104          if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
2105          {
2106             if (sockFd->protType == AF_INET)
2107             {
2108 #ifdef CMINETDBG
2109 #ifndef ALIGN_64BIT
2110                /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2111                /* cm_inet_c_001.main_62:Warning fix */
2112                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2113                      " sockFd->fd(%ld)\n", sockFd->fd);
2114                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
2115 #else
2116                /* cm_inet_c_001.main_62:Warning fix */
2117                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2118                      " sockFd->fd(%d)\n", sockFd->fd);
2119                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
2120 #endif /*ALIGN_64BIT*/
2121 #endif /* CMINETDBG */
2122                RETVALUE(RFAILED);
2123             }
2124
2125             addrs6[idx6].sin6_family      = AF_INET6;
2126             addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2127             CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr),
2128                                   &(addrLst->addrs[idx].u.ipv6NetAddr));
2129             addresses_array_size += sizeof(struct sockaddr_in6);
2130             ipv6_array_size += sizeof(struct sockaddr_in6);
2131             idx6++;
2132          }
2133          else 
2134          {
2135 #ifdef SUN_KSCTP
2136             if (sockFd->protType == AF_INET)
2137             {
2138 #ifdef CMINETDBG
2139 #ifndef ALIGN_64BIT
2140                /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2141                /* cm_inet_c_001.main_62:Warning fix */
2142                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2143                      " sockFd->fd(%ld)\n", sockFd->fd);
2144                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2145 #else
2146                /* cm_inet_c_001.main_62:Warning fix */
2147                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2148                      " sockFd->fd(%d)\n", sockFd->fd);
2149                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2150 #endif /*ALIGN_64BIT*/
2151 #endif /* CMINETDBG */
2152                RETVALUE(RFAILED);
2153             }
2154             addrs6[idx6].sin6_family      = AF_INET6;
2155             addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2156             ipv4NetAddr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2157             cmInetNtoa(ipv4NetAddr, &addrString);
2158             addrLen = cmStrlen((U8*)addrString);
2159             cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2160             ipv4Format[7+addrLen] = '\0';
2161             cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
2162             addresses_array_size += sizeof(struct sockaddr_in6);
2163             ipv6_array_size += sizeof(struct sockaddr_in6);
2164             idx6++;
2165 #else
2166             addrs[idx4].sin_family      = AF_INET;
2167             addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2168             addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2169             addresses_array_size += sizeof(struct sockaddr_in);
2170             ipv4_array_size += sizeof(struct sockaddr_in);
2171             idx4++;
2172 #endif /* SUN_KSCTP */
2173          }
2174 #else 
2175          addrs[idx4].sin_family      = AF_INET;
2176          addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2177          addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2178          addresses_array_size += sizeof(struct sockaddr_in);
2179          ipv4_array_size += sizeof(struct sockaddr_in);
2180          idx4++;
2181 #endif /* IPV6_SUPPORTED */
2182          /*cm_inet_c_001.main_39 */
2183          cnt++;
2184       }
2185    }
2186
2187    /* cm_inet_c_001.main_46: Moved SS_LINUX flag to here */
2188 #ifdef SS_LINUX
2189    /*cm_inet_c_001.main_58 : Added check array_size to fix klockwork issue */
2190    if((ipv4_array_size > 0) && (ipv4_array_size <= (CM_INET_NUM_NET_ADDR * \
2191                sizeof(struct sockaddr_in))))
2192    {
2193       cmMemcpy((U8*)address_array, (U8*)&addrs[0], ipv4_array_size); 
2194    }
2195    else
2196    {
2197       RETVALUE(RFAILED);
2198    }
2199
2200 #ifdef IPV6_SUPPORTED
2201    if((ipv6_array_size > 0) && (ipv6_array_size <= (CM_INET_NUM_NET_ADDR * \
2202                sizeof(struct sockaddr_in))))
2203    {
2204       cmMemcpy((U8*)(address_array + ipv4_array_size), (U8*)addrs6, ipv6_array_size); 
2205    }
2206    else
2207    {
2208       RETVALUE(RFAILED);
2209    }
2210 #endif /* IPV6_SUPPORTED */
2211
2212 /* cm_inet_c_001.main_64: Support for new definition of sctp_connectx */
2213 #ifndef SCTP_CONNECTX_NEW   
2214    ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt);
2215 #else
2216    ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt, (sctp_assoc_t *)&assocId);
2217 #endif
2218
2219 #else
2220    /* solaris */
2221    /* cm_inet_c_001.main_46: Use next provided address to connect if 
2222     * first one fails */
2223
2224 #ifdef CMINET_SUN_CONNECTX
2225    idx4 = 0;
2226 #ifdef IPV6_SUPPORTED
2227    idx6 = 0;
2228 #endif /* IPV6_SUPPORTED */
2229    for (idx = 0; idx < cnt; idx++)
2230    {
2231       if( addrs[idx4].sin_family == AF_INET)
2232       {
2233         sockAddrPtr = (CmInetSockAddr *)&addrs[idx4];
2234         sockAddrLen = sizeof(struct sockaddr_in);
2235         idx4++;
2236       }
2237 #ifdef IPV6_SUPPORTED
2238       else 
2239       {
2240         sockAddrPtr = (CmInetSockAddr *)&addrs6[idx6];
2241         sockAddrLen = sizeof(struct sockaddr_in6);
2242         idx6++;
2243       }
2244 #endif/* IPV6_SUPPORTED */
2245
2246       ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2247
2248         if ( ret != INET_ERR )
2249         {
2250             break;
2251         }
2252 #ifdef CMINETDBG
2253 #ifndef ALIGN_64BIT
2254       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2255       /* cm_inet_c_001.main_62:Warning fix */
2256       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2257             " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2258       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2259 #else
2260       /* cm_inet_c_001.main_62:Warning fix */
2261       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2262             " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2263       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2264 #endif /*ALIGN_64BIT*/
2265 #endif /* CMINETDBG */
2266
2267    }
2268 #else
2269
2270    if( addrs[0].sin_family == AF_INET)
2271    {
2272      sockAddrPtr = (CmInetSockAddr*)&addrs[0];
2273      sockAddrLen = sizeof(struct sockaddr_in);
2274      idx4++;
2275    }
2276 #ifdef IPV6_SUPPORTED
2277    else 
2278    {
2279      sockAddrPtr = (CmInetSockAddr*)&addrs6[0];
2280      sockAddrLen = sizeof(struct sockaddr_in6);
2281      idx6++;
2282    }
2283 #endif/* IPV6_SUPPORTED */
2284
2285    ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2286
2287 #endif /* CMINET_SUN_CONNECTX */
2288 #endif /* SS_LINUX */
2289
2290    if (ret == INET_ERR)
2291    {
2292 #ifdef CMINETDBG
2293 #ifndef ALIGN_64BIT
2294       /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2295       /* cm_inet_c_001.main_62:Warning fix */
2296       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2297             " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2298       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
2299 #else
2300       DU_LOG("\nCmInetSctpConnectx() Failed : error(%d), port(0x%1x),\
2301                    sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2302 #endif /*ALIGN_64BIT*/
2303 #endif /* CMINETDBG */
2304
2305       switch (INET_ERR_CODE)
2306       {
2307          /* non-blocking: connection is in progress */
2308          case ERR_INPROGRESS:
2309             RETVALUE(RINPROGRESS);
2310             break;   
2311
2312          /* 
2313           * non-blocking: connection is established 
2314           * blocking    : connection is already established
2315           */
2316          case ERR_ISCONN:
2317             RETVALUE(RISCONN);
2318             break;               
2319
2320          /* resource temporarily unavailable */
2321          case ERR_WOULDBLOCK:
2322             RETVALUE(ROKDNA);
2323             break;
2324
2325          /* non-blocking: connection is in progress */
2326          case ERR_ALREADY:
2327             RETVALUE(RINPROGRESS);
2328             break;
2329
2330          case ERR_INVAL:
2331             RETVALUE(RINPROGRESS);
2332             break;
2333
2334          /*  Check for connection refused and timeout errors */
2335          case ERR_CONNREFUSED:
2336          case ERR_TIMEDOUT:
2337             RETVALUE(RCLOSED);
2338             break;
2339
2340          /* it is a real error */ 
2341          default:
2342             RETVALUE(RFAILED);
2343             break;
2344       }
2345    }
2346
2347    RETVALUE(ROK);
2348 }
2349
2350 /*
2351 *
2352 *      Fun:   cmInetSctpPeelOff 
2353 *
2354 *      Desc:  Branches an existing sctp association off to a seperate socket 
2355 *
2356 *      Ret:   ROK     - successful
2357 *             RFAILED - failed
2358 *
2359 *      Notes: None.
2360 *
2361 *      File:  cm_inet.c
2362 *
2363 */
2364 #ifdef ANSI
2365 PUBLIC S16 cmInetSctpPeelOff
2366 (
2367 CmInetFd          *sockFd,       /* socket file descriptor */ 
2368 U32                assocId,      /* association id */
2369 CmInetFdType      *assocFd       /* association fd */
2370 )
2371 #else
2372 PUBLIC S16 cmInetSctpPeelOff(sockFd, assocId, assocFd)
2373 CmInetFd          *sockFd;       /* socket file descriptor */ 
2374 U32                assocId;      /* association id */
2375 CmInetFdType      *assocFd;      /* association fd */
2376 #endif
2377 {
2378    S32 ret;
2379
2380 #if (ERRCLASS & ERRCLS_INT_PAR)
2381    /* error check on parameters */
2382    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) || (assocFd == NULLP)) 
2383    {
2384       RETVALUE(RFAILED);
2385    }
2386 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2387
2388
2389    ret = sctp_peeloff(sockFd->fd, assocId);
2390    if (ret == INET_ERR)
2391    {
2392 #ifdef CMINETDBG
2393 #ifndef ALIGN_64BIT
2394       /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2395       /* cm_inet_c_001.main_62:Warning fix */
2396       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%ld),"
2397             " sockFd->fd(%ld)\n", INET_ERR_CODE, assocId, sockFd->fd);
2398       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2399 #else
2400       /* cm_inet_c_001.main_55: Fix for compilation warning */
2401       /* cm_inet_c_001.main_62:Warning fix */
2402       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%d),"
2403             " sockFd->fd(%d)\n", INET_ERR_CODE, assocId, sockFd->fd);
2404       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2405 #endif /*ALIGN_64BIT*/
2406 #endif /* CMINETDBG */
2407
2408       RETVALUE(RFAILED);
2409    }
2410
2411    *assocFd = ret;
2412
2413    RETVALUE(ROK);
2414 }
2415
2416 /*
2417 *
2418 *      Fun:   cmInetSctpSendMsg 
2419 *
2420 *      Desc:  invokes sctp socket API to send message to the remote addresses
2421 *
2422 *      Ret:   ROK     - successful
2423 *             RFAILED - failed
2424 *
2425 *      Notes: None.
2426 *
2427 *      File:  cm_inet.c
2428 *
2429 */
2430 #ifdef ANSI
2431 PUBLIC S16 cmInetSctpSendMsg
2432 (
2433 CmInetFd        *sockFd,       /* socket file descriptor */ 
2434 CmInetNetAddr   *dstAddr,      /* destination Internet address/port */
2435 U16              port,         /* destination port no. */
2436 CmInetMemInfo   *info,         /* buffer allocation info */
2437 Buffer          *mBuf,         /* buffer structure to send */
2438 MsgLen          *len,          /* number of actually sent octets */
2439 U16              strmId,       /* sctp stream identifier */
2440 Bool             unorderFlg,   /* flag to enable the unordered delivery */
2441 U16              ttl,          /* time to live */
2442 U32              ppId,         /* opaque value passed along with the message */
2443 U32              context       /* value to be passed back, if error occurs */
2444 )
2445 #else
2446 PUBLIC S16 cmInetSctpSendMsg(sockFd, dstAddr, port, info, mBuf, len, strmId, 
2447                              unorderFlg, ttl, ppId, context)
2448 CmInetFd        *sockFd;       /* socket file descriptor */ 
2449 CmInetNetAddr   *dstAddr;      /* destination Internet address/port */
2450 U16              port;         /* destination port no. */
2451 CmInetMemInfo   *info;         /* buffer allocation info */
2452 Buffer          *mBuf;         /* buffer structure to send */
2453 MsgLen          *len;          /* number of actually sent octets */
2454 U16              strmId;       /* sctp stream identifier */
2455 Bool             unorderFlg;   /* flag to enable the unordered delivery */
2456 U16              ttl;          /* time to live */
2457 U32              ppId;         /* opaque value passed along with the message */
2458 U32              context;      /* value to be passed back, if error occurs */
2459 #endif
2460 {
2461    S32     ret;   
2462  /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2463    MsgLen  msgLen = 0;              /* message length */    
2464    MsgLen  bufLen = 0;              /* send buffer length */     
2465    Data   *sendBuf = NULLP;             /* plain send buffer */
2466    U32     flags;
2467    CmInetSockAddr *sockAddrPtr = NULLP;
2468    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2469    MsgLen          sockAddrLen = 0; 
2470    struct sockaddr_in  addr;
2471 #ifdef IPV6_SUPPORTED
2472 #ifdef SUN_KSCTP
2473    S8     *addrString = NULLP;
2474    U32    addrLen = 0;
2475    S8     ipv4Format[23] = "::ffff:";
2476    CmInetIpAddr ipv4NetAddr;
2477 #endif /* SUN_KSCTP */
2478    struct sockaddr_in6  addr6;
2479 #endif /* IPV6_SUPPORTED */
2480
2481 #if (ERRCLASS & ERRCLS_INT_PAR)
2482    /* error check on parameters */
2483    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd)
2484        || (info == NULLP) || (mBuf == NULLP) || (len == NULLP))
2485    {
2486       RETVALUE(RFAILED);
2487    }
2488 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2489
2490
2491    cmMemset((U8*)&addr, 0, sizeof(struct sockaddr_in));
2492 #ifdef IPV6_SUPPORTED
2493    cmMemset((U8*)&addr6, 0, sizeof(struct sockaddr_in6));
2494 #endif /* IPV6_SUPPORTED */
2495
2496    /* copy message to a flat buffer */
2497    ret = SFndLenMsg(mBuf, &bufLen);
2498    if (ret != ROK)
2499    {
2500       RETVALUE(RFAILED);
2501    }
2502    /* max message length is limited to control the memory usage */
2503    /* casting bufLen to avoid warnings */
2504    if ((bufLen > 0) && ((U32)bufLen > CM_INET_MAX_MSG_LEN))
2505    {
2506       RETVALUE(RFAILED);
2507    }
2508    ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);                  
2509    if (ret != ROK)
2510    {
2511       RETVALUE(ROUTRES);
2512    }
2513    ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
2514    if ((ret != ROK) || (msgLen != bufLen)) 
2515    {
2516       SPutSBuf(info->region, info->pool, sendBuf, bufLen);       
2517       RETVALUE(RFAILED);
2518    }
2519
2520    if ( dstAddr != NULLP)
2521    {
2522 #ifdef IPV6_SUPPORTED 
2523       if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
2524       {
2525          if (sockFd->protType == AF_INET)
2526          {
2527             SPutSBuf(info->region, info->pool, sendBuf, bufLen);       
2528 #ifdef CMINETDBG
2529 #ifndef ALIGN_64BIT
2530             /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2531             /* cm_inet_c_001.main_62:Warning fix */
2532             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2533                   " IPV4 socket, sockFd->fd(%ld)\n", sockFd->fd);
2534             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2535 #else
2536             /* cm_inet_c_001.main_62:Warning fix */
2537             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2538                   " IPV4 socket, sockFd->fd(%d)\n", sockFd->fd);
2539             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2540 #endif /*ALIGN_64BIT*/
2541 #endif /* CMINETDBG */
2542             RETVALUE(RFAILED);
2543          }
2544
2545          addr6.sin6_family      = AF_INET6;
2546          addr6.sin6_port        = CM_INET_HTON_U16(port);
2547          CM_INET_COPY_IPV6ADDR(&addr6.sin6_addr.s6_addr, &dstAddr->u.ipv6NetAddr); 
2548          sockAddrLen = sizeof(struct sockaddr_in6);
2549          sockAddrPtr = (CmInetSockAddr*)&addr6;
2550       }
2551       else 
2552       {
2553
2554 #ifdef SUN_KSCTP
2555          if (sockFd->protType == AF_INET)
2556          {
2557 #ifdef CMINETDBG
2558 #ifndef ALIGN_64BIT
2559             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2560             /* cm_inet_c_001.main_62:Warning fix */
2561             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2562                   " socket, sockFd->fd(%ld)\n", sockFd->fd);
2563             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2564 #else
2565             /* cm_inet_c_001.main_62:Warning fix */
2566             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2567                   " socket, sockFd->fd(%d)\n", sockFd->fd);
2568             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2569 #endif /*ALIGN_64BIT*/
2570 #endif /* CMINETDBG */
2571             RETVALUE(RFAILED);
2572          }
2573          addr6.sin6_family      = AF_INET6;
2574          addr6.sin6_port        = CM_INET_HTON_U16(port);
2575          ipv4NetAddr = CM_INET_HTON_U32(dstAddr->u.ipv4NetAddr);
2576          cmInetNtoa(ipv4NetAddr, &addrString);
2577          addrLen = cmStrlen((U8*)addrString);
2578          cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2579          ipv4Format[7+addrLen] = '\0';
2580          cmInetPton6((CmInetIpAddr6*)(addr6.sin6_addr.s6_addr), ipv4Format);
2581          sockAddrLen = sizeof(struct sockaddr_in6);
2582          sockAddrPtr = (CmInetSockAddr*)&addr6;
2583 #else
2584          addr.sin_family      = AF_INET;
2585          addr.sin_port        = CM_INET_HTON_U16(port);
2586          addr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->u.ipv4NetAddr);
2587          sockAddrLen = sizeof(struct sockaddr_in);
2588          sockAddrPtr = (CmInetSockAddr*)&addr;
2589 #endif /* SUN_KSCTP */
2590       }
2591 #else 
2592       addr.sin_family      = AF_INET;
2593       addr.sin_port        = CM_INET_HTON_U16(port);
2594       addr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->u.ipv4NetAddr);
2595       /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2596       sockAddrLen = (MsgLen)sizeof(struct sockaddr_in);
2597       sockAddrPtr = (CmInetSockAddr*)&addr;
2598 #endif /* IPV6_SUPPORTED */
2599    }
2600    else
2601    {
2602 #ifdef SUN_KSCTP
2603       sockAddrPtr = NULL;
2604 #else
2605       sockAddrPtr = (CmInetSockAddr*)&addr;
2606 #endif
2607       /* cm_inet_c_001.main_58 : initialized sockAddrLen properly */
2608 #ifdef IPV6_SUPPORTED 
2609       sockAddrLen = sizeof(struct sockaddr_in6);
2610 #else
2611       sockAddrLen = sizeof(struct sockaddr_in);
2612 #endif
2613    }
2614
2615    /* Not validating the address, whether addr is a valid address or not */
2616
2617    *len  = 0;
2618    flags = 0x00000000;
2619
2620    if (unorderFlg == TRUE)
2621    {
2622 #ifdef SUN_KSCTP 
2623       flags |= MSG_UNORDERED;
2624 #else
2625       /* linux */
2626       flags |= SCTP_UNORDERED;
2627 #endif
2628    }
2629    /*cm_inet_c_001.main_54: converting ppid to network*/
2630    ppId = CM_INET_HTON_U32(ppId);
2631    ret = sctp_sendmsg(sockFd->fd, (Void*)sendBuf, bufLen, 
2632          (struct sockaddr*)sockAddrPtr, (size_t)sockAddrLen, 
2633          ppId, flags, strmId, ttl, context);
2634    if (ret == INET_ERR)
2635    {
2636       SPutSBuf(info->region, info->pool, sendBuf, bufLen);       
2637 #ifdef CMINETDBG
2638 #ifndef ALIGN_64BIT
2639       /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2640       /* cm_inet_c_001.main_62:Warning fix */
2641       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%ld),"
2642             " strmId(%u),sockFd->fd(%ld)\n",
2643             INET_ERR_CODE, ppId, strmId, sockFd->fd);
2644       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2645 #else
2646       /* cm_inet_c_001.main_55: Fix for compilation warning */
2647       /* cm_inet_c_001.main_62:Warning fix */
2648       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%d),"
2649             " strmId(%u),sockFd->fd(%d)\n",
2650             INET_ERR_CODE, ppId, strmId, sockFd->fd);
2651       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2652 #endif /*ALIGN_64BIT*/
2653 #endif /* CMINETDBG */
2654
2655       if ((INET_ERR_CODE == ERR_AGAIN) || (INET_ERR_CODE == ERR_WOULDBLOCK))
2656          RETVALUE(RWOULDBLOCK);
2657       else if (INET_ERR_CODE == ERR_PIPE)
2658          RETVALUE(RCLOSED);
2659       else 
2660          RETVALUE(RFAILED);
2661    }
2662
2663    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2664    *len = (MsgLen)ret; 
2665
2666    /* cleanup */
2667    SPutSBuf(info->region, info->pool, sendBuf, bufLen);       
2668
2669    RETVALUE(ROK);
2670 }
2671
2672 /*
2673 *
2674 *      Fun:   cmInetSctpRecvMsg 
2675 *
2676 *      Desc:  invokes sctp API to get the message received at sctp socket
2677 *
2678 *      Ret:   ROK     - successful
2679 *             RFAILED - failed
2680 *
2681 *      Notes: None.
2682 *
2683 *      File:  cm_inet.c
2684 *
2685 */
2686 #ifdef ANSI
2687 PUBLIC S16 cmInetSctpRecvMsg
2688 (
2689 CmInetFd               *sockFd,       /* socket file descriptor */ 
2690 CmInetNetAddr          *srcAddr,      /* source Internet address/port */
2691 U16                    *port,         /* source port no. */
2692 CmInetMemInfo          *meminfo,      /* buffer allocation info */
2693 Buffer                 **mBuf,         /* buffer structure received */
2694 MsgLen                 *len,          /* number of octets received */
2695 CmInetSctpSndRcvInfo   *sinfo,        /* sctp send-receive info */ 
2696 U32                    *flag,         /* flags */
2697 CmInetSctpNotification *ntfy        /* notification parameters */
2698 )
2699 #else
2700 PUBLIC S16 cmInetSctpRecvMsg(sockFd, srcAddr, port, meminfo, mBuf, len, 
2701                              sinfo, flag, ntfy)
2702 CmInetFd               *sockFd;       /* socket file descriptor */ 
2703 CmInetNetAddr          *srcAddr;      /* source Internet address/port */
2704 U16                    *port;         /* source port no. */
2705 CmInetMemInfo          *meminfo;      /* buffer allocation info */
2706 Buffer                 **mBuf;        /* buffer structure received */
2707 MsgLen                 *len;          /* number of octets received */
2708 CmInetSctpSndRcvInfo   *sinfo;        /* sctp send-receive info */ 
2709 U32                    *flag;         /* flags */
2710 CmInetSctpNotification *ntfy;         /* notification parameters */
2711 #endif
2712 {
2713    S32                        ret;   
2714    S32                        msgFlags;
2715    struct sctp_sndrcvinfo     info;
2716    struct sockaddr_storage    addr;
2717    struct sockaddr_in        *pAddr = NULLP;
2718 #ifdef IPV6_SUPPORTED
2719    struct sockaddr_in6       *pAddr6 = NULLP;
2720 #endif 
2721    socklen_t                  addrlen;
2722    Data                      *recvbuf = NULLP;
2723    MsgLen                     buflen;
2724    union sctp_notification   *sctpNtfy = NULLP;
2725    /* cm_inet_c_001.main_46: Defined new variable to store length of data */
2726 #ifdef SS_LINUX
2727    MsgLen                     datlen;
2728 #endif /* SS_LINUX */
2729
2730 #if (ERRCLASS & ERRCLS_INT_PAR)
2731    /* error check on parameters */
2732    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) || 
2733        (srcAddr == NULLP) || (port == NULLP) || (meminfo == NULLP) || 
2734        (mBuf == NULLP) || (len == NULLP) || (sinfo == NULLP) || (flag == NULLP))
2735    {
2736       RETVALUE(RFAILED);
2737    }
2738 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2739
2740
2741    *mBuf = NULLP;
2742    *len  = 0;
2743    cmMemset((U8*)ntfy, 0, sizeof(CmInetSctpNotification));
2744
2745    buflen = CM_INET_MAX_MSG_LEN;
2746
2747    /* allocate flat receive buffer */
2748    ret = SGetSBuf(meminfo->region, meminfo->pool, &recvbuf, buflen);
2749    if (ret != ROK)
2750    {
2751 #ifdef CMINETDBG
2752       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2753       /* cm_inet_c_001.main_62:Warning fix */
2754       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failed to allocate memory\n");
2755       CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET065, 0, prntBuf);
2756 #endif /* CMINETDBG */
2757       RETVALUE(RFAILED);
2758    }
2759
2760    addrlen = sizeof(struct sockaddr_storage);
2761    msgFlags = 0;
2762    cmMemset((U8*)&addr, 0, sizeof(struct sockaddr_storage));
2763    cmMemset((U8*)&info, 0, sizeof(struct sctp_sndrcvinfo));
2764
2765    ret = sctp_recvmsg(sockFd->fd, (Void *)recvbuf, (size_t)buflen, 
2766                       (struct sockaddr*)&addr, &addrlen, &info, 
2767                       (int*)&msgFlags);
2768    if (ret == INET_ERR)
2769    {
2770       /* cleanup */
2771       SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);       
2772 #ifdef CMINETDBG
2773 #ifndef ALIGN_64BIT
2774       /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2775       /* cm_inet_c_001.main_62:Warning fix */
2776       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2777             " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
2778       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2779 #else
2780       DU_LOG("\ncmInetSctpRecvMsg() Failed : error(%d), sockFd->fd(%d)", \
2781          INET_ERR_CODE, sockFd->fd);
2782 #endif /*ALIGN_64BIT*/
2783 #endif /* CMINETDBG */
2784
2785       RETVALUE(RFAILED);
2786    }
2787
2788    /* save the length of the received message */
2789    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2790    *len = (MsgLen)ret;
2791
2792 #ifdef IPV6_SUPPORTED 
2793    if (addr.ss_family == AF_INET6)
2794    {
2795        U8 ipv4Format[12] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff};
2796        pAddr6 = (struct sockaddr_in6*)&addr;
2797        *port = CM_INET_NTOH_U16(pAddr6->sin6_port);
2798
2799       if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
2800       {
2801          srcAddr->type          = CM_INET_IPV4ADDR_TYPE;
2802          cmMemcpy((U8*)&srcAddr->u.ipv4NetAddr, (U8*)((pAddr6->sin6_addr.s6_addr) + 12), sizeof(U32));
2803          srcAddr->u.ipv4NetAddr = CM_INET_HTON_U32(srcAddr->u.ipv4NetAddr);
2804       }
2805
2806       else
2807       {
2808          srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2809          CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr); 
2810       }
2811    }
2812    else 
2813    {
2814       pAddr = (struct sockaddr_in*)&addr;
2815       *port = CM_INET_NTOH_U16(pAddr->sin_port);
2816       srcAddr->type          = CM_INET_IPV4ADDR_TYPE;
2817       srcAddr->u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2818    }
2819 #else 
2820    pAddr = (struct sockaddr_in*)&addr;
2821    *port = CM_INET_NTOH_U16(pAddr->sin_port);
2822    srcAddr->type          = CM_INET_IPV4ADDR_TYPE;
2823    srcAddr->u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2824 #endif /* IPV6_SUPPORTED */
2825
2826    /* fill sndrcv info */
2827    sinfo->stream     = info.sinfo_stream;
2828    sinfo->ssn        = info.sinfo_ssn;
2829    sinfo->flags      = info.sinfo_flags;
2830    /*cm_inet_c_001.main_54: converting ppid to host*/
2831    sinfo->ppid       = CM_INET_NTOH_U32(info.sinfo_ppid);
2832    sinfo->context    = info.sinfo_context;
2833    sinfo->timetolive = info.sinfo_timetolive;
2834    sinfo->tsn        = info.sinfo_tsn;
2835    sinfo->cumtsn     = info.sinfo_cumtsn;
2836    sinfo->assocId    = info.sinfo_assoc_id;
2837
2838    /* fill message flags */
2839    *flag = 0;
2840    if ((msgFlags & MSG_EOR) != 0)
2841       *flag |= CM_INET_SCTP_MSG_EOR;
2842
2843    if ((msgFlags & MSG_NOTIFICATION) != 0)
2844    {
2845       *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2846       *mBuf = NULLP;
2847
2848       sctpNtfy = (union sctp_notification*)recvbuf;
2849
2850       ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2851       ntfy->header.nLen   = sctpNtfy->sn_header.sn_length;
2852
2853       switch(sctpNtfy->sn_header.sn_type)
2854       {
2855          case SCTP_ASSOC_CHANGE:
2856             ntfy->header.nType  = CM_INET_SCTP_ASSOC_CHANGE;
2857             switch(sctpNtfy->sn_assoc_change.sac_state)
2858             {
2859                 case SCTP_COMM_UP:
2860                      ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2861                      break;
2862                 case SCTP_COMM_LOST:
2863                      ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2864                      break;
2865                 case SCTP_RESTART:
2866                      ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2867                      break;
2868                 case SCTP_SHUTDOWN_COMP:
2869                      ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2870                      break;
2871                 case SCTP_CANT_STR_ASSOC:
2872                      ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
2873                      break;
2874                 default:
2875                      break;
2876             }
2877             ntfy->u.assocChange.error      = sctpNtfy->sn_assoc_change.sac_error;
2878             ntfy->u.assocChange.outStreams = sctpNtfy->sn_assoc_change.sac_outbound_streams;
2879             ntfy->u.assocChange.inStreams  = sctpNtfy->sn_assoc_change.sac_inbound_streams;
2880             ntfy->u.assocChange.assocId    = sctpNtfy->sn_assoc_change.sac_assoc_id;
2881 #ifdef SS_LINUX
2882             ntfy->u.assocChange.info       = sctpNtfy->sn_assoc_change.sac_info;
2883 #endif
2884             break;
2885          case SCTP_PEER_ADDR_CHANGE:
2886             ntfy->header.nType  = CM_INET_SCTP_PEER_ADDR_CHANGE;
2887             switch(sctpNtfy->sn_paddr_change.spc_state)
2888             {
2889                 case SCTP_ADDR_AVAILABLE:
2890                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2891                      break;
2892                 case SCTP_ADDR_UNREACHABLE:
2893                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2894                      break;
2895                 case SCTP_ADDR_REMOVED:
2896                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2897                      break;
2898                 case SCTP_ADDR_ADDED:
2899                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2900                      break;
2901                 case SCTP_ADDR_MADE_PRIM:
2902                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2903                      break;
2904 #ifdef SS_LINUX
2905                 case SCTP_ADDR_CONFIRMED:
2906                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2907                      break;
2908 #endif
2909                 default:
2910                 break;
2911             }
2912
2913 #ifdef IPV6_SUPPORTED 
2914             if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
2915             {
2916                pAddr6 = (struct sockaddr_in6*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2917                ntfy->u.paddrChange.addr.type = CM_INET_IPV6ADDR_TYPE;
2918                CM_INET_COPY_IPV6ADDR(&ntfy->u.paddrChange.addr.u.ipv6NetAddr, 
2919                                                     &pAddr6->sin6_addr.s6_addr); 
2920             }
2921             else 
2922             {
2923                pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2924                ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2925                ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2926             }
2927 #else 
2928             pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2929             ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2930             ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2931 #endif /* IPV6_SUPPORTED */
2932
2933             ntfy->u.paddrChange.error   = sctpNtfy->sn_paddr_change.spc_error;
2934             ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2935             break;
2936          case SCTP_REMOTE_ERROR:
2937             ntfy->header.nType  = CM_INET_SCTP_REMOTE_ERROR;
2938
2939             ntfy->u.remoteErr.error   = sctpNtfy->sn_remote_error.sre_error;
2940             ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2941 #ifdef SS_LINUX
2942             /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2943             datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2944
2945             ret = SGetSBuf( meminfo->region, meminfo->pool, \
2946                   &ntfy->u.remoteErr.data, datlen );
2947             if( ret != ROK )
2948             {
2949                ntfy->u.remoteErr.data = NULLP;
2950                break;
2951             }
2952             cmMemcpy(ntfy->u.remoteErr.data,\
2953                   sctpNtfy->sn_remote_error.sre_data, datlen);
2954 #endif
2955             break;
2956          case SCTP_SEND_FAILED:
2957             ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2958
2959             ntfy->u.sndFailed.error           = sctpNtfy->sn_send_failed.ssf_error;
2960             ntfy->u.sndFailed.assocId         = sctpNtfy->sn_send_failed.ssf_assoc_id;
2961 #ifdef SS_LINUX
2962             /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2963             datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2964
2965             ret = SGetSBuf( meminfo->region, meminfo->pool, \
2966                   &ntfy->u.sndFailed.data, datlen );
2967             if( ret != ROK )
2968             {
2969                ntfy->u.sndFailed.data = NULLP;
2970                break;
2971             }
2972             cmMemcpy(ntfy->u.sndFailed.data,\
2973                   sctpNtfy->sn_send_failed.ssf_data, datlen );
2974 #endif
2975             ntfy->u.sndFailed.info.stream     = sctpNtfy->sn_send_failed.ssf_info.sinfo_stream;
2976             ntfy->u.sndFailed.info.ssn        = sctpNtfy->sn_send_failed.ssf_info.sinfo_ssn;
2977             ntfy->u.sndFailed.info.flags      = sctpNtfy->sn_send_failed.ssf_info.sinfo_flags;
2978             ntfy->u.sndFailed.info.ppid       = sctpNtfy->sn_send_failed.ssf_info.sinfo_ppid;
2979             ntfy->u.sndFailed.info.context    = sctpNtfy->sn_send_failed.ssf_info.sinfo_context;
2980             ntfy->u.sndFailed.info.timetolive = sctpNtfy->sn_send_failed.ssf_info.sinfo_timetolive;
2981             ntfy->u.sndFailed.info.tsn        = sctpNtfy->sn_send_failed.ssf_info.sinfo_tsn;
2982             ntfy->u.sndFailed.info.cumtsn     = sctpNtfy->sn_send_failed.ssf_info.sinfo_cumtsn;
2983             ntfy->u.sndFailed.info.assocId    = sctpNtfy->sn_send_failed.ssf_info.sinfo_assoc_id;
2984             break;
2985          case SCTP_SHUTDOWN_EVENT:
2986             ntfy->header.nType  = CM_INET_SCTP_SHUTDOWN_EVENT;
2987
2988             ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2989             break;
2990 #ifdef SUN_KSCTP
2991          case SCTP_ADAPTION_INDICATION :
2992 #else
2993             /* linux */
2994          case SCTP_ADAPTATION_INDICATION :
2995 #endif
2996             ntfy->header.nType  = CM_INET_SCTP_ADAPTATION_INDICATION;
2997
2998 #ifdef SUN_KSCTP
2999             ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
3000             ntfy->u.adaptationEvt.assocId       = sctpNtfy->sn_adaption_event.sai_assoc_id;
3001 #else
3002             /* linux */
3003             ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
3004             ntfy->u.adaptationEvt.assocId       = sctpNtfy->sn_adaptation_event.sai_assoc_id;
3005 #endif
3006             break;
3007          case SCTP_PARTIAL_DELIVERY_EVENT:
3008             ntfy->header.nType  = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
3009
3010             ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
3011             ntfy->u.pdapiEvt.assocId    = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
3012             break;
3013          default:
3014             break;
3015       }
3016    }
3017    else
3018    {
3019       /* get a message buffer */
3020       ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
3021       if (ret != ROK)
3022       {
3023          SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3024          RETVALUE(RFAILED);
3025       }
3026
3027       ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
3028       if (ret != ROK)
3029       {
3030          SPutMsg(*mBuf);
3031          SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3032          RETVALUE(RFAILED);
3033       }
3034    }
3035
3036    /* cleanup */
3037    SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);       
3038
3039    RETVALUE(ROK);
3040 }
3041
3042 /*
3043 *
3044 *      Fun:   cmInetSctpGetPAddrs 
3045 *
3046 *      Desc:  returns the list of peer addresses 
3047 *
3048 *      Ret:   ROK     - successful
3049 *             RFAILED - failed
3050 *
3051 *      Notes: None.
3052 *
3053 *      File:  cm_inet.c
3054 *
3055 */
3056 #ifdef ANSI
3057 PUBLIC S16 cmInetSctpGetPAddrs
3058 (
3059 CmInetFd             *sockFd,       /* socket file descriptor */ 
3060 U32                   assocId,      /* association id */
3061 CmInetNetAddrLst     *addrlst       /* peer address list */
3062 )
3063 #else
3064 PUBLIC S16 cmInetSctpGetPAddrs(sockFd, assocId, addrlst)
3065 CmInetFd             *sockFd;       /* socket file descriptor */ 
3066 U32                   assocId;      /* association id */
3067 CmInetNetAddrLst     *addrlst;      /* peer address list */
3068 #endif
3069 {
3070    /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
3071    S32   cnt;
3072    S32   idx;
3073    U8    *byteAddress;   
3074    struct sockaddr    *peerAddrList;
3075    struct sockaddr_in *pAddr;
3076 #ifdef IPV6_SUPPORTED
3077    struct sockaddr_in6 *pAddr6;
3078 #endif /* IPV6_SUPPORTED */
3079
3080 #ifdef SUN_KSCTP
3081    if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
3082 #else
3083       if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
3084 #endif
3085       {
3086 #ifdef CMINETDBG
3087 #ifndef ALIGN_64BIT
3088          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3089          /* cm_inet_c_001.main_62:Warning fix */
3090          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
3091                " sockFd->fd(%ld), assocId(%ld)\n", 
3092                INET_ERR_CODE, sockFd->fd, assocId);
3093          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
3094 #else
3095       /* cm_inet_c_001.main_55: Fix for compilation warning */
3096       /* cm_inet_c_001.main_62:Warning fix */
3097          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
3098                " sockFd->fd(%d),assocId(%d)\n", 
3099                INET_ERR_CODE, sockFd->fd, assocId);
3100          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
3101 #endif /*ALIGN_64BIT*/
3102 #endif /* CMINETDBG */
3103
3104          RETVALUE(RFAILED);
3105       }
3106
3107    byteAddress = (U8*)peerAddrList;
3108    for (idx = 0; idx < cnt; idx++)
3109    {
3110 #ifdef IPV6_SUPPORTED 
3111
3112       if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
3113       {
3114          if (sockFd->protType == AF_INET)
3115          {
3116 #ifdef CMINETDBG
3117 #ifndef ALIGN_64BIT
3118             /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3119             sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
3120                   " sockFd->fd(%ld)", sockFd->fd);
3121             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
3122 #else
3123             sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
3124                   " sockFd->fd(%d)", sockFd->fd);
3125             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
3126 #endif /*ALIGN_64BIT*/
3127 #endif /* CMINETDBG */
3128
3129             sctp_freepaddrs(peerAddrList);
3130             RETVALUE(RFAILED);
3131          }
3132
3133          pAddr6 = (struct sockaddr_in6*)byteAddress;
3134
3135          addrlst->addrs[idx].type = CM_INET_IPV6ADDR_TYPE;
3136          CM_INET_COPY_IPV6ADDR(&(addrlst->addrs[idx].u.ipv6NetAddr), &(pAddr6->sin6_addr.s6_addr));
3137          byteAddress += sizeof(struct sockaddr_in6);
3138       }
3139       else 
3140       {
3141          pAddr = (struct sockaddr_in*)byteAddress;
3142          addrlst->addrs[idx].type          = CM_INET_IPV4ADDR_TYPE;
3143          addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3144          byteAddress += sizeof(struct sockaddr_in);
3145       }
3146 #else 
3147       pAddr = (struct sockaddr_in*)byteAddress;
3148       addrlst->addrs[idx].type          = CM_INET_IPV4ADDR_TYPE;
3149       addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3150       byteAddress += sizeof(struct sockaddr_in);
3151 #endif /* IPV6_SUPPORTED */
3152    }
3153
3154    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
3155    addrlst->count = (U8)cnt;   
3156
3157    sctp_freepaddrs(peerAddrList);
3158
3159    RETVALUE(ROK);
3160 }
3161
3162 /*
3163 *
3164 *      Fun:    cmInetGetOpt 
3165 *
3166 *      Desc:   invokes socket API to retrive specified socket options
3167 *
3168 *      Ret:   ROK     - successful
3169 *             RFAILED - failed
3170 *
3171 *      Notes:
3172 *
3173 *      File:   cm_inet.c
3174 *
3175 */
3176 #ifdef ANSI
3177 PUBLIC S16 cmInetGetOpt
3178 (
3179 CmInetFd *sockFd,               /* socket file descriptor */ 
3180 U32       level,                /* option level */
3181 U32       type,                 /* option type */
3182 Ptr       value                 /* option value */ 
3183
3184 #else
3185 PUBLIC S16 cmInetGetOpt(sockFd, level, type, value)
3186 CmInetFd *sockFd;               /* socket file descriptor */ 
3187 U32       level;                /* option level */
3188 U32       type;                 /* option type */
3189 Ptr       value;                /* option value */
3190 #endif
3191 {
3192    socklen_t                len;
3193    struct sctp_status       status;
3194    struct sctp_paddrinfo    addrInfo;
3195    struct sockaddr_in      *pAddr;
3196 #ifdef IPV6_SUPPORTED
3197    struct sockaddr_in6     *pAddr6;
3198 #endif /* IPV6_SUPPORTED */
3199    struct sctp_assocparams  assocParams;
3200 /*cm_inet_c_001.main_40 Updated for the support of configurable RTO parameters, 
3201                         HBeat value Max retransmissions (Init, Path, Association)*/
3202    struct sctp_initmsg      initMsg;
3203    struct sctp_rtoinfo      rtoInfo;
3204    struct sctp_paddrparams  addrParams;
3205    CmInetSctpStatus        *pSctpStatus;
3206    CmInetSctpPeerAddrInfo  *pPeerAddrInfo;
3207    CmInetSctpInitMsg       *pInitMsg;
3208    CmInetSctpAssocParams   *pAssocParams;
3209    CmInetSctpRtoInfo       *pRtoInfo;
3210    CmInetSctpPeerAddrParams *pPeerAddrParams;
3211    /*cm_inet_c_001.main_58  : fix for klockwork issue */
3212    S32                     ret;
3213
3214    TRC2(cmInetGetOpt);
3215
3216 #if (ERRCLASS & ERRCLS_INT_PAR)
3217    /* error check on parameters */
3218    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3219    {
3220       RETVALUE(RFAILED);
3221    }
3222 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3223
3224    switch (type) 
3225    {
3226       case CM_INET_OPT_SCTP_GET_ASSOC_STA:
3227          pSctpStatus = (CmInetSctpStatus*)value;
3228          cmMemset((U8*)&status, 0, sizeof(struct sctp_status));
3229          len = sizeof(status);
3230          status.sstat_assoc_id = pSctpStatus->assocId;
3231
3232          ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
3233
3234          pSctpStatus->rwnd      = status.sstat_rwnd;
3235          pSctpStatus->unackdata = status.sstat_unackdata;
3236          pSctpStatus->penddata  = status.sstat_penddata;
3237          pSctpStatus->instrms   = status.sstat_instrms;
3238          pSctpStatus->outstrms  = status.sstat_outstrms;
3239          pSctpStatus->fragPoint = status.sstat_fragmentation_point; 
3240
3241          switch (status.sstat_state)
3242          {
3243 #ifdef SUN_KSCTP
3244             case SCTPS_IDLE:
3245             case SCTPS_BOUND:
3246             case SCTPS_LISTEN:
3247 #else
3248             case SCTP_EMPTY:
3249 #endif
3250                {
3251                   pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3252                }
3253                break;
3254
3255 #ifdef SS_LINUX
3256             case SCTP_CLOSED:
3257                {
3258                   pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3259                }
3260                break;
3261 #endif
3262
3263 #ifdef SUN_KSCTP
3264             case SCTPS_COOKIE_WAIT:
3265 #else
3266             case SCTP_COOKIE_WAIT:
3267 #endif
3268                {
3269                   pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3270                }
3271                break;
3272
3273 #ifdef SUN_KSCTP
3274             case SCTPS_COOKIE_ECHOED:
3275 #else
3276             case SCTP_COOKIE_ECHOED:
3277 #endif
3278                {
3279                   pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3280                }
3281                break;
3282
3283 #ifdef SUN_KSCTP
3284             case SCTPS_ESTABLISHED:
3285 #else
3286             case SCTP_ESTABLISHED:
3287 #endif
3288                {
3289                   pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3290                }
3291                break;
3292
3293 #ifdef SUN_KSCTP
3294             case SCTPS_SHUTDOWN_PENDING:
3295 #else
3296             case SCTP_SHUTDOWN_PENDING:
3297 #endif
3298                {
3299                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3300                }
3301                break;
3302
3303 #ifdef SUN_KSCTP
3304             case SCTPS_SHUTDOWN_SENT:
3305 #else
3306             case SCTP_SHUTDOWN_SENT:
3307 #endif
3308                {
3309                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3310                }
3311                break;
3312
3313 #ifdef SUN_KSCTP
3314             case SCTPS_SHUTDOWN_RECEIVED:
3315 #else
3316             case SCTP_SHUTDOWN_RECEIVED:
3317 #endif
3318                {
3319                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3320                }
3321                break;
3322
3323 #ifdef SUN_KSCTP
3324             case SCTPS_SHUTDOWN_ACK_SENT:
3325 #else
3326             case SCTP_SHUTDOWN_ACK_SENT:
3327 #endif
3328                {
3329                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3330                }
3331                break;
3332
3333             default:
3334                {
3335                   RETVALUE(RFAILED);
3336                }
3337                break;
3338          }
3339
3340 #ifdef IPV6_SUPPORTED 
3341          if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3342          {
3343             pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3344             pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr6->sin6_port);
3345
3346             pSctpStatus->primary.addr.type = CM_INET_IPV6ADDR_TYPE;
3347             CM_INET_COPY_IPV6ADDR(&pSctpStatus->primary.addr.u.ipv6NetAddr, 
3348                   &pAddr6->sin6_addr.s6_addr); 
3349          }
3350          else 
3351          {
3352             pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3353             pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr->sin_port);
3354             pSctpStatus->primary.addr.type          = CM_INET_IPV4ADDR_TYPE;
3355             pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3356          }
3357 #else 
3358          pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3359          pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr->sin_port);
3360          pSctpStatus->primary.addr.type          = CM_INET_IPV4ADDR_TYPE;
3361          pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3362 #endif /* IPV6_SUPPORTED */
3363
3364          pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3365          if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3366              pSctpStatus->primary.isActive = TRUE;
3367          else
3368              pSctpStatus->primary.isActive = FALSE;
3369              pSctpStatus->primary.cwnd = status.sstat_primary.spinfo_cwnd;
3370              pSctpStatus->primary.srtt = status.sstat_primary.spinfo_srtt;
3371              pSctpStatus->primary.rto  = status.sstat_primary.spinfo_rto;
3372              pSctpStatus->primary.mtu  = status.sstat_primary.spinfo_mtu;
3373          break;
3374
3375       case CM_INET_OPT_SCTP_GET_PADDR_INFO:
3376          pPeerAddrInfo = (CmInetSctpPeerAddrInfo*)value;
3377          cmMemset((U8*)&addrInfo, 0, sizeof(struct sctp_paddrinfo));
3378          len = sizeof(addrInfo);
3379          addrInfo.spinfo_assoc_id = pPeerAddrInfo->assocId;
3380
3381 #ifdef IPV6_SUPPORTED 
3382          if (pPeerAddrInfo->addr.type == CM_INET_IPV6ADDR_TYPE)
3383          {
3384             if (sockFd->protType == AF_INET)
3385             {
3386 #ifdef CMINETDBG
3387 #ifndef ALIGN_64BIT
3388                /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3389                /* cm_inet_c_001.main_62:Warning fix */
3390                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3391                      " sockFd->fd(%ld)\n", sockFd->fd);
3392                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3393 #else
3394                /* cm_inet_c_001.main_62:Warning fix */
3395                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3396                      " sockFd->fd(%d)\n", sockFd->fd);
3397                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3398 #endif /*ALIGN_64BIT*/
3399 #endif /* CMINETDBG */
3400                RETVALUE(RFAILED);
3401             }
3402
3403             pAddr6 = (struct sockaddr_in6*)&(addrInfo.spinfo_address);
3404             pAddr6->sin6_family      = AF_INET6;
3405             pAddr6->sin6_port        = CM_INET_HTON_U16(pPeerAddrInfo->port);
3406             CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrInfo->addr.u.ipv6NetAddr); 
3407          }
3408          else 
3409          {
3410             pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3411             pAddr->sin_family      = AF_INET;
3412             pAddr->sin_port        = CM_INET_HTON_U16(pPeerAddrInfo->port);
3413             pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3414          }
3415 #else 
3416          pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3417          pAddr->sin_family      = AF_INET;
3418          pAddr->sin_port        = CM_INET_HTON_U16(pPeerAddrInfo->port);
3419          pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrInfo->addr.u.ipv4NetAddr); 
3420 #endif /* IPV6_SUPPORTED */
3421
3422          /* Not validating the address, whether Addr is a valid address or not */
3423
3424          ret = getsockopt(sockFd->fd, level, SCTP_GET_PEER_ADDR_INFO, &addrInfo, &len);
3425
3426          if (addrInfo.spinfo_state == SCTP_ACTIVE)
3427             pPeerAddrInfo->isActive = TRUE;
3428          else
3429             pPeerAddrInfo->isActive = FALSE;
3430          pPeerAddrInfo->cwnd = addrInfo.spinfo_cwnd;
3431          pPeerAddrInfo->srtt = addrInfo.spinfo_srtt;
3432          pPeerAddrInfo->rto  = addrInfo.spinfo_rto;
3433          pPeerAddrInfo->mtu  = addrInfo.spinfo_mtu;
3434          break;
3435
3436       case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
3437
3438          pPeerAddrParams = (CmInetSctpPeerAddrParams *)value;
3439
3440          cmMemset((U8*)&addrParams, 0, sizeof(struct sctp_paddrparams));
3441
3442          addrParams.spp_assoc_id = pPeerAddrParams->assocId;
3443
3444          if (pPeerAddrParams->s.addrPres == TRUE)
3445          {
3446 #ifdef IPV6_SUPPORTED 
3447             if (pPeerAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
3448             {
3449                if (sockFd->protType == AF_INET)
3450                {
3451 #ifdef CMINETDBG
3452 #ifndef ALIGN_64BIT
3453                   /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3454                   /* cm_inet_c_001.main_62:Warning fix */
3455                   snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%ld)\n",
3456                         sockFd->fd);
3457                   CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3458 #else
3459                   /* cm_inet_c_001.main_62:Warning fix */
3460                   snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%d)\n",
3461                         sockFd->fd);
3462                   CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3463 #endif /*ALIGN_64BIT*/
3464 #endif /* CMINETDBG */
3465                   RETVALUE(RFAILED);
3466                }
3467
3468                pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
3469                pAddr6->sin6_family      = AF_INET6;
3470                pAddr6->sin6_port        = CM_INET_HTON_U16(pPeerAddrParams->s.port);
3471                CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrParams->s.addr.u.ipv6NetAddr); 
3472             }
3473             else 
3474             {
3475                pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3476                pAddr->sin_family      = AF_INET;
3477                pAddr->sin_port        = CM_INET_HTON_U16(pPeerAddrParams->s.port);
3478                pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3479             }
3480 #else 
3481             pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3482             pAddr->sin_family      = AF_INET;
3483             pAddr->sin_port        = CM_INET_HTON_U16(pPeerAddrParams->s.port);
3484             pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3485 #endif /* IPV6_SUPPORTED */
3486          }
3487          else
3488          {
3489 #ifdef IPV6_SUPPORTED 
3490             if (sockFd->protType == AF_INET6)
3491                addrParams.spp_address.ss_family = AF_INET6;
3492             else
3493                addrParams.spp_address.ss_family = AF_INET;
3494 #else
3495             addrParams.spp_address.ss_family = AF_INET;
3496 #endif
3497          }
3498
3499          len = sizeof(addrParams);
3500
3501          ret = getsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, &len);
3502          /* cm_inet_c_001.main_41 : Fixed the Solaris compilation problem */
3503 #ifndef SUN_KSCTP
3504
3505          pPeerAddrParams->hbInterval    = addrParams.spp_hbinterval;
3506          pPeerAddrParams->pathMaxRxt    = addrParams.spp_pathmaxrxt;
3507          pPeerAddrParams->assocId       = addrParams.spp_assoc_id;
3508          pPeerAddrParams->pathMtu       = addrParams.spp_pathmtu;
3509          pPeerAddrParams->sackDelay     = addrParams.spp_sackdelay;
3510
3511          if (addrParams.spp_flags & SPP_HB_ENABLE)
3512             pPeerAddrParams->hbEnblFlag    = CM_INET_OPT_ENABLE;
3513          else
3514             pPeerAddrParams->hbEnblFlag    = CM_INET_OPT_DISABLE;
3515
3516          if (addrParams.spp_flags & SPP_PMTUD_ENABLE)
3517             pPeerAddrParams->pmtudFlag     = CM_INET_OPT_ENABLE;
3518          else
3519             pPeerAddrParams->pmtudFlag     = CM_INET_OPT_DISABLE;
3520
3521          if (addrParams.spp_flags & SPP_SACKDELAY_ENABLE)
3522             pPeerAddrParams->sackDelayFlag = CM_INET_OPT_ENABLE;
3523          else
3524             pPeerAddrParams->sackDelayFlag = CM_INET_OPT_DISABLE;
3525 #endif 
3526
3527          break;
3528
3529       case CM_INET_OPT_SCTP_ASSOC_PARAMS:
3530
3531          pAssocParams = (CmInetSctpAssocParams *)value;
3532
3533          cmMemset((U8*)&assocParams, 0, sizeof(struct sctp_assocparams));
3534
3535          assocParams.sasoc_assoc_id = pAssocParams->assocId;
3536
3537          len = sizeof(assocParams);
3538
3539          ret = getsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, &len);
3540
3541          pAssocParams->assocMaxReTx      = assocParams.sasoc_asocmaxrxt;
3542          pAssocParams->cookieLife        = assocParams.sasoc_cookie_life;
3543          pAssocParams->assocId           = assocParams.sasoc_assoc_id;
3544          pAssocParams->numberOfPeerDest  = assocParams.sasoc_number_peer_destinations;
3545          pAssocParams->peerRwnd          = assocParams.sasoc_peer_rwnd;
3546          pAssocParams->localRwnd         = assocParams.sasoc_local_rwnd;
3547
3548          break;
3549
3550       case CM_INET_OPT_SCTP_RTO_INFO:
3551
3552          pRtoInfo = (CmInetSctpRtoInfo *)value;
3553
3554          cmMemset((U8*)&rtoInfo, 0, sizeof(struct sctp_rtoinfo));
3555
3556          len = sizeof(rtoInfo);
3557
3558          ret = getsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoInfo, &len);
3559
3560          pRtoInfo->assocId    = rtoInfo.srto_assoc_id;
3561          pRtoInfo->rtoInitial = rtoInfo.srto_initial;
3562          pRtoInfo->rtoMax     = rtoInfo.srto_max;
3563          pRtoInfo->rtoMin     = rtoInfo.srto_min;
3564
3565          break;
3566
3567       case CM_INET_OPT_SCTP_INIT_MSG:
3568
3569          pInitMsg = (CmInetSctpInitMsg *)value;
3570
3571          cmMemset((U8*)&initMsg, 0, sizeof(struct sctp_initmsg));
3572
3573          len = sizeof(initMsg);
3574
3575          ret = getsockopt(sockFd->fd, level, SCTP_INITMSG, &initMsg, &len);
3576
3577          pInitMsg->maxInitReTx    = initMsg.sinit_max_attempts;
3578          pInitMsg->maxInitTimeout = initMsg.sinit_max_init_timeo;
3579          pInitMsg->numOstreams    = initMsg.sinit_num_ostreams;
3580          pInitMsg->maxInstreams   = initMsg.sinit_max_instreams;
3581
3582          break;
3583
3584       default:
3585          RETVALUE(RFAILED);
3586    }
3587
3588    if (ret == INET_ERR)
3589    {
3590 #ifdef CMINETDBG
3591 #ifndef ALIGN_64BIT
3592       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3593       /* cm_inet_c_001.main_62:Warning fix */
3594       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3595             " error(%d), sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3596       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3597 #else
3598       /* cm_inet_c_001.main_62:Warning fix */
3599       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3600             " error(%d), sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3601       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3602 #endif /*ALIGN_64BIT*/
3603 #endif /* CMINETDBG */
3604       RETVALUE(RFAILED);
3605    }          
3606
3607    RETVALUE(ROK);
3608 }
3609
3610 /* cm_inet_c_001.main_54: Added new function cmInetShutDownSctp()*/
3611 /*
3612  *
3613  *      Fun:   cmInetShutDownSctp 
3614  *
3615  *      Desc:  Shutdown the SCTP association gracefully.
3616  *
3617  *      Ret:   ROK     - successful
3618  *             RFAILED - failed
3619  *
3620  *      Notes: None.
3621  *
3622  *      File:  cm_inet.c
3623  *
3624  */
3625 #ifdef ANSI
3626 PUBLIC S16 cmInetShutDownSctp
3627 (
3628  CmInetFd          *sockFd       /* socket file descriptor */ 
3629  )
3630 #else
3631 PUBLIC S16 cmInetShutDownSctp(sockFd)
3632    CmInetFd          *sockFd;       /* socket file descriptor */ 
3633 #endif
3634 {
3635    /*cm_inet_c_001.main_58  : fix for klockwork issue */
3636    S32                    ret;
3637    struct sctp_sndrcvinfo sndRcvInfo;
3638
3639    TRC2(cmInetShutDownSctp);
3640
3641    cmMemset((U8*)&sndRcvInfo, 0, sizeof(sndRcvInfo));
3642
3643 #ifdef SUN_KSCTP
3644    sndRcvInfo.sinfo_flags = MSG_EOF;
3645 #else
3646    sndRcvInfo.sinfo_flags = SCTP_EOF;
3647 #endif
3648
3649    /* Call the sctp_send with flag set to termiante the association */
3650
3651    ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3652
3653    if(ret == INET_ERR)
3654    {
3655 #ifdef CMINETDBG
3656 #ifndef ALIGN_64BIT
3657       /* cm_inet_c_001.main_62:Warning fix */
3658       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%ld)\n",
3659             INET_ERR_CODE, sockFd->fd);
3660       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3661 #else
3662       /* cm_inet_c_001.main_62:Warning fix */
3663       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%d)\n",
3664             INET_ERR_CODE, sockFd->fd);
3665       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3666 #endif /*ALIGN_64BIT*/
3667 #endif /* CMINETDBG */
3668
3669       RETVALUE(RFAILED);
3670    }
3671
3672    RETVALUE(ROK);
3673 }
3674
3675 /* cm_inet_c_001.main_61: Added new function cmInetAbortSctpAssoc()*/
3676 /*
3677  *
3678  *      Fun:   cmInetAbortSctpAssoc
3679  *
3680  *      Desc:  ABORT the association.
3681  *
3682  *      Ret:   ROK     - successful
3683  *             RFAILED - failed
3684  *
3685  *      Notes: None.
3686  *
3687  *      File:  cm_inet.c
3688  *
3689  */
3690 #ifdef ANSI
3691 PUBLIC S16 cmInetAbortSctpAssoc
3692 (
3693  CmInetFd          *sockFd,       /* socket file descriptor */
3694  UConnId           assocId          /* Association ID */
3695  )
3696 #else
3697 PUBLIC S16 cmInetAbortSctpAssoc(sockFd, assocId)
3698    CmInetFd          *sockFd;       /* socket file descriptor */
3699    UConnId           assocId;          /* Association ID */
3700 #endif
3701 {
3702    S32                    ret;
3703    struct sctp_sndrcvinfo sndRcvInfo;
3704
3705    TRC2(cmInetAbortSctpAssoc);
3706
3707    cmMemset((U8*)&sndRcvInfo, 0, sizeof(sndRcvInfo));
3708
3709 #ifdef SUN_KSCTP
3710    sndRcvInfo.sinfo_flags = MSG_ABORT;
3711 #else
3712    sndRcvInfo.sinfo_flags = SCTP_ABORT;
3713 #endif
3714
3715    sndRcvInfo.sinfo_assoc_id = assocId;
3716
3717    /* Call the sctp_send with flag set to termiante the association */
3718
3719    ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3720
3721    if(ret == INET_ERR)
3722    {
3723 #ifdef CMINETDBG
3724 #ifndef ALIGN_64BIT
3725       /* cm_inet_c_001.main_62:Warning fix */
3726       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%ld)\n",
3727             INET_ERR_CODE, sockFd->fd);
3728       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3729 #else
3730       /* cm_inet_c_001.main_62:Warning fix */
3731       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%d)\n",
3732             INET_ERR_CODE, sockFd->fd);
3733       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3734 #endif /*ALIGN_64BIT*/
3735 #endif /* CMINETDBG */
3736
3737       RETVALUE(RFAILED);
3738    }
3739
3740    RETVALUE(ROK);
3741 }
3742
3743 #endif
3744
3745 \f
3746 /*
3747  *
3748  *      Fun:   cmInetConnect
3749  *
3750  *      Desc:  Establishs a connection to a foreign address (TCP) or associates
3751  *             a UDP socket to a foreign address.
3752  *
3753  *      Ret:   ROK         - successful
3754 *             ROKDNA      - resource temporarily unavaiable
3755 *             RINPROGRESS - connection is in progress (only non-blocking)
3756 *             RISCONN     - connection is established (only non-blocking)
3757 *             RFAILED     - failed
3758 *
3759 *      Notes: None.
3760 *
3761 *      File:  cm_inet.c
3762 *
3763 */
3764
3765 #ifdef ANSI
3766 PUBLIC S16 cmInetConnect
3767 (
3768 CmInetFd   *sockFd,             /* socket file descriptor */
3769 CmInetAddr *servAddr            /* foreign Internet address/port */  
3770 )
3771 #else
3772 PUBLIC S16 cmInetConnect(sockFd, servAddr)
3773    CmInetFd   *sockFd;             /* socket file descriptor */
3774    CmInetAddr *servAddr;           /* foreign Internet address/port */  
3775 #endif
3776 {
3777    S32 ret;                     /* temporary return value */
3778    struct sockaddr_in dstAddr;  /* foreign Internet address/port */
3779 #ifdef IPV6_SUPPORTED 
3780    struct sockaddr_in6 dstAddr6; /* foreign Internet IPV6 address/port */
3781 #ifdef CMINETDBG
3782    U16            port;
3783 #endif /* CMINETDBG */
3784 #endif /* IPV6_SUPPORTED */
3785    S32    sizeOfAddr;
3786    CmInetSockAddr *sockAddrPtr;  
3787
3788    TRC2(cmInetConnect);
3789
3790 #if (ERRCLASS & ERRCLS_INT_PAR)
3791    /* error check on parameters */
3792    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3793          (servAddr == NULLP))
3794    {
3795       RETVALUE(RFAILED);
3796    }
3797 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3798
3799 #ifdef IPV6_SUPPORTED 
3800    if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3801    {
3802       cmMemset((U8*)&dstAddr6, 0, sizeof(dstAddr6));
3803       dstAddr6.sin6_family     = AF_INET6;
3804       dstAddr6.sin6_port       = CM_INET_HTON_U16(servAddr->u.ipv6Addr.port);
3805       CM_INET_COPY_IPV6ADDR(&dstAddr6.sin6_addr, 
3806                             &servAddr->u.ipv6Addr.ipv6NetAddr);
3807       sizeOfAddr              = sizeof(struct sockaddr_in6);
3808       sockAddrPtr             = (CmInetSockAddr *)&dstAddr6;
3809    }
3810    else
3811    {
3812       cmMemset((U8*)&dstAddr, 0, sizeof(dstAddr));
3813       dstAddr.sin_family      = AF_INET;
3814       dstAddr.sin_port        = CM_INET_HTON_U16(servAddr->u.ipv4Addr.port);
3815       dstAddr.sin_addr.s_addr = CM_INET_HTON_U32(servAddr->u.ipv4Addr.address);
3816       sizeOfAddr              = sizeof(struct sockaddr_in);
3817       sockAddrPtr             = (CmInetSockAddr *)&dstAddr;
3818    }
3819 #else
3820    cmMemset((U8*)&dstAddr, 0, sizeof(dstAddr));
3821    dstAddr.sin_family      = AF_INET;
3822    dstAddr.sin_port        = CM_INET_HTON_U16(servAddr->port);
3823    dstAddr.sin_addr.s_addr = CM_INET_HTON_U32(servAddr->address);
3824    sizeOfAddr              = sizeof(struct sockaddr_in);
3825    sockAddrPtr             = (CmInetSockAddr *)&dstAddr;
3826 #endif /* IPV6_SUPPORTED */
3827
3828    ret = connect(sockFd->fd, sockAddrPtr, sizeOfAddr);
3829    if (ret == INET_ERR)
3830    {
3831       switch (INET_ERR_CODE)
3832       {
3833          /* non-blocking: connection is in progress */
3834          case ERR_INPROGRESS:
3835             RETVALUE(RINPROGRESS);
3836             break;   
3837
3838             /* 
3839              * non-blocking: connection is established 
3840              * blocking    : connection is already established
3841              */
3842          case ERR_ISCONN:
3843             RETVALUE(RISCONN);
3844             break;               
3845
3846             /* resource temporarily unavailable */
3847          case ERR_WOULDBLOCK:
3848             RETVALUE(ROKDNA);
3849             break;
3850
3851             /* non-blocking: connection is in progress */
3852          case ERR_ALREADY:
3853             RETVALUE(RINPROGRESS);
3854             break;
3855
3856          case ERR_INVAL:
3857             RETVALUE(RINPROGRESS);
3858             break;
3859
3860             /*  Check for connection refused and timeout errors */
3861          case ERR_CONNREFUSED:
3862          case ERR_TIMEDOUT:
3863             RETVALUE(RCLOSED);
3864             break;
3865
3866             /* it is a real error */ 
3867          default:
3868 #ifdef CMINETDBG
3869 #ifdef IPV6_SUPPORTED 
3870             if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3871                port = servAddr->u.ipv6Addr.port;
3872             else
3873                port = servAddr->u.ipv4Addr.port;
3874
3875             /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3876 #ifndef ALIGN_64BIT
3877             /* cm_inet_c_001.main_62:Warning fix */
3878             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3879                   " addrtype(0x%x), port(0x%1x), sockFd->fd(%ld)\n", 
3880                   INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3881             CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3882 #else
3883             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3884                   " addrtype(0x%x), port(0x%1x), sockFd->fd(%d)\n", 
3885                   INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3886             CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3887 #endif /*ALIGN_64BIT*/
3888 #else
3889 #ifndef ALIGN_64BIT
3890             /* cm_inet_c_001.main_62:Warning fix */
3891             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%lx),"
3892                   "port(0x%1x), sockFd->fd(%ld)\n", INET_ERR_CODE , 
3893                   servAddr->address, servAddr->port, sockFd->fd);
3894             CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3895 #else
3896             /* cm_inet_c_001.main_62:Warning fix */
3897             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%x),"
3898                   "port(0x%x), sockFd->fd(%d)\n", INET_ERR_CODE , 
3899                   servAddr->address, servAddr->port, sockFd->fd);
3900             CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3901 #endif /*ALIGN_64BIT*/
3902 #endif /* IPV6_SUPPORTED */
3903 #endif /* CMINETDBG */
3904             RETVALUE(RFAILED);
3905             break;
3906       }
3907    }
3908
3909    RETVALUE(ROK);
3910 } /* end of cmInetConnect */
3911
3912 \f
3913 /*
3914 *
3915 *      Fun:   cmInetListen
3916 *
3917 *      Desc:  Indicates the willingness of a socket to listen for incomming 
3918 *             connection requests.
3919 *
3920 *      Ret:   ROK     - successful
3921 *             RFAILED - failed
3922 *
3923 *      Notes: The backLog value has to be within 0..5
3924 *
3925 *      File:  cm_inet.c
3926 *
3927 */
3928
3929 #ifdef ANSI
3930 PUBLIC S16 cmInetListen
3931 (
3932 CmInetFd *sockFd,               /* socket file descriptor */ 
3933 S16       backLog               /* max. number of outstandig connections 0..5 */
3934 )
3935 #else
3936 PUBLIC S16 cmInetListen(sockFd, backLog)
3937 CmInetFd *sockFd;               /* socket file descriptor */ 
3938 S16       backLog;              /* max. number of outstandig connections 0..5 */
3939 #endif
3940 {
3941    S32 ret;                     /* temporary return value */
3942
3943    TRC2(cmInetListen);
3944
3945 #if (ERRCLASS & ERRCLS_INT_PAR)
3946    /* error check on parameters */
3947    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3948          (backLog < MIN_BACK_LOG) || (backLog > MAX_BACK_LOG))
3949    {
3950       RETVALUE(RFAILED);
3951    }
3952 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3953
3954    ret = listen(sockFd->fd, backLog);
3955    if (ret == INET_ERR) 
3956    {
3957 #ifdef CMINETDBG
3958 #ifndef ALIGN_64BIT
3959       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3960       /* cm_inet_c_001.main_62:Warning fix */
3961       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3962             " sockFd->fd(%ld)\n", INET_ERR_CODE, backLog, sockFd->fd);
3963       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3964 #else
3965       /* cm_inet_c_001.main_62:Warning fix */
3966       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3967             " sockFd->fd(%d)\n", INET_ERR_CODE, backLog, sockFd->fd);
3968       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3969 #endif /*ALIGN_64BIT*/
3970 #endif /* CMINETDBG */
3971       RETVALUE(RFAILED);
3972    }
3973
3974    RETVALUE(ROK);
3975 } /* end of cmInetListen */
3976
3977 \f
3978 /*
3979 *
3980 *      Fun:   cmInetAccept 
3981 *
3982 *      Desc:  Accepts an incoming connection.
3983 *             On default the new socket is non-blocking. The options can be 
3984 *             changed with the function cmInetSetOpt().
3985 *
3986 *      Ret:   ROK     - successful
3987 *             ROKDNA  - there is no connection present to accept (only 
3988 *                       non-blocking) 
3989 *             RFAILED - failed
3990 *
3991 *      Notes: None.
3992 *
3993 *      File:  cm_inet.c
3994 *
3995 */
3996
3997 #ifdef ANSI
3998 PUBLIC S16 cmInetAccept
3999 (
4000 CmInetFd   *sockFd,     /* socket file descriptor */ 
4001 CmInetAddr *fromAddr,   /* calling Internet address/port */
4002 CmInetFd   *newSockFd   /* socket file descriptor for new connection*/
4003 )
4004 #else
4005 PUBLIC S16 cmInetAccept(sockFd, fromAddr, newSockFd)
4006 CmInetFd   *sockFd;     /* socket file descriptor */ 
4007 CmInetAddr *fromAddr;   /* calling Internet address/port */
4008 CmInetFd   *newSockFd;  /* socket file descriptor for new connection*/
4009 #endif
4010 {
4011    S32 ret;                         /* temporary return value */
4012    S32 addrLen;                     /* address structure length */
4013    struct sockaddr_in  *peerAddr;   /* calling Internet address/port */
4014 #ifdef IPV6_SUPPORTED 
4015    struct sockaddr_in6 *peerAddr6;  /* calling Internet address/port */
4016    struct sockaddr_in6 sockAddr;
4017 #else
4018    CmInetSockAddr sockAddr;  
4019 #endif /* IPV6_SUPPORTED */
4020
4021    U32 optVal;
4022
4023    /* added */
4024    TRC2(cmInetAccept)
4025
4026 #if (ERRCLASS & ERRCLS_INT_PAR)
4027    /* error check on parameters */
4028    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
4029    {
4030       RETVALUE(RFAILED);
4031    }
4032 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4033
4034    /* change CmInetSockAddr to sockAddr */
4035    addrLen = sizeof(sockAddr);   
4036
4037    /* INSURE fix */
4038 #if ( defined(SUNOS) || defined(SS_LINUX)) 
4039    newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr, 
4040                           (socklen_t *)&addrLen);
4041 #else
4042    newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr, 
4043                           (int*)&addrLen);
4044 #endif /* SUNOS || SS_LINUX */   
4045
4046   /* cm_inet_c_001.main_58: Moved setting of protType below */
4047
4048    if (CM_INET_INV_SOCK_FD(newSockFd))
4049    {
4050       if (INET_ERR_CODE == ERR_WOULDBLOCK)
4051       {
4052          /* no connection present to accept */ 
4053          RETVALUE(ROKDNA);
4054       }
4055       else
4056       {
4057 #ifdef CMINETDBG
4058 #ifndef ALIGN_64BIT
4059          /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
4060          /* cm_inet_c_001.main_62:Warning fix */
4061          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
4062               " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4063          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
4064 #else
4065          /* cm_inet_c_001.main_62:Warning fix */
4066          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
4067                " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4068          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
4069 #endif /*ALIGN_64BIT*/
4070 #endif /* CMINETDBG */
4071          RETVALUE(RFAILED);
4072       }
4073    }     
4074
4075
4076   /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
4077    /* added for IPv6/IPv4 socket distinguishing */
4078 #ifdef IPV6_SUPPORTED   
4079    if (addrLen == sizeof(struct sockaddr_in))
4080       newSockFd->protType = AF_INET;
4081    else if(addrLen == sizeof(struct sockaddr_in6))
4082       newSockFd->protType = AF_INET6;
4083    else
4084    {
4085 #ifdef CMINETDBG
4086 #ifndef ALIGN_64BIT
4087       /* cm_inet_c_001.main_62:Warning fix */
4088       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%ld)\n", sockFd->fd);
4089       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
4090 #else
4091       /* cm_inet_c_001.main_62:Warning fix */
4092       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%d)\n", sockFd->fd);
4093       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
4094 #endif /*ALIGN_64BIT*/
4095 #endif /* CMINETDBG */
4096          RETVALUE(RFAILED);
4097    }
4098 #endif /* IPV6_SUPPORTED */      
4099
4100    /* set the new socket file descriptor type */
4101    newSockFd->type = CM_INET_STREAM;
4102
4103    /* set default options for new socket file descriptor */
4104    optVal = CM_INET_OPT_DISABLE;
4105    ret = cmInetSetOpt(newSockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, &optVal); 
4106    if ( ret != ROK) 
4107    {
4108       ret = cmInetClose(newSockFd);
4109       RETVALUE(RFAILED);
4110    }
4111
4112 #ifdef IPV6_SUPPORTED
4113    cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
4114    if (addrLen == sizeof(struct sockaddr_in))
4115    {
4116       peerAddr = (struct sockaddr_in *)&sockAddr;
4117       fromAddr->type = CM_INET_IPV4ADDR_TYPE;
4118       fromAddr->u.ipv4Addr.port    = CM_INET_NTOH_U16(peerAddr->sin_port);
4119       fromAddr->u.ipv4Addr.address = 
4120                               CM_INET_NTOH_U32(peerAddr->sin_addr.s_addr);
4121    }
4122    else if (addrLen == sizeof(struct sockaddr_in6))
4123    {
4124       peerAddr6 = (struct sockaddr_in6 *)&sockAddr;
4125       fromAddr->type = CM_INET_IPV6ADDR_TYPE;
4126       fromAddr->u.ipv6Addr.port    = CM_INET_NTOH_U16(peerAddr6->sin6_port);
4127       CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr, 
4128                             &peerAddr6->sin6_addr);
4129    }
4130 #else
4131    peerAddr = (struct sockaddr_in *)&sockAddr;
4132    fromAddr->port    = CM_INET_NTOH_U16(peerAddr->sin_port);
4133    fromAddr->address = CM_INET_NTOH_U32(peerAddr->sin_addr.s_addr);
4134 #endif /* IPV6_SUPPORTED */
4135    RETVALUE(ROK);
4136 } /* end of cmInetAccept */ 
4137
4138 \f
4139 /*
4140 *
4141 *      Fun:   cmInet4FillTos 
4142 *
4143 *      Desc:  This function inserts tos (into ancillary data) which 
4144 *             will be used to fill tos value in ip header in outgoing IP packet
4145 *             when sending that packet using sendmsg()function.
4146 *
4147 *      Ret:   ROK   
4148 *
4149 *      Notes:  
4150 *
4151 *      File:  cm_inet.c
4152 *
4153 */
4154
4155 #ifdef ANSI
4156 PRIVATE S16 cmInet4FillTos
4157 (
4158 U8  tos,        /* tos value to be filled in ipheader */
4159 U8  *cmsgBuf,   /* flat buffer where to build ext hdrs */
4160 U32 *curMsgIdx  /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4161 )
4162 #else
4163 PRIVATE S16 cmInet4FillTos(tos, cmsgBuf, curMsgIdx, protType)
4164 U8   tos;       /* tos value to be filled in ipheader */
4165 U8  *cmsgBuf;   /* flat buffer where to build ext hdrs */
4166 U32 *curMsgIdx; /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4167 #endif /* ANSI */
4168 {
4169    struct cmsghdr *tempHdr;
4170    U8     len;
4171
4172    TRC2(cmInet4FillTos)
4173
4174       len = 0;
4175
4176
4177    /* cmsghdr struc will appear before data in the ancillary data object. 
4178     * So put cmsghdr struc in flat buffer first. */
4179
4180    /* cmsghdr struc points to flat buffer's starting address */
4181    tempHdr = (struct cmsghdr *)cmsgBuf;  
4182
4183    /* fill up level & type of cmsghdr structure */
4184    tempHdr->cmsg_level = IPPROTO_IPV6;
4185    tempHdr->cmsg_type = IP_TOS;
4186    (*(U8*)CMSG_DATA(tempHdr)) = tos;
4187    len = CMSG_SPACE(sizeof tos); 
4188
4189
4190    /* fill up the length of cmsghdr structure */
4191    tempHdr->cmsg_len = len;  
4192    *curMsgIdx += len;
4193
4194    RETVALUE(ROK);
4195
4196 }/* end of cmInet4FillTos */ 
4197 /*
4198 *
4199 *      Fun:   cmInetSendDscpMsg
4200 *
4201 *      Desc:  Sends the message data hold by mBuf. 
4202 *             The len paramter gives the actual written octets. If the socket
4203 *             is non-blocking this value can be differ from the mBuf length 
4204 *             because there was not enough transmit buffer space available. If 
4205 *             this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4206 *             is sent.
4207 *             Values for flag parameter:
4208 *  
4209 *             CM_INET_NO_FLAG - no additional control flag
4210 *
4211 *      Ret:   ROK         - successful
4212 *             RWOULDBLOCK - no or not entire mBuf sent because would block
4213 *             ROUTRES     - failed, out of resources
4214 *             RCLOSED     - connection was closed by the peer
4215 *             RFAILED     - failed
4216 *                           
4217 *      Notes: The successful completion of a send call does not indicate that 
4218 *             the data has been successfully delivered! 
4219 *
4220 *             This function does not free any sent buffers.  
4221 *
4222 *   
4223 *      File:  cm_inet.c
4224 *
4225 */
4226
4227 #ifdef ANSI
4228 PUBLIC S16 cmInetSendDscpMsg
4229 (
4230 CmInetFd       *sockFd,         /* socket file descriptor */
4231 CmInetAddr     *dstAddr,        /* destination Internet address/port */
4232 CmInetMemInfo  *info,           /* buffer allocation info */
4233 Buffer         *mBuf,           /* buffer structure to send */
4234 MsgLen         *len,            /* number of actually sent octets */
4235 /* added for IPv6 ext hdr */
4236 CmInetIpHdrParm *ipHdrParams,   /* IPv6 extensions headers */
4237 S16             flags           /* additional control flags, unused */
4238 )
4239 #else
4240 /* added for IPv6 ext hdr */
4241 PUBLIC S16 cmInetSendDscpMsg(sockFd, dstAddr, info, mBuf, len, ipHdrParams, flags)
4242 CmInetFd       *sockFd;         /* socket file descriptor */
4243 CmInetAddr     *dstAddr;        /* destination Internet address/port */
4244 CmInetMemInfo  *info;           /* buffer allocation info */
4245 Buffer         *mBuf;           /* buffer structure to send */
4246 MsgLen         *len;            /* number of actually sent octets */
4247 CmInetIpHdrParm *ipHdrParams;   /* IPv6 extensions headers */
4248 S16             flags;          /* additional control flags, unused */
4249 #endif /* ANSI */
4250 {
4251 #if (defined(WIN32) || defined(CMINETFLATBUF))
4252    S32     ret;                 /* temporary return value */
4253    MsgLen  msgLen;              /* message length */ 
4254    MsgLen  bufLen;              /* send buffer length */
4255    Data   *sendBuf;             /* plain send buffer */
4256 #else
4257    S32 ret;                     /* temporary return value */
4258    S32 retVal;                  /* temporary return value */
4259    S16 i;                       /* loop index */
4260    CmInetIovec  txArr[CM_INET_MAX_DBUF]; /* scatter vector */
4261    S16      numDBufs;           /* number of dBufs in message */
4262    struct   msghdr msg;         /* sendmsg() message header */
4263    MsgLen   msgLen;             /* message length */ 
4264    U32      strtEndDBufNum;     /* starting/ending DBuf number */ 
4265    MsgLen   unSentLen;          /* sent len */
4266 #ifdef IPV6_SUPPORTED 
4267    U32    curMsgIdx;            /* indx in cmsgData where to write an ext hdr */
4268    /* added for IPv6 ext hdr */
4269 #if (defined(SS_LINUX) || defined(_XPG4_2))
4270    /* alloc from stack for IPv6 ancill data */
4271    U8     cmsgData[CM_INET_IPV6_ANCIL_DATA];
4272 #endif /* SS_LINUX || _XPG4_2 */
4273 #else
4274    U32    curMsgIdx;            /* indx in cmsgData where to write an ext hdr */
4275 #if (defined(SS_LINUX) || defined(_XPG4_2))
4276    /* alloc from stack for IPv4 ancill data */ 
4277     U8     cmsgData[CM_INET_IPV4_ANCIL_DATA];
4278 #endif /* SS_LINUX || _XPG4_2 */
4279 #endif /* IPV6_SUPPORTED */   
4280 #endif /* WIN32 | CMINETFLATBUF */  
4281
4282    struct  sockaddr_in remAddr; /* remote Internet address */   
4283 #ifdef IPV6_SUPPORTED
4284    struct   sockaddr_in6  remAddr6; /* remote Internet address */   
4285 #endif /* IPV8_SUPPORTED */
4286    CmInetSockAddr *sockAddrPtr;
4287    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4288    U32            sizeOfAddr;    
4289
4290    /* cm_inet_c_001.main_50 - Added for partial send handling */
4291    /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4292 #if (!defined(WIN32)) 
4293    MsgLen         ioLen; 
4294 #endif
4295
4296    TRC2(cmInetSendDscpMsg)
4297
4298       UNUSED(flags);
4299
4300 #if (ERRCLASS & ERRCLS_INT_PAR)
4301    /* error check on parameters */
4302    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4303          (info == NULLP) || (len == NULLP))
4304    {
4305       RETVALUE(RFAILED);
4306    }
4307 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4308
4309    /* added for IPv6 ext hdr */
4310 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4311 #if (defined(SS_LINUX) || defined(_XPG4_2))
4312 /*   cmMemset((U8*)cmsgData, 0, sizeof(cmsgData));    */
4313 #endif /* SS_LINUX || _XPG4_2 */
4314    curMsgIdx   = 0;
4315 #endif /* WIN32 | CMINETFLATBUF */
4316
4317    msgLen = 0;  /* need by CC to pass without warning */
4318    sockAddrPtr = NULLP;
4319    sizeOfAddr = 0;
4320
4321    /* setup remote address */
4322    if (dstAddr != NULLP)
4323    {
4324 #ifdef IPV6_SUPPORTED
4325       if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4326       {
4327          cmMemset((U8*)&remAddr6, 0, sizeof(remAddr6));
4328          remAddr6.sin6_family = AF_INET6;
4329          remAddr6.sin6_port   = CM_INET_HTON_U16(dstAddr->u.ipv6Addr.port);
4330          CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr, 
4331                &dstAddr->u.ipv6Addr.ipv6NetAddr); 
4332          sizeOfAddr = sizeof(remAddr6);
4333          sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4334       }
4335       else
4336       {
4337          cmMemset((U8*)&remAddr, 0, sizeof(remAddr));
4338          remAddr.sin_family = AF_INET;
4339          remAddr.sin_port   = CM_INET_HTON_U16(dstAddr->u.ipv4Addr.port);
4340          remAddr.sin_addr.s_addr = 
4341             CM_INET_HTON_U32(dstAddr->u.ipv4Addr.address);
4342          sizeOfAddr = sizeof(remAddr);
4343          sockAddrPtr = (CmInetSockAddr *)&remAddr;
4344       }
4345 #else
4346 /*      cmMemset((U8*)&remAddr, 0, sizeof(remAddr)); */
4347       remAddr.sin_family      = AF_INET;
4348       remAddr.sin_port        = CM_INET_HTON_U16(dstAddr->port);
4349       remAddr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->address);
4350       sizeOfAddr = sizeof(remAddr);
4351       sockAddrPtr = (CmInetSockAddr *)&remAddr;
4352 #endif /* IPV6_SUPPORTED */
4353    }
4354
4355 #if (defined(WIN32) || defined(CMINETFLATBUF))
4356    /* copy message to a flat buffer */
4357    ret = SFndLenMsg(mBuf, &bufLen);
4358    if (ret != ROK)
4359    {
4360       RETVALUE(RFAILED);
4361    }
4362    /* max message length is limited to control the memory usage */
4363    /* casting bufLen to avoid warnings */
4364    if ((bufLen > 0) && ((U32)bufLen > CM_INET_MAX_MSG_LEN))
4365    {
4366       RETVALUE(RFAILED);
4367    }
4368    ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);                  
4369    if (ret != ROK)
4370    {
4371       RETVALUE(ROUTRES);
4372    }
4373    ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4374    if ((ret != ROK) || (msgLen != bufLen)) 
4375    {
4376       /* cleanup */
4377       SPutSBuf(info->region, info->pool, sendBuf, bufLen);       
4378       RETVALUE(RFAILED);
4379    }
4380
4381    if (dstAddr == NULLP)
4382    {
4383       /* VxWorks sendto has some problem
4384        * with connected UDP socket, use send */
4385 #ifndef SS_VW
4386       ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0, 
4387             NULLP, sizeOfAddr);
4388 #else
4389       ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4390 #endif /* end of SS_VW */
4391    }
4392    else
4393       /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4394    {
4395 #if (defined(SS_VW) && defined(SS_VW6_7)) 
4396       if ((sockFd->type  == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4397       {
4398          ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4399       }
4400       else
4401 #endif /* end of SS_VW6_7 and SS_VW */
4402       {
4403          ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0, 
4404                sockAddrPtr, sizeOfAddr); 
4405       }
4406    }
4407    if (ret == INET_ERR)
4408    {
4409       /* cleanup */
4410       SPutSBuf(info->region, info->pool, sendBuf, bufLen);      
4411
4412       if(INET_ERR_CODE == ERR_AGAIN)
4413       {
4414          *len = 0;
4415          RETVALUE(RWOULDBLOCK);
4416       }
4417
4418       /* Check for ERR_WOULDBLOCK */
4419       if(INET_ERR_CODE == ERR_WOULDBLOCK)
4420       {
4421          *len = 0;
4422          RETVALUE(RWOULDBLOCK);
4423       }
4424
4425 #ifdef CMINETDBG
4426 #ifndef ALIGN_64BIT
4427       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4428       /* cm_inet_c_001.main_62:Warning fix */
4429       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4430             " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4431       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4432 #else
4433       /* cm_inet_c_001.main_62:Warning fix */
4434       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4435             " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4436       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4437 #endif /*ALIGN_64BIT*/
4438 #endif /* CMINETDBG */
4439
4440       /* cm_inet_c_001.main_37 network unreacheble error is added */
4441       /* check if network is reacheble*/
4442       if ((INET_ERR_CODE == ERR_NETUNREACH))
4443       {
4444          RETVALUE(RNETFAILED);
4445       }
4446
4447
4448       /*  Check if connection was closed */
4449       if ((INET_ERR_CODE == ERR_PIPE) ||
4450             (INET_ERR_CODE == ERR_CONNABORTED) || 
4451             (INET_ERR_CODE == ERR_CONNRESET))
4452       {
4453          *len = 0;
4454          RETVALUE(RCLOSED);
4455       }
4456
4457       RETVALUE(RFAILED);
4458    }
4459
4460    *len = ret;
4461
4462    /* check if entire message could be sent */
4463
4464    if (ret < bufLen) 
4465    {   
4466       /* cleanup */
4467       SPutSBuf(info->region, info->pool, sendBuf, bufLen);      
4468       RETVALUE(RWOULDBLOCK);
4469    }
4470
4471    /* cleanup */
4472    SPutSBuf(info->region, info->pool, sendBuf, bufLen);      
4473
4474 #else /* end of Win NT/flat buffer specific part */
4475    ret = SFndLenMsg(mBuf, &msgLen);
4476    if (ret != ROK)
4477    {
4478       RETVALUE(RFAILED);
4479    }
4480
4481    /* added */
4482 /*   cmMemset((U8*)&msg, 0, sizeof(msg)); */
4483    msg.msg_flags = 0;
4484
4485    if (dstAddr != NULLP)
4486    {
4487 #ifdef SS_LINUX
4488       msg.msg_name    = (Void*)sockAddrPtr;
4489 #else
4490 #ifdef SS_PS
4491       msg.msg_name    = (char *)sockAddrPtr;
4492 #else
4493       msg.msg_name    = (caddr_t)sockAddrPtr;
4494 #endif /* SS_PS */
4495 #endif /* SS_LINUX */
4496       msg.msg_namelen = sizeOfAddr;
4497    }
4498    else
4499    {
4500       msg.msg_name    = NULLP;         
4501       msg.msg_namelen = 0;
4502    }
4503    /* added  defined(_XPG4_2) */
4504 #if (defined(SS_LINUX) || defined(_XPG4_2))
4505    msg.msg_control    = NULLP;
4506    msg.msg_controllen  = 0;
4507 #else
4508    msg.msg_accrights     = 0;
4509    msg.msg_accrightslen  = NULLP; 
4510 #endif /* SS_LINUX */
4511
4512    /* allocate scatter vector */
4513    numDBufs = CM_INET_MAX_DBUF;
4514    retVal = RNA;
4515    ret = ROK;
4516    unSentLen = msgLen;
4517    strtEndDBufNum = 0;
4518    *len = 0;
4519    if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV4ADDR_TYPE))
4520       if((ipHdrParams->u.hdrParmIpv4.tos.pres == TRUE)&& \
4521             (ipHdrParams->u.hdrParmIpv4.tos.val != 0))
4522       {
4523          cmInet4FillTos(ipHdrParams->u.hdrParmIpv4.tos.val, 
4524                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
4525          msg.msg_control = cmsgData;     /* pointer to Ancillary Data */
4526          msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4527       } 
4528    /* if the sender wants to send Ipv6 exten. headers */
4529 #ifdef IPV6_OPTS_SUPPORTED
4530    if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4531    {     
4532 #ifdef SS_LINUX
4533       if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4534       {
4535          cmInetBuildSendHoplimit((U32)ipHdrParams->u.ipv6HdrParm.ttl.val,
4536                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);  
4537       }
4538 #endif /* SS_LINUX */
4539
4540 #ifdef LOCAL_INTF      
4541       /* have to decide how to get the src addr to add in in6_pktinfo */
4542       if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4543       {  
4544          cmInet6BuildSendPktinfo(
4545                &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr, 
4546                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx,
4547                sockFd->protType);
4548       }
4549 #endif /* LOCAL_INTF */
4550
4551       /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4552        * cmsgData one by one. */
4553
4554       if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4555          /* build HBH ext header in cmsgData starting at indx 0 */
4556          cmInet6BuildSendHBHOpts(
4557                &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr, 
4558                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 0);                           
4559
4560       /* now copy the elements from the Destination Option array one by
4561        * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx 
4562        * which is the end of HBH hdr. */          
4563       if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4564          /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4565          cmInet6BuildSendDestOpts(
4566                &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4567                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4568
4569       /* copy Route header to to the Flat Buffer cmsgData */
4570       if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4571          /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4572          cmInet6BuildSendRouteOpts(
4573                &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4574                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
4575
4576       /* msghrd struc's msg_control will point cmsgData and msg_controllen
4577        * will be the curMsgIdx */ 
4578       msg.msg_control = cmsgData;     /* pointer to Ancillary Data */
4579       msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4580
4581    }
4582 #endif /* IPV6_OPTS_SUPPORTED */
4583
4584    /* Loop till all the data is sent or till the sendmsg call cannot send 
4585     * any more data. */
4586    do
4587    {
4588       /* build the send vector */ 
4589       /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4590          total length of the packed dbufs */
4591       retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i, 
4592             &strtEndDBufNum, &ioLen);
4593       if (retVal != ROK)
4594       {
4595          if (retVal == RNA)
4596          {
4597             /* Incase of UDP/RAW messages call SCompressMsg. */
4598             if (sockFd->type != CM_INET_STREAM)
4599             {
4600                /* Compress the message into a single dBuf */
4601                ret = SCompressMsg(mBuf);
4602                if (ret != ROK)
4603                   RETVALUE(RFAILED);
4604
4605                strtEndDBufNum = 0;
4606                /* Rebuild the send vector */
4607                /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4608                   total length of the packed dbuf */
4609                ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4610                      &strtEndDBufNum, &ioLen);
4611                if (ret != ROK)
4612                   RETVALUE(RFAILED);
4613
4614                retVal = ROK;
4615             }
4616          }
4617          else
4618             RETVALUE(RFAILED);
4619       }
4620       msg.msg_iov           = txArr;
4621       msg.msg_iovlen        = i;
4622
4623
4624 #ifdef NTL_LIB
4625      {
4626          extern int ntl_hLib;
4627          if ( sockFd->fd >= 0xD001)
4628              ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4629              else
4630              ret = sendmsg(sockFd->fd, &msg, 0);
4631      }
4632 #else 
4633      ret = sendmsg(sockFd->fd, &msg, 0);
4634 #endif 
4635       /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4636       if (ret == INET_ERR)
4637       {
4638          if((INET_ERR_CODE == ERR_AGAIN) ||
4639                (INET_ERR_CODE == ERR_WOULDBLOCK))
4640          {
4641             /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial 
4642                message was sent earlier */
4643             RETVALUE(RWOULDBLOCK);
4644          }
4645 #ifdef CMINETDBG
4646 #ifndef ALIGN_64BIT
4647          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4648          /* cm_inet_c_001.main_62:Warning fix */
4649          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4650                " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4651          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4652 #else
4653          /* cm_inet_c_001.main_62:Warning fix */
4654          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4655                " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4656          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4657 #endif /*ALIGN_64BIT*/
4658 #endif /* CMINETDBG */
4659
4660          /* cm_inet_c_001.main_37 network unreacheble error is added */
4661          /* check if network is reacheble or not */
4662          if ((INET_ERR_CODE == ERR_NETUNREACH))      
4663          {
4664             RETVALUE(RNETFAILED);
4665          }
4666
4667          /*  Check if connection was closed by the peer */
4668          if ((INET_ERR_CODE == ERR_PIPE) ||
4669                (INET_ERR_CODE == ERR_CONNREFUSED) ||
4670                (INET_ERR_CODE == ERR_CONNABORTED))
4671          {
4672             *len = 0;
4673             RETVALUE(RCLOSED);
4674          }
4675          RETVALUE(RFAILED);
4676       }
4677
4678       /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4679       *len += ret;
4680
4681       /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4682        * to be sent, then return WOULDBLOCK
4683        */
4684       if (ret < ioLen)
4685          RETVALUE(RWOULDBLOCK);
4686
4687       unSentLen -= ret;
4688
4689    } while (*len < msgLen);
4690 #endif /* WIN32 | CMINETFLATBUF */
4691
4692    RETVALUE(ROK);
4693
4694 } /* end of cmInetSendDscpMsg */
4695
4696 /*
4697 *
4698 *      Fun:   cmInetSendMsg
4699 *
4700 *      Desc:  Sends the message data hold by mBuf. 
4701 *             The len paramter gives the actual written octets. If the socket
4702 *             is non-blocking this value can be differ from the mBuf length 
4703 *             because there was not enough transmit buffer space available. If 
4704 *             this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4705 *             is sent.
4706 *             Values for flag parameter:
4707 *  
4708 *             CM_INET_NO_FLAG - no additional control flag
4709 *
4710 *      Ret:   ROK         - successful
4711 *             RWOULDBLOCK - no or not entire mBuf sent because would block
4712 *             ROUTRES     - failed, out of resources
4713 *             RCLOSED     - connection was closed by the peer
4714 *             RFAILED     - failed
4715 *                           
4716 *      Notes: The successful completion of a send call does not indicate that 
4717 *             the data has been successfully delivered! 
4718 *
4719 *             This function does not free any sent buffers.  
4720 *
4721 *   
4722 *      File:  cm_inet.c
4723 *
4724 */
4725
4726 #ifdef ANSI
4727 PUBLIC S16 cmInetSendMsg
4728 (
4729 CmInetFd       *sockFd,         /* socket file descriptor */
4730 CmInetAddr     *dstAddr,        /* destination Internet address/port */
4731 CmInetMemInfo  *info,           /* buffer allocation info */
4732 Buffer         *mBuf,           /* buffer structure to send */
4733 MsgLen         *len,            /* number of actually sent octets */
4734 /* added for IPv6 ext hdr */
4735 #ifdef IPV6_OPTS_SUPPORTED
4736 CmInetIpHdrParm *ipHdrParams,   /* IPv6 extensions headers */
4737 #endif /* IPV6_OPTS_SUPPORTED */
4738 S16             flags           /* additional control flags, unused */
4739 )
4740 #else
4741 /* added for IPv6 ext hdr */
4742 #ifdef IPV6_OPTS_SUPPORTED
4743 PUBLIC S16 cmInetSendMsg(sockFd, dstAddr, info, mBuf, len, ipHdrParams, flags)
4744 CmInetFd       *sockFd;         /* socket file descriptor */
4745 CmInetAddr     *dstAddr;        /* destination Internet address/port */
4746 CmInetMemInfo  *info;           /* buffer allocation info */
4747 Buffer         *mBuf;           /* buffer structure to send */
4748 MsgLen         *len;            /* number of actually sent octets */
4749 CmInetIpHdrParm *ipHdrParams;   /* IPv6 extensions headers */
4750 S16             flags;          /* additional control flags, unused */
4751 #else
4752 PUBLIC S16 cmInetSendMsg(sockFd, dstAddr, info, mBuf, len, flags)
4753 CmInetFd       *sockFd;         /* socket file descriptor */
4754 CmInetAddr     *dstAddr;        /* destination Internet address/port */
4755 CmInetMemInfo  *info;           /* buffer allocation info */
4756 Buffer         *mBuf;           /* buffer structure to send */
4757 MsgLen         *len;            /* number of actually sent octets */
4758 S16             flags;          /* additional control flags, unused */
4759 #endif /* IPV6_OPTS_SUPPORTED */
4760 #endif /* ANSI */
4761 {
4762 #if (defined(WIN32) || defined(CMINETFLATBUF))
4763    S32     ret;                 /* temporary return value */
4764    MsgLen  msgLen;              /* message length */ 
4765    MsgLen  bufLen;              /* send buffer length */
4766    Data   *sendBuf;             /* plain send buffer */
4767 #else
4768    S32 ret;                     /* temporary return value */
4769    S32 retVal;                  /* temporary return value */
4770    S16 i;                       /* loop index */
4771    CmInetIovec  txArr[CM_INET_MAX_DBUF]; /* scatter vector */
4772    S16      numDBufs;           /* number of dBufs in message */
4773    struct   msghdr msg;         /* sendmsg() message header */
4774    MsgLen   msgLen;             /* message length */ 
4775    U32      strtEndDBufNum;     /* starting/ending DBuf number */ 
4776    MsgLen   unSentLen;          /* sent len */
4777 #ifdef IPV6_SUPPORTED 
4778    /* added for IPv6 ext hdr */
4779 #ifdef IPV6_OPTS_SUPPORTED
4780    U32    curMsgIdx;            /* indx in cmsgData where to write an ext hdr */
4781 #if (defined(SS_LINUX) || defined(_XPG4_2))
4782    /* alloc from stack for IPv6 ancill data */
4783    U8     cmsgData[CM_INET_IPV6_ANCIL_DATA];
4784 #endif /* SS_LINUX || _XPG4_2 */
4785 #endif /* IPV6_OPTS_SUPPORTED */
4786 #else
4787 #if (defined(SS_LINUX) || defined(_XPG4_2))
4788    /* alloc from stack for IPv4 ancill data */ 
4789    /* U8     cmsgData[CM_INET_IPV4_ANCIL_DATA];*/
4790 #endif /* SS_LINUX || _XPG4_2 */
4791 #endif /* IPV6_SUPPORTED */   
4792 #endif /* WIN32 | CMINETFLATBUF */  
4793
4794    struct  sockaddr_in remAddr; /* remote Internet address */   
4795 #ifdef IPV6_SUPPORTED
4796    struct   sockaddr_in6  remAddr6; /* remote Internet address */   
4797 #endif /* IPV8_SUPPORTED */
4798    CmInetSockAddr *sockAddrPtr;
4799    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4800    U32            sizeOfAddr;    
4801
4802    /* cm_inet_c_001.main_50 - Added for partial send handling */
4803    /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4804 #if (!defined(WIN32)) 
4805    MsgLen         ioLen; 
4806 #endif
4807
4808    TRC2(cmInetSendMsg)
4809
4810       UNUSED(flags);
4811
4812 #if (ERRCLASS & ERRCLS_INT_PAR)
4813    /* error check on parameters */
4814    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4815          (info == NULLP) || (len == NULLP))
4816    {
4817       RETVALUE(RFAILED);
4818    }
4819 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4820
4821    /* added for IPv6 ext hdr */
4822 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4823 #if (defined(SS_LINUX) || defined(_XPG4_2))
4824 /*   cmMemset((U8*)cmsgData, 0, sizeof(cmsgData));    */
4825 #endif /* SS_LINUX || _XPG4_2 */
4826 #ifdef IPV6_OPTS_SUPPORTED
4827    curMsgIdx   = 0;
4828 #endif /* IPV6_SUPPORTED */ 
4829 #endif /* WIN32 | CMINETFLATBUF */
4830
4831    msgLen = 0;  /* need by CC to pass without warning */
4832    sockAddrPtr = NULLP;
4833    sizeOfAddr = 0;
4834
4835    /* setup remote address */
4836    if (dstAddr != NULLP)
4837    {
4838 #ifdef IPV6_SUPPORTED
4839       if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4840       {
4841          cmMemset((U8*)&remAddr6, 0, sizeof(remAddr6));
4842          remAddr6.sin6_family = AF_INET6;
4843          remAddr6.sin6_port   = CM_INET_HTON_U16(dstAddr->u.ipv6Addr.port);
4844          CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr, 
4845                &dstAddr->u.ipv6Addr.ipv6NetAddr); 
4846          sizeOfAddr = sizeof(remAddr6);
4847          sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4848       }
4849       else
4850       {
4851          cmMemset((U8*)&remAddr, 0, sizeof(remAddr));
4852          remAddr.sin_family = AF_INET;
4853          remAddr.sin_port   = CM_INET_HTON_U16(dstAddr->u.ipv4Addr.port);
4854          remAddr.sin_addr.s_addr = 
4855             CM_INET_HTON_U32(dstAddr->u.ipv4Addr.address);
4856          sizeOfAddr = sizeof(remAddr);
4857          sockAddrPtr = (CmInetSockAddr *)&remAddr;
4858       }
4859 #else
4860 /*      cmMemset((U8*)&remAddr, 0, sizeof(remAddr)); */
4861       remAddr.sin_family      = AF_INET;
4862       remAddr.sin_port        = CM_INET_HTON_U16(dstAddr->port);
4863       remAddr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->address);
4864       sizeOfAddr = sizeof(remAddr);
4865       sockAddrPtr = (CmInetSockAddr *)&remAddr;
4866 #endif /* IPV6_SUPPORTED */
4867    }
4868
4869 #if (defined(WIN32) || defined(CMINETFLATBUF))
4870    /* copy message to a flat buffer */
4871    ret = SFndLenMsg(mBuf, &bufLen);
4872    if (ret != ROK)
4873    {
4874       RETVALUE(RFAILED);
4875    }
4876    /* max message length is limited to control the memory usage */
4877    /* casting bufLen to avoid warnings */
4878    if ((bufLen > 0) && ((U32)bufLen > CM_INET_MAX_MSG_LEN))
4879    {
4880       RETVALUE(RFAILED);
4881    }
4882    ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);                  
4883    if (ret != ROK)
4884    {
4885       RETVALUE(ROUTRES);
4886    }
4887    ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4888    if ((ret != ROK) || (msgLen != bufLen)) 
4889    {
4890       /* cleanup */
4891       SPutSBuf(info->region, info->pool, sendBuf, bufLen);       
4892       RETVALUE(RFAILED);
4893    }
4894
4895    if (dstAddr == NULLP)
4896    {
4897       /* VxWorks sendto has some problem
4898        * with connected UDP socket, use send */
4899 #ifndef SS_VW
4900       ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0, 
4901             NULLP, sizeOfAddr);
4902 #else
4903       ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4904 #endif /* end of SS_VW */
4905    }
4906    else
4907       /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4908    {
4909 #if (defined(SS_VW) && defined(SS_VW6_7)) 
4910       if ((sockFd->type  == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4911       {
4912          ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4913       }
4914       else
4915 #endif /* end of SS_VW6_7 and SS_VW */
4916       {
4917          ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0, 
4918                sockAddrPtr, sizeOfAddr); 
4919       }
4920    }
4921    if (ret == INET_ERR)
4922    {
4923       /* cleanup */
4924       SPutSBuf(info->region, info->pool, sendBuf, bufLen);      
4925
4926       if(INET_ERR_CODE == ERR_AGAIN)
4927       {
4928          *len = 0;
4929          RETVALUE(RWOULDBLOCK);
4930       }
4931
4932       /* Check for ERR_WOULDBLOCK */
4933       if(INET_ERR_CODE == ERR_WOULDBLOCK)
4934       {
4935          *len = 0;
4936          RETVALUE(RWOULDBLOCK);
4937       }
4938
4939 #ifdef CMINETDBG
4940 #ifndef ALIGN_64BIT
4941       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4942       /* cm_inet_c_001.main_62:Warning fix */
4943       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4944             " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4945       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4946 #else
4947       /* cm_inet_c_001.main_62:Warning fix */
4948       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4949             " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4950       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4951 #endif /*ALIGN_64BIT*/
4952 #endif /* CMINETDBG */
4953
4954       /* cm_inet_c_001.main_37 network unreacheble error is added */
4955       /* check if network is reacheble*/
4956       if ((INET_ERR_CODE == ERR_NETUNREACH))
4957       {
4958          RETVALUE(RNETFAILED);
4959       }
4960
4961
4962       /*  Check if connection was closed */
4963       if ((INET_ERR_CODE == ERR_PIPE) ||
4964             (INET_ERR_CODE == ERR_CONNABORTED) || 
4965             (INET_ERR_CODE == ERR_CONNRESET))
4966       {
4967          *len = 0;
4968          RETVALUE(RCLOSED);
4969       }
4970
4971       RETVALUE(RFAILED);
4972    }
4973
4974    *len = ret;
4975
4976    /* check if entire message could be sent */
4977
4978    if (ret < bufLen) 
4979    {   
4980       /* cleanup */
4981       SPutSBuf(info->region, info->pool, sendBuf, bufLen);      
4982       RETVALUE(RWOULDBLOCK);
4983    }
4984
4985    /* cleanup */
4986    SPutSBuf(info->region, info->pool, sendBuf, bufLen);      
4987
4988 #else /* end of Win NT/flat buffer specific part */
4989    ret = SFndLenMsg(mBuf, &msgLen);
4990    if (ret != ROK)
4991    {
4992       RETVALUE(RFAILED);
4993    }
4994
4995    /* added */
4996 /*   cmMemset((U8*)&msg, 0, sizeof(msg)); */
4997    msg.msg_flags = 0;
4998
4999    if (dstAddr != NULLP)
5000    {
5001 #ifdef SS_LINUX
5002       msg.msg_name    = (Void*)sockAddrPtr;
5003 #else
5004 #ifdef SS_PS
5005       msg.msg_name    = (char *)sockAddrPtr;
5006 #else
5007       msg.msg_name    = (caddr_t)sockAddrPtr;
5008 #endif /* SS_PS */
5009 #endif /* SS_LINUX */
5010       msg.msg_namelen = sizeOfAddr;
5011    }
5012    else
5013    {
5014       msg.msg_name    = NULLP;         
5015       msg.msg_namelen = 0;
5016    }
5017    /* added  defined(_XPG4_2) */
5018 #if (defined(SS_LINUX) || defined(_XPG4_2))
5019    msg.msg_control    = NULLP;
5020    msg.msg_controllen  = 0;
5021 #else
5022    msg.msg_accrights     = 0;
5023    msg.msg_accrightslen  = NULLP; 
5024 #endif /* SS_LINUX */
5025
5026    /* allocate scatter vector */
5027    numDBufs = CM_INET_MAX_DBUF;
5028    retVal = RNA;
5029    ret = ROK;
5030    unSentLen = msgLen;
5031    strtEndDBufNum = 0;
5032    *len = 0;
5033
5034    /* if the sender wants to send Ipv6 exten. headers */
5035 #ifdef IPV6_OPTS_SUPPORTED
5036    if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
5037    {     
5038 #ifdef SS_LINUX
5039       if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
5040       {
5041          cmInetBuildSendHoplimit((U32)ipHdrParams->u.ipv6HdrParm.ttl.val,
5042                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);  
5043       }
5044 #endif /* SS_LINUX */
5045
5046 #ifdef LOCAL_INTF      
5047       /* have to decide how to get the src addr to add in in6_pktinfo */
5048       if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
5049       {  
5050          cmInet6BuildSendPktinfo(
5051                &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr, 
5052                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx,
5053                sockFd->protType);
5054       }
5055 #endif /* LOCAL_INTF */
5056
5057       /* copy each ipv6 ext header from ipHdrParams to the flat buffer
5058        * cmsgData one by one. */
5059
5060       if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
5061          /* build HBH ext header in cmsgData starting at indx 0 */
5062          cmInet6BuildSendHBHOpts(
5063                &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr, 
5064                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 0);                           
5065
5066       /* now copy the elements from the Destination Option array one by
5067        * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx 
5068        * which is the end of HBH hdr. */          
5069       if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
5070          /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
5071          cmInet6BuildSendDestOpts(
5072                &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
5073                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
5074
5075       /* copy Route header to to the Flat Buffer cmsgData */
5076       if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
5077          /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
5078          cmInet6BuildSendRouteOpts(
5079                &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
5080                (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
5081
5082       /* msghrd struc's msg_control will point cmsgData and msg_controllen
5083        * will be the curMsgIdx */ 
5084       msg.msg_control = cmsgData;     /* pointer to Ancillary Data */
5085       msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
5086
5087    }
5088 #endif /* IPV6_OPTS_SUPPORTED */
5089
5090    /* Loop till all the data is sent or till the sendmsg call cannot send 
5091     * any more data. */
5092    do
5093    {
5094       /* build the send vector */ 
5095       /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
5096          total length of the packed dbufs */
5097       retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i, 
5098             &strtEndDBufNum, &ioLen);
5099       if (retVal != ROK)
5100       {
5101          if (retVal == RNA)
5102          {
5103             /* Incase of UDP/RAW messages call SCompressMsg. */
5104             if (sockFd->type != CM_INET_STREAM)
5105             {
5106                /* Compress the message into a single dBuf */
5107                ret = SCompressMsg(mBuf);
5108                if (ret != ROK)
5109                   RETVALUE(RFAILED);
5110
5111                strtEndDBufNum = 0;
5112                /* Rebuild the send vector */
5113                /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
5114                   total length of the packed dbuf */
5115                ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
5116                      &strtEndDBufNum, &ioLen);
5117                if (ret != ROK)
5118                   RETVALUE(RFAILED);
5119
5120                retVal = ROK;
5121             }
5122          }
5123          else
5124             RETVALUE(RFAILED);
5125       }
5126       msg.msg_iov           = txArr;
5127       msg.msg_iovlen        = i;
5128
5129
5130 #ifdef NTL_LIB
5131      {
5132          extern int ntl_hLib;
5133          if ( sockFd->fd >= 0xD001)
5134              ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
5135              else
5136              ret = sendmsg(sockFd->fd, &msg, 0);
5137      }
5138 #else 
5139      ret = sendmsg(sockFd->fd, &msg, 0);
5140 #endif 
5141       /* cm_inet_c_001.main_50 - Update the length only in successful cases */
5142       if (ret == INET_ERR)
5143       {
5144          if((INET_ERR_CODE == ERR_AGAIN) ||
5145                (INET_ERR_CODE == ERR_WOULDBLOCK))
5146          {
5147             /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial 
5148                message was sent earlier */
5149             RETVALUE(RWOULDBLOCK);
5150          }
5151 #ifdef CMINETDBG
5152 #ifndef ALIGN_64BIT
5153          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5154          /* cm_inet_c_001.main_62:Warning fix */
5155          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
5156                " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
5157          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
5158 #else
5159          /* cm_inet_c_001.main_62:Warning fix */
5160          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
5161                " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
5162          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
5163 #endif /*ALIGN_64BIT*/
5164 #endif /* CMINETDBG */
5165
5166          /* cm_inet_c_001.main_37 network unreacheble error is added */
5167          /* check if network is reacheble or not */
5168          if ((INET_ERR_CODE == ERR_NETUNREACH))      
5169          {
5170             RETVALUE(RNETFAILED);
5171          }
5172
5173          /*  Check if connection was closed by the peer */
5174          if ((INET_ERR_CODE == ERR_PIPE) ||
5175                (INET_ERR_CODE == ERR_CONNREFUSED) ||
5176                (INET_ERR_CODE == ERR_CONNABORTED))
5177          {
5178             *len = 0;
5179             RETVALUE(RCLOSED);
5180          }
5181          RETVALUE(RFAILED);
5182       }
5183
5184       /* cm_inet_c_001.main_50 - Update the length only in successful cases */
5185       *len += ret;
5186
5187       /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
5188        * to be sent, then return WOULDBLOCK
5189        */
5190       if (ret < ioLen)
5191          RETVALUE(RWOULDBLOCK);
5192
5193       unSentLen -= ret;
5194
5195    } while (*len < msgLen);
5196 #endif /* WIN32 | CMINETFLATBUF */
5197
5198    RETVALUE(ROK);
5199
5200 } /* end of cmInetSendMsg */
5201
5202 \f
5203 /* added new functions for IPv6 extension headers */
5204 #ifdef IPV6_OPTS_SUPPORTED
5205 #ifdef LOCAL_INTF
5206 /*
5207 *
5208 *      Fun:   cmInet6BuildSendPktinfo
5209 *
5210 *      Desc:  This function inserts src address (into ancillary data) which 
5211 *             will be used as the src addr in outgoing IP packet when sending
5212 *             that packet using sendmsg()function.
5213 *
5214 *      Ret:   ROK   
5215 *
5216 *      Notes:  
5217 *
5218 *      File:  cm_inet.c
5219 *
5220 */
5221
5222 #ifdef ANSI
5223 PRIVATE S16 cmInet6BuildSendPktinfo
5224 (
5225 CmInetIpAddr6 *srcAddr, /* src ip addr to set on outgoing packet */
5226 U8  *cmsgBuf,   /* flat buffer where to build ext hdrs */
5227 U32 *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5228 U8   protType   /* whether IPv4/IPv6 socket */
5229 )
5230 #else
5231 PRIVATE S16 cmInet6BuildSendPktinfo(srcAddr, cmsgBuf, curMsgIdx, protType)
5232 CmInetIpAddr6 *srcAddr; /* src ip addr to set on outgoing packet */
5233 U8  *cmsgBuf;   /* flat buffer where to build ext hdrs */
5234 U32 *curMsgIdx; /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5235 U8   protType;  /* whether IPv4/IPv6 socket */
5236 #endif /* ANSI */
5237 {
5238    struct cmsghdr *tempHdr;
5239    struct in6_pktinfo *ipv6Pktinfo;
5240    struct in6_addr lpBkAddr;
5241    U8     len;
5242
5243    TRC2(cmInet6BuildSendPktinfo)
5244
5245       len = 0;
5246
5247    lpBkAddr = in6addr_loopback;
5248
5249    /* cmsghdr struc will appear before data in the ancillary data object. 
5250     * So put cmsghdr struc in flat buffer first. */
5251
5252    /* cmsghdr struc points to flat buffer's starting address */
5253    tempHdr = (struct cmsghdr *)cmsgBuf;  
5254
5255    /* fill up level & type of cmsghdr structure */
5256    if (protType == AF_INET6)
5257    {   
5258       tempHdr->cmsg_level = IPPROTO_IPV6;
5259       tempHdr->cmsg_type = IPV6_PKTINFO;
5260    }
5261 #ifdef CMINETDBG   
5262    else if(protType == AF_INET)
5263    {
5264       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5265       /* cm_inet_c_001.main_62:Warning fix */
5266       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5267             "protType(%d)\n", protType);
5268       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET025, 0, prntBuf);
5269
5270    }
5271 #endif
5272    /* skip length of cmsghdr structure - 12 bytes */
5273    len += sizeof(struct cmsghdr); 
5274
5275    if(protType == AF_INET6)
5276       ipv6Pktinfo = (struct in6_pktinfo *)(cmsgBuf + len);
5277 #ifdef CMINETDBG   
5278    else
5279    {
5280       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5281       /* cm_inet_c_001.main_62:Warning fix */
5282       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5283             "protType(%d)\n",  protType);
5284       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET026, 0, prntBuf);
5285    }
5286 #endif
5287
5288    /* insert the hoplimit. This will override the kernel's
5289     * default hoplimit value */
5290    if(protType == AF_INET6)
5291    {  
5292       /* store ipv6 src addr */ 
5293       cmMemcpy((U8 *)&(ipv6Pktinfo->ipi6_addr), (U8 *)srcAddr, 16);
5294       len += 16;
5295
5296       /* store interface index */
5297       /* 0 is invalid intf indx it tells kernel to chose any intf it likes to
5298        * send this pkt. if we use nozero intf indx then kernel will send this
5299        * pkt only through that intf */
5300       ipv6Pktinfo->ipi6_ifindex = 0;
5301       len += sizeof(int);
5302    }   
5303 #ifdef CMINETDBG   
5304    else if(protType == AF_INET)
5305    {
5306       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5307       /* cm_inet_c_001.main_62:Warning fix */
5308       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5309             "protType(%d)\n", protType);
5310       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET027, 0, prntBuf);
5311    }
5312 #endif
5313
5314    /* fill up the length of cmsghdr structure */
5315    tempHdr->cmsg_len = len;  
5316    *curMsgIdx += len;
5317
5318    RETVALUE(ROK);
5319
5320 }/* end of cmInet6BuildSendPktinfo */ 
5321 #endif /* LOCAL_INTF */
5322
5323 \f
5324 #ifdef SS_LINUX
5325 /*
5326 *
5327 *      Fun:   cmInetBuildSendHoplimit
5328 *
5329 *      Desc:  This function inserts hoplimit value to be sent out by ancillary
5330 *             data by calling sendmsg()function.
5331 *
5332 *      Ret:   ROK   
5333 *
5334 *      Notes:  
5335 *
5336 *      File:  cm_inet.c
5337 *
5338 */
5339
5340 #ifdef ANSI
5341 PRIVATE S16 cmInetBuildSendHoplimit
5342 (
5343 U32   hoplimit,  /* the hoplimit value to be set on outgoing packet */
5344 U8  *cmsgBuf,   /* flat buffer where to build ext hdrs */
5345 U32 *curMsgIdx  /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5346 )
5347 #else
5348 PRIVATE S16 cmInetBuildSendHoplimit(hoplimit, cmsgBuf, curMsgIdx)
5349 U32  hoplimit;  /* the hoplimit value to be sent on outgoing packet */
5350 U8  *cmsgBuf;   /* flat buffer where to build ext hdrs */
5351 U32 *curMsgIdx; /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5352 #endif /* ANSI */
5353 {
5354    struct cmsghdr *tempHdr; 
5355    U8    len;
5356
5357    TRC2(cmInetBuildSendHoplimit)
5358
5359       len = 0;
5360
5361    /* cmsghdr struc will appear before data in the ancillary data object. 
5362     * So put cmsghdr struc in flat buffer first. */
5363
5364    /* cmsghdr struc points to flat buffer's starting address */
5365    tempHdr = (struct cmsghdr *)cmsgBuf;  
5366
5367    /* fill up level & type of cmsghdr structure */
5368    tempHdr->cmsg_level = IPPROTO_IPV6;
5369    tempHdr->cmsg_type = IPV6_HOPLIMIT;
5370
5371    /* skip cmsghdr struc (length of cmsghdr structure) */
5372    len += sizeof(struct cmsghdr); 
5373
5374    /* insert the hoplimit. This will override the kernel's
5375     * default hoplimit value */ 
5376    *(cmsgBuf + len) = hoplimit;
5377    len += sizeof(hoplimit);
5378
5379    /* fill up the length of cmsghdr structure */
5380    tempHdr->cmsg_len = len;
5381    *curMsgIdx += len;
5382
5383    RETVALUE(ROK);
5384 } /* end of cmInetBuildSendHoplimit  */
5385 #endif /* SS_LINUX */
5386
5387 \f
5388 /*
5389 *
5390 *      Fun:   cmInet6BuildSendHBHOpts
5391 *
5392 *      Desc:  This function builds the HopByHop option which will be put
5393 *             in the data portion of the ancillary data object. To build  
5394 *             the HopByHop option this function takes an array of 
5395 *             individual HopByHop option and fill them in a flat buffer.
5396 *             cmsghdr struc always appear before HopBYHop Options, Dest 
5397 *             Options and Route header option.
5398 *
5399 *             The address of the flat Buffer *cmsgBuf is passed to this
5400 *             function from cmInetSendMsg. This buffer will have all extension
5401 *             headers. This buffer is passed as ancillary data by sendmsg()
5402 *     
5403 *      Ret:   
5404 *
5405 *      Notes: This function will also be used for Destination options 
5406 *
5407 *      File:  cm_inet.c
5408 *
5409 */
5410
5411 #ifdef ANSI
5412 PRIVATE S16 cmInet6BuildSendHBHOpts
5413 (
5414 CmInetIpv6HBHHdrArr *hbhOptsArr,/* IPv6 extensions headers HBH/Dest opts */
5415 U8 *cmsgBuf,                    /* flat buffer where to build ext hdrs */
5416 U32 *curMsgIdx,                 /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5417 U8 hdrId                        /* 0: HBH hdr, 1:Dest Hdr */
5418 )
5419 #else
5420 PRIVATE S16 cmInet6BuildSendHBHOpts(hbhOptsArr, cmsgBuf, curMsgIdx, hdrId)
5421 CmInetIpv6HBHHdrArr *hbhOptsArr;/* IPv6 extensions headers HBH/Dest opts */
5422 U8 *cmsgBuf;                    /* flat buffer where to build ext hdrs */
5423 U32 *curMsgIdx;                 /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5424 U8 hdrId;                       /* 0: HBH hdr, 1:Dest Hdr */
5425 #endif
5426 {
5427    struct cmsghdr *tempHdr; 
5428    U8    len;
5429    U8    optsIdx;
5430
5431    TRC2(cmInet6BuildSendHBHOpts)
5432
5433       len = 0;
5434    optsIdx = 0;
5435
5436    /* cmsghdr struc will appear before data in the ancillary data object. 
5437     * So put cmsghdr struc in flat buffer first. */
5438
5439    /* cmsghdr struc points to flat buffer's starting address */
5440    tempHdr = (struct cmsghdr *)cmsgBuf;  
5441
5442    /* fill up level & type of cmsghdr structure */
5443    if (hdrId == 0)
5444    {   
5445       tempHdr->cmsg_level = IPPROTO_IPV6;
5446       tempHdr->cmsg_type = IPV6_HOPOPTS;
5447    }
5448    else if (hdrId == 1)
5449    {
5450       tempHdr->cmsg_level = IPPROTO_IPV6;
5451       tempHdr->cmsg_type = IPV6_DSTOPTS;
5452    }
5453
5454    /* skip cmsghdr struc (length of cmsghdr structure) */
5455    len += (sizeof(tempHdr->cmsg_level) + sizeof(tempHdr->cmsg_len) + 
5456          sizeof(tempHdr->cmsg_type));
5457
5458    /* Next Hdr: will be fill up accordingly by Kernel */ 
5459    *(cmsgBuf + len) = 0x00;
5460    len += 1;
5461
5462    /* Header Ext Length: will be fill up by us. In units of 8-byte excluding 
5463     * first 8 bytes starting from Next Header field. */       
5464    *(cmsgBuf + len) = 0x00; 
5465    len += 1;
5466
5467    /* fillup all HBH/dest options' TLV. Here, we assume that all the HBH/dest
5468     * options are packed inside 1 HBH option header. */      
5469    for (optsIdx = 0; optsIdx < hbhOptsArr->numHBHOpts; 
5470          optsIdx ++)
5471    {
5472       /* Copy the TLV into cmsgBuf data portion */
5473       /* copy type field of every HBH/dest option */
5474       *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].type;
5475       len += sizeof(hbhOptsArr->hbhOpts[optsIdx].type);
5476
5477       /* copy length field of every HBH/dest option */
5478       *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].length; 
5479       len += sizeof(hbhOptsArr->hbhOpts[optsIdx].length);         
5480
5481       /* copy all value bytes of current HBH/dest option to the flat buffer */
5482       cmMemcpy((U8 *)(cmsgBuf + len),
5483             (U8 *)(hbhOptsArr->hbhOpts[optsIdx].value), 
5484             hbhOptsArr->hbhOpts[optsIdx].length);
5485       len += hbhOptsArr->hbhOpts[optsIdx].length; 
5486    }
5487
5488    /* cuMsgIdx will have the total length of HBH options array */
5489    /* add this length to the length of cmsgHdr struc */
5490
5491    /* Padding: Different header has different padding requirement(xn+y). For
5492     * HBH Router Alert we need 2 bytes of padding. As this same function is
5493     * used for Destination option also and there is no option for it is yet
5494     * proposed, we are passing padN options - 6 bytes to make the Dest Option
5495     * hdr a multiple of 8 bytes. */
5496
5497    /* HBH: padN of 2 bytes needed for Router Alert */
5498    /* This logic is present currently to support router alert which is the 
5499     * only supported HBH option today. For other, generic method needed */ 
5500    if (hdrId == 0)
5501    {       
5502       *(cmsgBuf + len) = 0x01;
5503       len += 1;
5504       *(cmsgBuf + len) = 0x00;
5505       len += 1;
5506    }
5507
5508    /* fill up the length of cmsghdr structure */
5509    tempHdr->cmsg_len = len;
5510    *curMsgIdx += len;
5511
5512    RETVALUE(ROK);    
5513 } /* end of cmInet6BuildSendHBHOpts */
5514
5515 \f
5516 /*
5517 *
5518 *      Fun:   cmInet6BuildSendRouteOpts
5519 *
5520 *      Desc:  This function transfers bytes from the Route hdr array to the 
5521 *             flat buffer. First the top cmsghdr structure will be filled in
5522 *             the flat buffer, then route hdr type 0 will be added after 
5523 *             cmsghdr struc in the flat buffer. Then all IPV6 addresses will
5524 *             be filled up.
5525 *     
5526 *      Ret:   
5527 *
5528 *      Notes: None
5529 *
5530 *      File:  cm_inet.c
5531 *
5532 */
5533
5534 #ifdef ANSI
5535 PRIVATE S16 cmInet6BuildSendRouteOpts
5536 (
5537 CmInetIpv6RtHdr *rtOptsArr,  /* IPv6 destination options array */
5538 U8 *cmsgBuf,                 /* flat buffer where to build ext hdrs */
5539 U32 *curMsgIdx               /* idx in cmsgBuf where to start building RT hdr */
5540 )
5541 #else
5542 PRIVATE S16 cmInet6BuildSendRouteOpts(rtOptsArr, cmsgBuf, curMsgIdx)
5543 CmInetIpv6RtHdr *rtOptsArr;  /* IPv6 destination options array */
5544 U8 *cmsgBuf;                 /* flat buffer where to build ext hdrs */
5545 U32 *curMsgIdx;              /* idx in cmsgBuf where to start building RT hd */
5546 #endif /* ANSI */
5547 {
5548    struct cmsghdr *tempHdr;
5549    CmInetIpv6RtHdr0 *tempRtHdr;
5550    U8    len; 
5551    U8    addrIdx;
5552
5553    TRC2(cmInet6BuildSendRouteOpts);
5554
5555    len = 0;
5556    addrIdx = 0;
5557
5558    /* cmsghdr struc will appear before data in the ancillary data object. 
5559     * So put cmsghdr struc in flat buffer first */
5560
5561    /* cmsghdr struc points to flat buffer */
5562    tempHdr = (struct cmsghdr *)(cmsgBuf); 
5563
5564    tempHdr->cmsg_level = IPPROTO_IPV6;
5565    tempHdr->cmsg_type = IPV6_RTHDR;
5566
5567    /* skip cmsghdr structure */
5568    len += sizeof(struct cmsghdr);
5569
5570    /* we know the total size of Route hdr if we know the num of ipv6 addrs */
5571    tempHdr->cmsg_len = len + sizeof(CmInetIpv6RtHdr0)
5572       + rtOptsArr->numAddrs * sizeof(CmInetIpAddr6);
5573
5574    /* attach route hdr type 0 after cmsghdr structure */
5575    tempRtHdr = (CmInetIpv6RtHdr0 *)(cmsgBuf + len);
5576
5577    /* fill up fields of route hdr type 0 */
5578
5579    /* will be filled up by Kernel */
5580    tempRtHdr->ip6r0_nextHdr = 0x00;  
5581
5582    tempRtHdr->ip6r0_hdrExtLen = (2 * rtOptsArr->numAddrs); 
5583
5584    /* only type supported today */
5585    tempRtHdr->ip6r0_type = 0x00;        
5586
5587    tempRtHdr->ip6r0_segLeft = rtOptsArr->numAddrs; 
5588
5589    /* Note: rfc 2292(1998) mentions 1 reserve byte & 3 strict/loose bytes 
5590     * restricting total 23 ipv6 addresses can be added to the route header.
5591     * But rfc 2292(2002) mentions all 4 bytes are reserved which allows 
5592     * as many ipv6 addresses as wishes to be added to the route header */
5593
5594    tempRtHdr->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5595
5596    /* move pointer in the flat buffer to the end of this structure */
5597    len +=  sizeof(CmInetIpv6RtHdr0); 
5598
5599    /* fill up all IPV6 addresses from rtOptsArr in the flat buffer */
5600    for (addrIdx = 0; addrIdx < rtOptsArr->numAddrs; addrIdx++)
5601    {   
5602       cmMemcpy((U8 *)(cmsgBuf + len),
5603             (U8 *)(rtOptsArr->ipv6Addrs[addrIdx]), 16);
5604       len += 16;
5605    }
5606
5607    *curMsgIdx += len;  
5608    RETVALUE(ROK);
5609 } /* end of cmInet6BuildSendRouteOpts */
5610
5611 \f
5612 /*
5613 *
5614 *      Fun:   cmInet6BuildRecvHopOptsArr
5615 *
5616 *      Desc:  This function fills up the HopByHop Array of ipHdrParam from 
5617 *             the ancillary data received through recvmsg() call. The memory
5618 *             to hold the extension headers is allocated here. All received 
5619 *             ext hdr info will be passed to upper user as ipHdrParam.
5620 *     
5621 *      Ret:   ROK     - successful
5622 *             RFAILED - failed
5623 *
5624 *      Notes: None
5625 *
5626 *      File:  cm_inet.c
5627 *
5628 */
5629
5630 #ifdef ANSI
5631 PRIVATE S16 cmInet6BuildRecvHopOptsArr
5632 (
5633 U8 *cmsgData,                    /* flat buffer where to build ext hdrs */
5634 U32 hbhDataLen,                  /* byte len of cmsghdr + hbh ancil data */
5635 CmInetIpv6HBHHdrArr *hbhOptsArr, /* IPv6 extensions headers */
5636 U8 hdrId,                        /* 0: HBH, 1: DEST */
5637 CmInetMemInfo   *info            /* Memory information */
5638 )
5639 #else
5640 PRIVATE S16 cmInet6BuildRecvHopOptsArr(cmsgData, hbhDataLen, hbhOptsArr, hdrId, 
5641                                       info)
5642 U8 *cmsgData;                    /* flat buffer where to build ext hdrs  */
5643 U32 hbhDataLen;                  /* byte len of cmsghdr + hbh ancil data */
5644 CmInetIpv6HBHHdrArr *hbhOptsArr; /* IPv6 extensions headers */
5645 U8 hdrId;                        /* 0: HBH, 1: DEST */
5646 CmInetMemInfo   *info;           /* Memory information */
5647 #endif /* ANSI */
5648 {
5649    U32 curDataIdx;       /* to keep track where we are in the hbh Data */
5650    U8  optsIdx;          /* how many hbh opts present in data */
5651    U8  numOpts;          /* number of hbh opts present in data */
5652    U8  tempLen;
5653    U8  tempType;
5654    S16 ret;
5655
5656    TRC2(cmInet6BuildRecvHopOptsArr)
5657
5658       /* get length of actual hbh ancillary data */
5659       hbhDataLen -= sizeof(struct cmsghdr); 
5660
5661    curDataIdx = 0;                
5662    optsIdx = 0;
5663    numOpts = 0;
5664
5665    /* skip Next Hdr byte & Hdr Ext Length byte */
5666    curDataIdx += 2;               
5667
5668    /* First find out how many hop-by-hop headers we need to allocate */
5669    for (;;)   
5670    {
5671       /* break when all HBH data is copied to hbhOptsArr */
5672       if (curDataIdx >= hbhDataLen)
5673          break;   
5674
5675       numOpts += 1;
5676
5677       /* get type */ 
5678       tempType = *(U8 *)(cmsgData + curDataIdx);
5679       curDataIdx += 1;               
5680
5681       /* take care of pad1 option */
5682       if (tempType == 0) 
5683       {
5684          /* not considering the pad1 as valid option */
5685          numOpts -= 1; 
5686          continue;
5687       }
5688
5689       /* get length */
5690       tempLen = *(U8 *)(cmsgData + curDataIdx);
5691
5692       /* 1 is to skip length. tempLen to skip the value field */
5693       curDataIdx += (1 + tempLen);
5694
5695       /* considering the padN as valid option for Dest Opt Hdr!!! As this is
5696        * the "only" valid option today. Ignore for HBH hdr */
5697       if (hdrId != 1)
5698          if (tempType == 1) 
5699             numOpts -= 1;
5700    }
5701
5702    /* allocate mem needed to hold all HBH/Dest options */
5703    ret = SGetSBuf(info->region, info->pool, 
5704          (Data **)&hbhOptsArr->hbhOpts, 
5705          (Size)((sizeof(CmInetIpv6HBHHdr)) * numOpts)); 
5706    if (ret != ROK)
5707    {
5708 #ifdef CMINETDBG      
5709       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5710       /* cm_inet_c_001.main_62:Warning fix */
5711       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvHopOptsArr\n");
5712       CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET028, 0, prntBuf);
5713 #endif /* CMINETDBG */     
5714       RETVALUE(ROUTRES);
5715    }   
5716
5717    curDataIdx = 0;                
5718    optsIdx = 0;
5719
5720    /* skip Next Hdr byte & Hdr Ext Length byte */
5721    curDataIdx += 2;               
5722
5723    hbhOptsArr->numHBHOpts = numOpts;
5724
5725    /* fill up HBH/dest opt array from recvd ancillary data */
5726    for (;;)   
5727    {
5728       /* break when all HBH data is copied to hbhOptsArr */
5729       if (curDataIdx >= hbhDataLen)
5730          break;   
5731
5732       /* only copy Router Alert HBH option part which has type 5. Otherwise,
5733        * skip it when it is a PAD1, PADN or Jumbogram option for HBH. But 
5734        * consider padN as valid option for dest opt hdr. */
5735
5736       /* get the type of current HBH/dest option */
5737       tempType = *(cmsgData + curDataIdx);
5738       curDataIdx += 1;
5739
5740       /* ignore PAD1 for both HBH/dest by skipping to next option */
5741       if (tempType == 0)
5742          continue; 
5743
5744       /* calculate how much to skip for padN in case of HBH */
5745       if (hdrId != 1)
5746       {   
5747          if (tempType == 1)
5748          {
5749             /* get the length field of padN option */
5750             tempLen = *(cmsgData + curDataIdx);
5751             curDataIdx += 1;
5752
5753             /* move pointer forward to skip value field */
5754             curDataIdx += tempLen;
5755             continue;
5756          }
5757       } 
5758       hbhOptsArr->hbhOpts[optsIdx].type = tempType; 
5759
5760       /* copy the length */
5761       hbhOptsArr->hbhOpts[optsIdx].length = *(cmsgData + curDataIdx);
5762       curDataIdx += 1;
5763
5764       /* take care of PADN = 2 when value field empty. We also don't need
5765        * to allocate memory for empty value field */
5766       if (hbhOptsArr->hbhOpts[optsIdx].length == 0)
5767          hbhOptsArr->hbhOpts[optsIdx].value = NULLP;
5768       else
5769       {   
5770          /* take care of all other options having valid value field
5771           * such as Router Alert, PADN >= 3 bytes and Jumbo */
5772          ret = SGetSBuf(info->region, info->pool, 
5773                (Data **)&hbhOptsArr->hbhOpts[optsIdx].value, 
5774                (Size)hbhOptsArr->hbhOpts[optsIdx].length);
5775          if (ret != ROK)
5776          {
5777 #ifdef CMINETDBG            
5778             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5779             /* cm_inet_c_001.main_62:Warning fix */
5780             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 2 cmInet6BuildRecvHopOptsArr\n");
5781             CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET029, 0, prntBuf);
5782 #endif /* CMINETDBG */           
5783             /* now go inside every separate HBH option and free the memory
5784              * allocated for its value field */
5785             for (; optsIdx > 0; optsIdx --)
5786             {
5787                if (hbhOptsArr->hbhOpts[optsIdx - 1].value != NULLP)
5788                {
5789 #ifdef CMINETDBG                  
5790                   /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5791                   /* cm_inet_c_001.main_62:Warning fix */
5792                   snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 1 in BuildRecvHopOptsArr\n");
5793                   CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET030, 0, prntBuf);
5794 #endif /* CMINETDBG */                  
5795                   SPutSBuf(info->region, info->pool, 
5796                         (Data *)hbhOptsArr->hbhOpts[optsIdx - 1].value,
5797                         (Size)hbhOptsArr->hbhOpts[optsIdx - 1].length);
5798                }
5799             }
5800             /* clean up all CmInetIpv6HBHHdr structures allocated for all
5801              * arrived HBH options OR numOpts CmInetIpv6HBHHdr structures
5802              * allocated after counting numOpts */
5803 #ifdef CMINETDBG                                     
5804             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5805             /* cm_inet_c_001.main_62:Warning fix */
5806             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 2 in BuildRecvHopOptsArr\n");
5807             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET031, 0, prntBuf);
5808 #endif /* CMINETDBG */            
5809             SPutSBuf(info->region, info->pool, 
5810                   (Data *)hbhOptsArr->hbhOpts, numOpts * sizeof(CmInetIpv6HBHHdr));
5811             hbhOptsArr->numHBHOpts = 0;
5812             hbhOptsArr->hbhOpts = NULLP;
5813             RETVALUE(ROUTRES);
5814          }
5815          /* copy the value bytes */
5816          cmMemcpy((U8 *)hbhOptsArr->hbhOpts[optsIdx].value, 
5817                (U8 *)(cmsgData + curDataIdx),
5818                hbhOptsArr->hbhOpts[optsIdx].length);
5819          curDataIdx += hbhOptsArr->hbhOpts[optsIdx].length;      
5820       }  
5821
5822       /* get next option */
5823       optsIdx++; 
5824    }
5825    RETVALUE(ROK);
5826 } /* end of cmInet6BuildRecvHopOptsArr() */
5827
5828 \f
5829 /*
5830 *
5831 *      Fun:   cmInet6BuildRecvRtHdr
5832 *
5833 *      Desc:  This function fills up the Route Header in the cmInetIpv6HdrParm
5834 *             from the recvd ancillary data from recvmsg system call.
5835 *     
5836 *      Ret:   ROK     - successful
5837 *             RFAILED - failed
5838 *
5839 *      Notes: None
5840 *
5841 *      File:  cm_inet.c
5842 *
5843 */
5844
5845 #ifdef ANSI
5846 PRIVATE S16 cmInet6BuildRecvRtHdr
5847 (
5848 U8 *cmsgData,              /* flat buffer where to build Route hdr */ 
5849 U32 rtDataLen,             /* byte len of cmsghdr struc+rtHdr ancil data */
5850 CmInetIpv6RtHdr0 *rtHdr0,  /* rtHeader0 struct that precedes IPV6 addrss */
5851 CmInetIpv6RtHdr *rtOptsArr,/* IPv6 extensions headers */
5852 CmInetMemInfo   *info      /* Memory information */
5853 )
5854 #else
5855 PRIVATE S16 cmInet6BuildRecvRtHdr(cmsgData, rtDataLen, rtHdr0, rtOptsArr, info)
5856 U8 *cmsgData;              /* flat buffer where to build Route hdr */
5857 U32 rtDataLen;             /* byte len of cmsghdr struc+rtHdr ancil data */
5858 CmInetIpv6RtHdr0 *rtHdr0;  /* rtHeader0 struct that precedes IPV6 addrss */
5859 CmInetIpv6RtHdr *rtOptsArr;/* IPv6 extensions headers */
5860 CmInetMemInfo   *info;     /* Memory information */
5861 #endif /* ANSI */
5862 {
5863    U32 curDataIdx;         /* to keep track where we are in hbh Data */
5864    U8 i;                   /* loop counter */
5865    S16 ret;                /* temporary return value */
5866
5867    TRC2(cmInet6BuildRecvRtHdr)
5868    
5869    /* byte len of actual rtHdr ancil data */
5870    rtDataLen -= sizeof(struct cmsghdr);
5871
5872    /* start from beginning */
5873    curDataIdx = 0;                
5874
5875    /* copy next header byte */
5876    rtHdr0->ip6r0_nextHdr = *(cmsgData + curDataIdx);
5877    curDataIdx += 1;  
5878
5879    /* copy header extension length byte */
5880    rtHdr0->ip6r0_hdrExtLen = *(cmsgData + curDataIdx);
5881    curDataIdx += 1;
5882
5883    /* copy type byte (always 0) */
5884    rtHdr0->ip6r0_type = 0x00;
5885    curDataIdx += 1;
5886
5887    /* copy segment left byte */
5888    rtHdr0->ip6r0_segLeft = *(cmsgData + curDataIdx);
5889    curDataIdx += 1;
5890
5891    /* copy 1 reserve byte + 3 strict/loose bytes */  
5892    cmMemcpy((U8 *)(&rtOptsArr->slMap),
5893          (U8 *)(cmsgData + curDataIdx), 4);
5894    curDataIdx += 4;
5895
5896    /* also save reserv byte + 3 sl bytes to rtHdro struc */
5897    rtHdr0->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5898
5899    /* subtract 8 bytes for Next Hdr, Hdr Ext Len, .... + SL bit map */
5900    rtOptsArr->numAddrs = (rtDataLen - 8)/16;
5901
5902    ret = SGetSBuf(info->region, info->pool, 
5903          (Data **)&rtOptsArr->ipv6Addrs, 
5904          (Size)rtOptsArr->numAddrs * 16);
5905    if (ret != ROK)
5906    {
5907 #ifdef CMINETDBG      
5908       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5909       /* cm_inet_c_001.main_62:Warning fix */
5910       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvRtHdr\n");
5911       CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET032, 0, prntBuf);
5912 #endif /* CMINETDBG */     
5913       RETVALUE(ROUTRES);
5914    }
5915
5916    /* copy all the ipv6 addresses */
5917    for(i=0; i < rtOptsArr->numAddrs; i++)
5918    {
5919       cmMemcpy((U8 *)(rtOptsArr->ipv6Addrs[i]),
5920             (U8 *)(cmsgData + curDataIdx), 16);
5921       curDataIdx += 16;
5922    }
5923
5924    RETVALUE(ROK);
5925 } /* end of cmInet6BuildRecvRtHdr() */
5926
5927 \f
5928 /*
5929 *
5930 *      Fun:   cmInet6GetHopLimitValue
5931 *
5932 *      Desc:  This function extracts the hop limit value(ttl) of from the 
5933 *             ancillary data received through recvmsg() call. Then this
5934 *             hoplimit value will be passed to upper user as ipHdrParam.
5935 *     
5936 *      Ret:   ROK     - successful
5937 *
5938 *      Notes: None
5939 *
5940 *      File:  cm_inet.c
5941 *
5942 */
5943
5944 #ifdef ANSI
5945 PRIVATE S16 cmInet6GetHopLimitValue
5946 (
5947 U8 *cmsgData,        /* flat buffer where to build ext hdrs */
5948 U32 hopLimitDataLen, /* byte len of cmsghdr + hbh ancil data */
5949 CmInetIpv6HdrParm *ipv6HdrParam /* ipv6 header parameters */ 
5950 )
5951 #else
5952 PRIVATE S16 cmInet6GetHopLimitValue(cmsgData, hopLimitDataLen, ipv6HdrParam)
5953 U8 *cmsgData;         /* flat buffer where to build ext hdrs */
5954 U32 hopLimitDataLen;  /* byte len of cmsghdr + hbh ancil data */
5955 CmInetIpv6HdrParm *ipv6HdrParam; /* ipv6 header parameters */
5956 #endif /* ANSI */
5957 {
5958    U16 curDataIdx;       /* to keep track where we are in the ancillary Data */
5959    U32 *hopLimitValue;   /* ttl/hoplimit value */
5960
5961    hopLimitValue = NULL;
5962    curDataIdx = 0;                
5963
5964    /* get length of actual hbh ancillary data */
5965    hopLimitDataLen -= sizeof(struct cmsghdr);
5966
5967    /* go to the first byte of hop limit which present after cmsghdr struc */
5968    curDataIdx += sizeof(struct cmsghdr);
5969
5970    /* mark that hoplimit(ttl) is present */
5971    ipv6HdrParam->ttl.pres = TRUE;
5972
5973    /* the first byte will be the HopLimit value */
5974    hopLimitValue = (U32 *)(cmsgData);
5975    ipv6HdrParam->ttl.val = (U8)(*hopLimitValue);
5976
5977    RETVALUE(ROK);
5978 }
5979 #endif /* IPV6_OPTS_SUPPORTED */
5980
5981 \f
5982 /*
5983 *
5984 *      Fun:   cmInetRecvMsg
5985 *
5986 *      Desc:  Reads data from a socket into a message. 
5987 *             The buffers for the message  are allocated within the 
5988 *             cmInetRead() function from the pool and region Id set in the 
5989 *             info struct.  
5990 *             If the number of octets given by the paramter len is not 
5991 *             available the function immediately returns with RKDNA. 
5992 *             If the len parameter is set to CM_INET_READ_ANY, the currently 
5993 *             available data is read. 
5994 *             Values for flag parameter:
5995 *  
5996 *             CM_INET_NO_FLAG  - no additional control flag
5997 *             CM_INET_MSG_PEEK - do not destroy data on receive buffer
5998 *
5999 *      Ret:   ROK     - successful
6000 *             ROKDNA  - ok, data not available
6001 *             RCLOSED - connection closed by peer
6002 *             ROUTRES - failed, out of resources
6003 *             RFAILED - failed
6004 *
6005 *      Notes: None.
6006 *
6007 *      File:  cm_inet.c
6008 *
6009 */
6010 #ifdef ANSI
6011 PUBLIC S16 cmInetRecvMsg
6012 (
6013 CmInetFd        *sockFd,        /* socket file descriptor */ 
6014 CmInetAddr      *fromAddr,      /* sender Internet address/port */ 
6015 CmInetMemInfo   *info,          /* buffer allocation info */
6016 Buffer         **mPtr,          /* received buffer structure */
6017 MsgLen          *len,           /* number of octets to read */ 
6018 /*  added for IPv6 */
6019 #ifdef IPV6_OPTS_SUPPORTED
6020 CmInetIpHdrParm *ipHdrParams,    /* IPv6 extensions headers */
6021 #endif /* IPV6_OPTS_SUPPORTED */
6022 #ifdef LOCAL_INTF
6023 CmInetLocalInf  *localIf,       /* local interface on which pkt was recvd */
6024 #endif /* LOCAL_INTF */ 
6025 S32              flags          /* additional control flags */
6026 )
6027 #else
6028 /*  added for IPv6 */
6029 #ifdef IPV6_OPTS_SUPPORTED
6030 #ifdef LOCAL_INTF
6031 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len,
6032       ipHdrParams, localIf, flags)
6033 CmInetFd        *sockFd;        /* socket file descriptor */ 
6034 CmInetAddr      *fromAddr;      /* sender Internet address/port */ 
6035 CmInetMemInfo   *info;          /* buffer allocation info */
6036 Buffer         **mPtr;          /* received buffer structure */
6037 MsgLen          *len;           /* number of octets to read */ 
6038 CmInetIpHdrParm *ipHdrParams;   /* IPv6 extensions headers */
6039 CmInetLocalInf  *localIf;       /* local interface on which pkt was recvd */
6040 S32              flags;         /* additional control flags */
6041 #else
6042 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len, ipHdrParams, flags)
6043 CmInetFd        *sockFd;        /* socket file descriptor */ 
6044 CmInetAddr      *fromAddr;      /* sender Internet address/port */ 
6045 CmInetMemInfo   *info;          /* buffer allocation info */
6046 Buffer         **mPtr;          /* received buffer structure */
6047 MsgLen          *len;           /* number of octets to read */ 
6048 CmInetIpHdrParm *ipHdrParams;   /* IPv6 extensions headers */
6049 S32              flags;         /* additional control flags */
6050 #endif /* LOCAL_INTF */
6051 #else
6052 #ifdef LOCAL_INTF
6053 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len, localIf, flags)
6054 CmInetFd        *sockFd;        /* socket file descriptor */ 
6055 CmInetAddr      *fromAddr;      /* sender Internet address/port */ 
6056 CmInetMemInfo   *info;          /* buffer allocation info */
6057 Buffer         **mPtr;          /* received buffer structure */
6058 MsgLen          *len;           /* number of octets to read */ 
6059 CmInetLocalInf  *localIf;       /* local interface on which pkt was recvd */
6060 S32              flags;         /* additional control flags */
6061 #else
6062 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len, flags)
6063 CmInetFd        *sockFd;        /* socket file descriptor */ 
6064 CmInetAddr      *fromAddr;      /* sender Internet address/port */ 
6065 CmInetMemInfo   *info;          /* buffer allocation info */
6066 Buffer         **mPtr;          /* received buffer structure */
6067 MsgLen          *len;           /* number of octets to read */ 
6068 S32              flags;         /* additional control flags */
6069 #endif /* LOCAL_INTF */
6070 #endif /* IPV6_OPTS_SUPPORTED */
6071 #endif /* ANSI */
6072 {
6073 #if (defined(WIN32) || defined(CMINETFLATBUF))
6074    S32           ret;            /* temporary return value */
6075    U32           pendLen;        /* pending data length */
6076    S32           recvLen;        /* number of received octets by recvmsg() */
6077    MsgLen        bufLen;         /* entire number of received octets */
6078    MsgLen        curLen;         /* current number of octets in buffer */ 
6079    Data         *recvBuf;        /* receive buffer */
6080    Data         *bufPtr;         /* current buffer position */   
6081    Buffer       *mBuf;           /* received message */ 
6082    U32           remAddrLen;     /* length of remote address */
6083    struct sockaddr_in  *remAddr;    /* remote Internet address */       
6084 #ifdef IPV6_SUPPORTED 
6085    struct sockaddr_in6  *remAddr6;  /* remote Internet address */       
6086    struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6087 #else
6088    CmInetSockAddr  remSockAddr;     /* to get packet's source IP address */
6089 #endif /* IPV6_SUPPORTED */
6090 #else
6091    S32           ret;            /* temporary return value */
6092   /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
6093    U16           i;              /* index */
6094    U32           pendLen;        /* pending data length */
6095    S32           numBuf;         /* number of allocated dBufs */
6096    S32           recvLen;        /* number of received octets by recvmsg() */
6097    MsgLen        bufLen;         /* entire number of received octets */
6098    struct msghdr msg;            /* message header */ 
6099    /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6100    Buffer       *tempMsg = NULLP;        /* temporary message */
6101    CmInetIovec  rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
6102    Buffer      **dBufs = NULLP;   /* dynamic array with allocated dBufs */
6103    S16           numDBufs;       /* number of allocated dBufs */
6104
6105    /* cm_inet_c_001.main_55: As remAddrLen is only being used when
6106     * WIN32 or CMINETFLATBUF is defined, then Removed variable
6107     * in else part*/
6108    struct sockaddr_in *remAddr;  /* remote Internet address */       
6109 #ifdef IPV6_SUPPORTED 
6110    struct sockaddr_in6 *remAddr6;  /* remote Internet address */       
6111    struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
6112    /* added for IPv6 ext headers support */
6113 #ifdef IPV6_OPTS_SUPPORTED
6114    CmInetIpv6RtHdr0     rtHdr0;          /* type 0 route header */      
6115 #endif /* IPV6_OPTS_SUPPORTED */
6116
6117 #ifdef LOCAL_INTF
6118    struct in6_pktinfo  *pkt6Info;        /* IPv6 IP_PKTINFO */
6119 #endif /* LOCAL_INTF */   
6120
6121 #if (defined(SS_LINUX) || defined(_XPG4_2))
6122    U8                   ancillData[CM_INET_IPV6_ANCIL_DATA];
6123    /* from stack for IPv6 ancill data */
6124 #endif
6125 #else
6126    CmInetSockAddr       remSockAddr;     /* to get packet's src IP address */
6127 #if (defined(SS_LINUX) || defined(_XPG4_2))
6128    U8                   ancillData[CM_INET_IPV4_ANCIL_DATA];
6129    /* from stack for IPv4 ancill data */
6130 #endif
6131 #endif /* IPV6_SUPPORTED */
6132    /* added new definitions */
6133    Bool                 allocFlatBuf;    /* allocate a flat buffer */
6134    /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6135    Data                 *recvBuf = NULLP;        /* receive buffer */
6136 #ifdef SS_LINUX
6137 #ifdef LOCAL_INTF
6138    struct in_pktinfo    *pkt4Info;       /* IPv4 IP_PKTINFO */
6139 #endif
6140 #endif /* SS_LINUX */
6141 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))   
6142    struct               cmsghdr *cmsgptr;/* pointer to struct cmsghdr */
6143 #endif
6144 #endif /* WIN32 | CMINETFLATBUF */
6145    /* used by getsockopt */
6146
6147    /* cm_inet_c_001.main_55:Removed unused variables errValue and optLen */
6148
6149    TRC2(cmInetRecvMsg)
6150
6151 #if (ERRCLASS & ERRCLS_INT_PAR)
6152       /* error check on parameters */
6153       if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6154             (info == NULLP) || (mPtr == NULLP) || (len == NULLP))
6155       {
6156          RETVALUE(RFAILED);
6157       }
6158 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6159
6160    *mPtr = NULLP;
6161
6162    /*cm_inet_c_001.main_48 variables declaration */
6163 #if !((defined(WIN32) || defined(CMINETFLATBUF)))
6164    numBuf = 0;
6165    numDBufs = 0;
6166 #endif
6167
6168 #if (defined(WIN32) || defined(CMINETFLATBUF))
6169    remAddr = NULLP;  
6170 #ifdef IPV6_SUPPORTED 
6171    remAddr6 = NULLP;
6172 #endif /* IPV6_SUPPORTED */   
6173 #else
6174 #ifdef IPV6_SUPPORTED 
6175    remAddr = NULLP;
6176    remAddr6 = NULLP;
6177 #endif /* IPV6_SUPPORTED */  
6178
6179 #if (defined(SS_LINUX) || defined(_XPG4_2))
6180    cmMemset((U8*)ancillData, 0, sizeof(ancillData));
6181 #endif /* SS_LINUX || _XPG4_2 */
6182
6183 #endif /* (WIN32 | CMINETFLATBUF) */
6184
6185    /* clear the structure */   
6186    cmMemset((U8*)&remSockAddr, 0, sizeof(remSockAddr));
6187
6188    /* get number of pending data */
6189    /* removed 3rd arg memInfo. MemInfo is no longer
6190       needed as we call ioctl for all sockets */
6191
6192    /* cm_inet_c_001.main_48 : call ioctl only for STREAM 
6193     * sockets now. For Non-Stream sockets(Raw & UDP), fix
6194     * pending length to CM_INET_MAX_UDPRAW_MSGSIZE
6195     */
6196    if(sockFd->type == CM_INET_STREAM)
6197    {
6198       ret = cmInetGetNumRead(sockFd, &pendLen);
6199       if (ret != ROK)
6200       {
6201          /* ret may be RFAILED or ROUTRES */
6202          RETVALUE(ret);
6203       }
6204    }
6205    else 
6206    {  
6207       /* cm_inet_c_001.main_48 : pendLen is set 1 greater 
6208        * than the #defined value. If recvFrom/recvMsg 
6209        * returns the len == pendLen, we would drop the 
6210        * message as the msg len is larger than the largest 
6211        * msg we are willing to accept.
6212        */
6213       pendLen = CM_INET_MAX_UDPRAW_MSGSIZE+1;
6214    } 
6215
6216
6217    /* check if connection got closed */
6218    if (pendLen == 0)
6219    {
6220       if (sockFd->type == CM_INET_STREAM)
6221       {
6222          /* cm_inet_c_001.main_50: 
6223           * cm_inet_c_001.main_56: Removed comment for cm_inet_c_001.main_50 as
6224           * the current patch changes its functionality */
6225          U8  readBuf[1]; /* declaration of variable for Peek */
6226
6227          /* 
6228           * cm_inet_c_001.main_56:
6229           * We are peeking the socket buffer again with peek as on some machines
6230           * like solaris, there is a latency observed in ioctl. In such cases, 
6231           * ioctl may return 0, even though there are bytes available to read. 
6232           * We reconfirm through peek whether 0 means EOF or its ioctl latency
6233           * issue.
6234           */
6235          ret = cmInetPeekNew(sockFd, NULLP, info, 0, 1, readBuf);
6236          if (ret == RCLOSED)
6237          {
6238             RETVALUE(ret);
6239          }
6240          /* cm_inet_c_001.main_56:
6241           * Returning ROKDNA even cmInetPeekNew returns ROK. Because currently
6242           * we are not sure about pending length. Anyway socket FD already set,
6243           * we do another iteration to get exact pendLen value. We cannot call 
6244           * cmInetGetNumRead at this point because of latency between the ioctl
6245           * call and recvfrom call issues on some machines ioctl call may 
6246           * return ZERO even their a data to read.  */
6247          RETVALUE(ROKDNA);
6248       }
6249    } 
6250    /* cm_inet_c_001.main_52:  Support for partial reception */
6251    /* cm_inet_c_001.main_59: Fix for compilation warning */
6252    if ((sockFd->type == CM_INET_STREAM) && (*len > (MsgLen)pendLen)) 
6253    {
6254       /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6255       *len = (MsgLen)pendLen;
6256    }
6257
6258    /* check if there are enough pending data to read */
6259    if ((*len == CM_INET_READ_ANY) || ((U32)*len <= pendLen))
6260    {
6261       if (*len == CM_INET_READ_ANY)
6262       {
6263          /* added check for TCP socket. Pending data length in 
6264             the socket recv buffer is determined by ioctl call in 
6265             cmInetGetNumRead. 
6266             For TCP it can't be > CM_INET_MAX_MSG_LEN. */
6267          if (sockFd->type == CM_INET_STREAM) 
6268          {
6269             /* max message length is limited to control the memory usage */
6270             if (pendLen > CM_INET_MAX_MSG_LEN)
6271                pendLen = CM_INET_MAX_MSG_LEN;
6272          }
6273          /* cm_inet_c_001.main_48 : removed the check for 
6274           * Non Stream sockets (pendLen < MAX_UDPRAW_MSGSIZE)
6275           * as we are hardcoding pendLen for Non-Stream sockets.
6276           */
6277
6278          /* read all pending data */ 
6279          /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6280          bufLen = (MsgLen)pendLen;
6281          *len = (MsgLen)pendLen; 
6282       }
6283       else
6284       {
6285          /*  cm_inet_c_001.main_45- Returning  CM_INET_MAX_MSG_LEN when input is larger than
6286           * this */
6287 #ifdef LONG_MSG
6288          /* max message length is limited to control the memory usage */
6289          if ((*len) > CM_INET_MAX_MSG_LEN)
6290          {
6291             (*len) = CM_INET_MAX_MSG_LEN;
6292          }
6293 #endif
6294          /* read data length given by user */ 
6295          bufLen = *len;
6296       }
6297
6298 #if (defined(WIN32) || defined(CMINETFLATBUF))
6299
6300       /* set destination Internet address structure */
6301       if (fromAddr != NULLP)
6302       {
6303          remAddrLen = sizeof(remSockAddr); 
6304       }
6305       else
6306       {
6307          remAddrLen = 0;
6308       }
6309
6310       /* allocate flat receive buffer */
6311       ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6312       if (ret != ROK)
6313       {
6314          RETVALUE(ROUTRES);
6315       }          
6316       curLen = bufLen;
6317       bufPtr = recvBuf;
6318
6319       /* 
6320        * maybe needs more than one recvfrom() call to read an entire 
6321        * message from a stream socket (TCP)
6322        */
6323       while (curLen > 0)
6324       {
6325          /* added separate recvfrom calls different OS */
6326
6327          /*cm_inet_c_001.main_42   1. In Vx-Works the 5th and 6th parameter of recvfrom
6328            system call are either NULL or should be valid pointer.*/
6329 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
6330          if (remAddrLen)
6331             recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0, 
6332                   (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
6333          else
6334             recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0, 
6335                   NULLP, (int *)&remAddrLen);
6336 #else         
6337 #if ( defined(SUNOS) || defined(SS_LINUX))
6338          if (remAddrLen)
6339             recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0, 
6340                   (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
6341          else
6342             recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0, 
6343                   NULLP, (socklen_t *)&remAddrLen); 
6344 #else
6345          if (remAddrLen)
6346             recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0, 
6347                   &remSockAddr, (S32 *)&remAddrLen);
6348          else
6349             recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0, 
6350                   NULLP, (S32 *)&remAddrLen); 
6351
6352 #endif /* defined(SUNOS) || defined(SS_LINUX) */
6353 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */ 
6354
6355          if (recvLen == INET_ERR)
6356          {
6357             /* cleanup */
6358             /* moved cleanup here */
6359             SPutSBuf(info->region, info->pool, recvBuf, bufLen); 
6360
6361             /*  added check ERR_WOULDBLOCK */
6362             if ((INET_ERR_CODE == ERR_AGAIN) ||
6363                   (INET_ERR_CODE == ERR_WOULDBLOCK))
6364             {
6365                *len = 0;
6366                RETVALUE(ROKDNA);
6367             }
6368
6369
6370             /*  In Windows the recvfrom function fails
6371              *  with error code which maps to either WSAECONNABORTED. If
6372              *  this happens then cmInetRecvMsg must return RCLOSED */
6373             if ((INET_ERR_CODE == ERR_CONNABORTED) || 
6374                   (INET_ERR_CODE == ERR_CONNRESET))
6375             {
6376                *len = 0;
6377                RETVALUE(RCLOSED);
6378             }
6379
6380 #ifdef CMINETDBG
6381 #ifndef ALIGN_64BIT
6382             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6383             /* cm_inet_c_001.main_62:Warning fix */
6384             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6385                   " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6386             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6387 #else
6388             /* cm_inet_c_001.main_62:Warning fix */
6389             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6390                   " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6391             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6392 #endif /*ALIGN_64BIT*/
6393 #endif /* CMINETDBG */
6394
6395             RETVALUE(RFAILED);
6396          } 
6397          curLen -= recvLen;
6398          bufPtr += recvLen;
6399
6400          /* 
6401           * a message is always read atomically on a datagram socket,
6402           * therefore it's ok to read less than pending data!
6403           */
6404 #ifdef CM_INET2  
6405          if ((sockFd->type == CM_INET_RAW) || 
6406                (sockFd->type == CM_INET_DGRAM))
6407          {
6408             *len = recvLen;
6409             break; 
6410          }
6411 #else /* CM_INET2 */ 
6412          if (sockFd->type == CM_INET_DGRAM)
6413          {
6414             *len = recvLen;
6415             break; 
6416          }
6417 #endif /* CM_INET2 */ 
6418       } /* while (curLen > 0) (only for stream sockets) */ 
6419
6420       /* For UDP, it is possible to receive
6421        * a 0 byte datagram, in this case just return ROKDNA.
6422        */ 
6423 #ifdef CM_INET2
6424       if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW) 
6425             && (*len == 0))
6426 #else
6427          if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6428 #endif
6429          {
6430             SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6431             RETVALUE(ROKDNA);
6432          }
6433
6434       /* cm_inet_c_001.main_48 : If Received 
6435        * len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6436        * Drop this message 
6437        */ 
6438 #ifdef CM_INET2
6439       if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW) 
6440             && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6441 #else
6442          if ((sockFd->type == CM_INET_DGRAM) 
6443                && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6444 #endif
6445          {
6446 #ifdef CMINETDBG
6447 #ifndef ALIGN_64BIT
6448             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6449             /* cm_inet_c_001.main_62:Warning fix */
6450             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6451                   " > than allowed(%lu), sockFd->fd(%ld) \n", 
6452                   CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6453             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6454 #else
6455             /* cm_inet_c_001.main_62:Warning fix */
6456             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6457                   " > than allowed(%lu), sockFd->fd(%d) \n", 
6458                   CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6459             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6460 #endif /*ALIGN_64BIT*/
6461 #endif
6462             SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6463             RETVALUE(ROKDNA);
6464          }
6465
6466       /* cm_inet_c_001.main_48 : copy data to a message structure */
6467       ret = SGetMsg(info->region, info->pool, &mBuf);
6468       if (ret != ROK)
6469       {
6470          /* cleanup */
6471          SPutSBuf(info->region, info->pool, recvBuf, bufLen);       
6472          RETVALUE(ret);
6473       }
6474
6475 #ifdef CM_INET2  
6476       if ((sockFd->type == CM_INET_DGRAM) ||
6477             (sockFd->type == CM_INET_RAW))
6478       {
6479          ret = SAddPstMsgMult(recvBuf, *len, mBuf);        
6480       }
6481       else
6482       {
6483          ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);        
6484       }
6485
6486 #else /* CM_INET2 */ 
6487       if (sockFd->type == CM_INET_DGRAM)
6488       {
6489          ret = SAddPstMsgMult(recvBuf, *len, mBuf);        
6490       }
6491       else
6492       {
6493          ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);        
6494       }
6495 #endif /* CM_INET2 */ 
6496
6497       if (ret != ROK)
6498       {
6499          SPutSBuf(info->region, info->pool, recvBuf, bufLen);    
6500          SPutMsg(mBuf); 
6501          RETVALUE(ret);
6502       }
6503       *mPtr = mBuf;
6504
6505       /* setup return destination Internet address */
6506       /* added the check of (remAddrLen > 0) */
6507       if ((fromAddr != NULLP) && (remAddrLen > 0))
6508       {
6509 #ifdef IPV6_SUPPORTED
6510          if (remAddrLen == sizeof(struct sockaddr_in6))
6511          {
6512             remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6513             fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6514             fromAddr->u.ipv6Addr.port = CM_INET_NTOH_U16(remAddr6->sin6_port);
6515             CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr, 
6516                   &remAddr6->sin6_addr);
6517          }
6518          else
6519          {
6520             remAddr = (struct sockaddr_in *)&remSockAddr;
6521             fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6522             fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
6523             fromAddr->u.ipv4Addr.address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6524          }
6525 #else
6526          remAddr = (struct sockaddr_in *)&remSockAddr;
6527          fromAddr->port    = CM_INET_NTOH_U16(remAddr->sin_port);
6528          fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6529 #endif /* IPV6_SUPPORTED */
6530       }   
6531
6532       /* cleanup */
6533       SPutSBuf(info->region, info->pool, recvBuf, bufLen);      
6534
6535 #else  /* end of Win NT/flat buffer specific part */
6536
6537       /* Initialise variable */
6538       allocFlatBuf = FALSE;
6539
6540       /* 
6541        * maybe needs more than one recvmsg() call to read entire message 
6542        * on a stream socket 
6543        */
6544       while (bufLen > 0)
6545       {
6546          /* allocate gather vector, it's a dynamic array */    
6547          numDBufs =  CM_INET_MAX_DBUF;
6548
6549          ret = SGetSBuf(info->region, info->pool, (Data**)&dBufs, 
6550                numDBufs*sizeof(Buffer*));
6551          if (ret != ROK)
6552          {
6553             RETVALUE(ROUTRES);
6554          }                     
6555
6556          /* Allocate dBufs for gather read */ 
6557          /* allocate dBufs for gathering read */
6558          if (sockFd->type == CM_INET_STREAM)
6559             ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6560                   TRUE);
6561          else
6562             ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6563                   FALSE);
6564          if (ret != ROK)
6565          {
6566             /* check if the function returned RNA */ 
6567             if (ret == RNA)
6568             {
6569                /* Incase of UDP/RAW messages allocate a flat buffer. Incase
6570                 * of TCP ignore this error condition. The user will call 
6571                 * cmInetRecvMsg again */
6572                /* cm_inet_c_001.main_62:Warning fix */
6573                if (sockFd->type != (U8)CM_INET_STREAM)/* G++ */
6574                {
6575
6576 #ifdef T2K_MEM_LEAK_DBG
6577                        char * file = __FILE__;
6578                        U32  line   = __LINE__;
6579 #endif
6580
6581                   /* cleanup  the dBuf array */
6582                   for (i = 0; i < msg.msg_iovlen; i++)
6583                      SPutDBuf(info->region, info->pool, dBufs[i]);   
6584
6585                   SPutSBuf(info->region, info->pool, (Data*)dBufs, 
6586                         numDBufs * sizeof(Buffer*)); 
6587
6588                   /* allocate flat receive buffer */
6589                   ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6590                   if (ret != ROK)
6591                      RETVALUE(ROUTRES);
6592
6593                   allocFlatBuf = TRUE;
6594
6595                   /* update the message structure */
6596 #ifdef SS_LINUX
6597                   rxArr[0].iov_base = (Void*)recvBuf;  
6598                   rxArr[0].iov_len = (U32)bufLen;    
6599 #else
6600                   rxArr[0].iov_base = (S8*)recvBuf;
6601                   rxArr[0].iov_len = bufLen;
6602 #endif /* SS_LINUX */
6603                   msg.msg_iov           = rxArr;
6604                   msg.msg_iovlen        = 1;
6605                }
6606             }
6607             else
6608             {
6609                SPutSBuf(info->region, info->pool, (Data*)dBufs, 
6610                      numDBufs*sizeof(Buffer*)); 
6611                RETVALUE(ret);
6612             }
6613          }
6614
6615          numBuf =  msg.msg_iovlen;
6616
6617          /* setup destination Internet address structure */
6618          if (fromAddr != NULLP)
6619          {
6620 #ifdef SS_LINUX
6621             msg.msg_name    = (Void*)&remSockAddr;
6622 #else
6623 #ifdef SS_PS
6624             msg.msg_name    = (char *)&remSockAddr;
6625 #else
6626             msg.msg_name    = (caddr_t)&remSockAddr;
6627 #endif /* SS_PS */
6628 #endif /* SS_LINUX */
6629             msg.msg_namelen = sizeof(remSockAddr);
6630          }
6631          else
6632          {
6633             msg.msg_name    = NULLP;
6634             msg.msg_namelen = 0;
6635          }
6636
6637          /* added defined(_XPG4_2). Also changed the
6638           * assignments */
6639 #if (defined(SS_LINUX) || defined(_XPG4_2))
6640          msg.msg_control      = ancillData;
6641          msg.msg_controllen   = sizeof(ancillData);
6642 #else
6643          msg.msg_accrights     = NULLP;
6644          msg.msg_accrightslen  = 0;
6645 #endif /* SS_LINUX */
6646
6647          recvLen = recvmsg(sockFd->fd, &msg, flags);
6648          if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
6649          {
6650             /* Moved up the cleanup precedures here before returning */
6651             /* Cleanup flat buffer if allocated */
6652             if (allocFlatBuf)
6653                SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6654             else
6655             {
6656                /* cleanup */
6657                for (i = 0; i < numBuf; i++)
6658                { 
6659                 #ifdef T2K_MEM_LEAK_DBG
6660                    char * file = __FILE__;
6661                    U32  line   = __LINE__;
6662                 #endif
6663
6664                   SPutDBuf(info->region, info->pool, dBufs[i]);   
6665                }
6666                SPutSBuf(info->region, info->pool, (Data*)dBufs, 
6667                      numDBufs*sizeof(Buffer*)); 
6668             }
6669
6670             /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6671              * it has partially received data
6672              */
6673             /* added check ERR_AGAIN when CMINETFLATBUF is not defined. 
6674                added check ERR_WOULDBLOCK */
6675             if ((INET_ERR_CODE == ERR_AGAIN) ||
6676                   (INET_ERR_CODE == ERR_WOULDBLOCK))
6677             {
6678                /* cm_inet_c_001.main_50 : If message is read partially then just return
6679                 * OK without freeing the mPtr. This will gaurd us
6680                 * against unexpected WOULDBLOCKS observed in solaris
6681                 */
6682                if (*mPtr != NULLP)
6683                   RETVALUE(ROK);
6684
6685                RETVALUE(ROKDNA);
6686             }
6687
6688             /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6689              * it has partially received data
6690              */
6691             if (*mPtr != NULLP)
6692             {
6693                SPutMsg(*mPtr);
6694             }
6695 #ifdef CMINETDBG
6696 #ifndef ALIGN_64BIT
6697             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6698             /* cm_inet_c_001.main_62:Warning fix */
6699             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6700                   " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6701             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6702 #else
6703             /* cm_inet_c_001.main_62:Warning fix */
6704             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6705                   " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6706             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6707 #endif /*ALIGN_64BIT*/
6708 #endif /* CMINETDBG */
6709
6710             /*  If this happens then cmInetRecvMsg must return RCLOSED. 
6711              *  Needed for getting icmp msgs */
6712             if (INET_ERR_CODE == ERR_CONNABORTED)
6713             {
6714                *len = 0;
6715                RETVALUE(RCLOSED);
6716             }
6717             RETVALUE(RFAILED); 
6718          } 
6719
6720          bufLen -= recvLen;
6721
6722          /* added for IPv6 extn headers */
6723 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6724
6725          /* check if ancillary data has been received. 
6726           * Return the allocated memory when no ancillary data received */
6727 #if (defined(SS_LINUX) || defined(_XPG4_2))         
6728          if (msg.msg_controllen)
6729          {   
6730             cmsgptr = CMSG_FIRSTHDR(&msg);
6731          }   
6732          else 
6733             cmsgptr = NULLP;
6734 #else
6735          cmsgptr = NULLP;         
6736 #endif  /* SS_LINUX || _XPG4_2 */        
6737
6738          if (cmsgptr != NULLP) 
6739          {
6740 #ifdef IPV6_OPTS_SUPPORTED            
6741             if(ipHdrParams != NULLP)
6742             {   
6743                ipHdrParams->u.ipv6HdrParm.ttl.pres = FALSE;
6744                ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt = FALSE;
6745                ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt = FALSE;
6746                ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt = FALSE;
6747
6748                /* get all ancillary data objects recvd one by one */
6749                for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP; 
6750                      cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6751                {
6752                   if (cmsgptr->cmsg_level == IPPROTO_IPV6)
6753                   {
6754                      /* Initialise ipHdrParams properly */
6755                      ipHdrParams->type = CM_INET_IPV6ADDR_TYPE;   
6756
6757                      if (cmsgptr->cmsg_type == IPV6_HOPOPTS) 
6758                      {
6759                         /* build up HBH opt array from recvd ancillary data */
6760                         ret = cmInet6BuildRecvHopOptsArr(
6761                               (U8 *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, 
6762                               &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
6763                               0, info);
6764                         if (ret != ROK)
6765                            RETVALUE(ret);
6766                         ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt = 
6767                            TRUE; 
6768                      }
6769 #ifdef SS_LINUX
6770                      else if(cmsgptr->cmsg_type == IPV6_DSTOPTS)
6771 #else
6772                      else if ((cmsgptr->cmsg_type == IPV6_DSTOPTS) ||
6773                            (cmsgptr->cmsg_type == IPV6_RTHDRDSTOPTS))
6774 #endif /* SS_LINUX */  
6775                      {
6776                         /* build up Dest opt array from recvd ancillary data */
6777                         ret = cmInet6BuildRecvDstOptsArr(
6778                               (U8 *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, 
6779                               &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr,
6780                               1, info); 
6781                         if (ret != ROK)
6782                            RETVALUE(ret);
6783                         ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt = 
6784                            TRUE;
6785                      }
6786                      else if (cmsgptr->cmsg_type == IPV6_RTHDR)
6787                      {
6788                         /* build up Route Hdr from recvd ancillary data */
6789                         ret = cmInet6BuildRecvRtHdr(
6790                               (U8 *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, &rtHdr0,
6791                               &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr, 
6792                               info);
6793                         if (ret != ROK)
6794                            RETVALUE(ret);
6795                         ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt = 
6796                            TRUE; 
6797                      }
6798                      else if(cmsgptr->cmsg_type == IPV6_HOPLIMIT)
6799                      {
6800                         /* get the received hoplimit */
6801                         ret = cmInet6GetHopLimitValue((U8 *)CMSG_DATA(cmsgptr),
6802                               cmsgptr->cmsg_len, &ipHdrParams->u.ipv6HdrParm);
6803                         if (ret != ROK)
6804                            RETVALUE(ret);
6805                      }
6806                   }
6807                }  /* for */            
6808             } /* ipHdrParams */
6809 #endif /* IPV6_OPTS_SUPPORTED */
6810
6811 #ifdef IPV6_SUPPORTED
6812 #ifdef LOCAL_INTF 
6813             for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP; 
6814                   cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6815             {   
6816                if(cmsgptr->cmsg_type == IPV6_PKTINFO)
6817                {
6818                   pkt6Info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
6819                   localIf->intfPrsnt = TRUE;
6820                   localIf->localIf = pkt6Info->ipi6_ifindex;
6821                   localIf->localIfAddr.type =  CM_INET_IPV6ADDR_TYPE;
6822                   cmMemcpy((U8 *)&localIf->localIfAddr.u.ipv6NetAddr,
6823                         (U8 *)(int *)&pkt6Info->ipi6_addr, 16);
6824                }
6825             }   
6826 #endif /* LOCAL_INTF */
6827 #endif            
6828
6829 #if (defined(SS_LINUX) && defined(LOCAL_INTF))
6830 #ifdef IPV6_SUPPORTED        
6831             if(sockFd->protType == AF_INET) 
6832             { 
6833 #endif               
6834                for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; 
6835                      cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6836                {
6837                   if (cmsgptr->cmsg_level == IPPROTO_IP && 
6838                         cmsgptr->cmsg_type == IP_PKTINFO)
6839                   {
6840                      pkt4Info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
6841                      localIf->intfPrsnt = TRUE;
6842                      localIf->localIf = pkt4Info->ipi_ifindex;
6843                      localIf->localIfAddr.type =  CM_INET_IPV4ADDR_TYPE;
6844                      localIf->localIfAddr.u.ipv4NetAddr = 
6845                         ntohl(*(int *)&pkt4Info->ipi_addr);     
6846                   }
6847                }
6848 #ifdef IPV6_SUPPORTED               
6849             }
6850 #endif 
6851 #endif /* SS_LINUX */ 
6852          }
6853 #endif /* IPV6_OPTS_SUPPORTED || LOCAL_INTF */
6854
6855          /* setup return destination Internet address */
6856          if (fromAddr != NULLP)
6857          {
6858 #ifdef IPV6_SUPPORTED
6859             if (msg.msg_namelen == sizeof(struct sockaddr_in6))
6860             {
6861                remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6862                fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6863                fromAddr->u.ipv6Addr.port = 
6864                   CM_INET_NTOH_U16(remAddr6->sin6_port);
6865                CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr, 
6866                      &remAddr6->sin6_addr);
6867             }
6868             else
6869             {
6870                remAddr = (struct sockaddr_in *)&remSockAddr;
6871                fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6872                fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
6873                fromAddr->u.ipv4Addr.address = 
6874                   CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6875             }
6876 #else
6877             remAddr = (struct sockaddr_in *)&remSockAddr;
6878             fromAddr->port    = CM_INET_NTOH_U16(remAddr->sin_port);
6879             fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6880 #endif /* IPV6_SUPPORTED */
6881          }
6882
6883          /* Incase a flat buffer was allocated get
6884           * a message to pass up */
6885          if (allocFlatBuf)
6886          {
6887             bufLen += recvLen;
6888
6889             /* Get a message */
6890             ret = SGetMsg(info->region, info->pool, &tempMsg);
6891             if (ret != ROK)
6892             {
6893                /* cleanup */
6894                SPutSBuf(info->region, info->pool, recvBuf, bufLen);       
6895                RETVALUE(ret);
6896             }
6897
6898             /* cm_inet_c_001.main_48 : A 0 len UDP packet could be received */
6899             if ( recvLen > 0)
6900             {
6901                ret = SAddPstMsgMult(recvBuf, recvLen, tempMsg);        
6902                if (ret != ROK)
6903                {
6904                   SPutSBuf(info->region, info->pool, recvBuf, bufLen);    
6905                   SPutMsg(tempMsg); 
6906                   RETVALUE(ret);
6907                }
6908             }
6909
6910             *mPtr = tempMsg;
6911
6912             SPutSBuf(info->region, info->pool, recvBuf, bufLen);    
6913             /* cm_inet_c_001.main_48 :flat buffers are allocated 
6914              * for non -TCP sockets. On these sockets we can receive 
6915              * only one message at a time 
6916              */
6917             /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6918             *len = (MsgLen)recvLen;
6919             break;
6920          }
6921          else
6922          {
6923             /* build message out of dBufs */
6924             ret = buildRecvMsg(info, rxArr, numBuf, recvLen, dBufs, &tempMsg);
6925             if (ret != ROK)
6926             {
6927                /* Deallocate previously allocated
6928                 * mBuf */
6929                if (*mPtr != NULLP)
6930                   SPutMsg(*mPtr);
6931                SPutSBuf(info->region, info->pool, (Data*)dBufs, 
6932                      numDBufs*sizeof(Buffer*)); 
6933                RETVALUE(ret);
6934             }
6935          }
6936
6937          if (*mPtr == NULLP)
6938          {
6939             /* it's first recvmsg() call */ 
6940             *mPtr = tempMsg;
6941          }
6942          else
6943          {
6944             /* concatenate messages */  
6945             ret = SCatMsg(*mPtr, tempMsg, M1M2);
6946             if (ret != ROK)
6947             {
6948                /* cleanup */
6949                SPutMsg(*mPtr);
6950                SPutMsg(tempMsg);
6951                SPutSBuf(info->region, info->pool, (Data*)dBufs, 
6952                      numDBufs*sizeof(Buffer*)); 
6953                RETVALUE(RFAILED);
6954             }
6955             SPutMsg(tempMsg);
6956          }
6957
6958          SPutSBuf(info->region, info->pool, (Data*)dBufs, 
6959                numDBufs*sizeof(Buffer*)); 
6960
6961          /* 
6962           * a message is always read atomically on a datagram socket,
6963           * therefore it's ok to read less than pending data!
6964           */
6965 #ifdef CM_INET2  
6966          if ((sockFd->type == CM_INET_DGRAM) ||
6967                (sockFd->type == CM_INET_RAW))
6968          {
6969             /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6970             *len = (MsgLen)recvLen;
6971             break; 
6972          }
6973 #else /* CM_INET2 */ 
6974          if (sockFd->type == CM_INET_DGRAM)
6975          {
6976             /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6977             *len = (MsgLen)recvLen;
6978             break; 
6979          }
6980 #endif /* CM_INET2 */ 
6981       } /* while(bufLen > 0) (only for stream sockets) */
6982
6983       /* cm_inet_c_001.main_48 : For UDP, it is possible to receive
6984        * a 0 byte datagram, in this case just return ROKDNA 
6985        */
6986
6987 #ifdef CM_INET2
6988       if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6989             && (*len == 0))
6990 #else
6991          if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6992 #endif
6993          {
6994             *len = 0;
6995             if (*mPtr != NULLP)
6996             {
6997                SPutMsg(*mPtr);
6998             }
6999             RETVALUE(ROKDNA);
7000
7001          }
7002
7003       /* Received len == CM_INET_MAX_UDPRAW_MSGSIZE+1
7004        * Drop this message 
7005        */
7006
7007 #ifdef CM_INET2
7008       if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
7009             && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
7010 #else
7011          if ((sockFd->type == CM_INET_DGRAM) 
7012                && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
7013 #endif
7014          {
7015             *len = 0;
7016             if (*mPtr != NULLP)
7017             {
7018                SPutMsg(*mPtr);
7019             }
7020
7021 #ifdef CMINETDBG
7022 #ifndef ALIGN_64BIT
7023             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7024             /* cm_inet_c_001.main_62:Warning fix */
7025             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
7026                   " allowed(%d),sockFd->fd(%ld)\n", 
7027                   CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
7028             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
7029 #else
7030             /* cm_inet_c_001.main_62:Warning fix */
7031             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
7032                   " allowed(%d),sockFd->fd(%d)\n", 
7033                   CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
7034             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
7035 #endif
7036 #endif
7037             RETVALUE(ROKDNA);
7038
7039          }
7040
7041 #endif /* WIN32 | CMINETFLATBUF  */
7042    }
7043    else
7044    {
7045       /* not enough data pending yet */
7046       RETVALUE(ROKDNA);
7047    }
7048
7049    RETVALUE(ROK);
7050 } /* end of cmInetRecvMsg */
7051
7052
7053 /* cm_inet_c_001.main_56: Added new function cmInetPeekNew() */
7054 \f
7055 /*
7056  *
7057  *      Fun:   cmInetPeekNew
7058  *
7059  *      Desc:  Reads some data from the socket without destroying the socket
7060  *             receive buffer.
7061  *             The data is specified by the byte positon (first byte is at
7062  *             position 0) and the length.  
7063  *
7064  *      Ret:   ROK     - successful
7065  *             ROKDNA  - ok, data not available
7066  *             RCLOSED - connection closed by peer
7067  *             RFAILED - failed
7068  *
7069  *      Notes: Following are the differences from the cmInetPeek to cmInetPeekNew.
7070  *       This primitive does not call the select function as this is already
7071  *       taken care by the called primitive. This primitive will not use any 
7072  *       ioctl calls, because on some machines due to latency in ioctl call 
7073  *       length may return as ZERO, even there is some data to be read from 
7074  *       the socket and this primitive only peek buffer using recvfrom. 
7075  *       
7076  *       Caller of this function need to allocate the sufficient memory to hold
7077  *       the data peeked from the socket i.e. dataPos + dataLen. Socket data 
7078  *       will be copied in the "data" starting from dataPos offset.
7079  *
7080  *       For example, caller passed the following values to this function. 
7081  *       dataPos = 2 and dataLen = 10,then size of data buffer received should
7082  *       be minimum of (dataPos + dataLen)12 bytes and socket data will be 
7083  *       copied in the data buffer from offset 2 (dataPos) onwards.   
7084  *
7085  *             
7086  *      File:  cm_inet.c
7087  */
7088
7089 #ifdef ANSI
7090 PUBLIC S16 cmInetPeekNew
7091 (
7092  CmInetFd        *sockFd,        /* socket file descriptor */ 
7093  CmInetAddr      *fromAddr,      /* sender Internet address/port */ 
7094  CmInetMemInfo   *info,          /* buffer allocation info */
7095  MsgLen           dataPos,       /* position of data */
7096  MsgLen           dataLen,       /* length of read data */
7097  Data            *data           /* read data */
7098  )
7099 #else
7100 PUBLIC S16 cmInetPeekNew(sockFd, fromAddr, info, dataPos, dataLen, data)
7101    CmInetFd        *sockFd;        /* socket file descriptor */ 
7102    CmInetAddr      *fromAddr;      /* sender Internet address/port */ 
7103    CmInetMemInfo   *info;          /* buffer allocation info */
7104    MsgLen           dataPos;       /* position of data */
7105    MsgLen           dataLen;       /* length of read data */
7106    Data            *data;          /* read data */
7107 #endif
7108 {
7109    /* cm_inet_c_001.main_57 - Fix for validation and compilation warning */
7110    S32          recvLen;           /* number of received octets */
7111    S32          remAddrLen;        /* length of remote address length */
7112    struct sockaddr_in  *remAddr;    /* remote Internet address */      
7113 #ifdef IPV6_SUPPORTED
7114    struct sockaddr_in6  *remAddr6;  /* remote Internet IPV6 address */      
7115    struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
7116 #else
7117    CmInetSockAddr  remSockAddr;     /* to get packet's source IP address */
7118 #endif /* IPV6_SUPPORTED */
7119
7120    TRC2(cmInetPeeknew);
7121
7122 #if (ERRCLASS & ERRCLS_INT_PAR)
7123    /* error check on parameters */
7124    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
7125          (info == NULLP) || (data == NULLP) ||
7126          (dataPos < 0) || (dataLen < 0))
7127    {
7128       RETVALUE(RFAILED);
7129    }
7130 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7131
7132    /* check if fromAddr is present or not */
7133    if (fromAddr != NULLP)
7134    {
7135       remAddrLen = sizeof(remSockAddr); 
7136    }
7137    else
7138    {
7139       remAddrLen = 0;
7140    }
7141
7142    /* added different recvfrom calls with different 6th arg for 
7143     * different OS If remAddrLen is 0, pass NULLP */
7144 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7145    if(remAddrLen)
7146       recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen), 
7147             CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7148    else
7149       recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen), 
7150             CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7151 #else
7152 #if ( defined(SUNOS) || defined(SS_LINUX))
7153    if(remAddrLen)
7154       recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen), 
7155             CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr, 
7156             (socklen_t *)&remAddrLen);
7157    else
7158       recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen), 
7159             CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7160 #else
7161    if(remAddrLen)
7162       recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen), 
7163             CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7164    else
7165       recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen), 
7166             CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7167 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7168 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7169
7170    /* removed the check of returned remAddrLen */ 
7171    if (recvLen == INET_ERR)
7172    {
7173       /* added check ERR_WOULDBLOCK */
7174       if ((INET_ERR_CODE == ERR_AGAIN) ||
7175             (INET_ERR_CODE == ERR_WOULDBLOCK))
7176       {
7177          recvLen = 0;
7178          RETVALUE(ROKDNA);
7179       }
7180       /* cm_inet_c_001.main_61: added host unreachable check */
7181       if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7182             (INET_ERR_CODE == ERR_CONNRESET) ||
7183             (INET_ERR_CODE == ERR_HOSTUNREACH) ||
7184             (INET_ERR_CODE == ERR_CONNREFUSED))
7185       {
7186          recvLen = 0;
7187          RETVALUE(RCLOSED);
7188       }
7189 #ifdef CMINETDBG
7190 #ifndef ALIGN_64BIT
7191       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7192       /* cm_inet_c_001.main_62:Warning fix */
7193       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%ld)\n", 
7194             INET_ERR_CODE, sockFd->fd);
7195       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
7196 #else
7197       /* cm_inet_c_001.main_62:Warning fix */
7198       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%d)\n", 
7199             INET_ERR_CODE, sockFd->fd);
7200       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
7201 #endif
7202 #endif /* CMINETDBG */
7203
7204       RETVALUE(RFAILED);
7205    } 
7206    else if (recvLen == 0)
7207    {
7208       RETVALUE(RCLOSED);
7209    }
7210
7211    /* cm_inet_c_001.main_57 - Fix for validation */
7212    if (recvLen < (S32)dataLen)  /* maybe happen */
7213    {
7214       RETVALUE(ROKDNA);
7215    } 
7216
7217    /* setup return destination Internet address */
7218    /* added the check of (remAddLen > 0) */
7219    if ((fromAddr != NULLP) && (remAddrLen > 0))
7220    {
7221 #ifdef IPV6_SUPPORTED
7222       cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
7223       if (remAddrLen == sizeof(struct sockaddr_in6))
7224       {
7225          remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7226          fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7227          fromAddr->u.ipv6Addr.port = 
7228             CM_INET_NTOH_U16(remAddr6->sin6_port);
7229          CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr, 
7230                &remAddr6->sin6_addr);
7231       }
7232       else
7233       {
7234          remAddr = (struct sockaddr_in *)&remSockAddr;
7235          fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7236          fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
7237          fromAddr->u.ipv4Addr.address = 
7238             CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7239       } 
7240 #else
7241       remAddr = (struct sockaddr_in *)&remSockAddr;
7242       fromAddr->port    = CM_INET_NTOH_U16(remAddr->sin_port);
7243       fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7244 #endif /* IPV6_SUPPORTED */
7245    }
7246
7247    RETVALUE(ROK);
7248 } /* end of cmInetPeeknew */
7249
7250 \f
7251 /*
7252 *
7253 *      Fun:   cmInetPeek
7254 *
7255 *      Desc:  Reads some data from the socket without destroying the socket
7256 *             receive buffer.
7257 *             The data is specified by the byte positon (first byte is at
7258 *             position 0) and the length.  
7259 *     
7260 *      Ret:   ROK     - successful
7261 *             ROKDNA  - ok, data not available
7262 *             RCLOSED - connection closed by peer
7263 *             RFAILED - failed
7264 *
7265 *      Notes: None.
7266 *
7267 *      File:  cm_inet.c
7268 *
7269 */
7270
7271 #ifdef ANSI
7272 PUBLIC S16 cmInetPeek
7273 (
7274 CmInetFd        *sockFd,        /* socket file descriptor */ 
7275 CmInetAddr      *fromAddr,      /* sender Internet address/port */ 
7276 CmInetMemInfo   *info,          /* buffer allocation info */
7277 MsgLen           dataPos,       /* position of data */
7278 MsgLen           dataLen,       /* length of read data */
7279 Data            *data           /* read data */
7280 )
7281 #else
7282 PUBLIC S16 cmInetPeek(sockFd, fromAddr, info, dataPos, dataLen, data)
7283 CmInetFd        *sockFd;        /* socket file descriptor */ 
7284 CmInetAddr      *fromAddr;      /* sender Internet address/port */ 
7285 CmInetMemInfo   *info;          /* buffer allocation info */
7286 MsgLen           dataPos;       /* position of data */
7287 MsgLen           dataLen;       /* length of read data */
7288 Data            *data;          /* read data */
7289 #endif
7290 {
7291    /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7292    Data        *recvBuf = NULLP;   /* plain receive buffer */
7293    /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
7294    MsgLen       bufLen;            /* buffer length */ 
7295    MsgLen       i;                 /* index */
7296    MsgLen       j;                 /* index */
7297    S32          ret;               /* temporary return value */
7298    U32          timeout;           /* timeout for cmInetSelect() */ 
7299    U32         *timeoutPtr;        /* pointer to timeout */
7300    S16          numFdS;            /* number of ready descriptors */
7301    /* cm_inet_c_001.main_45 - fixing the UMR issue in 64bit linux */
7302    U32          pendLen = 0;           /* pending data length */
7303    S32          recvLen;           /* number of received octets */
7304    S32          remAddrLen;        /* length of remote address length */
7305    CmInetFdSet  readFdS;           /* socket file descriptor set */
7306    struct sockaddr_in  *remAddr;    /* remote Internet address */      
7307 #ifdef IPV6_SUPPORTED
7308    struct sockaddr_in6  *remAddr6;  /* remote Internet IPV6 address */      
7309    struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
7310 #else
7311    CmInetSockAddr  remSockAddr;     /* to get packet's source IP address */
7312 #endif /* IPV6_SUPPORTED */
7313
7314    TRC2(cmInetPeek);
7315
7316 #if (ERRCLASS & ERRCLS_INT_PAR)
7317    /* error check on parameters */
7318    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
7319          (info == NULLP) || (data == NULLP) ||
7320          (dataPos < 0) || (dataLen < 0))
7321    {
7322       RETVALUE(RFAILED);
7323    }
7324 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7325
7326    /* check if there are some datas */
7327    if (sockFd->blocking) 
7328    {
7329       /* blocking */ 
7330       timeoutPtr = NULLP;  
7331    } 
7332    else 
7333    {
7334       /* poll (non-blocking) */ 
7335       timeout = 0;
7336       timeoutPtr = &timeout;
7337    }
7338    CM_INET_FD_ZERO(&readFdS);
7339    CM_INET_FD_SET(sockFd, &readFdS);
7340
7341    ret = cmInetSelect(&readFdS, NULLP, timeoutPtr, &numFdS);
7342    if (CM_INET_FD_ISSET(sockFd, &readFdS))
7343    {
7344       /* get number of pending data */
7345       /* removed 3rd arg memInfo. MemInfo is no longer needed as we 
7346          call ioctl for all sockets */
7347       ret = cmInetGetNumRead(sockFd, &pendLen);
7348       if (ret != ROK)
7349       {
7350          /* cm_inet_c_001.main_50
7351           * Return RCLOSED if cmInetGetNumRead returns RCLOSED. For other
7352           * errors just return RFAILED.
7353           */
7354          if (ret == RCLOSED)
7355             RETVALUE(RCLOSED);
7356
7357          RETVALUE(RFAILED);
7358       }
7359
7360       /* check if connection got closed */
7361       if (pendLen == 0)
7362       {
7363
7364          /* cm_inet_c_001.main_50 
7365           * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
7366           * (inside cmInetGetNumRead) returns pend length as 0 on a TCP 
7367           * socket that select says is ready to read. This should not be 
7368           * considered as connection closed. So return ROKDNA instead of 
7369           * RCLOSED even for TCP sockets
7370           */
7371          RETVALUE(ROKDNA);
7372       }
7373       /* added check for TCP/UDP socket. Pending data len in the socket 
7374          recv buffer is determined by ioctl call in cmInetGetNumRead. 
7375          For TCP it can't be > CM_INET_MAX_MSG_LEN. 
7376          For UDP it can't be > CM_INET_MAX_UDPRAW_MSGSIZE. */ 
7377       if (sockFd->type == CM_INET_STREAM) 
7378       {
7379          /* max message length is limited to control the memory usage */
7380          if (pendLen > CM_INET_MAX_MSG_LEN)
7381             pendLen = CM_INET_MAX_MSG_LEN;
7382          /* In STREAM remote address is not required */
7383          remAddrLen = 0;
7384       }
7385       else
7386       {
7387          if (pendLen > CM_INET_MAX_UDPRAW_MSGSIZE)
7388             pendLen = CM_INET_MAX_UDPRAW_MSGSIZE;
7389
7390          remAddrLen = sizeof(CmInetSockAddr);
7391       }
7392
7393       /* check if there are enough pending data to read */
7394       bufLen = dataPos + dataLen;
7395
7396       /* check if fromAddr is present or not */
7397       if (fromAddr != NULLP)
7398       {
7399          remAddrLen = sizeof(remSockAddr); 
7400       }
7401       else
7402       {
7403          remAddrLen = 0;
7404       }
7405
7406       /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
7407       if ((MsgLen)pendLen >= bufLen)
7408       {        
7409          /* allocate receive buffer (flat structure) */
7410          ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);                  
7411          if (ret != ROK)
7412          {
7413             RETVALUE(ROUTRES);
7414          }          
7415
7416          /* added different recvfrom calls with 
7417           * different 6th arg for different OS */
7418
7419          /* If remAddrLen is 0, pass NULLP */
7420 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7421          if(remAddrLen)
7422             recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen, 
7423                   CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7424          else
7425             recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen, 
7426                   CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7427 #else
7428 #if ( defined(SUNOS) || defined(SS_LINUX))
7429          if(remAddrLen)
7430             recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen, 
7431                   CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr, 
7432                   (socklen_t *)&remAddrLen);
7433          else
7434             recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen, 
7435                   CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7436 #else         
7437          if(remAddrLen)
7438             recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen, 
7439                   CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7440          else
7441             recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen, 
7442                   CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7443 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7444 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7445
7446          /* removed the check of returned remAddrLen */ 
7447          if (recvLen == INET_ERR)
7448          {
7449             /* cleanup */
7450             /* moved cleanup here */
7451             SPutSBuf(info->region, info->pool, recvBuf, bufLen); 
7452
7453             /* added check ERR_WOULDBLOCK */
7454             if ((INET_ERR_CODE == ERR_AGAIN) ||
7455                   (INET_ERR_CODE == ERR_WOULDBLOCK))
7456             {
7457                recvLen = 0;
7458                RETVALUE(ROKDNA);
7459             }
7460
7461             /* moved up the cleanup */
7462
7463 #ifdef CMINETDBG
7464 #ifndef ALIGN_64BIT
7465             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7466             /* cm_inet_c_001.main_62:Warning fix */
7467             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%ld)\n", 
7468                   INET_ERR_CODE, sockFd->fd);
7469             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7470 #else
7471             /* cm_inet_c_001.main_62:Warning fix */
7472             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%d)\n", 
7473                   INET_ERR_CODE, sockFd->fd);
7474             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7475 #endif
7476 #endif /* CMINETDBG */
7477
7478             if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7479                   (INET_ERR_CODE == ERR_CONNRESET))
7480             {
7481                recvLen = 0;
7482                RETVALUE(RCLOSED);
7483             }
7484             RETVALUE(RFAILED);
7485          } 
7486
7487          if (recvLen < (S32)bufLen)  /* maybe happen */
7488          {
7489             /* cleanup */
7490             SPutSBuf(info->region, info->pool, recvBuf, bufLen);                            
7491             RETVALUE(ROKDNA);
7492          } 
7493
7494          /* copy data */
7495          for (j = 0, i = dataPos; i < bufLen; j++, i++)
7496             data[j] = recvBuf[i];             
7497
7498          /* setup return destination Internet address */
7499          /* added the check of (remAddLen > 0) */
7500          if ((fromAddr != NULLP) && (remAddrLen > 0))
7501          {
7502 #ifdef IPV6_SUPPORTED
7503             cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
7504             if (remAddrLen == sizeof(struct sockaddr_in6))
7505             {
7506                remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7507                fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7508                fromAddr->u.ipv6Addr.port = 
7509                   CM_INET_NTOH_U16(remAddr6->sin6_port);
7510                CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr, 
7511                      &remAddr6->sin6_addr);
7512             }
7513             else
7514             {
7515                remAddr = (struct sockaddr_in *)&remSockAddr;
7516                fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7517                fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
7518                fromAddr->u.ipv4Addr.address = 
7519                   CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7520             } 
7521 #else
7522             remAddr = (struct sockaddr_in *)&remSockAddr;
7523             fromAddr->port    = CM_INET_NTOH_U16(remAddr->sin_port);
7524             fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7525 #endif /* IPV6_SUPPORTED */
7526          }   
7527
7528          /* cleanup */
7529          SPutSBuf(info->region, info->pool, recvBuf, bufLen);                            
7530       }
7531       else
7532       {
7533          /* not enough data pending yet */
7534          RETVALUE(ROKDNA);
7535       }
7536    }
7537    else
7538    {
7539       /* no data pending */ 
7540       RETVALUE(ROKDNA);
7541    }   
7542
7543    RETVALUE(ROK);
7544 } /* end of cmInetPeek */
7545
7546 \f
7547 /*
7548 *
7549 *      Fun:   cmInetClose 
7550 *
7551 *      Desc:  Close a socket gracefully. 
7552 *
7553 *      Ret:   ROK     - successful
7554 *             RFAILED - failed
7555 *
7556 *      Notes: None.
7557 *
7558 *      File:  cm_inet.c
7559 *
7560 */
7561
7562 #ifdef ANSI
7563 PUBLIC S16 cmInetClose
7564 (
7565 CmInetFd *sockFd                /* socket file descriptor */
7566 )
7567 #else
7568 PUBLIC S16 cmInetClose(sockFd)
7569 CmInetFd *sockFd;               /* socket file descriptor */
7570 #endif
7571 {
7572    S32 ret;                     /* temporary return value */
7573
7574    TRC2(cmInetClose);
7575
7576 #if (ERRCLASS & ERRCLS_INT_PAR)
7577    /* error check on parameters */
7578    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7579    {
7580       RETVALUE(RFAILED);
7581    }
7582 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7583
7584 #ifdef WIN32
7585    ret = closesocket(sockFd->fd);
7586 #else
7587    ret = close(sockFd->fd);
7588 #endif /* WIN32 */
7589    if (ret == INET_ERR) 
7590    {
7591 #ifdef CMINETDBG
7592 #ifndef ALIGN_64BIT
7593       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7594       /* cm_inet_c_001.main_62:Warning fix */
7595       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%ld)\n",
7596             INET_ERR_CODE, sockFd->fd);
7597       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7598 #else
7599       /* cm_inet_c_001.main_62:Warning fix */
7600       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%d)\n",
7601             INET_ERR_CODE, sockFd->fd);
7602       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7603 #endif /*ALIGN_64BIT*/
7604 #endif /* CMINETDBG */
7605       RETVALUE(RFAILED);
7606    }
7607
7608    RETVALUE(ROK);
7609 } /* end of cmInetClose */
7610
7611 \f
7612 /*
7613 *
7614 *      Fun:   cmInetShutdown
7615 *
7616 *      Desc:  Close an Internet connection with more control over the data of 
7617 *             the full-duplex connection.
7618 *             Values for the howTo parameter:
7619 *
7620 *             CM_INET_SHTDWN_RECV - discard data in receive buffer
7621 *             CM_INET_SHTDWN_SEND - discard data in transmit buffer
7622 *             CM_INET_SHTDWN_BOTH - discard data in receive and transmit buffer      
7623 *
7624 *      Ret:   ROK     - successful
7625 *             RFAILED - failed
7626 *
7627 *      Notes: This function does not free the socket descriptor but only closes the 
7628 *             connection (cmInetClose() has to be called afterwards).
7629 *             No error is returned if the socket is not connected while calling
7630 *             this function. 
7631 *
7632 *      File:  cm_inet.c
7633 *
7634 */
7635
7636 #ifdef ANSI
7637 PUBLIC S16 cmInetShutdown
7638 (
7639 CmInetFd *sockFd,               /* socket file descriptor */
7640 S32       howTo                 /* operation flag */
7641 )
7642 #else
7643 PUBLIC S16 cmInetShutdown(sockFd, howTo)
7644 CmInetFd *sockFd;               /* socket file descriptor */
7645 S32       howTo;                /* operation flag */
7646 #endif
7647 {
7648    S32 ret;                     /* temporary return value */
7649
7650    TRC2(cmInetShutdown);
7651
7652 #if (ERRCLASS & ERRCLS_INT_PAR)
7653    /* error check on parameters */
7654    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7655    {
7656       RETVALUE(RFAILED);
7657    }
7658 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7659
7660    ret = shutdown(sockFd->fd, howTo);
7661    if (ret == INET_ERR)
7662    {
7663       if (INET_ERR_CODE == ERR_NOTCONN)
7664       {
7665          /* socket is not connected */ 
7666          RETVALUE(ROK); 
7667       }
7668       else
7669       {
7670          /* real problem */ 
7671 #ifdef CMINETDBG
7672 #ifndef ALIGN_64BIT
7673          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7674          /* cm_inet_c_001.main_62:Warning fix */
7675          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7676                " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
7677          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7678 #else
7679          /* cm_inet_c_001.main_62:Warning fix */
7680          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7681                " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
7682          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7683 #endif /*ALIGN_64BIT*/
7684 #endif /* CMINETDBG */
7685          RETVALUE(RFAILED);
7686       }
7687    }   
7688
7689    RETVALUE(ROK);
7690 } /* end of cmInetShutdown */
7691
7692 \f
7693 /*
7694 *
7695 *      Fun:   cmInetSelect   
7696 *
7697 *      Desc:  Allows multiplex i/o requests among multiple sockets.
7698 *             If the parameter mSecTimeout points to a value of zero the 
7699 *             call immediatley returns (poll), if it is a null pointer, the
7700 *             timeout is set to infinit.
7701 *             numFdS returns the number of ready file  descriptors  contained  
7702 *             in  the  file  descriptor  sets 
7703 *
7704 *      Ret:   ROK      - successful
7705 *             RTIMEOUT - timout expired
7706 *             RFAILED  - failed
7707 *
7708 *      Notes: None.
7709 *
7710 *      File:  cm_inet.c
7711 *
7712 */
7713
7714 #ifdef ANSI
7715 PUBLIC S16 cmInetSelect
7716 (
7717 CmInetFdSet *readFdS,           /* read socket descriptor file set */  
7718 CmInetFdSet *writeFdS,          /* write socket descriptor file set */
7719 U32         *mSecTimeout,       /* timeout in msecs */
7720 S16         *numFdS             /* number of ready descriptors */
7721 )
7722 #else
7723 PUBLIC S16 cmInetSelect(readFdS, writeFdS, mSecTimeout, numFdS)
7724 CmInetFdSet *readFdS;           /* read socket descriptor file set */  
7725 CmInetFdSet *writeFdS;          /* write socket descriptor file set */
7726 U32         *mSecTimeout;       /* timeout in msecs */
7727 S16         *numFdS;            /* number of ready descriptors */
7728 #endif
7729 {
7730    S32 ret;                     /* temporary return value */
7731    struct timeval  timeout;     /* timeout structure */
7732    struct timeval *timeoutPtr;
7733    S32 errCode;
7734
7735 #if (ERRCLASS & ERRCLS_INT_PAR)
7736    /* error check on parameters */
7737    if (numFdS == NULLP)
7738    {
7739       RETVALUE(RFAILED);
7740    }
7741 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7742
7743    *numFdS = 0;
7744
7745    if (mSecTimeout != NULLP)
7746    {
7747       timeout.tv_sec  = *mSecTimeout / 1000;
7748       timeout.tv_usec = (*mSecTimeout % 1000) * 1000;
7749       timeoutPtr      = &timeout;
7750    }
7751    else
7752    {
7753       /* infinite timeout */ 
7754       timeoutPtr = NULLP;
7755    }
7756
7757 #ifdef TUCL_TTI_RCV
7758    timeout.tv_sec  = 0;
7759    timeout.tv_usec = 1;
7760 #endif
7761
7762    /* cm_inet_c_001.main_53 - Removed do-while loop */
7763    ret = select(FD_SETSIZE, readFdS, writeFdS, (fd_set*)0, timeoutPtr);
7764
7765    /* cm_inet_c_001.main_53 -  Return ROKDNA in case select was interrupted */
7766    if ((ret == INET_ERR) && (INET_ERR_CODE == ERR_EINTR))
7767    {
7768       RETVALUE(ROKDNA);
7769    }
7770
7771    /* timeout occured */
7772    if (ret == 0)
7773    { 
7774       RETVALUE(RTIMEOUT);
7775    }
7776
7777    if (ret == INET_ERR)
7778    {
7779       /* asa: Added a check for ERR_INVAL to return ROK
7780        * readFdS and writeFdS may be passed as NULL to
7781        * cmInetSelect() call
7782        */
7783       switch(errCode = INET_ERR_CODE)
7784       {
7785          case ERR_INVAL:
7786             RETVALUE(ROK);
7787
7788          default:
7789 #ifdef CMINETDBG
7790             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7791             /* cm_inet_c_001.main_62:Warning fix */
7792             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSelect() Failed : error(%d)\n",
7793                   INET_ERR_CODE);
7794             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET039, 0, prntBuf);
7795 #endif /* CMINETDBG */
7796             RETVALUE(RFAILED);
7797
7798       } /* end of switch */
7799    }
7800
7801    /* return number of ready file descriptors */
7802    /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7803    *numFdS = (S16)ret;   
7804
7805    RETVALUE(ROK); 
7806 } /* end of  cmInetSelect */
7807
7808 \f
7809 /*
7810 *
7811 *      Fun:   cmInetSetOpt
7812 *
7813 *      Desc:  Sets a socket option.
7814 *             The function supports following options:
7815 *
7816 *             CM_INET_OPT_BLOCK:
7817 *                value: CM_INET_OPT_DISABLE  non-blocking
7818 *                value: CM_INET_OPT_ENABLE   blocking
7819 *
7820 *             CM_INET_OPT_REUSEADDR:   
7821 *                value: CM_INET_OPT_ENABLE   reuse address 
7822 *
7823 *             CM_INET_OPT_BROADCAST:
7824 *                value: CM_INET_OPT_DISABLE
7825 *                value: CM_INET_OPT_ENABLE
7826 *
7827 *             CM_INET_OPT_KEEPALIVE:
7828 *                value: CM_INET_OPT_DISABLE
7829 *                value: CM_INET_OPT_ENABLE
7830 *
7831 *             CM_INET_OPT_RX_BUF_SIZE:
7832 *                value: receive buffer size in bytes
7833 *
7834 *             CM_INET_OPT_TX_BUF_SIZE:
7835 *                value: transmitter buffer size in bytes
7836 *
7837 *             CM_INET_OPT_ADD_MCAST_MBR:
7838 *                value: address of CmInetMCastInf structure
7839 *
7840 *             CM_INET_OPT_DRP_MCAST_MBR:
7841 *                value: address of CmInetMCastInf structure
7842 *
7843 *             CM_INET_OPT_TCP_NODELAY:  
7844 *                value: CM_INET_OPT_DISABLE
7845 *                value: CM_INET_OPT_ENABLE
7846 *
7847 *             CM_INET_OPT_BSD_COMPAT: For Linux only
7848 *                value: CM_INET_OPT_ENABLE   
7849 *                value: CM_INET_OPT_DISABLE 
7850 *
7851 *             CM_INET_OPT_HDR_INCLD: 
7852 *                value: CM_INET_ENABLE
7853 *                value: CM_INET_DISABLE
7854 *
7855 *             CM_INET_OPT_DONT_FRAGMENT:
7856 *                value: CM_INET_OPT_ENABLE
7857 *                value: CM_INET_DISABLE
7858 *
7859 *             CM_INET_OPT_TOS:
7860 *                value: Type of Service.
7861
7862 *             CM_INET_OPT_TTL:
7863 *                value: Time To Live.
7864 *
7865 *             CM_INET_OPT_IP_OPTIONS:
7866 *                value: IPv4 header option value 
7867 *                ENABLE/DISABLE.
7868 *
7869 *             CM_INET_OPT_IP_ROUTER_ALERT:
7870 *                value: CM_INET_OPT_DISABLE
7871 *                value: CM_INET_OPT_ENABLE
7872 *
7873 *             CM_INET_OPT_IPV4_PKTINFO
7874 *                value: CM_INET_OPT_ENABLE
7875 *                value: CM_INET_OPT_DISABLE
7876 *
7877 *             CM_INET_OPT_MCAST_LOOP:  
7878 *                value: CM_INET_OPT_DISABLE
7879 *                value: CM_INET_OPT_ENABLE
7880 *
7881 *             CM_INET_OPT_MCAST_IF:
7882 *                value: Address of interface.
7883 *
7884 *             CM_INET_OPT_MCAST_TTL:
7885 *                value: TTL of the outgoing multicast packet.
7886 *
7887 *             The next  options are defined only if IPV6 is 
7888 *             supported.
7889 *
7890 *             CM_INET_OPT_ADD_MCAST6_MBR:
7891 *                value: address of CmInetMCastInf6 structure
7892 *
7893 *             CM_INET_OPT_DRP_MCAST6_MBR:
7894 *                value: address of CmInetMCastInf6 structure
7895 *
7896 *             CM_INET_OPT_MCAST6_LOOP:  
7897 *                value: CM_INET_OPT_DISABLE
7898 *                value: CM_INET_OPT_ENABLE
7899 *
7900 *             CM_INET_OPT_MCAST6_IF:
7901 *                value: Interface index
7902 *
7903 *             CM_INET_OPT_MCAST6_HOPS:  
7904 *                value: multicast hop limit 
7905 *
7906 *             CM_INET_OPT_RECVIPV6_HOPLIM:
7907 *                value: CM_INET_OPT_ENABLE   hop limit will be returned
7908 *                                            on the socket.
7909 *                value: CM_INET_OPT_DISABLE  hop limit wont be returned 
7910 *                                            on the socket.
7911 *
7912 *             CM_INET_OPT_RECVIPV6_HBHOPTS:
7913 *                value: CM_INET_OPT_ENABLE   HBH Options will be returned
7914 *                                            on the socket.
7915 *                value: CM_INET_OPT_DISABLE  HBH Options wont be returned 
7916 *                                            on the socket. 
7917 *                                            
7918 *             CM_INET_OPT_RECVIPV6_DSTOPTS:
7919 *                value: CM_INET_OPT_ENABLE   Dest Options will be returned
7920 *                                            on the socket.
7921 *                value: CM_INET_OPT_DISABLE  Dest Options wont be returned 
7922 *                                            on the socket.                     
7923 *                                            
7924 *             CM_INET_OPT_RECVIPV6_RTHDR:
7925 *                value: CM_INET_OPT_ENABLE   Route Hdr Opt will be turned
7926 *                                            ON on the socket.
7927 *                value: CM_INET_OPT_DISABLE  Route Hdr Opt will be turned 
7928 *                                            OFF on the socket.
7929 *
7930 *             CM_INET_OPT_IP_ROUTER_ALERT6  
7931 *                value: CM_INET_OPT_ENABLE
7932 *                value: CM_INET_OPT_DISABLE
7933
7934 *             CM_INET_OPT_IPV6_PKTINFO
7935 *                value: CM_INET_OPT_ENABLE   Enable sending and receiving
7936 *                                            of packet info
7937 *                value: CM_INET_OPT_DISABLE  Disable sending and receiving
7938 *                                            of packet info
7939
7940 *             CM_INET_OPT_LINGER
7941 *                value: address of CmInetSockLinger structure
7942 *
7943 *             CM_INET_OPT_SCTP_EVENTS
7944 *                value: address of CmInetSctpSockEvent structure
7945 *
7946 *             CM_INET_OPT_SCTP_PRIM_ADDR
7947 *                value: address of CmInetSctpPrimAddr structure
7948 *
7949 *             CM_INET_OPT_SCTP_PEERADDR_PARAMS
7950 *                value: address of CmInetSctpPeerAddrParams structure
7951 *
7952 *
7953 *      Ret:   ROK     - successful
7954 *             RFAILED - failed
7955 *             RNA     - failed, option not available
7956 *             (Only when CM_INET2 is defined)
7957 *
7958 *      Notes: The send and receive buffer size may be system
7959 *             specific. The cmInetSetOpt() call may return
7960 *             successfuly although not the entire buffer size 
7961 *             could be set!
7962 *
7963 *      File:  cm_inet.c
7964 *
7965 */
7966 #ifdef ANSI
7967 PUBLIC S16 cmInetSetOpt
7968 (
7969 CmInetFd *sockFd,               /* socket file descriptor */ 
7970 U32       level,                /* option level */
7971 U32       type,                 /* option type */
7972 Ptr       value                 /* option value */ 
7973
7974 #else
7975 PUBLIC S16 cmInetSetOpt(sockFd, level, type, value)
7976 CmInetFd *sockFd;               /* socket file descriptor */ 
7977 U32       level;                /* option level */
7978 U32       type;                 /* option type */
7979 Ptr       value;                /* option value */
7980 #endif
7981 {
7982    S32  ret = ROK;              /* temporary return value */
7983    U32  disable = 0;            /* disable option */
7984    U32  enable = 1;             /* enable option */
7985
7986    /* added for IPv4 options */
7987 #ifdef IPV4_OPTS_SUPPORTED
7988 #if((!defined (SS_VW)) && (!defined(SS_LINUX)))   
7989    TknStr64 *tempTknStr64;      /* points TknStr64 structure */
7990    /* which has value for IPv4 hdr options.*/
7991 #endif /* SS_VW && SS_LINUX */   
7992 #ifdef WIN32   
7993    int disableOpt = 0;
7994 #endif /* WIN32 */   
7995 #endif /* IPV4_OPTS_SUPPORTED */ 
7996
7997 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST)\
7998       || defined(HPOS))
7999    U8   lpEnable = 1;           /* multicast loop enable */
8000    U8   lpDisable = 0;          /* multicast loop disable */
8001 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8002
8003 #ifdef WIN32
8004    BOOL boolEnable = TRUE;      /* enable option */
8005    BOOL boolDisable = FALSE;    /* disable option */
8006 #endif /* WIN32 */
8007
8008 #if (defined(SUNOS) || defined(WIN32) || defined(SS_PS) || \
8009       defined(SS_VW_MCAST) || defined(HPOS))
8010    struct ip_mreq stMreq;
8011    CmInetMCastInf *mCast;
8012 #endif /* SUNOS || WIN32  || SS_PS || SS_VW_MCAST || HPOS */
8013
8014 #ifdef IPV6_SUPPORTED
8015    U32    loopEna = 1;     /* IPv6 multicast loop enable */
8016    U32    loopDis = 0;     /* IPv6 multicast loop disable */
8017    struct ipv6_mreq     *stMreq6Ptr;
8018    /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so 
8019       this flag is gaurded under ICMPV6_FILTER_SUPPORTED. so if user want this 
8020       support he has to enable the above flag.*/
8021    /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8022     * to support filteration  of ICMP messages */
8023 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8024    struct icmp6_filter  *icmp6Filter; 
8025 #endif /* ICMPV6_FILTER_SUPPORTED */
8026 #endif /* IPV6_SUPPORTED */
8027
8028    /* cm_inet_c_001.main_58 : Added new local variables to support filteration 
8029     * of ICMP messages */
8030 #ifdef SS_LINUX
8031 #ifdef CM_ICMP_FILTER_SUPPORT
8032   struct icmp_filter icmpFilter; 
8033 #endif  
8034 #endif  
8035
8036    /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8037 #ifdef CM_LKSCTP
8038    struct linger               lngr;
8039    struct sctp_event_subscribe event; 
8040    struct sctp_paddrparams     addrParams;
8041    struct sctp_setprim         setPrim;
8042    struct sockaddr_in         *pAddr;
8043    struct sctp_assocparams     assocParams;
8044    struct sctp_initmsg         initmsg;
8045    struct sctp_rtoinfo         rtoinfo;
8046 #ifdef IPV6_SUPPORTED
8047    struct sockaddr_in6        *pAddr6;
8048 #endif /* IPV6_SUPPORTED */
8049
8050    CmInetSockLinger           *pSockLinger;
8051    CmInetSctpSockEvent        *pSctpEvent;
8052    CmInetSctpPrimAddr         *pSctpPrimAddr;
8053    CmInetSctpPeerAddrParams   *pSctpPAddrParams;
8054    CmInetSctpRtoInfo          *pSctpRtoInfo;
8055    CmInetSctpInitMsg          *pSctpInitMsg;
8056    CmInetSctpAssocParams      *pSctpAssocParams;
8057 #endif
8058
8059    U32    *optVal;
8060
8061    TRC2(cmInetSetOpt);
8062
8063    /* cm_inet_c_001.main_58 : Added NULL check for value field */ 
8064    if(value == NULLP)
8065    {
8066       RETVALUE(RFAILED);
8067    }
8068
8069 #if (ERRCLASS & ERRCLS_INT_PAR)
8070    /* error check on parameters */
8071    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
8072    {
8073       RETVALUE(RFAILED);
8074    }
8075 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8076
8077    switch (type)
8078    {
8079       case CM_INET_OPT_BLOCK:
8080          optVal = (U32*)value;
8081          switch(*optVal)
8082          {
8083             case CM_INET_OPT_ENABLE:
8084
8085 #ifdef WIN32
8086                /* cm_inet_c_001.main_59: Fix for compilation warning */
8087                ret = ioctlsocket(sockFd->fd, FIONBIO, (U32 *)&disable);
8088 #else
8089 #ifdef SS_PS
8090                ret = ioctl(sockFd->fd, FIONBIO, (char*)&disable);
8091 #else
8092 #ifdef SS_VW
8093                ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&disable);
8094 #else
8095                ret = ioctl(sockFd->fd, (S32)FIONBIO, &disable);
8096
8097 #endif /* SS_VW */
8098 #endif /* SS_PS */
8099 #endif /* WIN32 */
8100                sockFd->blocking = 1;
8101                break;
8102
8103             case CM_INET_OPT_DISABLE:
8104 #ifdef WIN32
8105               /* cm_inet_c_001.main_59: Fix for compilation warning */
8106               ret = ioctlsocket(sockFd->fd, FIONBIO, (U32 *)&enable); 
8107 #else
8108 #ifdef SS_PS
8109                ret = ioctl(sockFd->fd, FIONBIO, (char*)&enable);
8110 #else
8111 #ifdef SS_VW
8112                ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&enable);
8113 #else
8114                ret = ioctl(sockFd->fd, (S32)FIONBIO, &enable);
8115 #endif /* SS_VW */
8116 #endif /* SS_PS */
8117 #endif /* WIN32 */
8118                sockFd->blocking = 0;
8119                break;
8120
8121             default:
8122                /* wrong value */
8123                RETVALUE(RFAILED);
8124                break;
8125          }
8126          break;
8127
8128       case CM_INET_OPT_REUSEADDR:
8129          optVal = (U32*)value;
8130          if (*optVal == CM_INET_OPT_ENABLE)
8131          {
8132 #ifdef WIN32
8133             ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8134                   (char*)&boolEnable, sizeof(boolEnable));
8135 #else
8136             ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8137                   (char*)&enable, sizeof(enable));
8138 #ifdef SS_VW
8139             setsockopt(sockFd->fd, level, SO_REUSEPORT,
8140                   (char*)&enable, sizeof(enable));
8141 #endif /* SS_VW */
8142 #endif /* WIN32 */
8143          }
8144          else if (*optVal == CM_INET_OPT_DISABLE)
8145          {
8146 #ifdef WIN32
8147             ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8148                   (char*)&boolDisable, sizeof(boolDisable));
8149 #else
8150             ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8151                   (char*)&disable, sizeof(disable));
8152 #ifdef SS_VW
8153             ret = setsockopt(sockFd->fd, level, SO_REUSEPORT,
8154                   (char*)&disable, sizeof(disable));
8155 #endif /* SS_VW */
8156 #endif /* WIN32 */
8157          }
8158          break;
8159
8160       case CM_INET_OPT_BROADCAST:
8161          optVal = (U32*)value;
8162          if (*optVal == CM_INET_OPT_ENABLE)
8163          {
8164 #ifdef WIN32
8165             ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8166                   (char*)&boolEnable, sizeof(boolEnable));
8167 #else
8168             ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8169                   (char*)&enable, sizeof(enable));
8170 #endif /* WIN32 */
8171          }
8172          else if (*optVal == CM_INET_OPT_DISABLE)
8173          {
8174 #ifdef WIN32
8175             ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8176                   (char*)&boolDisable, sizeof(boolDisable));
8177 #else
8178             ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8179                   (char*)&disable, sizeof(disable));
8180 #endif /* WIN32 */
8181          }
8182          break; 
8183
8184       case CM_INET_OPT_KEEPALIVE:
8185          optVal = (U32*)value;
8186          if (*optVal == CM_INET_OPT_ENABLE)
8187          {
8188 #ifdef WIN32
8189             ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8190                   (char*)&boolEnable, sizeof(boolEnable));
8191 #else
8192             ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8193                   (char*)&enable, sizeof(enable));
8194 #endif /* WIN32 */
8195          }
8196          else if (*optVal == CM_INET_OPT_DISABLE)
8197          {
8198 #ifdef WIN32
8199             ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8200                   (char*)&boolDisable, sizeof(boolDisable));
8201 #else
8202             ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8203                   (char*)&disable, sizeof(disable));
8204 #endif /* WIN32 */
8205          }
8206          break;
8207
8208       case CM_INET_OPT_RX_BUF_SIZE:
8209          optVal = (U32*)value;
8210          ret = setsockopt(sockFd->fd, level, SO_RCVBUF, 
8211                (char*)optVal, sizeof(*optVal));
8212          break;
8213
8214       case CM_INET_OPT_TX_BUF_SIZE:
8215          optVal = (U32*)value;
8216          ret = setsockopt(sockFd->fd, level, SO_SNDBUF, 
8217                (char*)optVal, sizeof(*optVal));
8218          break;
8219
8220       case CM_INET_OPT_TCP_NODELAY:
8221          optVal = (U32*)value;
8222          if (*optVal == CM_INET_OPT_ENABLE)
8223          {
8224 #ifdef WIN32
8225 #ifndef SS_WINCE
8226             ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8227                   (char*)&boolEnable, sizeof(boolEnable));
8228 #endif /* SS_WINCE */
8229 #else
8230             ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8231                   (char*)&enable, sizeof(enable)); 
8232 #endif /* WIN32 */
8233          }
8234          else if (*optVal == CM_INET_OPT_DISABLE)
8235          {
8236 #ifdef WIN32
8237 #ifndef SS_WINCE
8238             ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8239                   (char*)&boolDisable, sizeof(boolDisable));
8240 #endif /* SS_WINCE */
8241 #else
8242             ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8243                   (char*)&disable, sizeof(disable));
8244 #endif /* WIN32 */
8245          }
8246          break;
8247
8248 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || \
8249       defined(SS_VW_MCAST) || defined(HPOS))
8250
8251       case CM_INET_OPT_ADD_MCAST_MBR:
8252          mCast = (CmInetMCastInf*)value;
8253
8254          /* Copy the addresses to stMreq structure */
8255 #ifdef SS_PS
8256          stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8257 #else
8258          stMreq.imr_multiaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8259 #endif
8260          stMreq.imr_interface.s_addr = CM_INET_HTON_U32(mCast->localAddr);
8261
8262          ret = setsockopt(sockFd->fd, level, IP_ADD_MEMBERSHIP,
8263                (char*)&stMreq, sizeof(stMreq));
8264          break;
8265
8266       case CM_INET_OPT_DRP_MCAST_MBR:
8267          mCast = (CmInetMCastInf*)value;
8268
8269          /* Copy the addresses to stMreq structure */
8270 #ifdef SS_PS
8271          stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8272 #else
8273          stMreq.imr_multiaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8274 #endif
8275          stMreq.imr_interface.s_addr = CM_INET_HTON_U32(mCast->localAddr);
8276
8277          ret = setsockopt(sockFd->fd, level, IP_DROP_MEMBERSHIP,
8278                (char*)&stMreq, sizeof(stMreq));
8279          break;
8280
8281 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8282
8283 #ifdef SS_LINUX
8284          /* cm_inet_c_001.main_37 - Enable CMINET_BSDCOMPAT flag if system doesnt
8285             support CM_INET_OPT_BSD_COMPAT */
8286 #ifndef CMINET_BSDCOMPAT
8287       case CM_INET_OPT_BSD_COMPAT:
8288          optVal = (U32*)value;
8289          if (*optVal == CM_INET_OPT_ENABLE)
8290          {
8291             ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
8292                   &enable, sizeof(enable));
8293          }
8294          else if (*optVal == CM_INET_OPT_DISABLE)
8295          {
8296             ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
8297                   &disable, sizeof(disable));
8298          }
8299          break;
8300 #endif /* CMINET_BSDCOMPAT */
8301 #endif /* SS_LINUX */
8302
8303 #ifdef CM_INET2  
8304          /* Added for support of Raw socket  modify according to the 
8305           * option available on different platform  */
8306 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW) \
8307       || defined(HPOS))
8308       case CM_INET_OPT_HDR_INCLD:
8309          optVal = (U32*)value;
8310          if (*optVal == CM_INET_OPT_ENABLE)
8311          {
8312 #ifdef WIN32 
8313             RETVALUE(RNA);    
8314 #else
8315             ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
8316                   (char*)&enable, sizeof(enable));
8317 #endif /* WIN32 */
8318          }
8319          else if (*optVal == CM_INET_OPT_DISABLE)
8320          {
8321 #ifdef WIN32
8322             RETVALUE(RNA);    
8323 #else
8324             ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
8325                   (char*)&disable, sizeof(disable));
8326 #endif /* WIN32 */
8327          }
8328          break;
8329
8330          /* added new options */
8331 #ifdef IPV4_OPTS_SUPPORTED
8332 #ifdef SS_LINUX
8333          /* Linux: set Router Alert socket option to Intercept RAW RSVP 
8334             packets at the Intermediate node(Router) with Router Alert SET.
8335             This socket option is MUST be set (when this server is opened)
8336             if the RSVP server wants to intercept raw RSVP packets. */
8337       case CM_INET_OPT_IP_ROUTER_ALERT:
8338          optVal = (U32*)value;
8339          if (*optVal == CM_INET_OPT_ENABLE)
8340          {   
8341             ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
8342                   (char*)&enable, sizeof(enable));
8343             if (ret != ROK)
8344                RETVALUE(RFAILED);
8345          }
8346          else if (*optVal == CM_INET_OPT_DISABLE)
8347          {   
8348             ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
8349                   (char*)&disable, sizeof(disable));
8350             if (ret != ROK)
8351                RETVALUE(RFAILED);
8352          }   
8353          break;         
8354 #endif /* SS_LINUX */
8355
8356          /* set Router Alert socket option */
8357       case CM_INET_OPT_IP_OPTIONS:
8358 #if (defined (SS_VW) || defined(SS_LINUX))
8359          RETVALUE(RNA);
8360 #else  
8361          tempTknStr64=(TknStr64 *)value;
8362          if (tempTknStr64->pres == TRUE)
8363          {
8364             if (tempTknStr64->len == 0)
8365             {
8366                /* disable the IP_OPTIONS for Router Alert.  */
8367 #ifdef WIN32                          
8368                ret = setsockopt(sockFd->fd, level, IP_OPTIONS, 
8369                      (CONSTANT char *)&disableOpt, sizeof(int));
8370 #else
8371                ret = setsockopt(sockFd->fd, level, IP_OPTIONS, NULL, 0);
8372 #endif /* WIN32 */                  
8373             }  
8374             else
8375                /* enable the IP_OPTIONS for Router Alert */
8376                ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
8377                      (char *)tempTknStr64->val, tempTknStr64->len);
8378          }
8379          else
8380             RETVALUE(RFAILED); /* Trying to set IPv4 Hdr option
8381                                 * without giving option values*/
8382 #endif /* SS_VW || SS_LINUX */
8383          break;
8384 #endif /* IPV4_OPTS_SUPPORTED */
8385
8386          /* added new options */
8387 #if (defined(SS_LINUX) && (!defined(SS_VW) && !defined(WIN32)))
8388 #ifdef LOCAL_INTF
8389       case CM_INET_OPT_IPV4_PKTINFO:
8390          optVal = (U32*)value;
8391          if (*optVal == CM_INET_OPT_ENABLE)
8392          {   
8393             /* set IP_PKTINFO option when IP_ROUTER_ALERT is set in linux */
8394             ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
8395                   (char*)&enable, sizeof(enable));
8396
8397             if (ret != ROK)
8398                RETVALUE(RFAILED);
8399          }
8400          else if (*optVal == CM_INET_OPT_DISABLE)
8401          {   
8402             /* disable IP_PKTINFO when IP_ROUTER_ALERT is set in linux */ 
8403             ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
8404                   (char*)&disable, sizeof(disable));
8405
8406             if (ret != ROK)
8407                RETVALUE(RFAILED);
8408          }   
8409          break;   
8410 #endif /* LOCAL_INTF */            
8411 #endif /* SS_LINUX */
8412
8413 #endif /* SUNOS || WIN32 || SS_PS || SS_VW || HPOS */
8414
8415       case CM_INET_OPT_DONTFRAGMENT:
8416          optVal = (U32*)value;
8417          if (*optVal == CM_INET_OPT_ENABLE)
8418          {
8419 #ifdef WIN32
8420             ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8421                   (char*)&boolEnable, sizeof(boolEnable));
8422 #endif /* WIN32 */
8423          }
8424          else if (*optVal == CM_INET_OPT_DISABLE)
8425          {
8426 #ifdef WIN32
8427             ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8428                   (char*)&boolDisable, sizeof(boolDisable));
8429 #endif /* WIN32 */
8430          }
8431          break;
8432
8433          /* also add these 2 options for VxWorks */         
8434 #if (defined(SUNOS)|| defined(WIN32) || defined(HPOS) || defined(SS_VW))
8435       case CM_INET_OPT_TOS:
8436          optVal = (U32*)value;
8437          ret = setsockopt(sockFd->fd, level, IP_TOS,
8438                (char*)optVal, sizeof(*optVal));
8439          break;
8440
8441       case CM_INET_OPT_TTL:
8442          optVal = (U32*)value;
8443          ret = setsockopt(sockFd->fd, level, IP_TTL,
8444                (char*)optVal, sizeof(*optVal));
8445          break;
8446 #endif /* SUNOS || WIN32 || HPOS || SS_VW */
8447 #endif  /* CM_INET2 */ 
8448
8449 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST) \
8450       || defined(HPOS))
8451       case CM_INET_OPT_MCAST_LOOP:
8452          optVal = (U32*)value;
8453          if (*optVal == CM_INET_OPT_ENABLE)
8454          {
8455 #ifdef SS_VW            
8456             ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8457                   (char *)&lpEnable, sizeof(lpEnable));
8458 #else
8459             ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8460                   (CONSTANT char *)&lpEnable, sizeof(lpEnable));
8461 #endif /* SS_VW */           
8462          }
8463          else
8464          {
8465 #ifdef SS_VW            
8466             ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8467                   (char *)&lpDisable, sizeof(lpDisable));
8468 #else
8469             ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8470                   (CONSTANT char *)&lpDisable, sizeof(lpDisable));
8471 #endif /* SS_VW */            
8472          }
8473          break;
8474
8475       case CM_INET_OPT_MCAST_IF:
8476          optVal = (U32*)value;
8477          *optVal = CM_INET_HTON_U32((U32)*optVal); 
8478          ret = setsockopt(sockFd->fd, level, IP_MULTICAST_IF,
8479                (char *)optVal, sizeof(struct in_addr));
8480          break;
8481
8482       case CM_INET_OPT_MCAST_TTL:
8483          optVal = (U32*)value;
8484          /* remove CONSTANT in setsockopt for VW */
8485 #ifdef SS_VW      
8486          ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8487                (char *)optVal, sizeof(U8));
8488 #else
8489          ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8490                (CONSTANT char *)optVal, sizeof(U8));
8491 #endif /* SS_VW */         
8492          break;
8493 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8494
8495 #ifdef IPV6_SUPPORTED
8496       case CM_INET_OPT_IPV6_TTL:
8497          optVal = (U32*)value;
8498          ret = setsockopt(sockFd->fd, level, IPV6_UNICAST_HOPS,
8499                (char*)optVal, sizeof(*optVal));
8500          break;
8501
8502       case CM_INET_OPT_ADD_MCAST6_MBR:
8503          stMreq6Ptr = (struct ipv6_mreq *)value;
8504          ret = setsockopt(sockFd->fd, level, IPV6_JOIN_GROUP,
8505                (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8506          break;
8507
8508       case CM_INET_OPT_DRP_MCAST6_MBR:
8509          stMreq6Ptr = (struct ipv6_mreq *)value;
8510          ret = setsockopt(sockFd->fd, level, IPV6_LEAVE_GROUP,
8511                (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8512          break;
8513
8514       case CM_INET_OPT_MCAST6_LOOP:  
8515          optVal = (U32*)value;
8516          if (*optVal == CM_INET_OPT_ENABLE)
8517          {
8518             ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8519                   &loopEna, sizeof(loopEna));
8520          }
8521          else
8522          {
8523             ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8524                   &loopDis, sizeof(loopDis));
8525          }
8526          break;
8527
8528       case CM_INET_OPT_MCAST6_IF:
8529          ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_IF,
8530                (U32 *)value, sizeof(U32));
8531          break;
8532
8533       case CM_INET_OPT_MCAST6_HOPS:
8534          optVal = (U32*)value;
8535          ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_HOPS,
8536                (char *)optVal, sizeof(U32));
8537          break;
8538
8539          /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so 
8540             this flag is gaurded under ICMPV6_SUPPORTED. so if user want this 
8541             support he has to enable the above flag.*/
8542          /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8543           * to support filteration  of ICMP messages */
8544 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8545       case CM_INET_OPT_ICMP6_FILTER:  
8546          icmp6Filter = (struct icmp6_filter *)value;
8547          ret = setsockopt(sockFd->fd, level, ICMP6_FILTER,
8548                (char *)icmp6Filter, sizeof(struct icmp6_filter));
8549          break;
8550 #endif /* ICMPV6_FILTER_SUPPORTED */
8551
8552          /* added new options */
8553 #ifdef IPV6_OPTS_SUPPORTED
8554       case CM_INET_OPT_RECVIPV6_HOPLIM:
8555          optVal = (U32*)value;
8556 #ifdef SS_LINUX         
8557          ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8558                (char *)optVal, sizeof(U32)); 
8559 #else
8560          ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8561                (char *)optVal, sizeof(U32)); 
8562          /* enable the reception of IPv6 HopLimit value as ancillary data */
8563          ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPLIMIT,
8564                (char*)&enable, sizeof(enable)); 
8565 #endif /* SS_LINUX */
8566
8567          break;
8568
8569       case CM_INET_OPT_RECVIPV6_HBHOPTS:
8570          optVal = (U32*)value;
8571 #ifdef SS_LINUX
8572          ret = setsockopt(sockFd->fd, level, IPV6_HOPOPTS,
8573                (char *)optVal, sizeof(U32));
8574 #else
8575          ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPOPTS,
8576                (char *)optVal, sizeof(U32)); 
8577 #endif /* SS_LINUX */          
8578          break;
8579
8580       case CM_INET_OPT_RECVIPV6_DSTOPTS:
8581          optVal = (U32*)value;
8582 #ifdef SS_LINUX         
8583          ret = setsockopt(sockFd->fd, level, IPV6_DSTOPTS,
8584                (char *)optVal, sizeof(U32));
8585 #else         
8586          ret = setsockopt(sockFd->fd, level, IPV6_RECVDSTOPTS,
8587                (char *)optVal, sizeof(U32));
8588 #endif /* SS_LINUX */
8589          break;
8590
8591       case CM_INET_OPT_RECVIPV6_RTHDR:
8592          optVal = (U32*)value;
8593 #ifdef SS_LINUX         
8594          ret = setsockopt(sockFd->fd, level, IPV6_RTHDR,
8595                (char *)optVal, sizeof(U32));
8596 #else
8597          ret = setsockopt(sockFd->fd, level, IPV6_RECVRTHDR,
8598                (char *)optVal, sizeof(U32));
8599 #endif /* SS_LINUX */         
8600          break;      
8601
8602          /* works ONLY for IPPROTO_RAW type socket. so if it this socket
8603           * option is tried to set for IPPROTO_RSVP, then it is supposed
8604           * to fail with EINVAL according to net/ipv6/ipv6_sockglue.c 
8605           *
8606           * if HI_SRVC_RAW_RAW is not used during ServOpenReq as the server 
8607           * type, then it will fail here due to above reason */
8608 #ifdef SS_LINUX
8609       case CM_INET_OPT_IP_ROUTER_ALERT6:
8610          optVal = (U32*)value;
8611          if(*optVal == CM_INET_OPT_ENABLE)
8612             ret = setsockopt(sockFd->fd, IPPROTO_IPV6, IPV6_ROUTER_ALERT,
8613                   (char *)&enable, sizeof(enable));          
8614          else
8615             ret = setsockopt(sockFd->fd, level, IPV6_ROUTER_ALERT,
8616                   (char *)&disable, sizeof(disable));
8617
8618          break;
8619 #endif /* SS_LINUX */
8620 #endif /* IPV6_OPTS_SUPPORTED */
8621
8622 #ifdef LOCAL_INTF         
8623       case CM_INET_OPT_IPV6_PKTINFO:
8624          optVal = (U32*)value;
8625 #ifdef SS_LINUX         
8626          ret = setsockopt(sockFd->fd, level, IPV6_PKTINFO,
8627                (char *)optVal, sizeof(U32));
8628 #else         
8629          ret = setsockopt(sockFd->fd, level, IPV6_RECVPKTINFO,
8630                (char *)&enable, sizeof(enable));
8631 #endif /* SS_LINUX */
8632          break;
8633 #endif /* LOCAL_INTF */
8634
8635 #endif /* IPV6_SUPPORTED */
8636
8637          /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8638 #ifdef CM_LKSCTP
8639       case CM_INET_OPT_LINGER:
8640          pSockLinger = (CmInetSockLinger *)value;
8641
8642          cmMemset((U8*)&lngr, 0, sizeof(struct linger));
8643
8644          if (pSockLinger->enable == TRUE)
8645             lngr.l_onoff = 1;
8646          else 
8647             lngr.l_onoff = 0;
8648
8649          lngr.l_linger = pSockLinger->lingerTime;
8650          ret = setsockopt(sockFd->fd, level, SO_LINGER, &lngr, sizeof(lngr));
8651          break;
8652
8653       case CM_INET_OPT_SCTP_EVENTS:
8654          pSctpEvent = (CmInetSctpSockEvent *)value;
8655
8656          cmMemset((U8*)&event, 0, sizeof(struct sctp_event_subscribe));
8657
8658          if (pSctpEvent->dataIoEvent == TRUE)
8659             event.sctp_data_io_event = 1;
8660
8661          if (pSctpEvent->associationEvent == TRUE)
8662             event.sctp_association_event = 1;
8663
8664          if (pSctpEvent->addressEvent == TRUE)
8665             event.sctp_address_event = 1;
8666
8667          if (pSctpEvent->sendFailureEvent == TRUE)
8668             event.sctp_send_failure_event = 1;
8669
8670          if (pSctpEvent->peerErrorEvent == TRUE)
8671             event.sctp_peer_error_event = 1;
8672
8673          if (pSctpEvent->shutdownEvent == TRUE)
8674             event.sctp_shutdown_event = 1;
8675
8676          if (pSctpEvent->partialDeliveryEvent == TRUE)
8677             event.sctp_partial_delivery_event = 1;
8678
8679          if (pSctpEvent->adaptationLayerEvent == TRUE)
8680 #ifdef SUN_KSCTP
8681             event.sctp_adaption_layer_event = 1;
8682 #else
8683          event.sctp_adaptation_layer_event = 1;
8684 #endif
8685
8686          ret = setsockopt(sockFd->fd, level, SCTP_EVENTS, &event, sizeof(event));
8687          break;
8688
8689       case CM_INET_OPT_SCTP_PRIM_ADDR:
8690          pSctpPrimAddr = (CmInetSctpPrimAddr *)value;
8691
8692          cmMemset((U8*)&setPrim, 0, sizeof(struct sctp_setprim));
8693
8694 #ifdef IPV6_SUPPORTED 
8695          if (pSctpPrimAddr->addr.type == CM_INET_IPV6ADDR_TYPE)
8696          {
8697             if (sockFd->protType == AF_INET)
8698             {
8699 #ifdef CMINETDBG
8700 #ifndef ALIGN_64BIT
8701                /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8702                /* cm_inet_c_001.main_62:Warning fix */
8703                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8704                      " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8705                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8706 #else
8707                /* cm_inet_c_001.main_62:Warning fix */
8708                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8709                      " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8710                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8711 #endif /*ALIGN_64BIT*/
8712 #endif /* CMINETDBG */
8713                RETVALUE(RFAILED);
8714             }
8715
8716             pAddr6 = (struct sockaddr_in6*)&(setPrim.ssp_addr);
8717             pAddr6->sin6_family      = AF_INET6;
8718             pAddr6->sin6_port        = CM_INET_HTON_U16(pSctpPrimAddr->port);
8719             CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPrimAddr->addr.u.ipv6NetAddr); 
8720          }
8721          else 
8722          {
8723             pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8724             pAddr->sin_family      = AF_INET;
8725             pAddr->sin_port        = CM_INET_HTON_U16(pSctpPrimAddr->port);
8726             pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8727          }
8728 #else 
8729          pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8730          pAddr->sin_family      = AF_INET;
8731          pAddr->sin_port        = CM_INET_HTON_U16(pSctpPrimAddr->port);
8732          pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8733 #endif /* IPV6_SUPPORTED */
8734
8735          setPrim.ssp_assoc_id   = pSctpPrimAddr->assocId;
8736
8737          ret = setsockopt(sockFd->fd, level, SCTP_PRIMARY_ADDR, &setPrim, sizeof(setPrim));
8738          break;
8739
8740       case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
8741          pSctpPAddrParams = (CmInetSctpPeerAddrParams *)value;
8742
8743          cmMemset((U8*)&addrParams, 0, sizeof(struct sctp_paddrparams));
8744
8745
8746          if (pSctpPAddrParams->s.addrPres == TRUE)
8747          {
8748 #ifdef IPV6_SUPPORTED 
8749             if (pSctpPAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
8750             {
8751                if (sockFd->protType == AF_INET)
8752                {
8753 #ifdef CMINETDBG
8754 #ifndef ALIGN_64BIT
8755                   /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8756                   /* cm_inet_c_001.main_62:Warning fix */
8757                   snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8758                         " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8759                   CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8760 #else
8761                   /* cm_inet_c_001.main_62:Warning fix */
8762                   snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8763                         " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8764                   CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8765 #endif /*ALIGN_64BIT*/
8766 #endif /* CMINETDBG */
8767
8768                   RETVALUE(RFAILED);
8769                }
8770
8771                pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
8772                pAddr6->sin6_family      = AF_INET6;
8773                pAddr6->sin6_port        = CM_INET_HTON_U16(pSctpPAddrParams->s.port);
8774                CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPAddrParams->s.addr.u.ipv6NetAddr); 
8775             }
8776             else 
8777             {
8778                pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8779                pAddr->sin_family      = AF_INET;
8780                pAddr->sin_port        = CM_INET_HTON_U16(pSctpPAddrParams->s.port);
8781                pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8782             }
8783 #else 
8784             pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8785             pAddr->sin_family      = AF_INET;
8786             pAddr->sin_port        = CM_INET_HTON_U16(pSctpPAddrParams->s.port);
8787             pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8788 #endif /* IPV6_SUPPORTED */
8789          }
8790          else
8791          {
8792 #ifdef IPV6_SUPPORTED 
8793             if (sockFd->protType == AF_INET6)
8794                addrParams.spp_address.ss_family = AF_INET6;
8795             else
8796                addrParams.spp_address.ss_family = AF_INET;
8797 #else
8798             addrParams.spp_address.ss_family = AF_INET;
8799 #endif
8800          }
8801
8802          /* Not validating the address, whether addr is a valid address or not */
8803
8804          addrParams.spp_assoc_id   = pSctpPAddrParams->assocId;
8805          /*cm_inet_c_001.main_58  : fix for klockwork issue */
8806          addrParams.spp_pathmaxrxt = (U16)pSctpPAddrParams->pathMaxRxt;
8807 #ifdef SUN_KSCTP
8808          if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8809             addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8810          else
8811             addrParams.spp_hbinterval = 0;
8812 #else
8813          /* linux */
8814          addrParams.spp_flags = 0;
8815
8816          if (pSctpPAddrParams->pmtudFlag == CM_INET_OPT_ENABLE)
8817          {
8818             addrParams.spp_flags     |= SPP_PMTUD_ENABLE;
8819             addrParams.spp_pathmtu    = pSctpPAddrParams->pathMtu;
8820          }
8821          else if(pSctpPAddrParams->pmtudFlag == CM_INET_OPT_DISABLE)
8822             addrParams.spp_flags     |= SPP_PMTUD_DISABLE;
8823
8824          if (pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_ENABLE)
8825          {
8826             addrParams.spp_flags     |= SPP_SACKDELAY_ENABLE;
8827             addrParams.spp_sackdelay  = pSctpPAddrParams->sackDelay;
8828          }
8829          else if(pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_DISABLE)
8830             addrParams.spp_flags     |= SPP_SACKDELAY_DISABLE;
8831
8832          if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8833          {
8834             addrParams.spp_flags     |= SPP_HB_ENABLE;
8835             addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8836          }
8837          else if(pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_DISABLE)
8838             addrParams.spp_flags |= SPP_HB_DISABLE;
8839 #endif
8840          ret = setsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, sizeof(addrParams));
8841          break;
8842
8843       case CM_INET_OPT_SCTP_ASSOC_PARAMS:
8844          pSctpAssocParams = (CmInetSctpAssocParams *)value;
8845
8846          cmMemset((U8*)&assocParams, 0, sizeof(struct sctp_assocparams));
8847
8848          assocParams.sasoc_cookie_life              = pSctpAssocParams->cookieLife;
8849          assocParams.sasoc_asocmaxrxt               = pSctpAssocParams->assocMaxReTx;
8850          assocParams.sasoc_assoc_id                 = pSctpAssocParams->assocId;
8851          assocParams.sasoc_number_peer_destinations = pSctpAssocParams->numberOfPeerDest;
8852          assocParams.sasoc_peer_rwnd                = pSctpAssocParams->peerRwnd;
8853          assocParams.sasoc_local_rwnd               = pSctpAssocParams->localRwnd;
8854
8855          ret = setsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams));
8856          break;
8857
8858       case CM_INET_OPT_SCTP_RTO_INFO:
8859          pSctpRtoInfo = (CmInetSctpRtoInfo *)value;
8860
8861          cmMemset((U8*)&rtoinfo, 0, sizeof(struct sctp_rtoinfo));
8862
8863          rtoinfo.srto_assoc_id = pSctpRtoInfo->assocId;
8864          rtoinfo.srto_initial  = pSctpRtoInfo->rtoInitial;
8865          rtoinfo.srto_max      = pSctpRtoInfo->rtoMax;
8866          rtoinfo.srto_min      = pSctpRtoInfo->rtoMin;
8867
8868          ret = setsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
8869          break;
8870
8871       case CM_INET_OPT_SCTP_INIT_MSG:
8872          pSctpInitMsg = (CmInetSctpInitMsg *)value;
8873
8874          cmMemset((U8*)&initmsg, 0, sizeof(struct sctp_initmsg));
8875
8876          initmsg.sinit_max_attempts   = pSctpInitMsg->maxInitReTx;
8877          initmsg.sinit_max_init_timeo = pSctpInitMsg->maxInitTimeout;
8878          initmsg.sinit_num_ostreams   = pSctpInitMsg->numOstreams;
8879          initmsg.sinit_max_instreams  = pSctpInitMsg->maxInstreams;
8880
8881          ret = setsockopt(sockFd->fd, level, SCTP_INITMSG, &initmsg, sizeof(initmsg));
8882          break;
8883
8884 #endif /*CM_LKSCTP*/
8885
8886          /* cm_inet_c_001.main_58 : Added to support filteration  of ICMP 
8887           * messages and protected under CM_ICMP_FILTER_SUPPORT flag. Its a
8888           *  partial implementaion for icmp filter done for TUCL */
8889 #ifdef SS_LINUX
8890 #ifdef CM_ICMP_FILTER_SUPPORT
8891       case CM_INET_OPT_ICMP_FILTER:
8892          optVal = (U32*)value;
8893          ret = setsockopt(sockFd->fd, level, ICMP_FILTER,
8894                optVal, sizeof(icmpFilter));
8895          break;
8896 #endif
8897 #endif
8898
8899       default:  
8900          /* wrong socket option type */
8901          RETVALUE(RFAILED);
8902          break;
8903    }
8904
8905    if (ret == INET_ERR)
8906    {
8907 #ifdef CMINETDBG
8908 #ifndef ALIGN_64BIT
8909       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8910       /* cm_inet_c_001.main_62:Warning fix */
8911       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%ld)\n",
8912             INET_ERR_CODE, sockFd->fd);
8913       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8914 #else
8915       /* cm_inet_c_001.main_62:Warning fix */
8916       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%d)\n",
8917             INET_ERR_CODE, sockFd->fd);
8918       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8919 #endif /*ALIGN_64BIT*/
8920 #endif /* CMINETDBG */
8921       RETVALUE(RFAILED);
8922    }          
8923    RETVALUE(ROK);
8924 } /* end of cmInetSetOpt */
8925
8926
8927 \f
8928 /*
8929 *
8930 *      Fun:   cmInetGetNumRead
8931 *
8932 *      Desc:  Gives the number of pending octets in the socket receive buffer.
8933 *
8934 *      Ret:   ROK     - successful
8935 *             RFAILED - failed
8936 *             
8937 *      Notes: None.
8938 *
8939 *      File:  cm_inet.c
8940 *
8941 */
8942
8943 #ifdef ANSI
8944 PUBLIC S16 cmInetGetNumRead
8945 (
8946 CmInetFd *sockFd,               /* socket file descriptor */
8947 U32      *dataLen               /* number of pending octets */
8948 /* removed 3rd argument memInfo */
8949 )
8950 #else
8951 PUBLIC S16 cmInetGetNumRead(sockFd, dataLen)
8952 CmInetFd *sockFd;               /* socket file descriptor */
8953 U32      *dataLen;              /* number of pending octets */
8954 /* removed 3rd argument memInfo */
8955 #endif
8956 {
8957    S32 ret;                     /* temporary return value */
8958
8959    /* removed local variables added for recvfrom call */
8960
8961    TRC2(cmInetGetNumRead);   
8962
8963 #if (ERRCLASS & ERRCLS_INT_PAR)
8964    /* error check on parameters */
8965    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
8966          (dataLen == NULLP))
8967    {
8968       RETVALUE(RFAILED);
8969    }
8970 #endif
8971
8972    /* use ioctl call for all types of socket to get length of 
8973       pending data in the socket recv buffer */
8974 #ifdef WIN32
8975    /* cm_inet_c_001.main_59: Fix for compilation warning */
8976    ret = ioctlsocket(sockFd->fd, FIONREAD, (U32 *)dataLen);  
8977 #else 
8978 #ifdef SS_PS
8979    ret = ioctl(sockFd->fd, FIOREAD, (char*)dataLen);
8980 #else
8981 #ifdef SS_VW
8982    ret = ioctl(sockFd->fd, FIONREAD, (S32)dataLen);
8983 #else
8984    ret = ioctl(sockFd->fd, FIONREAD, dataLen);
8985 #endif /* SS_VW */
8986 #endif /* SS_PS */
8987 #endif /* WIN32 */
8988
8989    /* For UDP socket assign the length of pending data in the 
8990       socket recv buffer to largest datagram size. 
8991       Removed recvfrom call & necessary processing for it. */
8992
8993    if (ret == INET_ERR)
8994    {
8995       /* removed error check CONABORTED added for recvfrom call. 
8996          Also return value changed from RCLOSED to ROK */
8997       /*  Check for reset connection */
8998       /* cm_inet_c_001.main_45: Close the TCP connection only when err is one of these*/
8999       if ((INET_ERR_CODE == ERR_CONNREFUSED) ||
9000             (INET_ERR_CODE == ERR_CONNABORTED) ||
9001             (INET_ERR_CODE == ERR_TIMEDOUT))
9002       {
9003          *dataLen = 0;
9004
9005          /* cm_inet_c_001.main_50 
9006           * Return RCLOSED instead of ROK to initiate connection closure.
9007           * ROK will be returned only if the ioctl call above returns ROK.
9008           * The routines calling this function have been modified to not
9009           * return RCLOSED when this function returns ROK with pending data 
9010           * length value of 0. This modification is needed because:
9011           * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
9012           * returns successfully with pend length as 0 on a TCP socket that 
9013           * select says is ready to read. This should not be considered as 
9014           * connection closed.
9015           */
9016          RETVALUE(RCLOSED);
9017       }
9018
9019       /* removed error check ERR_WOULDBLOCK */ 
9020       /* cm_inet_c_001.main_45: Dont close the connection in case of ERR_CONNRESET */
9021       if ((INET_ERR_CODE == ERR_AGAIN) ||
9022             (INET_ERR_CODE == ERR_CONNRESET))
9023       {
9024          *dataLen = 0;
9025          RETVALUE(ROKDNA);
9026       }
9027
9028 #ifdef SS_LINUX
9029       /* cm_inet_c_001.main_45: Change 2048 to CM_INET_MAX_UDPRAW_MSGSIZE */
9030       *dataLen = CM_INET_MAX_UDPRAW_MSGSIZE;
9031       RETVALUE(ROK);
9032 #endif /* SS_LINUX */
9033
9034       /* removed error debug printing added for recvfrom call. */
9035
9036 #ifdef CMINETDBG
9037 #ifndef ALIGN_64BIT
9038       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9039       /* cm_inet_c_001.main_62:Warning fix */
9040       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
9041             " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9042       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
9043 #else
9044       /* cm_inet_c_001.main_62:Warning fix */
9045       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
9046             " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9047       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
9048 #endif /*ALIGN_64BIT*/
9049 #endif /* CMINETDBG */
9050       RETVALUE(RFAILED);
9051    }
9052
9053    RETVALUE(ROK);
9054 } /* end of cmInetGetNumRead */
9055
9056 \f
9057 #ifndef SS_PS
9058 /*
9059 *
9060 *      Fun:   cmInetGetHostByName
9061 *
9062 *      Desc:  Resolves a host name into the appropriate 4 byte Internet 
9063 *             address.     
9064 *
9065 *      Ret:   ROK     - successful
9066 *             RFAILED - failed
9067 *
9068 *      Notes: None.
9069 *
9070 *      File:  cm_inet.c
9071 *
9072 */
9073  
9074 #ifdef ANSI
9075 PUBLIC S16 cmInetGetHostByName
9076 (
9077 S8              *hostName,         /* host name */  
9078 CmInetIpAddrTbl *addrTbl           /* Address Table of IPV4 Addresses */
9079 )
9080 #else
9081 PUBLIC S16 cmInetGetHostByName (hostName, addrTbl)
9082 S8              *hostName;         /* host name */  
9083 CmInetIpAddrTbl *addrTbl;          /* Address Table of IPV4 Addresses */
9084 #endif
9085 {
9086 #ifndef SS_VW
9087    U8            numAddrs;       /* Number of Addresses */
9088 #endif /* SS_VW */
9089
9090 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
9091    struct hostent *hostid;       /* pointer to host information */
9092 #else
9093 #ifndef SS_VW
9094    struct hostent hostid;        /* host information */
9095    S8 infoBuf[CM_INET_MAX_INFO]; /* info buffer */
9096    S32 err;                      /* error code */
9097 #endif /* SS_VW */
9098 #endif /* WIN32 || SS_LINUX || HPOS  */
9099
9100    TRC2(cmInetGetHostByName)
9101
9102 #if (ERRCLASS & ERRCLS_INT_PAR)
9103       /* error check on parameters */
9104       if ((hostName == NULLP) || (addrTbl == NULLP))
9105       {
9106          RETVALUE(RFAILED);
9107       }
9108 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9109
9110    /* Initialise */
9111 #ifndef SS_VW
9112    numAddrs       = 0;
9113 #endif /* SS_VW */
9114
9115    addrTbl->count = 0;
9116
9117 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
9118    hostid = gethostbyname(hostName);
9119    if (hostid == 0) 
9120    {
9121 #ifdef CMINETDBG
9122       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9123       /* cm_inet_c_001.main_62:Warning fix */
9124       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9125             " hostName(%p)\n", INET_ERR_CODE, hostName);
9126       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET044, 0, prntBuf);
9127 #endif /* CMINETDBG */
9128       RETVALUE(RFAILED);
9129    }
9130    if (hostid->h_addrtype != AF_INET)
9131    {
9132 #ifdef CMINETDBG
9133       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9134       /* cm_inet_c_001.main_62:Warning fix */
9135       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetHostByName() Failed : error(%d),"
9136             " hostName(%p), hostid->h_addrtype(%d)\n",
9137             INET_ERR_CODE, hostName, hostid->h_addrtype);
9138       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET045, 0, prntBuf);
9139 #endif /* CMINETDBG */
9140       RETVALUE(RFAILED);
9141    }
9142    else
9143    {
9144       while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9145             (hostid->h_addr_list[numAddrs] != NULLP))
9146       {
9147          addrTbl->netAddr[addrTbl->count++] = 
9148             CM_INET_NTOH_U32 (*((U32 *) hostid->h_addr_list[numAddrs]));
9149          numAddrs += 1;
9150       }
9151    }
9152 #else
9153
9154 #ifdef SS_VW
9155    {
9156       S32 vwIpAddr;
9157
9158       vwIpAddr = hostGetByName(hostName);
9159       if (vwIpAddr == INET_ERR)
9160       {
9161 #ifdef CMINETDBG
9162          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9163          /* cm_inet_c_001.main_62:Warning fix */
9164          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9165                " hostName(%p)\n", INET_ERR_CODE, hostName);
9166          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET046, 0, prntBuf);
9167 #endif /* CMINETDBG */
9168          RETVALUE(RFAILED);
9169       }
9170       CM_COPY_VWIPADDR(vwIpAddr, &(addrTbl->netAddr[addrTbl->count]));
9171       addrTbl->count++;
9172    }
9173 #else
9174
9175    err = 0;                     /* err is not reset by gethostnyname_r()! */
9176
9177    gethostbyname_r(hostName, &hostid, infoBuf, CM_INET_MAX_INFO, (int*)&err);
9178    if ((hostid.h_addrtype != AF_INET) || (err < 0))
9179    {
9180 #ifdef CMINETDBG
9181       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9182       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d), hostName(%p),"
9183             " hostid.h_addrtype(%d)\n",
9184             INET_ERR_CODE, hostName, hostid.h_addrtype);
9185       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET047, 0, prntBuf);
9186 #endif /* CMINETDBG */
9187       RETVALUE(RFAILED);
9188    }
9189    else
9190    {
9191       while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9192             (hostid.h_addr_list[numAddrs] != NULLP))
9193       {
9194          addrTbl->netAddr[addrTbl->count++] = 
9195             CM_INET_NTOH_U32 (*((U32 *) hostid.h_addr_list[numAddrs]));
9196          numAddrs += 1;
9197       }
9198    }
9199 #endif /* SS_VW */
9200
9201 #endif /* WIN32  || SS_LINUX || HPOS */
9202
9203    RETVALUE(ROK);
9204
9205 } /* end of cmInetGetHostByName */
9206
9207 \f
9208 /* The getipnodebyname is not supported on all the Solaris Operating system
9209  * versions. This has to be supported on operating systems that support IPV6
9210  * as per the RFC on the IPV6 socket interface. Hence this function is moved
9211  * under the IPV6_SUPPORTED flag */
9212
9213 /* This function now can be called for both IPv4 and IPv6. However, we will 
9214  * call cmInetGetHostByName inside for IPv4. Move all flag dependencies 
9215  * inside this function. */
9216 /*
9217 *
9218 *      Fun:   cmInetGetIpNodeByName
9219 *
9220 *      Desc:  Resolves a host name into the appropriate 4 byte Internet 
9221 *             address or into the appropriate 16 byte IPV6 address.
9222 *             This function is expected to be thread safe and should be used
9223 *             instead of the cmInetGetHostByName function.
9224 *
9225 *      Ret:   ROK     - successful
9226 *             RFAILED - failed
9227 *
9228 *      Notes: None.
9229 *
9230 *      File:  cm_inet.c
9231 *
9232 */
9233 #ifdef ANSI
9234 PUBLIC S16 cmInetGetIpNodeByName
9235 (
9236 S8              *hostName,         /* host name */  
9237 CmInetIpAddrArr *addrArr           /* Array of addressed filled in */
9238 )
9239 #else
9240 PUBLIC S16 cmInetGetIpNodeByName(hostName, addrArr)
9241 S8              *hostName;         /* host name */  
9242 CmInetIpAddrArr *addrArr;          /* Array of addressed filled in */
9243 #endif
9244 {
9245    /* for return value from cmInetGetHostByName */
9246 #ifndef IPV6_SUPPORTED   
9247    S16    ret; 
9248 #else   
9249 #ifdef SUNOS
9250 #ifndef SS_LINUX
9251    U8     numAddrs=0;              /* Number of addresses */
9252    int    err=0;                   /* error code */
9253    struct hostent *hostid;       /* host information */
9254 #endif /* SS_LINUX */
9255 #endif /* SUNOS */
9256 #endif /* IPV6_SUPPORTED */
9257
9258    TRC2(cmInetGetIpNodeByName)
9259
9260
9261 #if (ERRCLASS & ERRCLS_INT_PAR)
9262    /* error check on parameters */
9263    if ((hostName == NULLP) || (addrArr == NULLP))
9264    {
9265       RETVALUE(RFAILED);
9266    }
9267 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9268
9269 #ifdef IPV6_SUPPORTED
9270 #ifdef SUNOS
9271 #ifndef SS_LINUX
9272
9273 #ifdef IPV6_SUPPORTED
9274    if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
9275       hostid = getipnodebyname(hostName, AF_INET6, 0, &err);
9276    else
9277 #endif /* IPV6_SUPPORTED */
9278       hostid = getipnodebyname(hostName, AF_INET, 0, &err);
9279    if (!hostid)
9280    {
9281 #ifdef CMINETDBG
9282       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9283       /* cm_inet_c_001.main_62:Warning fix */
9284       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetIpNodeByName() Failed : error(%d),"
9285             " hostName(%p), addrArr->type(%d)n", 
9286             err, hostName, addrArr->type);
9287       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET048, 0, prntBuf);
9288 #endif /* CMINETDBG */
9289       RETVALUE(RFAILED);
9290    }
9291
9292 #ifdef IPV6_SUPPORTED
9293    if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
9294    {
9295       if (hostid->h_addrtype == AF_INET6)
9296       {
9297          while ((numAddrs < CM_INET_IPV6_NUM_ADDR) &&
9298                (hostid->h_addr_list[numAddrs] != NULLP))
9299          {
9300             /* Use the cminet fill macro here */
9301             CM_INET_COPY_IPV6ADDR(&addrArr->u.ipv6AddrArr.netAddr[numAddrs],
9302                   hostid->h_addr_list[numAddrs]);
9303             addrArr->u.ipv6AddrArr.count++; 
9304             numAddrs += 1;
9305          }
9306       }
9307       else
9308       {
9309 #ifdef CMINETDBG
9310          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9311          /* cm_inet_c_001.main_62:Warning fix */
9312          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
9313                " hostName(%p), addrArr->type(%d),hostid->h_addrtype(%d) \n",
9314                err, hostName, addrArr->type, hostid->h_addrtype);
9315          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET049, 0, prntBuf);
9316 #endif /* CMINETDBG */
9317          RETVALUE(RFAILED);
9318       }
9319    }
9320    else
9321 #endif /* IPV6_SUPPORTED */
9322    {
9323       if (hostid->h_addrtype == AF_INET)
9324       {
9325          while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9326                (hostid->h_addr_list[numAddrs] != NULLP))
9327          {
9328             addrArr->u.ipv4AddrArr.count ++;
9329             addrArr->u.ipv4AddrArr.netAddr[numAddrs] =
9330                CM_INET_NTOH_U32 (*((U32 *) hostid->h_addr_list[numAddrs]));
9331             numAddrs += 1;
9332          }
9333       }
9334       else
9335       {
9336 #ifdef CMINETDBG
9337          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9338          /* cm_inet_c_001.main_62:Warning fix */
9339          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
9340                " hostName(%p), hostid->h_addrtype(%d), addrArr->type(%d)\n",
9341                err, hostName, hostid->h_addrtype, addrArr->type);
9342          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET050, 0, prntBuf);
9343 #endif /* CMINETDBG */
9344          RETVALUE(RFAILED);
9345       }
9346    }
9347 #endif /* SS_LINUX */
9348 #endif /* SUNOS */
9349
9350    RETVALUE(ROK);
9351 #else
9352    ret = cmInetGetHostByName(hostName, &addrArr->u.ipv4AddrArr); 
9353    RETVALUE(ret);
9354 #endif /* IPV6_SUPPORTED */
9355
9356 } /* end of cmInetGetIpNodeByName */
9357
9358 \f
9359 /*
9360 *
9361 *      Fun:   cmInetAddr
9362 *
9363 *      Desc:  Converts an ASCII string containig an internet address
9364 *             ("xxx.xxx.xxx.xxx") into a CmInetIpAddr (U32) format.
9365 *             This function is a wrapper for the inet_addr() call.
9366 *
9367 *      Ret:   ROK     - successful
9368 *             RFAILED - failed
9369 *
9370 *      Notes: None.
9371 *
9372 *      File:  cm_inet.c
9373 *
9374 */
9375
9376 #ifdef ANSI
9377 PUBLIC S16 cmInetAddr(
9378 S8           *asciiAddr,        /* ascii address representation */
9379 CmInetIpAddr *address           /* 4 byte interent address */
9380 )
9381 #else
9382 PUBLIC S16 cmInetAddr(asciiAddr, address)
9383 S8           *asciiAddr;        /* ascii address representation */
9384 CmInetIpAddr *address;          /* 4 byte interent address */
9385 #endif
9386 {
9387    TRC2(cmInetAddr); 
9388
9389 #if (ERRCLASS & ERRCLS_INT_PAR)
9390    /* error check on parameters */
9391    if (asciiAddr == NULLP)
9392    {
9393       RETVALUE(RFAILED);
9394    }
9395 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9396
9397    *address = inet_addr(asciiAddr);
9398    if (*address == (U32)ERR_INADDRNONE)
9399    {
9400       /* asciiAddr does not contain a valid internet address */ 
9401       RETVALUE(RFAILED);
9402    }
9403
9404    RETVALUE(ROK);
9405 }
9406
9407 \f
9408 /*
9409 *
9410 *      Fun:   cmInetNtoa
9411 *
9412 *      Desc:  Converts an CmInetIPAddr based IP address into a string 
9413 *             of the format "xxx.xxx.xxx.xxx".
9414 *             This function is a wrapper for the inet_ntoa() call.
9415 *
9416 *      Ret:   ROK     - successful
9417 *             RFAILED - failed
9418 *
9419 *      Notes: This function delivers a pointer to a static buffer 
9420 *             within the system. Therefore the string has to be copied 
9421 *             by the caller before another call is made!
9422 *
9423 *      File:  cm_inet.c
9424 *
9425 */
9426
9427 #ifdef ANSI
9428 PUBLIC S16 cmInetNtoa(
9429 CmInetIpAddr   address,         /* 4 byte interent address */
9430 S8           **asciiAddr        /* ascii address representation */
9431 )
9432 #else
9433 PUBLIC S16 cmInetNtoa(address, asciiAddr)
9434 CmInetIpAddr   address;         /* 4 byte interent address */
9435 S8           **asciiAddr;       /* ascii address representation */
9436 #endif
9437 {
9438    struct in_addr inetAddr;     /* internet address structure */
9439
9440    TRC2(cmInetNtoa); 
9441
9442 #if (ERRCLASS & ERRCLS_INT_PAR)
9443    /* error check on parameters */
9444    if (asciiAddr == NULLP)
9445    {
9446       RETVALUE(RFAILED);
9447    }
9448 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9449
9450    inetAddr.s_addr = address;
9451
9452    *asciiAddr = inet_ntoa(inetAddr);
9453    if (*asciiAddr == NULL)
9454    { 
9455       RETVALUE(RFAILED);
9456    }
9457
9458    RETVALUE(ROK);
9459 }
9460 /*
9461 *
9462 *      Fun:   cmInetNtop
9463 *
9464 *      Desc:  Converts an network address into a string. 
9465 *             This function is a wrapper for the inet_ntop() call.
9466 *
9467 *      Ret:   ROK     - successful
9468 *             RFAILED - failed
9469 *
9470 *      Notes: This function copies the resulting string to the buffer pointed to
9471 *              by asciiaddr,which must be a non NULL pointer.The caller specifies
9472 *              the number of bytes available in this buffer in the argument len.
9473 *     
9474 *      File:  cm_inet.c
9475 *
9476 */
9477
9478 #ifdef ANSI
9479 PUBLIC S16 cmInetNtop(
9480 U8             type,              /* ip address type */
9481 Void           *address,         /* 4/16 byte interent address */
9482 S8             *asciiAddr,      /* ascii adress representation */
9483 U32            len
9484 )
9485 #else
9486 PUBLIC S16 cmInetNtop(type,address, asciiAddr,len)
9487 U8             type;              /* ip address type */  
9488 Void           *address;         /* 4/16 byte interent address */
9489 S8             *asciiAddr;      /* ascii adress representation */
9490 U32            len;
9491 #endif
9492 {
9493                              
9494    S32  domain = 0;
9495    TRC2(cmInetNtop);
9496
9497 #if (ERRCLASS & ERRCLS_INT_PAR)
9498    /* error check on parameters */
9499    if (asciiAddr == NULLP || address == NULLP || len == 0 )
9500    {
9501       RETVALUE(RFAILED);
9502    }
9503    
9504 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9505    switch(type)
9506    {
9507       case CM_INET_IPV4ADDR_TYPE :
9508          domain = AF_INET;
9509          break;
9510       case CM_INET_IPV6ADDR_TYPE :
9511          domain = AF_INET6;
9512          break;     
9513    }
9514    if(inet_ntop(domain,address,asciiAddr,len) == NULL)
9515    {
9516       RETVALUE(RFAILED);
9517    }
9518
9519    RETVALUE(ROK);
9520 }
9521
9522
9523 /* The inet_pton is not supported on all the Solaris Operating system 
9524  * versions. This has to be supported on operating systems that support 
9525  * IPV6 as per the RFC on the IPV6 socket interface. Hence this function
9526  *is moved under the IPV6_SUPPORTED flag */
9527 #ifdef IPV6_SUPPORTED
9528 #ifdef SUNOS
9529 \f
9530 /*
9531 *
9532 *      Fun:   cmInetPton
9533 *
9534 *      Desc:  Converts a IP address string to address.
9535 *
9536 *      Ret:   ROK     - successful
9537 *             RFAILED - failed
9538 *
9539 *      Notes: 
9540 *
9541 *      File:  cm_inet.c
9542 *
9543 */
9544
9545 #ifdef ANSI
9546 PUBLIC S16 cmInetPton(
9547 CmInetIpAddr  *address,         /* 4 byte interent address */
9548 S8           *asciiAddr         /* ascii address representation */
9549 )
9550 #else
9551 PUBLIC S16 cmInetPton(address, asciiAddr)
9552 CmInetIpAddr  *address;         /* 4 byte interent address */
9553 S8            *asciiAddr;       /* ascii address representation */
9554 #endif
9555 {
9556    S16    ret;
9557
9558    TRC2(cmInetPton); 
9559
9560 #if (ERRCLASS & ERRCLS_INT_PAR)
9561    /* error check on parameters */
9562    if ((asciiAddr == NULLP) || (address == NULLP))
9563    {
9564       RETVALUE(RFAILED);
9565    }
9566 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9567
9568    ret = inet_pton(AF_INET, asciiAddr, (void *)address);
9569    if (ret != 1)
9570    { 
9571       RETVALUE(RFAILED);
9572    }
9573
9574    RETVALUE(ROK);
9575 } /* end of cmInetPton */
9576 #endif /* SUNOS */
9577 #endif /* IPV6_SUPPORTED */
9578
9579 #ifdef IPV6_SUPPORTED
9580 \f
9581 /*
9582 *
9583 *      Fun:   cmInetPton6
9584 *
9585 *      Desc:  Converts a IP address string to IPV6 address suitable 
9586 *             to be used in bind.
9587 *
9588 *      Ret:   ROK     - successful
9589 *             RFAILED - failed
9590 *
9591 *      Notes: 
9592 *
9593 *      File:  cm_inet.c
9594 *
9595 */
9596 #ifdef ANSI
9597 PUBLIC S16 cmInetPton6(
9598 CmInetIpAddr6  *address6,       /* 16 byte interent address */
9599 S8             *asciiAddr       /* ascii address representation */
9600 )
9601 #else 
9602 PUBLIC S16 cmInetPton6(address6, asciiAddr)
9603 CmInetIpAddr6 *address6;        /* 16 byte interent address */
9604 S8            *asciiAddr;       /* ascii address representation */
9605 #endif
9606 {
9607    S16    ret;
9608
9609 #ifdef WIN32
9610    struct sockaddr_storage ss;
9611    U32    sslen = sizeof(ss);
9612 #endif /* WIN32 */
9613    TRC2(cmInetPton); 
9614
9615 #if (ERRCLASS & ERRCLS_INT_PAR)
9616    /* error check on parameters */
9617    if ((asciiAddr == NULLP) || (address6 == NULLP))
9618    {
9619       RETVALUE(RFAILED);
9620    }
9621 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9622
9623 #ifndef WIN32 
9624    ret = inet_pton(AF_INET6, asciiAddr, (void *)address6);
9625    if (ret != 1)
9626    { 
9627       RETVALUE(RFAILED);
9628    }
9629 #else
9630    /* cm_inet_c_001.main_44 : In windows inet_pton is not implemented. so we are using the below function
9631     * to convert the ipv6 address string to appropriate form */
9632    WSAStringToAddressA((LPTSTR)asciiAddr, AF_INET6, NULL, (struct sockaddr*)&ss, &sslen);
9633    cmMemcpy((U8*)address6, (U8*)&(((struct sockaddr_in6 *)&ss)->sin6_addr), sizeof(CmInetIpAddr6));
9634 #endif /* WIN32 */
9635
9636    RETVALUE(ROK);
9637 } /* end of cmInetPton6 */
9638 #endif /* IPV6_SUPPORTED */
9639 #endif /* SS_PS */
9640
9641 \f
9642 /*
9643 *
9644 *      Fun:   cmInetGetMemSize
9645 *
9646 *      Desc:  This function gives the max number of static buffer space that
9647 *             the internet library will allocate. 
9648 *
9649 *      Ret:   ROK - successful
9650 *
9651 *      Notes: None.
9652 *
9653 *      File:  cm_inet.c
9654 *
9655 */
9656
9657 #ifdef ANSI
9658 PUBLIC S16 cmInetGetMemSize(
9659 S32 *size                       /* max used memory size */
9660 )
9661 #else
9662 PUBLIC S16 cmInetGetMemSize(size)
9663 S32 *size;                      /* max used memory size */
9664 #endif
9665 {
9666 #ifdef WIN32
9667    /* max static memory size depends on max flat buffer size */
9668    *size = CM_INET_MAX_MSG_LEN;
9669 #else   
9670    /* max static memory size depends on max flat buffer or iovect size */
9671    *size = CM_INET_MAX_MSG_LEN;
9672 #endif 
9673
9674    RETVALUE(ROK);
9675 }
9676
9677
9678 \f
9679 /*
9680 *
9681 *      Fun:   cmInetInit
9682 *
9683 *      Desc:  This function initializes the socket library.
9684 *
9685 *      Ret:   ROK - successful
9686 *
9687 *      Notes: Required only for Winsock and not for 4.3BSD
9688 *
9689 *      File:  cm_inet.c
9690 *
9691 */
9692  
9693 #ifdef ANSI
9694 PUBLIC S16 cmInetInit(
9695 Void
9696 )
9697 #else
9698 PUBLIC S16 cmInetInit(Void)
9699 #endif
9700 {
9701 #ifdef WIN32
9702    U16     version;
9703    S32     err;
9704    WSADATA data;
9705
9706    version = MAKEWORD(CM_INET_HIGH_VER, CM_INET_LOW_VER);
9707    err = WSAStartup(version, &data);
9708    if (err != 0)
9709    {
9710       RETVALUE(RFAILED);
9711    }
9712 #endif
9713
9714    RETVALUE(ROK);
9715 }
9716
9717 \f
9718 /*
9719 *
9720 *      Fun:   cmInetDeInit
9721 *
9722 *      Desc:  This function de initializes the socket library. The
9723 *             WINSOCK implementation de registers the application and
9724 *             releases any resources allocated on behalf of the
9725 *             application.
9726 *
9727 *      Ret:   ROK - successful
9728 *
9729 *      Notes: Required only for Winsock and not for 4.3BSD
9730 *
9731 *      File:  cm_inet.c
9732 *
9733 */
9734  
9735 #ifdef ANSI
9736 PUBLIC S16 cmInetDeInit(
9737 Void
9738 )
9739 #else
9740 PUBLIC S16 cmInetDeInit(Void)
9741 #endif
9742 {
9743 #ifdef WIN32
9744    S32     err;
9745
9746    err = WSACleanup();
9747    if (err != 0)
9748    {
9749       RETVALUE(RFAILED);
9750    }
9751 #endif
9752
9753    RETVALUE(ROK);
9754 }/* end of cmInetDeInit() */
9755
9756 \f
9757 /*
9758 *
9759 *      Fun:   cmInetGetSockName
9760 *
9761 *      Desc:  This function is used to retireve the current name 
9762 *             for the specified socket descriptor. It returns the 
9763 *             local association(address and port) for the socket.
9764
9765 *      Ret:   ROK     - successful
9766 *             RFAILED - failed
9767 *
9768 *      Notes: Please note if the socket was bound to CM_INET_INADDR_ANY
9769 *             cmInetGetSockName() will not necessarily return the local
9770 *             address information unless the socket has been connected.
9771 *
9772 *      File:  cm_inet.c
9773 *
9774 */
9775 \f
9776 #ifdef ANSI
9777 PUBLIC S16 cmInetGetSockName
9778 (
9779 CmInetFd *sockFd,               /* socket file descriptor */ 
9780 CmInetAddr *locAddr
9781
9782 #else
9783 PUBLIC S16 cmInetGetSockName(sockFd, locAddr)
9784 CmInetFd *sockFd;               /* socket file descriptor */ 
9785 CmInetAddr *locAddr;
9786 #endif
9787 {
9788    struct sockaddr_in *sockAddr; 
9789 #ifdef IPV6_SUPPORTED
9790    struct sockaddr_in6 *sockAddr6;
9791    struct sockaddr_in6 lclSockAddr;
9792 #else
9793    CmInetSockAddr lclSockAddr;
9794 #endif /* IPV6_SUPPORTED */
9795 #ifdef UNIX
9796    socklen_t size;
9797 #else
9798    U32  size;
9799 #endif /* SS_LINUX */
9800    S32  errCode;
9801    /*cm_inet_c_001.main_58  : fix for klockwork issue */
9802    S32  ret;
9803
9804    TRC2(cmInetGetSockName);
9805
9806 #if (ERRCLASS & ERRCLS_INT_PAR)
9807    /* error check on parameters */
9808    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
9809          (locAddr == NULLP))
9810    {
9811       RETVALUE(RFAILED);
9812    }
9813 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9814
9815    cmMemset((U8*)&lclSockAddr, 0, sizeof(lclSockAddr));
9816    size = sizeof(lclSockAddr);
9817
9818 #ifdef UNIX
9819    ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, 
9820          (socklen_t *)&size);
9821 #else
9822    ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, (int*)&size);
9823 #endif /* SS_LINUX */
9824
9825    if(ret == INET_ERR)
9826    {
9827       switch(errCode = INET_ERR_CODE)
9828       {
9829          case ERR_INVAL:
9830             sockAddr = (struct sockaddr_in *)&lclSockAddr;
9831 #ifdef IPV6_SUPPORTED
9832             locAddr->type = CM_INET_IPV4ADDR_TYPE;
9833             locAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(sockAddr->sin_port);
9834 #else
9835             locAddr->port = CM_INET_NTOH_U16(sockAddr->sin_port);
9836 #endif /* IPV6_SUPPORTED */
9837             RETVALUE(ROK);
9838
9839          default:
9840 #ifdef CMINETDBG
9841 #ifndef ALIGN_64BIT
9842             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9843             /* cm_inet_c_001.main_62:Warning fix */
9844             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9845                   " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9846             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9847 #else
9848             /* cm_inet_c_001.main_62:Warning fix */
9849             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9850                   " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9851             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9852 #endif /* ALIGN_64BIT */
9853 #endif /* CMINETDBG */
9854             RETVALUE(RFAILED);
9855       }/* end of switch */
9856
9857    }/* end if */
9858
9859    /* Fill the returned address in to locAddr */
9860 #ifdef IPV6_SUPPORTED
9861    cmMemset((U8*)locAddr, 0, sizeof(CmInetAddr));
9862    if (size == sizeof(struct sockaddr_in6))
9863    {
9864       sockAddr6 = (struct sockaddr_in6 *)&lclSockAddr;
9865       locAddr->type = CM_INET_IPV6ADDR_TYPE;
9866       locAddr->u.ipv6Addr.port = CM_INET_NTOH_U16(sockAddr6->sin6_port);
9867       CM_INET_COPY_IPV6ADDR(&locAddr->u.ipv6Addr.ipv6NetAddr, 
9868             &sockAddr6->sin6_addr);
9869    }
9870    else
9871    {
9872       sockAddr = (struct sockaddr_in *)&lclSockAddr;
9873       locAddr->type = CM_INET_IPV4ADDR_TYPE;
9874       locAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(sockAddr->sin_port);
9875       locAddr->u.ipv4Addr.address = 
9876          CM_INET_NTOH_U32(sockAddr->sin_addr.s_addr);
9877    }
9878 #else
9879    sockAddr = (struct sockaddr_in *)&lclSockAddr;
9880    locAddr->port    = CM_INET_NTOH_U16(sockAddr->sin_port);
9881    locAddr->address = CM_INET_NTOH_U32(sockAddr->sin_addr.s_addr);
9882 #endif /* IPV6_SUPPORTED */
9883    RETVALUE(ROK);
9884 }/* end of cmInetGetSockName() */
9885
9886 /*  New functions to peek into the file descriptor 
9887  * set */
9888 #if (defined(SUNOS) || defined(WIN32) || defined(SS_LINUX) || defined(SS_VW) \
9889       || defined(HPOS))
9890 \f
9891 /*
9892 *
9893 *      Fun:   cmInetFdSetInfoInit
9894 *
9895 *      Desc:  This function is used to initialise operating system specific
9896 *             data that will be used to peek into the file descriptor lists
9897 *             to get the sockets that are set 
9898
9899 *      Ret:   ROK     - successful
9900 *             RFAILED - failed
9901 *
9902 *      Notes: 
9903 *
9904 *      File:  cm_inet.c
9905 *
9906 */
9907 \f
9908 #ifdef ANSI
9909 PUBLIC S16 cmInetFdSetInfoInit
9910 (
9911 CmInetFdSetInfo *fdSetInfo
9912
9913 #else
9914 PUBLIC S16 cmInetFdSetInfoInit(fdSetInfo)
9915 CmInetFdSetInfo *fdSetInfo;
9916 #endif
9917 {
9918 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW) || defined(HPOS))
9919    U16   arIdx;
9920    U8    curByte;
9921    U8    bitPos;
9922    CmInetFdSet *fdSet;
9923 #endif /* SUNOS || SS_LINUX || SS_VW */
9924
9925 #if (ERRCLASS & ERRCLS_INT_PAR)
9926    if (fdSetInfo == NULLP)
9927       RETVALUE(RFAILED);
9928 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9929
9930    if (fdSetInfo->initDone == TRUE)
9931       RETVALUE(ROK);
9932
9933 #ifdef WIN32
9934    fdSetInfo->numFds = 0;
9935 #endif /* WIN32 */
9936
9937 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW)|| defined(HPOS))
9938    /* Check if we are on a big endian machine */
9939    arIdx = 0x01;
9940    if (*(U8 *)&arIdx)
9941       fdSetInfo->bigEndian = FALSE;
9942    else
9943       fdSetInfo->bigEndian = TRUE;
9944
9945    fdSetInfo->arIdx = 0;
9946    fdSetInfo->ar[0] = 0xff;
9947
9948    /* Initialise the array */
9949    /* The array contains bit positions for the first bit 
9950     * for each integer from 1 to 2^8. 
9951     */
9952    for (arIdx = 1; arIdx < 256; arIdx++)
9953    {
9954       /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9955       curByte = (U8)arIdx;
9956       bitPos = 0;
9957
9958       while(bitPos < 8)
9959       {
9960          if (curByte & 0x01)
9961          {
9962             fdSetInfo->ar[arIdx] = bitPos;
9963             break;
9964          }
9965          bitPos += 1;
9966          curByte = curByte >> 1;
9967       }
9968    }
9969    /* Calculate the number of array elements in this fd_set */
9970 #if (defined(SS_LINUX)  &&  !defined(_GNU_SOURCE))
9971    fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->__fds_bits[0]);
9972 #else
9973    fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->fds_bits[0]);
9974 #endif /* SS_LINUX */
9975 #endif /* SUNOS  || SS_LINUX || SS_VW || HPOS */   
9976
9977    fdSetInfo->initDone = TRUE;
9978    RETVALUE(ROK);
9979 }/* end of cmInetFdSetInfoInit() */
9980
9981 \f
9982 /*
9983 *
9984 *      Fun:   cmInetGetFd
9985 *
9986 *      Desc:  This function is used to get the file descriptor from the
9987 *             file descriptor set.
9988
9989 *      Ret:   ROK     - successful
9990 *             ROKDNA  - socket not found
9991 *             RFAILED - failed
9992 *             RNA     - failed, initialisation not done
9993 *
9994 *      Notes: If the application modifies fdSet between calls to this
9995 *             function then the results are undefined. This function should
9996 *             be called in a loop till either it returns - not ROK, or if 
9997 *             all sockets in the file descriptor set are processed. 
9998 *
9999 *      File:  cm_inet.c
10000 *
10001 */
10002 \f
10003 #ifdef ANSI
10004 PUBLIC S16 cmInetGetFd
10005 (
10006 CmInetFdSetInfo *fdSetInfo,
10007 CmInetFdSet     *fdSet,
10008 CmInetFdType    *sockFd
10009
10010 #else
10011 PUBLIC S16 cmInetGetFd(fdSetInfo, fdSet, sockFd)
10012 CmInetFdSetInfo *fdSetInfo;
10013 CmInetFdSet     *fdSet;
10014 CmInetFdType    *sockFd;
10015 #endif
10016 {
10017   /*cm_inet_c_001.main_58 : Fix for klockwork issue */
10018 #if (!defined (WIN32))
10019    U32 sizOfFdSetArElem;  
10020    U8 bytesScanned;
10021    Bool found;
10022    U32 curIdx;
10023    U8 *tempByte;
10024    U8 bitPos;
10025 #endif /* !defined (WIN32) */
10026
10027 #if (ERRCLASS & ERRCLS_INT_PAR)
10028    if ((fdSetInfo == NULLP) || (fdSet == NULLP) || (sockFd == NULLP))
10029       RETVALUE(RFAILED);
10030
10031    if (fdSetInfo->initDone != TRUE)
10032       RETVALUE(RNA);
10033 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10034
10035 #ifdef WIN32
10036 #if (ERRCLASS & ERRCLS_DEBUG)
10037    if (fdSetInfo->numFds > FD_SETSIZE)
10038       RETVALUE(RFAILED);
10039 #endif /* ERRCLASS & ERRCLS_DEBUG */
10040    /* cm_inet_c_001.main_32 :  Corrected check for number of fd set in
10041       a fdset for WIN32*/
10042    if (fdSetInfo->numFds >= fdSet->fd_count)
10043       RETVALUE(ROKDNA);
10044
10045    *sockFd = fdSet->fd_array[fdSetInfo->numFds];
10046    fdSetInfo->numFds += 1;
10047    RETVALUE(ROK);
10048 #endif /* WIN32 */
10049
10050    /* cm_inet_c_001.main_59: Protected under if not defined WIN32 */
10051 #if (!defined (WIN32))
10052    /* Start with arIdx and continue upto number of array elements. */
10053    curIdx = fdSetInfo->arIdx;
10054    found = FALSE;
10055
10056 #if (defined(SS_LINUX)  &&  !defined(_GNU_SOURCE))
10057    sizOfFdSetArElem = sizeof(fdSet->__fds_bits[0]);
10058 #else
10059    sizOfFdSetArElem = sizeof(fdSet->fds_bits[0]);
10060 #endif /* SS_LINUX */
10061
10062    for (curIdx = fdSetInfo->arIdx; curIdx < fdSetInfo->numArElems;
10063          curIdx ++)
10064    {
10065 #if (defined(SS_LINUX)  &&  !defined(_GNU_SOURCE))
10066       if (fdSet->__fds_bits[curIdx])
10067 #else
10068          if (fdSet->fds_bits[curIdx])
10069 #endif /* SS_LINUX */
10070          {
10071             /* Walk through the bytes in this element */
10072 #if (defined(SS_LINUX)  &&  !defined(_GNU_SOURCE))
10073             tempByte = (U8 *)&fdSet->__fds_bits[curIdx];
10074 #else
10075             tempByte = (U8 *)&fdSet->fds_bits[curIdx];
10076 #endif /* SS_LINUX */
10077
10078             /* Set the starting byte offset */
10079             if (fdSetInfo->bigEndian)
10080                tempByte += sizOfFdSetArElem - 1;
10081
10082             for (bytesScanned = 0; bytesScanned < sizOfFdSetArElem; 
10083                   bytesScanned ++)
10084             {
10085                if (*tempByte)
10086                {
10087                   bitPos = fdSetInfo->ar[*tempByte];
10088                   /* cm_inet_c_001.main_54: Fix for Klockworks issue */
10089                   fdSetInfo->arIdx = (U16)curIdx;
10090                   /* Calculate fd depending on where we are */
10091                   *sockFd = ((bytesScanned << 3) + bitPos);
10092                   *sockFd += (curIdx  * (sizOfFdSetArElem << 3));
10093                   /* Clear the file descriptor */
10094                   *tempByte &= ~(1 << bitPos);
10095                   RETVALUE(ROK);
10096                }
10097                if (fdSetInfo->bigEndian)
10098                   tempByte -= 1;
10099                else
10100                   tempByte += 1;
10101             }
10102             break;
10103          }
10104    }
10105
10106    if (!found)
10107       RETVALUE(ROKDNA);
10108
10109    RETVALUE(ROK);
10110 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
10111 } /* end of cmInetGetFd */
10112
10113 #endif /* SUNOS || WIN32  || SS_LINUX || SS_VW || HPOS  */ 
10114
10115 \f
10116 /* add cmInetConvertStrToIpAddr and
10117  * cmInetAsciiToIpv4 functions */
10118 /*
10119 *
10120 *       Fun:   cmInetConvertStrToIpAddr
10121 *
10122 *       Desc:  This function parses the input string for an IPV4/IPV6 address.
10123 *              formats:
10124 *              1) IPV4 in dot number format:
10125 *                    206.216.108.253
10126 *              2) IPV6, in uncompressed, compressed, and IPV4 embedded format 
10127 *                    10:20:30:40:502:610:70C:80ad
10128 *                    A5::34:45
10129 *                    45::AB:34:123.34.5.667
10130 *
10131 *       Ret:   ROK     - SUCCESS
10132 *              RFAILED - FAILURE
10133 *
10134 *       Notes: 
10135 *
10136 *       File:  cm_inet.c
10137 *
10138 */
10139
10140 #ifdef ANSI
10141 PUBLIC S16 cmInetConvertStrToIpAddr
10142 (
10143 U16                len,                /* Length of IP address */
10144 U8                 *val,               /* Domain Name String */
10145 CmInetNetAddr      *address            /* IP Address */
10146 )
10147 #else
10148 PUBLIC S16 cmInetConvertStrToIpAddr(len, val, address)
10149 U16                len;                /* Length of IP address */
10150 U8                 *val;               /* Domain Name String */
10151 CmInetNetAddr      *address;           /* IP Address */
10152 #endif
10153 {
10154    U8              idx;                /* Index for string*/
10155    U8              ipv4[CM_INET_IPV4ADDR_SIZE]; /* IPV4 Address bytes */
10156 #ifdef IPV6_SUPPORTED
10157    U16             *ipv6;                 /* IPV6 Address bytes */
10158    U16             ipv6Reg[8];           /* regular IPV6 Address bytes */
10159    U16             ipv6Cmp[8];           /* compressed IPV6 Address bytes */
10160    U8              numBlk;               /* number of blocks in IPV6 addr */
10161    Bool            compressed;           /* IPV6 in compressed format */
10162    U8              ipv6Idx;              /* counter for IPV6 */
10163    U8              blkBeginIdx;          /* IPV6, char index for the 
10164                                             beginning of the block */
10165    U8              i;                    /* counter for IPV6 */
10166    S16             retVal;               /* return value */
10167    Bool            embedIPV4 = FALSE;    /* IPV4 embedded in IPV6 ? */
10168 #endif /* IPV6_SUPPORTED*/
10169
10170    TRC2(cmInetConvertStrToIpAddr)
10171
10172       idx = 0;
10173 #ifdef IPV6_SUPPORTED
10174    numBlk = 0;
10175    ipv6Idx = 0;
10176    compressed = FALSE;
10177    embedIPV4 = FALSE;
10178    ipv6 = ipv6Reg; /* assign pointer to IPV6 regular, uncompressed */
10179    cmMemset((U8 *)ipv6Reg, 0, CM_INET_IPV6ADDR_SIZE);
10180    cmMemset((U8 *)ipv6Cmp, 0, CM_INET_IPV6ADDR_SIZE);
10181 #endif /* IPV6_SUPPORTED*/
10182
10183    cmMemset((U8 *)ipv4, 0, CM_INET_IPV4ADDR_SIZE);
10184
10185    /* Check for IP Address */
10186    while ((val[idx] != '.') && (val[idx] != ':') && 
10187          (idx < len))
10188    {
10189 #if (ERRCLASS & ERRCLS_DEBUG)
10190       if (((val[idx] < '0') || (val[idx] > '9')) &&
10191             ((val[idx] < 'a') || (val[idx] > 'f')) &&
10192             ((val[idx] < 'A') || (val[idx] > 'F')))
10193       {
10194          /* Not a digit */
10195          RETVALUE(RFAILED);
10196       }
10197 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10198
10199       /* Convert Ascii to integer */
10200       CM_INET_ATOI(ipv4[0], val[idx]);
10201
10202 #ifdef IPV6_SUPPORTED
10203       /* convert Ascii to hex */
10204       CM_INET_ATOH(ipv6[0], val[idx]);
10205 #endif /* IPV6_SUPPORTED */
10206
10207       idx++; /* move to the next character */
10208    } /* while, try to determine IPV4 or IPV6 */
10209
10210 #if (ERRCLASS & ERRCLS_DEBUG)
10211    if ((val[idx] != '.') && (val[idx] != ':'))
10212    {
10213       /* Not a digit */
10214       RETVALUE(RFAILED);
10215    } /* if, couldn't determine IPV4 or IPV6 */
10216 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10217
10218
10219    if (val[idx] == '.')
10220    {
10221       idx++;
10222       cmInetAsciiToIpv4(3, &(ipv4[1]), (U16)(len - idx), &(val[idx]));
10223
10224       address->type = CM_INET_IPV4ADDR_TYPE;
10225       CM_INET_GET_IPV4_ADDR_FRM_STRING(address->u.ipv4NetAddr, ipv4);
10226    } /* if, IPV4 */
10227 #ifdef IPV6_SUPPORTED
10228    else 
10229    {
10230       numBlk = 1; /* already converted the 1st block */
10231       ipv6Idx = 0;
10232       while ((val[idx] != '\0') && (idx < len) && (numBlk <= 8))
10233       {
10234          idx++; /* go to the next char, either a number or the 2nd : */
10235          if (val[idx] == ':')
10236          {
10237 #if (ERRCLASS & ERRCLS_DEBUG)
10238             if (compressed == TRUE)
10239             {
10240                /* can't have 2 :: */
10241                RETVALUE(RFAILED);
10242             } /* if, 2 :: */
10243 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10244
10245             compressed = TRUE;
10246             idx++; /* skip the : */
10247             ipv6 = ipv6Cmp;
10248             ipv6Idx = 0;
10249          } /* if, IPV6 in compressed format :: */
10250          else
10251          {
10252             ipv6Idx++;
10253          } /* else, uncompressed, convert next block */
10254
10255          numBlk++; /* increase number of blocks */
10256
10257          /* assign the index the beginning of the block */
10258          blkBeginIdx = idx;
10259
10260          while(val[idx] != ':' && val[idx] != '\0' && idx < len)
10261          {
10262             if (val[idx] == '.')
10263             {
10264                /* convert number to IPV4 */
10265                ipv6[ipv6Idx] = 0; /* clear out whatever we did */
10266                cmMemset((U8 *)ipv4, 0, CM_INET_IPV4ADDR_SIZE);
10267                retVal = cmInetAsciiToIpv4(4, ipv4, len - blkBeginIdx, 
10268                      &(val[blkBeginIdx]));
10269                /* stop the loop, embedded IPV4 is the last part of
10270                   an IPV6 address */
10271                if (retVal != ROK)
10272                {
10273                   RETVALUE(retVal);
10274                }
10275                embedIPV4 = TRUE;
10276                break;
10277             } /* if, '.' means IPV4 address embedded in IPV6 */
10278
10279 #if (ERRCLASS & ERRCLS_DEBUG)
10280             if (((val[idx] < '0') || (val[idx] > '9')) &&
10281                   ((val[idx] < 'a') || (val[idx] > 'f')) &&
10282                   ((val[idx] < 'A') || (val[idx] > 'F')))
10283             {
10284                /* Not a digit */
10285                RETVALUE(RFAILED);
10286             }
10287 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10288
10289             /* Convert Ascii to integer */
10290             CM_INET_ATOH(ipv6[ipv6Idx], val[idx]);
10291
10292             /* move to the next index */
10293             idx++;
10294          } /* while, convert a block of 16 bits Hex number */
10295          if (embedIPV4 == TRUE)
10296          {
10297             ipv6Idx--; /* deccrease in case of compressed IPV6 */
10298             break; /* stop the while look */
10299          } /* if, IPV4 embedded in IPV6 */
10300       } /* while, IPV6 parsing */
10301       if (compressed == TRUE)
10302       {
10303          if (embedIPV4 == TRUE)
10304          {
10305             numBlk = 5; /* the last 2 blocks are IPV4 */
10306          } /* if, IPV4 embedded */
10307          else
10308          {
10309             numBlk = 7; /* copy from the last block */
10310          } /* else, no embedded IPV4 */
10311
10312          /* type cast U8 over -1 becasue we want to copy the last block,
10313             ipv6Cmp[0]
10314             */
10315          for (i = ipv6Idx; i != (U8) (-1); i --)
10316          {
10317             ipv6Reg[numBlk] = ipv6Cmp[i];
10318             numBlk--;
10319          } /* for, copying compress IPV6 to regular IPV6 */
10320       } /* if, compressed format */
10321
10322       if (embedIPV4 == TRUE)
10323       {
10324          ipv6Reg[6] = PutHiByte(ipv6Reg[6], ipv4[0]);
10325          ipv6Reg[6] = PutLoByte(ipv6Reg[6], ipv4[1]);
10326          ipv6Reg[7] = PutHiByte(ipv6Reg[7], ipv4[2]);
10327          ipv6Reg[7] = PutLoByte(ipv6Reg[7], ipv4[3]);
10328       } /* if, IPV4 embedded */
10329
10330       /* convert IPV6 to cmInetIpv6 */
10331       address->type = CM_INET_IPV6ADDR_TYPE;
10332       cmMemcpy((U8 *)address->u.ipv6NetAddr,
10333             (CONSTANT U8 *) ipv6Reg,  CM_INET_IPV6ADDR_SIZE);
10334    } /* else, IPV6 */
10335 #endif /* IPV6_SUPPORTED */
10336
10337    RETVALUE(ROK);
10338 } /* cmInetConvertStrToIpAddr */
10339
10340 \f
10341 /*
10342 *
10343 *       Fun:   cmInetAsciiToIpv4
10344 *
10345 *       Desc:  This function parses the input string to an IPV4 address.
10346 *              The input string can be 
10347 *              - the whole IPV4 address, '123.43.45.56', or
10348 *              - a part of it. '34.56.454'
10349 *              numBytes: number of bytes needs to be converted, IPV4 has
10350 *                        4 bytes. If we are only converting the end of an
10351 *                        address, this number needs to be adjusted. For
10352 *                        example, when converting '34.56.454]', the number
10353 *                        is 3.
10354 *
10355 *       Ret:   ROK     - SUCCESS
10356 *              RFAILED - FAILURE
10357 *
10358 *       Notes: 
10359 *
10360 *       File:  cm_inet.c
10361 *
10362 */
10363 #ifdef ANSI 
10364 PUBLIC S16  cmInetAsciiToIpv4
10365 (
10366 U8                 numBytes,           /* number of Byte to convert */
10367 U8                 *ipv4Addr,          /* IPV4 Address */
10368 U16                len,                /* Length of IP address */
10369 U8                 *val                /* Domain Name String */
10370 )
10371 #else
10372 PUBLIC S16 cmInetAsciiToIpv4(numBytes, ipv4Addr, len, val)
10373 U8                 numBytes;           /* number of Byte to convert */
10374 U8                 *ipv4Addr;          /* IPV4 Address */
10375 U16                len;                /* Length of IP address */
10376 U8                 *val;               /* Domain Name String */
10377 #endif
10378 {
10379    U8              byteCount;          /* Byte Count */
10380    U8              idx;                /* Index for string*/
10381
10382    TRC2(cmInetAsciiToIpv4)
10383
10384       idx = 0;
10385    for (byteCount = 0; byteCount < numBytes; byteCount++)
10386    {
10387       while((val[idx] != '.') && (idx < len))
10388       {
10389 #if (ERRCLASS & ERRCLS_DEBUG)
10390          if (val[idx] < '0' || val[idx] > '9')
10391          {
10392             /* Not a digit */
10393             RETVALUE(RFAILED);
10394          }
10395 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10396
10397          /* Convert Ascii to integer */
10398          CM_INET_ATOI(ipv4Addr[byteCount], val[idx]);
10399
10400          /* move to the next index */
10401          idx++;
10402       }
10403       idx++;
10404    }
10405
10406    RETVALUE(ROK);
10407 } /* cmInetAsciiToIpv4 */
10408
10409 /* cm_inet_c_001.main_34:Added wrapper function for getaddrinfo and freeaddrinfo */
10410 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
10411 \f
10412 /*
10413 *
10414 *      Fun:   cmInetGetAddrInfo 
10415 *
10416 *      Desc:  a socket file descriptor to a local Internet 
10417 *             address/port.
10418 *
10419 *      Ret:   Value returned by getaddrinfo 
10420 *
10421 *      Notes: None.
10422 *
10423 *      File:  cm_inet.c
10424 *
10425 */
10426
10427 #ifdef ANSI
10428 PUBLIC S32 cmInetGetAddrInfo
10429 (
10430 CONSTANT S8              *node,          /* Network addr which has to be resolved */
10431 CONSTANT S8              *service,       /* Sets the port number in network addr */
10432 CONSTANT CmInetAddrInfo  *hints,         /* Specifies preferred socket type or protocol */
10433 CmInetAddrInfo           **res           /* Link list of addrInfo structure */
10434 )
10435 #else
10436 PUBLIC S32 cmInetGetAddrInfo(node,service,hints,res)
10437 CONSTANT S8              *node;          /* Network addr which has to be resolved */
10438 CONSTANT S8              *service;       /* Sets the port number in network addr */
10439 CONSTANT CmInetAddrInfo  *hints;         /* Specifies preferred socket type or protocol */
10440 CmInetAddrInfo           **res;          /* Link list of addrInfo structure */
10441 #endif
10442 {
10443    S32 ret;
10444    TRC2(cmInetGetAddrInfo);
10445    ret = ROK;
10446
10447 #if (ERRCLASS & ERRCLS_INT_PAR)
10448    /* error check on parameters */
10449    if ((node == NULLP) || (hints == NULLP))
10450    {
10451       RETVALUE(RFAILED);
10452    }
10453 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10454
10455    ret = getaddrinfo(node,service,hints,res); 
10456    if (ret != ROK)
10457    {
10458 #ifdef CMINETDBG
10459 #ifndef ALIGN_64BIT
10460       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10461       /* cm_inet_c_001.main_62:Warning fix */
10462       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%ld), node(%p),"
10463             " service(%p)\n",  ret, node, service);
10464       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET052, 0, prntBuf);
10465 #else
10466       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10467       /* cm_inet_c_001.main_62:Warning fix */
10468       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%d), node(%p),"
10469             " service(%p)\n ", ret,  node, service);
10470       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET053, 0, prntBuf);
10471 #endif /* ALIGN_64BIT */
10472 #endif /* CMINETDBG */
10473    }
10474    RETVALUE(ret); 
10475 } /* end of cmInetGetAddrInfo */
10476
10477 \f
10478 /*
10479 *
10480 *      Fun:   cmInetFreeAddrInfo 
10481 *
10482 *      Desc:  Free the dynamically allocated addrinfo structure 
10483 *
10484 *      Ret:   None 
10485 *
10486 *      Notes: None.
10487 *
10488 *      File:  cm_inet.c
10489 *
10490 */
10491
10492 #ifdef ANSI
10493 PUBLIC Void cmInetFreeAddrInfo
10494 (
10495 CmInetAddrInfo           *res           /* Link list of addrInfo structure */
10496 )
10497 #else
10498 PUBLIC Void cmInetFreeAddrInfo(res)
10499 CmInetAddrInfo           *res;          /* Link list of addrInfo structure */
10500 #endif
10501 {
10502    TRC2(cmInetFreeAddrInfo);
10503
10504 #if (ERRCLASS & ERRCLS_INT_PAR)
10505    /* error check on parameters */
10506    if (res == NULLP) 
10507       RETVOID;   
10508 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10509
10510    freeaddrinfo(res); 
10511 } /* end of cmInetFreeAddrInfo */
10512
10513 #endif /* SS_VW | SS_PS | WIN32*/
10514
10515 /* cm_inet_c_001.main_36 : 1. Added new interface - cmInetFlushRecvBuf()
10516    to flush the data from socket receive buffer. */
10517 #ifdef CM_INET_FLUSH_RECV_BUF
10518 \f
10519 /*
10520 *
10521 *      Fun:   cmInetFlushRcvBuf
10522 *
10523 *      Desc:  Reads all the data from a socket and throw it!!
10524 *             The buffers for the receive buffer for recvfrom() are allocated from the stack. 
10525 *
10526 *      Ret:   ROK     - successful
10527 *             ROKDNA  - ok, data not available
10528 *             RCLOSED - connection closed by peer
10529 *             ROUTRES - failed, out of resources
10530 *             RFAILED - failed
10531 *
10532 *      Notes: None.
10533 *
10534 *      File:  cm_inet.c
10535 *
10536 */
10537 #ifdef ANSI
10538 PUBLIC S16 cmInetFlushRecvBuf
10539 (
10540 CmInetFd        *sockFd,        /* socket file descriptor */ 
10541 MsgLen          *len,           /* number of octects to be flushed */
10542 S32              flags          /* additional control flags */
10543 )
10544 #else
10545 PUBLIC S16 cmInetFlushRecvBuf(sockFd, len, flags)
10546 CmInetFd        *sockFd;        /* socket file descriptor */ 
10547 MsgLen          *len;           /* number of octects to be flushed */
10548 S32              flags;         /* additional control flags */
10549 #endif /* ANSI */
10550 {
10551
10552    Data recvTempBuf[CM_INET_MAX_BYTES_READ];
10553
10554 #if (defined(WIN32) || defined(CMINETFLATBUF))
10555    S32           ret;            /* temporary return value */
10556    U32           pendLen;        /* pending data length */
10557    S32           recvLen;        /* number of received octets by recvmsg() */
10558    MsgLen        curLen;         /* current number of octets in buffer */ 
10559    U32           remAddrLen;     /* length of remote address */
10560    struct sockaddr_in  *remAddr;    /* remote Internet address */       
10561 #ifdef IPV6_SUPPORTED 
10562    struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
10563 #else
10564    CmInetSockAddr  remSockAddr;     /* to get packet's source IP address */
10565 #endif /* IPV6_SUPPORTED */
10566 #else
10567    S32           ret;            /* temporary return value */
10568    MsgLen        curLen;         /* current number of octets in buffer */ 
10569    U32           pendLen;        /* pending data length */
10570    S32           recvLen;        /* number of received octets by recvmsg() */
10571    struct msghdr msg;            /* message header */ 
10572    CmInetIovec  rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
10573    U32           remAddrLen;     /* length of remote address */
10574 #ifdef IPV6_SUPPORTED 
10575    struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
10576
10577 #if (defined(SS_LINUX) || defined(_XPG4_2))
10578    U8                   ancillData[CM_INET_IPV6_ANCIL_DATA];
10579    /* from stack for IPv6 ancill data */
10580 #endif
10581 #else
10582    CmInetSockAddr       remSockAddr;     /* to get packet's src IP address */
10583 #if (defined(SS_LINUX) || defined(_XPG4_2))
10584    U8                   ancillData[CM_INET_IPV4_ANCIL_DATA];
10585    /* from stack for IPv4 ancill data */
10586 #endif
10587 #endif /* IPV6_SUPPORTED */
10588 #endif /* WIN32 | CMINETFLATBUF */
10589
10590    /* used by getsockopt */
10591    U32          errValue;                /* error value */
10592    U32          optLen;                  /* option length */
10593
10594    TRC2(cmInetFlushRcvBuf)
10595
10596 #if (ERRCLASS & ERRCLS_INT_PAR)
10597       /* error check on parameters */
10598       if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
10599       {
10600          RETVALUE(RFAILED);
10601       }
10602 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10603
10604
10605 #if (defined(WIN32) || defined(CMINETFLATBUF))
10606    remAddr = NULLP;  
10607 #endif /* (WIN32 | CMINETFLATBUF) */
10608
10609    /* clear the structure */   
10610    cmMemset((U8*)&remSockAddr, 0, sizeof(remSockAddr));
10611
10612    /* get number of pending data */
10613    ret = cmInetGetNumRead(sockFd, &pendLen);
10614    if (ret != ROK)
10615    {
10616       /* ret may be RFAILED or ROUTRES */
10617       RETVALUE(ret);
10618    }
10619
10620    /* check if connection got closed */
10621    if (pendLen == 0)
10622    {
10623       if (sockFd->type == CM_INET_STREAM)
10624       {
10625
10626          /* cm_inet_c_001.main_50 
10627           * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
10628           * (inside cmInetGetNumRead) returns pend length as 0 on a TCP 
10629           * socket that select says is ready to read. This should not be 
10630           * considered as connection closed. So return ROKDNA instead of 
10631           * RCLOSED
10632           */
10633          RETVALUE(ROKDNA);
10634       }
10635       else
10636          /* clear error if there is any, because if there is internal error
10637           * here it will cause infinite loop in TUCL */
10638       {
10639          errValue = 0;
10640          optLen = sizeof(int);
10641 #ifdef UNIX
10642          ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10643                (char*)&errValue, (socklen_t *)&optLen);
10644 #else
10645 #if (defined(SS_VW) || defined(SS_PS))
10646          ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10647                (char*)&errValue, (int *)&optLen);
10648 #else
10649 #ifndef SS_WINCE
10650          ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10651                (char*)&errValue, (int *)&optLen);
10652 #endif /* SS_WINCE */
10653 #endif /* SS_VW */
10654 #endif /* SS_LINUX */
10655          if (ret == INET_ERR)
10656          {
10657 #ifdef CMINETDBG
10658 #ifndef ALIGN_64BIT
10659             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10660             /* cm_inet_c_001.main_62:Warning fix */
10661             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10662                   " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10663             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10664 #else
10665             /* cm_inet_c_001.main_62:Warning fix */
10666             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10667                   " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10668             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10669 #endif /*ALIGN_64BIT*/
10670 #endif /* CMINETDBG */
10671             RETVALUE(RFAILED);
10672          }
10673          else
10674          {
10675             U8 tempBuf;
10676             /* added separate recvfrom calls different OS */
10677 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10678             recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0, 
10679                   (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10680 #else
10681 #if ( defined(SUNOS) || defined(SS_LINUX))
10682             recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10683                   NULLP, (socklen_t *)&remAddrLen);
10684 #else
10685             recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10686                   NULLP, (S32 *)&remAddrLen);
10687
10688 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10689 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10690
10691             RETVALUE(ROKDNA);
10692          }      
10693       }
10694    }/* if (pendLen == 0)*/
10695
10696
10697    if((*len == CM_INET_READ_THROW) || (*len >= CM_INET_MAX_BYTES_READ))
10698    {
10699       curLen = CM_INET_MAX_BYTES_READ;
10700    }
10701    else
10702    {
10703       curLen = *len; /*set to given number of messasges to be flushed */
10704    }
10705
10706    if((*len != CM_INET_READ_THROW) && (*len < pendLen))
10707    {
10708       pendLen = *len;
10709    }
10710
10711 #if (defined(WIN32) || defined(CMINETFLATBUF))
10712
10713    remAddrLen = 0;
10714    /* 
10715     * maybe needs more than one recvfrom() call to read an entire 
10716     * message 
10717     */
10718    while (curLen > 0)
10719    {
10720       cmMemset((U8*)recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10721       /* added separate recvfrom calls different OS */
10722
10723 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10724       recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0, 
10725             (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10726 #else         
10727 #if ( defined(SUNOS) || defined(SS_LINUX))
10728       recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0, 
10729             (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen); 
10730 #else
10731       recvLen = recvfrom(sockFd->fd, (S8 *)recvTempbuf, curLen, 0, 
10732             &remSockAddr, (S32 *)&remAddrLen); 
10733
10734 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10735 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */ 
10736
10737       if (recvLen == INET_ERR)
10738       {
10739
10740          /*  added check ERR_WOULDBLOCK */
10741          if ((INET_ERR_CODE == ERR_AGAIN) ||
10742                (INET_ERR_CODE == ERR_WOULDBLOCK))
10743          {
10744             *len = 0; 
10745             RETVALUE(ROKDNA);
10746          }
10747
10748
10749          /*  In Windows the recvfrom function fails
10750           *  with error code which maps to either WSAECONNABORTED. If
10751           *  this happens then cmInetFlushRecvBuf must return RCLOSED */
10752          if ((INET_ERR_CODE == ERR_CONNABORTED) || 
10753                (INET_ERR_CODE == ERR_CONNRESET))
10754          {
10755             *len = 0;
10756             RETVALUE(RCLOSED);
10757          }
10758
10759 #ifdef CMINETDBG
10760 #ifndef ALIGN_64BIT
10761          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10762          /* cm_inet_c_001.main_62:Warning fix */
10763          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10764                " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10765          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10766 #else
10767          /* cm_inet_c_001.main_62:Warning fix */
10768          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10769                " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10770          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10771 #endif /*ALIGN_64BIT*/
10772 #endif /* CMINETDBG */
10773
10774          RETVALUE(RFAILED);
10775       } 
10776
10777       if(recvLen < curLen)
10778          break;
10779
10780       pendLen -= recvLen;
10781
10782       if(pendLen < curLen)
10783          curLen = pendLen;
10784
10785    } /* while (curLen > 0)  */ 
10786
10787 #else  /* end of Win NT/flat buffer specific part */
10788
10789    /* 
10790     * maybe needs more than one recvmsg() call to read entire message 
10791     * on a stream socket 
10792     */
10793    while (curLen > 0)
10794    {
10795       cmMemset((U8*)recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10796       /* update the message structure */
10797 #ifdef SS_LINUX
10798       rxArr[0].iov_base = (Void*)recvTempBuf;  
10799       rxArr[0].iov_len = (U32)curLen;    
10800 #else
10801       rxArr[0].iov_base = (S8*)recvTempBuf;
10802       rxArr[0].iov_len = curLen; 
10803 #endif /* SS_LINUX */
10804       msg.msg_iov           = rxArr;
10805       msg.msg_iovlen        = 1;
10806
10807       msg.msg_name    = NULLP;
10808       msg.msg_namelen = 0;
10809
10810       /* added defined(_XPG4_2). Also changed the
10811        * assignments */
10812 #if (defined(SS_LINUX) || defined(_XPG4_2))
10813       msg.msg_control      = ancillData;
10814       msg.msg_controllen   = sizeof(ancillData);
10815       msg.msg_flags   = 0; 
10816 #else
10817       msg.msg_accrights     = NULLP;
10818       msg.msg_accrightslen  = 0;
10819 #endif /* SS_LINUX */
10820
10821       recvLen = recvmsg(sockFd->fd, &msg, flags);
10822       if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
10823       {
10824          /* added check ERR_AGAIN when CMINETFLATBUF is not defined. 
10825             added check ERR_WOULDBLOCK */
10826          if ((INET_ERR_CODE == ERR_AGAIN) ||
10827                (INET_ERR_CODE == ERR_WOULDBLOCK))
10828          {
10829             *len = 0;  
10830             RETVALUE(ROKDNA);
10831          }
10832
10833 #ifdef CMINETDBG
10834 #ifndef ALIGN_64BIT
10835          /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
10836          /* cm_inet_c_001.main_62:Warning fix */
10837          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10838                " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10839          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10840 #else
10841          /* cm_inet_c_001.main_62:Warning fix */
10842          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10843                " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10844          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10845 #endif /*ALIGN_64BIT*/
10846 #endif /* CMINETDBG */
10847
10848          /*  If this happens then cmInetFlushRecvBuf must return RCLOSED. 
10849           *  Needed for getting icmp msgs */
10850          if (INET_ERR_CODE == ERR_CONNABORTED)
10851          {
10852             *len = 0;
10853             RETVALUE(RCLOSED);
10854          }
10855          RETVALUE(RFAILED); 
10856       }/* if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))*/ 
10857
10858       if(recvLen < curLen)
10859          break;
10860
10861       pendLen -= recvLen;
10862
10863       if(pendLen < curLen)
10864          curLen = pendLen;
10865
10866    } /* while(curLen > 0) */
10867
10868 #endif /* WIN32 | CMINETFLATBUF  */
10869
10870
10871    RETVALUE(ROK);
10872 } /* end of cmInetFlushRecvBuf */
10873
10874 #endif /* CM_INET_FLUSH_RECV_BUF*/
10875
10876 /**********************************************************************
10877          End of file
10878 **********************************************************************/