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