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