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