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