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