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