3dd19aba625471ad61c06b9a5eee87c1f391b721
[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
156 \f  
157 /* local defines */
158
159 /* BSD and Winsock error handling is different */
160 #ifdef WIN32
161 #define INET_ERR             SOCKET_ERROR
162 #define INET_ERR_CODE        WSAGetLastError()
163 #define ERR_INPROGRESS       WSAEINPROGRESS  
164 #define ERR_ISCONN           WSAEISCONN
165 #define ERR_WOULDBLOCK       WSAEWOULDBLOCK
166 #define ERR_INADDRNONE       INADDR_NONE
167 #define ERR_NOTCONN          WSAENOTCONN
168 #define ERR_ALREADY          WSAEALREADY
169 #define ERR_AGAIN            WSAEWOULDBLOCK 
170 #define ERR_INVAL            WSAEINVAL
171 #define ERR_CONNREFUSED       WSAECONNREFUSED
172 #define ERR_PIPE             WSAENOTCONN
173 /* Changed ERR_TIMEOUT for pSos compilation */
174 #define ERR_TIMEDOUT         WSAETIMEDOUT
175 #define ERR_CONNRESET        WSAECONNRESET
176 #define ERR_CONNABORTED      WSAECONNABORTED
177 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
178 #define ERR_EINTR            WSAEINTR
179 /* cm_inet_c_001.main_37 network unreacheble error is added */
180 #define ERR_NETUNREACH       WSAENETUNREACH
181 /* cm_inet_c_001.main_61: host unreachable is added */
182 #define ERR_HOSTUNREACH      WSAEHOSTUNREACH
183 #else
184 #define INET_ERR             -1
185 #define INET_ERR_CODE        errno
186 #define ERR_INPROGRESS       EINPROGRESS
187 #define ERR_ISCONN           EISCONN
188 #define ERR_WOULDBLOCK       EWOULDBLOCK
189 #define ERR_INADDRNONE       -1
190 #define ERR_NOTCONN          ENOTCONN       
191 #define ERR_ALREADY          EALREADY
192 #define ERR_AGAIN            EAGAIN
193 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
194 #define ERR_EINTR            EINTR
195 /* EINVAL is not mapped because it is a valid error code here */
196 #define ERR_INVAL            0 
197 #define ERR_CONNREFUSED      ECONNREFUSED
198 #define ERR_PIPE             EPIPE 
199 /* Changed ERR_TIMEOUT for pSos compilation */
200 #define ERR_TIMEDOUT         ETIMEDOUT
201 #define ERR_CONNRESET        ECONNRESET
202 #define ERR_CONNABORTED      ECONNABORTED
203 /* cm_inet_c_001.main_37 network unreacheble error is added */
204 #define ERR_NETUNREACH       ENETUNREACH
205 /* cm_inet_c_001.main_61: host unreachable is added */
206 #define ERR_HOSTUNREACH      EHOSTUNREACH
207 #endif /* WIN32 */
208
209 /* back log range */
210 #define MIN_BACK_LOG  0
211
212 /* added a win2k specific defines in. */
213 #ifdef WIN32
214 #ifdef WIN2K
215 #ifndef SIO_UDP_CONNRESET
216 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
217 #endif 
218 #endif /* WIN2K */
219 #define MAX_BACK_LOG  1
220 #else
221 #define MAX_BACK_LOG  5
222 #endif /* WIN32 */
223
224 #ifdef IPV6_OPTS_SUPPORTED
225 #ifndef IPV6_SUPPORTED
226 #error "Enable IPV6_SUPPORTED flag if IPV6_OPTS_SUPPORTED is defined."
227 #endif 
228 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
229 #error "Enable _XPG4_2 or SS_LINUX if IPV6_OPTS_SUPPORTED is defined."
230 #endif /* SS_LINUX || _XPG4_2 */
231 #endif /* IPV6_OPTS_SUPPORTED */
232
233 #ifdef LOCAL_INTF
234 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
235 #error "Enable _XPG4_2 or SS_LINUX if LOCAL_INTF is defined."
236 #endif /* SS_LINUX || _XPG4_2 */
237 #endif /* LOCAL_INTF */
238
239 /* local typedefs */
240
241 /* local externs */
242   
243 /* forward references */
244
245 /* added !(defined(CMINETFLATBUF) */
246 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
247 /* Added another function parameter */
248 PRIVATE S16 buildRecvBuf ARGS((CmInetMemInfo *info, MsgLen len, 
249                                CmInetIovec rxArr[], Buffer *dBuf[], U16 maxSize,
250                                struct msghdr *msg, Bool isStrmMsg));
251 PRIVATE S16 buildRecvMsg ARGS((CmInetMemInfo *info, CmInetIovec rxArr[], 
252                                S16 numBduf, MsgLen msgLen, Buffer *dBufs[], 
253                                Buffer **mPtr));
254 /* cm_inet_c_001.main_50 - Added parameter to get length of dbufs packed for partial
255  *               send handling 
256  */
257 PRIVATE S16 buildSendIovec ARGS((Buffer *mBuf, MsgLen msgLen, 
258                                  CmInetIovec txArr[], S16 numDBuf, 
259                                  S16 *numIovElems, U32 *strtEndDBufNum,
260                                  MsgLen *ioLen)); 
261 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
262
263 /* prototypes of new functions needed to send and 
264  * process after receiving the extension headers through ancillary data */
265
266 #ifdef IPV6_SUPPORTED
267 #ifdef IPV6_OPTS_SUPPORTED
268 PRIVATE S16 cmInet6BuildSendHBHOpts    ARGS((CmInetIpv6HBHHdrArr *hbhOptsArr, 
269                                             U8 *cmsgBuf, U32 *curMsgIdx, 
270                                             U8 hdrId));
271 PRIVATE S16 cmInet6BuildSendRouteOpts  ARGS((CmInetIpv6RtHdr *rtOptsArr, 
272                                             U8 *cmsgBuf, U32 *curMsgIdx));
273
274 PRIVATE S16 cmInet6BuildRecvRtHdr      ARGS((U8 *cmsgData, U32 rtDataLen, 
275                                             CmInetIpv6RtHdr0 *rtHdr0, 
276                                             CmInetIpv6RtHdr *rtOptsArr,
277                                             CmInetMemInfo *info));
278 PRIVATE S16 cmInet6BuildRecvHopOptsArr ARGS((U8 *cmsgData, U32 hbhDataLen, 
279                                             CmInetIpv6HBHHdrArr *hbhOptsArr, 
280                                             U8 hdrId, CmInetMemInfo *info));
281 PRIVATE S16 cmInet6GetHopLimitValue    ARGS((U8 *cmsgData, U32 hopLimitDataLen,
282                                             CmInetIpv6HdrParm *ipv6HdrParam));
283
284 #ifdef SS_LINUX
285 PRIVATE S16 cmInetBuildSendHoplimit        ARGS((U32 hoplimit, U8 *cmsgBuf, 
286                                             U32 *curMsgIdx));
287 #endif /* SS_LINUX */
288 #ifdef LOCAL_INTF
289 PRIVATE S16 cmInet6BuildSendPktinfo         ARGS((CmInetIpAddr6 *srcAddr,
290                                             U8 *cmsgBuf, U32 *curMsgIdx,
291                                             U8 protType));
292 #endif /* LOCAL_INTF */
293 #endif /* IPV6_OPTS_SUPPORTED */
294 #endif /* IPV6_SUPPORTED */
295
296 /* public variable declarations */
297
298 /* private variable declarations */
299
300 #ifdef CMINETDBG
301 /* Global buffer for debug prints */
302 /*cm_inet_c_001.main_62:Warning fix*/
303 Txt   prntBuf[CMINET_PRNT_BUF_SIZE];
304 #endif /* CMINETDBG */
305
306 /* cm_inet_c_001.main_60 POLL Specific Functions defined */
307
308 /*
309 *
310 *      Fun:   cmInetPoll
311 *
312 *      Desc:  Poll on pollfdarr
313 *
314 *      Ret:   Number of File Descriptor Selected
315 *
316 *      Notes: None
317 *
318 *      File:  cm_inet.c
319 *
320 */
321
322 #ifdef ANSI
323 PUBLIC S16 cmInetPoll
324 (
325 CmInetPollFd  *pollFdArr,               /* poll FD Array */
326 U32               numFds,               /* Number of Fds to be monitored */
327 S16              *numRdyFds,            /* number of ready descriptors */
328 U32              timeout                /* timeout value for Poll */
329 )
330 #else
331 PUBLIC S16 cmInetPoll(pollFdArr,numFds,numRdyFds,timeout)
332 CmInetPollFd  *pollFdArr;               /* poll FD Array */
333 U32               numFds;               /* Number of Fds to be monitored */
334 S16              *numRdyFds;            /* number of ready descriptors */
335 U32               timeout;              /* timeout value for Poll */
336 #endif
337 {
338    S32  ret;
339
340    TRC2(cmInetPoll); 
341    ret = 0;
342    *numRdyFds = 0;
343
344    if(numFds > CM_INET_POLL_MAXFDSUPP)
345    {
346 #ifdef CMINETDBG
347 /* cm_inet_c_001.main_62:Warning fix */
348 #ifndef ALIGN_64BIT
349       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%lu) invalid \n",numFds);
350 #else
351       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%u) invalid \n",numFds);
352 #endif
353       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
354 #endif /* CMINETDBG */      
355       RETVALUE(RFAILED);
356    } 
357
358 #if (ERRCLASS & ERRCLS_INT_PAR)
359       /* error check on parameters */
360       if (pollFdArr == NULLP)
361       {
362 #ifdef CMINETDBG
363       /* cm_inet_c_001.main_62:Warning fix */
364       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : Invalid Parameter (pollFdArr is NULL)");
365       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
366 #endif /* CMINETDBG */      
367          RETVALUE(RFAILED);
368       }
369 #endif /* ERRCLASS & ERRCLS_INT_PAR */
370
371    ret = poll(pollFdArr,numFds,timeout);
372    if (ret == 0)
373    { 
374       RETVALUE(RTIMEOUT);
375    }
376    if (ret == INET_ERR)
377    {
378       switch(INET_ERR_CODE)
379       {
380          case ERR_EINTR:
381             RETVALUE(ROKDNA);
382
383          default:
384 #ifdef CMINETDBG
385             /* cm_inet_c_001.main_62:Warning fix */
386             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "File: %s, cmInetPoll() failed on line: %d \n\
387                     error(%d)\n", __FILE__, __LINE__, INET_ERR_CODE);
388             SPrint(prntBuf);
389 #endif /* CMINETDBG */
390             RETVALUE(RFAILED);
391
392       } /* end of switch */
393    }
394    
395    *numRdyFds = (S16)ret;
396   
397    RETVALUE(ROK);
398
399 }
400
401 /*
402 *
403 *      Fun:   cmInetPollSetFd
404 *
405 *      Desc:  Set the selected fd in pollFdArr with event eventMask
406 *
407 *      Ret:   RFAILED : if file descriptor is out of range
408 *             ROK     : if pollFdArr is set.
409 *
410 *      Notes: None
411 *
412 *      File:  cm_inet.c
413 *
414 */
415
416 #ifdef ANSI
417 PUBLIC S16 cmInetPollSetFd
418 (
419 CmInetFd         *sockFd,               /* socket file descriptor */
420 CmInetPollFd  *pollFdArr,               /* poll FD Array */
421 S16               idx,                  /* poll Fd Array Index */
422 U16               eventMask             /* Event Mask to be set */
423 )
424 #else
425 PUBLIC S16 cmInetPollSetFd(sockFd,pollFdArr,idx,eventMask)
426 CmInetFd         *sockFd;               /* socket file descriptor */
427 CmInetPollFd  *pollFdArr;               /* poll FD Array */
428 S16              idx;                   /* poll Fd Array Index */
429 U16              eventMask;             /* Event Mask to be set */
430 #endif
431 {
432    
433    TRC2(cmInetPollSetFd); 
434
435    if ((idx) >= CM_INET_POLL_MAXFDSUPP || (idx) < 0)
436    {
437 #ifdef CMINETDBG
438       /* cm_inet_c_001.main_62:Warning fix */
439       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid idx(%d) \n",idx);
440       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
441 #endif /* CMINETDBG */
442
443       RETVALUE(RFAILED);
444    }
445
446 #if (ERRCLASS & ERRCLS_INT_PAR)
447       /* error check on parameters */
448       if (pollFdArr == NULLP)
449       {
450 #ifdef CMINETDBG
451       /* cm_inet_c_001.main_62:Warning fix */
452       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid Parameter (pollFdArr is NULL)");
453       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
454 #endif /* CMINETDBG */      
455          RETVALUE(RFAILED);
456       }
457 #endif /* ERRCLASS & ERRCLS_INT_PAR */
458
459 #ifdef CMINETDBG
460 #ifndef ALIGN_64BIT
461       /* cm_inet_c_001.main_62:Warning fix */
462       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, 
463                "cmInetPollSetFd() Before Setting fd : sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set   fd(%ld) event(%d) \n",
464                pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
465       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf); 
466 #else
467       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,
468                "cmInetPollSetFd() Before Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set   fd(%d) event(%d) \n",
469                pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
470       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
471 #endif /*ALIGN_64BIT */
472 #endif /* CMINETDBG */
473
474 /* Setting fd and events with eventMask */
475    pollFdArr[idx].fd = sockFd->fd;
476    pollFdArr[idx].events |= eventMask;
477
478
479 #ifdef CMINETDBG
480 #ifndef ALIGN_64BIT
481       /* cm_inet_c_001.main_62:Warning fix */
482       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
483             pollFdArr[idx].fd,idx, pollFdArr[idx].events);
484       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
485 #else
486       /* cm_inet_c_001.main_62:Warning fix */
487       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
488             pollFdArr[idx].fd,idx, pollFdArr[idx].events);
489       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
490 #endif /*ALIGN_64BIT */
491 #endif /* CMINETDBG */
492
493    RETVALUE(ROK);
494
495 }
496
497
498 /*
499 *
500 *      Fun:   cmInetPollFdIsSet
501 *
502 *      Desc:  Checks whether fd is selected
503 *
504 *      Ret:   TRUE : If Fd is Selected
505 *             FALSE: If Fd is not Selected
506 *
507 *      Notes: None
508 *
509 *      File:  cm_inet.c
510 *
511 */
512
513 #ifdef ANSI
514 PUBLIC S16 cmInetPollFdIsSet
515 (
516 CmInetPollFd  *pollFdArr,            /* poll FD Array */
517 S16               idx,               /* poll Fd Array Index */
518 U16               eventMask          /* Event Mask to be set */
519 )
520 #else
521 PUBLIC S16 cmInetPollFdIsSet(pollFdArr,idx,eventMask)
522 CmInetPollFd  *pollFdArr;            /* poll FD Array */
523 S16               idx;               /* poll Fd Array Index */
524 U16               eventMask;         /* Event Mask to be set */
525 #endif
526 {
527    S16  ret;
528
529    TRC2(cmInetPollFdIsSet); 
530
531    if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
532    {
533 #ifdef CMINETDBG
534       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Index (%d) \n",idx);
535       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
536 #endif /* CMINETDBG */
537       RETVALUE(RFAILED);
538    }
539
540 #if (ERRCLASS & ERRCLS_INT_PAR)
541       /* error check on parameters */
542       if (pollFdArr == NULLP)
543       {
544 #ifdef CMINETDBG
545       /* cm_inet_c_001.main_62:Warning fix */
546       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Parameter (pollFdArr is NULL)");
547       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
548 #endif /* CMINETDBG */      
549          RETVALUE(RFAILED);
550       }
551 #endif /* ERRCLASS & ERRCLS_INT_PAR */
552
553    ret = (pollFdArr[idx].revents & eventMask);
554
555    RETVALUE(ret);
556 }
557
558 /*
559 *
560 *      Fun:   cmInetPollClearFdREvent
561 *
562 *      Desc:  clears the reventMask in revent of the givent FD.
563 *
564 *      Ret:   ROK
565 *             
566 *
567 *      Notes: None
568 *
569 *      File:  cm_inet.c
570 *
571 */
572
573 #ifdef ANSI
574 PUBLIC S16 cmInetPollClearFdREvent
575 (
576 CmInetPollFd  *pollFdArr,            /* poll FD Array */
577 S16               idx,               /* poll Fd Array Index */
578 U16               eventMask          /* Event Mask to be set */
579 )
580 #else
581 PUBLIC S16 cmInetPollClearFdREvent(sockFd,pollFdArr,eventMask)
582 CmInetPollFd  *pollFdArr;            /* poll FD Array */
583 S16               idx;               /* poll Fd Array Index */
584 U16               eventMask;         /* Event Mask to be set */
585 #endif
586 {
587
588    TRC2(cmInetPollClearFdREvent); 
589
590
591    if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
592    {
593 #ifdef CMINETDBG
594       /* cm_inet_c_001.main_62:Warning fix */
595       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Index (%d) \n",idx);
596       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
597 #endif /* CMINETDBG */
598       RETVALUE(RFAILED);
599    }
600
601 #if (ERRCLASS & ERRCLS_INT_PAR)
602       /* error check on parameters */
603       if (pollFdArr == NULLP)
604       {
605 #ifdef CMINETDBG
606       /* cm_inet_c_001.main_62:Warning fix */
607       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Parameter (pollFdArr is NULL)");
608       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
609 #endif /* CMINETDBG */      
610          RETVALUE(RFAILED);
611       }
612 #endif /* ERRCLASS & ERRCLS_INT_PAR */
613
614 #ifdef CMINETDBG
615 #ifndef ALIGN_64BIT
616       /* cm_inet_c_001.main_62:Warning fix */
617       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
618             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
619       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
620 #else
621       /* cm_inet_c_001.main_62:Warning fix */
622       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
623             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
624       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
625 #endif /*ALIGN_64BIT */
626 #endif /* CMINETDBG */
627
628 /* Clearing the events with eventMask */
629    pollFdArr[idx].revents = (pollFdArr[idx].revents & (~(eventMask)));
630
631 #ifdef CMINETDBG
632 #ifndef ALIGN_64BIT
633       /* cm_inet_c_001.main_62:Warning fix */
634       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
635             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
636       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
637 #else
638       /* cm_inet_c_001.main_62:Warning fix */
639       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
640             pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
641       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
642 #endif /*ALIGN_64BIT */
643 #endif /* CMINETDBG */
644
645    RETVALUE(ROK);
646
647 }
648
649
650 /*
651 *
652 *      Fun:   cmInetPollClearFdEvent
653 *
654 *      Desc:  clears the eventMask in event of the givent FD.
655 *
656 *      Ret:   ROK
657 *             
658 *
659 *      Notes: None
660 *
661 *      File:  cm_inet.c
662 *
663 */
664
665 #ifdef ANSI
666 PUBLIC S16 cmInetPollClearFdEvent
667 (
668 CmInetPollFd  *pollFdArr,            /* poll FD Array */
669 S16               idx,               /* poll Fd Array Index */
670 U16               eventMask          /* Event Mask to be set */
671 )
672 #else
673 PUBLIC S16 cmInetPollClearFdEvent(sockFd,pollFdArr,eventMask)
674 CmInetPollFd   *pollFdArr;            /* poll FD Array */
675 S16             idx;                  /* poll Fd Array Index */
676 U16             eventMask;            /* Event Mask to be set */
677 #endif
678 {
679
680    TRC2(cmInetPollClearFdEvent); 
681
682
683    if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
684    {
685 #ifdef CMINETDBG
686       /* cm_inet_c_001.main_62:Warning fix */
687       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Index (%d) \n",idx);
688       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
689 #endif /* CMINETDBG */
690       RETVALUE(RFAILED);
691    }
692
693 #if (ERRCLASS & ERRCLS_INT_PAR)
694       /* error check on parameters */
695       if (pollFdArr == NULLP)
696       {
697 #ifdef CMINETDBG
698       /* cm_inet_c_001.main_62:Warning fix */
699       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Parameter (pollFdArr is NULL)");
700       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
701 #endif /* CMINETDBG */      
702          RETVALUE(RFAILED);
703       }
704 #endif /* ERRCLASS & ERRCLS_INT_PAR */
705
706 #ifdef CMINETDBG
707 #ifndef ALIGN_64BIT
708       /* cm_inet_c_001.main_62:Warning fix */
709       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask: \n sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
710             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
711       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
712 #else
713       /* cm_inet_c_001.main_62:Warning fix */
714       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask:\n  sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
715             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
716       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
717 #endif /*ALIGN_64BIT */
718 #endif /* CMINETDBG */
719
720 /* Clearing events with eventMask */
721    pollFdArr[idx].events = (pollFdArr[idx].events & (~(eventMask)));
722
723 #ifdef CMINETDBG
724 #ifndef ALIGN_64BIT
725       /* cm_inet_c_001.main_62:Warning fix */
726       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
727             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
728       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
729 #else
730       /* cm_inet_c_001.main_62:Warning fix */
731       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
732             pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
733       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
734 #endif /*ALIGN_64BIT */
735 #endif /* CMINETDBG */
736
737    RETVALUE(ROK);
738
739 }
740
741
742 /*
743 *
744 *      Fun:   cmInetPollDelFd
745 *
746 *      Desc:  Delete the given FD from the pollFdArray
747 *             delIdx : Poll Fd Array Index at which fd has to be deleted.
748 *             lastIdx: Last index of poll fd array.
749 *
750 *             It deletes fd from array by swapping lastIdx pollFd
751 *             values to index to be deleted and deinitializes the 
752 *             lastIdx values.
753 *
754 *      Ret:   ROK
755 *             
756 *
757 *      Notes: It does not decrement the lastIdx and it has to be 
758 *             decremented by the caller of this function.
759 *
760 *      File:  cm_inet.c
761 *
762 */
763
764 #ifdef ANSI
765 PUBLIC S16 cmInetPollDelFd
766 (
767 CmInetPollFd  *pollFdArr,             /* poll FD Array */
768 S16               delIdx,             /* poll Fd Array Index for which fd has to be deleted*/
769 S16               lastIdx             /* Last index of poll Fd Array */
770 )
771 #else
772 PUBLIC S16 cmInetPollDelFd(pollFdArr, delIdx, lastIdx)
773 CmInetPollFd  *pollFdArr;            /* poll FD Array */
774 S16               delIdx;            /* poll Fd Array Index for which fd has to be deleted*/
775 S16               lastIdx;           /* Last index of poll Fd Array */
776 #endif
777 {
778
779    TRC2(cmInetPollDelFd); 
780
781    if(lastIdx < delIdx || lastIdx < 0 || delIdx < 0)
782    {
783 #ifdef CMINETDBG
784       /* cm_inet_c_001.main_62:Warning fix */
785       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Index \n Current Index (%d) Delete Index (%d) \n",lastIdx,delIdx);
786       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
787 #endif /* CMINETDBG */
788       RETVALUE(RFAILED);
789    }
790
791
792 #if (ERRCLASS & ERRCLS_INT_PAR)
793       /* error check on parameters */
794       if (pollFdArr == NULLP)
795       {
796 #ifdef CMINETDBG
797       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Parameter (pollFdArr is NULL)");
798       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
799 #endif /* CMINETDBG */      
800          RETVALUE(RFAILED);
801       }
802 #endif /* ERRCLASS & ERRCLS_INT_PAR */
803
804 #ifdef CMINETDBG
805 #ifndef ALIGN_64BIT
806       /* cm_inet_c_001.main_62:Warning fix */
807       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() Deleting the sockFd->fd(%d) Index(%d) Event(%d) revent(%d) \n",
808             pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
809       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
810 #else
811       /* cm_inet_c_001.main_62:Warning fix */
812       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
813             pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
814       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
815 #endif /*ALIGN_64BIT */
816 #endif /* CMINETDBG */
817
818    pollFdArr[delIdx].fd = pollFdArr[lastIdx].fd;
819    pollFdArr[delIdx].events = pollFdArr[lastIdx].events;
820    pollFdArr[delIdx].revents = pollFdArr[lastIdx].revents;
821
822    pollFdArr[lastIdx].fd = -1;
823    pollFdArr[lastIdx].events = 0;
824    pollFdArr[lastIdx].revents = 0;
825    
826    RETVALUE(ROK);
827
828 }
829
830 /*
831 *
832 *      Fun:   cmInetPollInitFdArr
833 *
834 *      Desc: Cleans all elements of fd array. 
835 *
836 *      Ret:   ROK
837 *             
838 *
839 *      Notes:  It does not allocates/deallocates memory for Poll Fd Array.
840 *              Caller of function has to allocate/deallocate memory for 
841 *              array.
842 *
843 *      File:  cm_inet.c
844 *
845 */
846
847 #ifdef ANSI
848 PUBLIC S16 cmInetPollInitFdArr
849 (
850 CmInetPollFd  *pollFdArr             /* poll FD Array */
851 )
852 #else
853 PUBLIC S16 cmInetPollInitFdArr(pollFdArr)
854 CmInetPollFd  *pollFdArr;            /* poll FD Array */
855 #endif
856 {
857    S16 idx;
858
859    TRC2(cmInetPollInitFdArr); 
860 /* Sets each element of pollFdArr to initial value
861    fd = -1
862    events = 0
863    revents = 0
864 */
865 #if (ERRCLASS & ERRCLS_INT_PAR)
866       /* error check on parameters */
867       if (pollFdArr == NULLP)
868       {
869 #ifdef CMINETDBG
870       /* cm_inet_c_001.main_62:Warning fix */
871       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollInitFdArr() : Invalid Parameter (pollFdArr is NULL)");
872       CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
873 #endif /* CMINETDBG */      
874          RETVALUE(RFAILED);
875       }
876 #endif /* ERRCLASS & ERRCLS_INT_PAR */
877
878    for(idx=0; idx < CM_INET_POLL_MAXFDSUPP; idx++)
879    {
880       pollFdArr[idx].fd = -1;
881       pollFdArr[idx].events = 0;
882       pollFdArr[idx].revents = 0;
883    }
884    RETVALUE(ROK);
885 }
886
887 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
888 /*
889 *
890 *      Fun:   buildRecvBuf
891 *
892 *      Desc:  Allocates dBufs to receive an entire message.
893 *
894 *      Ret:   ROK     - successful
895 *             RFAILED - failed
896 *             ROUTRES - failed, out of resources
897 *
898 *      Notes: None
899 *
900 *      File:  cm_inet.c
901 *
902 */
903
904 #ifdef ANSI
905 PRIVATE S16 buildRecvBuf
906 (
907 CmInetMemInfo  *info,           /* buffer allocation info */
908 MsgLen          len,            /* message length */
909 CmInetIovec     rxArr[],        /* gather array */
910 Buffer         *dBuf[],         /* allocated dBufs */
911 U16             maxSize,        /* size of rxArr/dBuf array */       
912 struct msghdr  *msg,            /* message header for recvmsg() */           
913 Bool           isStrmMsg        /* Is a TCP message */
914 )
915 #else
916 PRIVATE S16 buildRecvBuf(info, len, rxArr, dBuf, maxSize, msg, isStrmMsg)
917    CmInetMemInfo   *info;          /* buffer allocation info */
918    MsgLen           len;           /* message length */        
919    CmInetIovec      rxArr[];       /* gather array */         
920    Buffer          *dBuf[];        /* allocated dBufs */
921    U16              maxSize;       /* size of rxArr/dBuf array */       
922    struct msghdr   *msg;           /* message header for recvmsg() */        
923    Bool            isStrmMsg;      /* Is a TCP message */
924 #endif
925 {
926    S16     ret;                 /* temporary return value */
927    U16     numBuf;              /* number of dBufs */
928    U16     i;                   /* dBuf index counter */
929    Data   *dPtr;                /* data pointer */
930    /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
931    MsgLen  bufLen;              /* entire receive buffer length, if S16 
932                                    could wrap to negative number */
933    MsgLen  dLen;                /* buffer length */ 
934
935    numBuf = 0;
936    bufLen = 0; 
937
938    /* Initialise ret and part of msg here */
939    ret = ROK;
940
941    /* added defined(_XPG4_2) */
942    /* Moved initialisation of msg here. */
943
944 #if (defined(SS_LINUX) || defined(_XPG4_2))
945    msg->msg_control    = NULLP;
946    msg->msg_controllen  = 0;
947 #else
948    msg->msg_accrights     = NULLP;
949    msg->msg_accrightslen  = 0;
950 #endif /* SS_LINUX */   
951
952    /* Check if maxSize if enough to hold the entire message length before 
953     * going into the loop. If the boolean isStrmMsg is TRUE then the recv 
954     * buf is built even if the whole message cannot be accomodated. */
955
956 #ifdef T2K_MEM_LEAK_DBG
957    char * file = __FILE__;
958    U32  line   = __LINE__;
959    ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]); 
960 #else
961    ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]); 
962 #endif
963    if (ret != ROK)
964       RETVALUE(ret);
965
966    /* Get the data part */
967    ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
968    if (ret != ROK)
969    {
970       numBuf++;           /* because of cleanup */
971       goto cleanup;
972    }
973
974    if (!isStrmMsg)
975    {
976       /* The assumption here is that all dBuf's from a given region and 
977        * pool have a constance size */
978       if (len > (maxSize * dLen))
979       {
980          ret = RNA;
981          numBuf++;           /* because of cleanup */
982          goto cleanup;
983       }
984    }
985
986 #ifdef SS_LINUX
987   rxArr[numBuf].iov_base = (Void*)dPtr;  
988   rxArr[numBuf].iov_len = (U32)dLen;    
989 #else
990   rxArr[numBuf].iov_base = (S8*)dPtr;
991   rxArr[numBuf].iov_len = dLen;
992 #endif /* SS_LINUX */
993
994   bufLen += dLen;
995   numBuf++;  
996
997    /* allocate buffer space for entire message length */
998    while (bufLen < len)
999    {
1000       if (numBuf >= maxSize)
1001       {
1002          /* to big to fit in gather vector array */ 
1003          ret = RNA;
1004          break;
1005       }
1006       ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]); 
1007       if (ret != ROK)
1008       {
1009          goto cleanup;
1010       } 
1011       ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
1012       if (ret != ROK)
1013       {
1014          numBuf++;           /* because of cleanup */
1015          goto cleanup;
1016       }
1017 #ifdef SS_LINUX
1018       rxArr[numBuf].iov_base = (Void*)dPtr;  
1019       rxArr[numBuf].iov_len = (U32)dLen;    
1020 #else
1021       rxArr[numBuf].iov_base = (S8*)dPtr;
1022       rxArr[numBuf].iov_len = dLen;
1023 #endif /* SS_LINUX */
1024
1025       bufLen += dLen;
1026       numBuf++;  
1027    }
1028    /* adjust last buffer length */
1029    /*  check if we broke out because numBuf >= maxSize */
1030    if (bufLen < len)
1031       rxArr[numBuf - 1].iov_len = dLen;
1032    else
1033       rxArr[numBuf - 1].iov_len = dLen - (bufLen - len); 
1034
1035    /* setup recvmsg() message header */
1036    msg->msg_iov           = rxArr;
1037    msg->msg_iovlen        = numBuf;
1038
1039    RETVALUE(ret);
1040
1041 cleanup:
1042    /* cleanup */
1043    for (i = 0; i < numBuf; i++)
1044       SPutDBuf(info->region, info->pool, dBuf[i]);
1045
1046    msg->msg_iovlen = 0;
1047
1048    RETVALUE(ret);
1049 } /* end of buildRecvBuf */
1050
1051 /*
1052 *
1053 *      Fun:   buildRecvMsg
1054 *
1055 *      Desc:  Builds a message out of the received dBufs.
1056 *
1057 *      Ret:   ROK     - successful
1058 *             RFAILED - failed
1059 *             ROUTRES - failed, out of resources
1060 *
1061 *      Notes: None
1062 *
1063 *      File:  cm_inet.c
1064 *
1065 */
1066
1067 #ifdef ANSI
1068 PRIVATE S16 buildRecvMsg
1069 (
1070 CmInetMemInfo  *info,           /* buffer allocation info */
1071 CmInetIovec     rxArr[],        /* scatter array */  
1072 S16             numBuf,         /* number of allocated dBufs */
1073 MsgLen          msgLen,         /* message length */
1074 Buffer         *dBufs[],        /* dBufs */
1075 Buffer        **mPtr            /* message built from dBufs */     
1076 )
1077 #else
1078 PRIVATE S16 buildRecvMsg(info, rxArr, numBuf, msgLen, dBufs, mPtr)
1079 CmInetMemInfo  *info;           /* buffer allocation info */   
1080 CmInetIovec     rxArr[];        /* scatter array */            
1081 S16             numBuf;         /* number of allocated dBufs */
1082 MsgLen          msgLen;         /* length of one particular dBuf */          
1083 Buffer         *dBufs[];        /* dBufs */
1084 Buffer        **mPtr;           /* message built from dBufs */   
1085 #endif
1086 {
1087    S16      ret;                 /* return value */ 
1088    S16      i;                   /* dBuf index counter */
1089    MsgLen   bufLen;              /* length of one particular dBuf */
1090    /* cm_inet_c_001.main_54: Fix for Klockworks issue */
1091    Buffer  *mBuf = NULLP;        /* allocated message */  
1092
1093    ret = RFAILED;   
1094    i   = 0;
1095
1096    /* build message */
1097    ret = SGetMsg(info->region, info->pool, &mBuf);
1098    if (ret != ROK)
1099    {
1100       goto cleanup;
1101    }
1102
1103    /* link buffers to message */
1104    while (i < numBuf)
1105    {
1106       /* cm_inet_c_001.main_58: fix for klockwork issue */
1107       bufLen = (MsgLen)rxArr[i].iov_len; 
1108       if (msgLen < bufLen)
1109       {
1110          bufLen = msgLen;
1111       }
1112       ret = SUpdMsg(mBuf, dBufs[i], bufLen);
1113       if (ret != ROK)
1114       { 
1115          SPutMsg(mBuf);
1116          goto cleanup;
1117       }
1118       msgLen -= bufLen;
1119       i++;
1120       if (msgLen <= 0)
1121       {
1122          ret = ROK;      
1123          break;
1124       }
1125    }
1126
1127    *mPtr = mBuf;
1128
1129 cleanup:
1130    /* cleanup unused buffers */
1131    while (i < numBuf)
1132    {
1133 #ifdef T2K_MEM_LEAK_DBG
1134    char * file = __FILE__;
1135    U32  line   = __LINE__;
1136    SPutDBuf(info->region, info->pool, dBufs[i]);
1137 #else
1138    SPutDBuf(info->region, info->pool, dBufs[i]);
1139 #endif
1140     i++;
1141    }
1142
1143    RETVALUE(ret);
1144 } /* end of buildRecvMsg */
1145
1146 \f
1147
1148 /*
1149 *
1150 *      Fun:   buildSendIovec 
1151 *
1152 *      Desc:  Builds a io vector to send a message.
1153 *
1154 *      Ret:   ROK     - successful
1155 *             RFAILED - failed
1156 *             ROUTRES - failed, out of resources
1157 *             RNA     - failed, not available, indicates that the
1158 *                       maximum number of dBufs are not sufficient
1159 *                       to hold the entire message.
1160 *
1161 *      Notes: None
1162 *
1163 *      File:  cm_inet.c
1164 *
1165 */
1166 #ifdef ANSI
1167 PRIVATE S16 buildSendIovec
1168 (
1169 Buffer         *mBuf,           /* Message buffer */
1170 MsgLen         msgLen,          /* Length of mBuf */
1171 CmInetIovec    txArr[],         /* transmit scatter vector array */ 
1172 S16            numDBufs,        /* Maximum number of dBufs to use */
1173 S16            *numIovElems,    /* Number of iov elements in array */
1174 U32            *strtEndDBufNum, /* dBuf number to start and end */
1175 MsgLen         *ioLen           /* cm_inet_c_001.main_50 - Len of dbuf packed into IO-vector */ 
1176 )
1177 #else
1178 PRIVATE S16 buildSendIovec(mBuf, msgLen, txArr, numDBufs, numIovElems, 
1179                            strtEndDBufNum,ioLen) 
1180 Buffer         *mBuf;           /* Message buffer */
1181 MsgLen         msgLen;          /* Length of mBuf */
1182 CmInetIovec    txArr[];         /* transmit scatter vector array */ 
1183 S16            numDBufs;        /* Maximum number of dBufs to use */
1184 S16            *numIovElems;    /* Number of iov elements in array */
1185 U32            *strtEndDBufNum; /* dBuf number to start and end */
1186 MsgLen         *ioLen;          /* cm_inet_c_001.main_50 - Len of dbuf packed into IO-vector */ 
1187 #endif
1188 {
1189    S16         ret;
1190    MsgLen      dLen;
1191    S16         iovIdx;       
1192    Buffer      *dBuf;
1193    Data        *dPtr;
1194    MsgLen      allocLen;
1195    U32         dBufsToSkip;
1196
1197    /* Initialisations */
1198    (*numIovElems) = 0;
1199    iovIdx = 0;
1200    allocLen = 0;
1201
1202    /* cm_inet_c_001.main_50 - Intialize the newly added parameter */
1203    *ioLen = 0;
1204
1205    /* Set up vector for gathering send */
1206    ret = SInitNxtDBuf(mBuf);
1207    if (ret != ROK)
1208    {
1209       RETVALUE(RFAILED);
1210    }
1211
1212    iovIdx = 0;
1213    txArr[iovIdx].iov_len = 0;
1214
1215    if ((*strtEndDBufNum != 0))
1216    {
1217       /* Skip through the required number of dBufs */
1218       dBufsToSkip = *strtEndDBufNum;
1219
1220       while(dBufsToSkip)
1221       {
1222          ret = SGetNxtDBuf(mBuf, &dBuf);
1223          if (ret != ROK)
1224             RETVALUE(RFAILED);
1225          dBufsToSkip --;
1226       }
1227    }
1228
1229    for (;;)
1230    {
1231       ret = SGetNxtDBuf(mBuf, &dBuf);
1232       if (ret == ROK)
1233       {
1234          ret = SGetDataTx(dBuf, &dPtr, &dLen);
1235          if (ret != ROK)
1236          {  
1237             ret = RFAILED;
1238             break;
1239          }
1240
1241          txArr[iovIdx].iov_base = (S8 *)dPtr;
1242          txArr[iovIdx].iov_len = dLen;
1243
1244          allocLen += dLen;
1245       }
1246       else if  (ret == ROKDNA)
1247       {  
1248          ret = ROK;
1249          break;
1250       }
1251       else
1252       {
1253          ret = RFAILED;
1254          break;
1255       }
1256
1257       iovIdx += 1;
1258
1259       if (iovIdx >= numDBufs)
1260       {
1261          if (allocLen >= msgLen)
1262             ret = ROK;
1263          else
1264             ret = RNA;
1265          break;
1266       }
1267    }
1268
1269    (*numIovElems) = iovIdx;
1270    (*strtEndDBufNum) += iovIdx;
1271
1272    /* cm_inet_c_001.main_50 - Assign the value of dbufs packed in IO-vector */
1273    *ioLen = allocLen;
1274
1275    RETVALUE(ret);
1276
1277 } /* end of buildSendIovec */
1278 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
1279
1280 \f
1281 /*
1282 *
1283 *      Fun:   cmInetSocket
1284 *
1285 *      Desc:  Creates an Internet socket descriptor.
1286 *             On default the socket is non-blocking ( can be changed 
1287 *             with the function cmInetSetOpt()).
1288 *             Values for type:
1289 *
1290 *             CM_INET_STREAM   (TCP)
1291 *             CM_INET_DGRAM    (UDP)
1292 *
1293 *      Ret:   ROK     - successful
1294 *             RFAILED - failed
1295 *
1296 *      Notes: None
1297 *
1298 *      File:  cm_inet.c
1299 *
1300 */
1301 #ifdef ANSI
1302 #ifdef CM_INET2  
1303 #ifdef IPV6_SUPPORTED
1304 PUBLIC S16 cmInetSocket
1305 (
1306 U8        type,                 /* socket type */
1307 CmInetFd *sockFd,               /* socket file descriptor */
1308 U8       protocol,              /* protocol value */
1309 U8       domain                 /* domain */
1310 )
1311 #else
1312 PUBLIC S16 cmInetSocket
1313 (
1314 U8        type,                 /* socket type */
1315 CmInetFd *sockFd,               /* socket file descriptor */
1316 U8       protocol               /* protocol value */
1317 )
1318 #endif /* IPV6_SUPPORTED */
1319 #else   /* CM_INET2 */ 
1320 PUBLIC S16 cmInetSocket
1321 (
1322 U8        type,                 /* socket type */
1323 CmInetFd *sockFd                /* socket file descriptor */
1324 )
1325 #endif /* CM_INET2 */ 
1326 #else
1327 #ifdef CM_INET2  
1328 #ifdef IPV6_SUPPORTED
1329 PUBLIC S16 cmInetSocket(type, sockFd, protocol, domain)
1330 U8        type;                 /* socket type */
1331 CmInetFd *sockFd;               /* socket file descriptor */
1332 U8        protocol;             /* protocol value */
1333 U8        domain;               /* domain */
1334 #else
1335 PUBLIC S16 cmInetSocket(type, sockFd, protocol)
1336 U8        type;                 /* socket type */
1337 CmInetFd *sockFd;               /* socket file descriptor */
1338 U8        protocol;             /* protocol value */
1339 #endif /* IPV6_SUPPORTED */
1340 #else /* CM_INET2 */ 
1341 PUBLIC S16 cmInetSocket(type, sockFd)
1342 U8        type;                 /* socket type */
1343 CmInetFd *sockFd;               /* socket file descriptor */
1344 #endif /* CM_INET2 */ 
1345 #endif /* ANSI */
1346 {
1347    S32 ret;                     /* temporary return value */
1348
1349    U32 optVal;
1350
1351 #if (defined(WIN32) && defined(WIN2K))
1352    S32 bytesReturned;
1353    Bool bNewBehavior;
1354 #endif /* WIN2K && WIN32 */
1355
1356    TRC2(cmInetSocket);
1357
1358 #if (defined(WIN32) && defined(WIN2K))
1359    bytesReturned = 0;
1360    bNewBehavior = FALSE;
1361 #endif /* WIN32 && WIN2K */  
1362
1363    /* create socket */
1364 #ifdef CM_INET2  
1365 #ifdef IPV6_SUPPORTED
1366    sockFd->fd = socket(domain, type, protocol);
1367 #else
1368    sockFd->fd = socket(AF_INET, type, protocol);
1369 #endif /* IPV6_SUPPORTED */
1370 #else   /* CM_INET2 */ 
1371    sockFd->fd = socket(AF_INET, type, 0);
1372 #endif  /* CM_INET2 */ 
1373    if (CM_INET_INV_SOCK_FD(sockFd))
1374    {   
1375 #ifdef CMINETDBG
1376 #ifndef ALIGN_64BIT
1377       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1378       /* cm_inet_c_001.main_62:Warning fix */
1379       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%ld)\n", 
1380             INET_ERR_CODE, sockFd->fd);
1381       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1382 #else
1383       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%d)\n", 
1384             INET_ERR_CODE, sockFd->fd);
1385       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1386 #endif /*ALIGN_64BIT */
1387 #endif /* CMINETDBG */
1388       /* Set sockFd->fd to invalid socket */
1389       sockFd->fd = CM_INET_INV_SOCKFD;
1390       RETVALUE(RFAILED);   
1391    }
1392
1393    /* set socket type */
1394    sockFd->type = type;
1395
1396    /* set socket protocol type (IPv4/IPv6) */
1397 #ifdef IPV6_SUPPORTED   
1398    sockFd->protType = domain; 
1399 #endif /* IPV6_SUPPORTED */
1400
1401    /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1402 #ifdef CM_LKSCTP
1403    if (protocol != IPPROTO_SCTP)
1404    {
1405 #endif
1406    /* set default options */
1407    optVal = CM_INET_OPT_DISABLE;
1408    ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal); 
1409    if (ret != ROK) 
1410    {
1411       ret = cmInetClose(sockFd);
1412       RETVALUE(RFAILED);
1413    }
1414
1415 #ifdef SS_LINUX
1416 #ifndef CMINET_BSDCOMPAT
1417    optVal = CM_INET_OPT_ENABLE;
1418    ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BSD_COMPAT, (Ptr)&optVal);
1419    if (ret != ROK) 
1420    {
1421       ret = cmInetClose(sockFd);
1422       RETVALUE(RFAILED);
1423    }
1424 #endif /* CMINET_BSDCOMPAT */
1425 #endif /* SS_LINUX */
1426
1427 #if (defined(WIN32) && defined(WIN2K))   
1428    if(type == CM_INET_DGRAM)
1429       {
1430          ret = WSAIoctl(sockFd->fd, SIO_UDP_CONNRESET, &bNewBehavior,
1431                sizeof(bNewBehavior), NULLP, 0, &bytesReturned,
1432                NULLP, NULLP);
1433          if(ret == INET_ERR)
1434          {
1435 #ifdef CMINETDBG
1436 #ifndef ALIGN_64BIT
1437             /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1438             /* cm_inet_c_001.main_62:Warning fix */
1439             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%ld)\n", 
1440                   INET_ERR_CODE, sockFd->fd);
1441             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1442 #else
1443             /* cm_inet_c_001.main_62:Warning fix */
1444             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%d)\n", 
1445                   INET_ERR_CODE, sockFd->fd);
1446             CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1447 #endif /*ALIGN_64BIT*/
1448 #endif /* CMINETDBG */      
1449             ret = cmInetClose(sockFd);
1450             RETVALUE(RFAILED);
1451          }
1452       }
1453 #endif /* WIN2K && WIN32 */   
1454       /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1455 #ifdef CM_LKSCTP
1456    }
1457 #ifdef CM_LKSCTP_NONBLOCK
1458    else
1459    {
1460       /* cm_inet_c_001.main_47:if non-blocking SCTP socket compile time
1461        *        * flag is set then even for kernel SCTP make the socket
1462        *               * non-blocking
1463        *                      */
1464       optVal = CM_INET_OPT_DISABLE;
1465       ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1466       if (ret != ROK)
1467       {
1468          ret = cmInetClose(sockFd);
1469          RETVALUE(RFAILED);
1470       }
1471    }
1472 #endif  /* CM_LKSCTP_NONBLOCK ends */
1473 #endif
1474    RETVALUE(ROK);
1475 } /* end of cmInetSocket */
1476
1477 \f
1478 /*
1479 *
1480 *      Fun:   cmInetBind 
1481 *
1482 *      Desc:  Binds a socket file descriptor to a local Internet 
1483 *             address/port.
1484 *
1485 *      Ret:   ROK     - successful
1486 *             RFAILED - failed
1487 *
1488 *      Notes: None.
1489 *
1490 *      File:  cm_inet.c
1491 *
1492 */
1493
1494 #ifdef ANSI
1495 PUBLIC S16 cmInetBind
1496 (
1497 CmInetFd   *sockFd,             /* socket file descriptor */ 
1498 CmInetAddr *myAddr              /* locale Internet address/port */
1499 )
1500 #else
1501 PUBLIC S16 cmInetBind(sockFd, myAddr)
1502 CmInetFd   *sockFd;             /* socket file descriptor */ 
1503 CmInetAddr *myAddr;             /* locale Internet address/port */
1504 #endif
1505 {
1506    S32 ret;                     /* temporary return value */
1507    struct sockaddr_in srcAddr;  /* local Internet address/port */
1508 #ifdef IPV6_SUPPORTED 
1509    struct sockaddr_in6 srcAddr6; /* local IPV6 address/port */
1510 #ifdef CMINETDBG
1511    U16    port;
1512 #endif /* CMINETDBG */
1513 #endif /* IPV6_SUPPORTED */
1514    U32    sizeOfAddr;            /* sizeof address passed to the bind call */
1515    CmInetSockAddr *sockAddrPtr; 
1516
1517    TRC2(cmInetBind);
1518
1519 #if (ERRCLASS & ERRCLS_INT_PAR)
1520    /* error check on parameters */
1521    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1522        (myAddr == NULLP))
1523    {
1524       RETVALUE(RFAILED);
1525    }
1526 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1527
1528 #ifdef IPV6_SUPPORTED 
1529    if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1530    {
1531       cmMemset((U8*)&srcAddr6, 0, sizeof(srcAddr6));
1532       srcAddr6.sin6_family      = AF_INET6;
1533       srcAddr6.sin6_port        = CM_INET_HTON_U16(myAddr->u.ipv6Addr.port);
1534       CM_INET_COPY_IPV6ADDR(&srcAddr6.sin6_addr, 
1535                             &myAddr->u.ipv6Addr.ipv6NetAddr);
1536       sizeOfAddr               = sizeof(struct sockaddr_in6);
1537       sockAddrPtr              = (CmInetSockAddr *)&srcAddr6;
1538    }
1539    else 
1540    {
1541       cmMemset((U8*)&srcAddr, 0, sizeof(srcAddr));
1542       srcAddr.sin_family      = AF_INET;
1543       srcAddr.sin_port        = CM_INET_HTON_U16(myAddr->u.ipv4Addr.port);
1544       srcAddr.sin_addr.s_addr = CM_INET_HTON_U32(myAddr->u.ipv4Addr.address);
1545       sizeOfAddr               = sizeof(struct sockaddr_in);
1546       sockAddrPtr              = (CmInetSockAddr *)&srcAddr;
1547    }
1548 #else 
1549    cmMemset((U8*)&srcAddr, 0, sizeof(srcAddr));
1550    srcAddr.sin_family      = AF_INET;
1551    srcAddr.sin_port        = CM_INET_HTON_U16(myAddr->port);
1552    srcAddr.sin_addr.s_addr = CM_INET_HTON_U32(myAddr->address);
1553    sizeOfAddr              = sizeof(struct sockaddr_in);
1554    sockAddrPtr             = (CmInetSockAddr *)&srcAddr;
1555 #endif /* IPV6_SUPPORTED */
1556
1557    ret = bind(sockFd->fd, sockAddrPtr, sizeOfAddr); 
1558    if (ret == INET_ERR)
1559    {
1560 #ifdef CMINETDBG
1561 #ifdef IPV6_SUPPORTED 
1562       if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1563          port = myAddr->u.ipv6Addr.port;
1564       else
1565          port = myAddr->u.ipv4Addr.port;
1566 #ifndef ALIGN_64BIT
1567       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1568       /* cm_inet_c_001.main_62:Warning fix */
1569       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d)," 
1570             " port(%d), sockFd->fd(%ld)\n", 
1571             INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1572       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1573 #else
1574       /* cm_inet_c_001.main_62:Warning fix */
1575       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d)," 
1576             " port(%d), sockFd->fd(%d)\n ", 
1577             INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1578       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1579 #endif /*ALIGN_64BIT*/
1580 #else
1581 #ifndef ALIGN_64BIT
1582       /* cm_inet_c_001.main_62:Warning fix */
1583       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%lx), port(%d),"
1584             "sockFd->fd(%ld)\n",
1585             INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1586       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1587 #else
1588       /* cm_inet_c_001.main_62:Warning fix */
1589       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%x), port(%d),"
1590             " sockFd->fd(%d)\n",
1591             INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1592       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1593 #endif /*ALIGN_64BIT*/
1594 #endif /* IPV6_SUPPORTED */
1595 #endif /* CMINETDBG */
1596       RETVALUE(RFAILED);
1597    }
1598
1599    RETVALUE(ROK); 
1600 } /* end of cmInetBind */
1601
1602 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1603 /* cm_inet_c_001.main_51 Added Ipv6 support to KSCtP implementation */
1604 #ifdef CM_LKSCTP
1605 /*
1606 *
1607 *      Fun:   cmInetSctpBindx 
1608 *
1609 *      Desc:  Binds a SCTP socket file descriptor to local Internet 
1610 *             address list
1611 *
1612 *      Ret:   ROK     - successful
1613 *             RFAILED - failed
1614 *
1615 *      Notes: None.
1616 *
1617 *      File:  cm_inet.c
1618 *
1619 */
1620 #ifdef ANSI
1621 PUBLIC S16 cmInetSctpBindx
1622 (
1623 CmInetFd          *sockFd,       /* socket file descriptor */ 
1624 CmInetNetAddrLst  *addrLst,      /* local Internet address list */
1625 U16                port          /* port number */
1626 )
1627 #else
1628 PUBLIC S16 cmInetSctpBindx(sockFd, addrLst, port)
1629 CmInetFd          *sockFd;       /* socket file descriptor */ 
1630 CmInetNetAddrLst  *addrLst;      /* locale Internet address list */
1631 U16                port;         /* port number */
1632 #endif
1633 {
1634    S32    ret;                     /* temporary return value */
1635    S32    idx;
1636    S32    idx4 = 0;
1637    U32    ipv4_array_size = 0;
1638    struct sockaddr_in  addrs[CM_INET_NUM_NET_ADDR];
1639 #ifndef IPV6_SUPPORTED
1640    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1641 #else
1642    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1643 #endif /* IPV6_SUPPORTED */
1644
1645 #ifdef SUN_KSCTP
1646    Data   *tempAddrPtr = NULLP;
1647 #endif 
1648    U32    addresses_array_size = 0;
1649 #ifdef IPV6_SUPPORTED 
1650 #ifdef SUN_KSCTP
1651    S8     *addrString = NULLP;
1652    U32    addrLen = 0;
1653    S8     ipv4Format[23] = "::ffff:";
1654 #endif /* SUN_KSCTP */
1655    S32    idx6 = 0;
1656    U32    ipv6_array_size = 0;
1657    struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1658 #endif /* IPV6_SUPPORTED */
1659    struct sockaddr *sockAddrPtr = NULLP;
1660    U32    sockAddrLen = 0;
1661
1662 #if (ERRCLASS & ERRCLS_INT_PAR)
1663    /* error check on parameters */
1664    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1665        (addrLst == NULLP))
1666    {
1667       RETVALUE(RFAILED);
1668    }
1669
1670    if(addrLst->count > CM_INET_NUM_NET_ADDR)
1671    {
1672 #ifdef CMINETDBG
1673 #ifndef ALIGN_64BIT
1674       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1675       /* cm_inet_c_001.main_62:Warning fix */
1676       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1677             " sockFd->fd(%ld)\n",
1678             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1679       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);   
1680 #else
1681       /* cm_inet_c_001.main_62:Warning fix */
1682       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1683             " sockFd->fd(%d)\n", 
1684             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1685       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);   
1686 #endif /*ALIGN_64BIT*/
1687 #endif /* CMINETDBG */
1688       RETVALUE(RFAILED);
1689    }
1690 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1691
1692    cmMemset((U8*)&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1693 #ifdef IPV6_SUPPORTED 
1694    cmMemset((U8*)&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1695 #endif /* IPV6_SUPPORTED */
1696
1697    for (idx = 0; idx < addrLst->count; idx++)
1698    {
1699 #ifdef IPV6_SUPPORTED 
1700       if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1701       {
1702          ipv6_array_size += sizeof(struct sockaddr_in6);
1703          addresses_array_size += sizeof(struct sockaddr_in6);
1704          if (sockFd->protType == AF_INET)
1705          {
1706 #ifdef CMINETDBG
1707 #ifndef ALIGN_64BIT
1708             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1709             /* cm_inet_c_001.main_62:Warning fix */
1710             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1711                   " sockFd->fd(%ld)\n", sockFd->fd);
1712             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1713 #else
1714            /* cm_inet_c_001.main_62:Warning fix */
1715             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket," 
1716                   " sockFd->fd(%d)\n", sockFd->fd);
1717             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1718 #endif /*ALIGN_64BIT*/
1719 #endif /* CMINETDBG */
1720             RETVALUE(RFAILED);
1721          }
1722
1723          addrs6[idx6].sin6_family      = AF_INET6;
1724          addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
1725          CM_INET_COPY_IPV6ADDR((addrs6[idx6].sin6_addr.s6_addr), &(addrLst->addrs[idx].u.ipv6NetAddr));
1726          idx6++;
1727       }
1728       else 
1729       {
1730 #ifdef SUN_KSCTP
1731
1732          ipv6_array_size += sizeof(struct sockaddr_in6);
1733          addresses_array_size += sizeof(struct sockaddr_in6);
1734          if (sockFd->protType == AF_INET)
1735          {
1736 #ifdef CMINETDBG
1737 #ifndef ALIGN_64BIT
1738             /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1739             /* cm_inet_c_001.main_62:Warning fix */
1740             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1741                   " sockFd->fd(%ld)\n", sockFd->fd);
1742             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1743 #else
1744             /* cm_inet_c_001.main_62:Warning fix */
1745             snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket," 
1746                   " sockFd->fd(%d)\n", sockFd->fd);
1747             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1748 #endif /*ALIGN_64BIT*/
1749 #endif /* CMINETDBG */
1750             RETVALUE(RFAILED);
1751          }
1752
1753          addrs6[idx6].sin6_family      = AF_INET6;
1754          addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
1755          addrLst->addrs[idx].u.ipv4NetAddr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
1756          cmInetNtoa(addrLst->addrs[idx].u.ipv4NetAddr, &addrString);
1757          addrLen = cmStrlen((U8*)addrString);
1758          cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
1759          ipv4Format[7+addrLen] = '\0';
1760          cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
1761          idx6++;
1762 #else
1763          ipv4_array_size += sizeof(struct sockaddr_in);
1764          addresses_array_size += sizeof(struct sockaddr_in);
1765          addrs[idx4].sin_family      = AF_INET;
1766          addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
1767          addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
1768          idx4++;
1769 #endif /* SUN_KSCTP */
1770       }
1771 #else 
1772       ipv4_array_size += sizeof(struct sockaddr_in);
1773       addresses_array_size += sizeof(struct sockaddr_in);
1774       addrs[idx4].sin_family      = AF_INET;
1775       addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
1776       addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
1777       idx4++;
1778 #endif /* IPV6_SUPPORTED */
1779    }
1780
1781
1782    if(ipv4_array_size > 0)
1783    {
1784        sockAddrPtr = (struct sockaddr*)address_array;
1785       sockAddrLen = sizeof(struct sockaddr_in);
1786       cmMemcpy((U8*)address_array, (U8*)addrs, ipv4_array_size); 
1787    }
1788 #ifdef IPV6_SUPPORTED
1789    else
1790    {
1791        sockAddrPtr = (struct sockaddr*)address_array;
1792       sockAddrLen = sizeof(struct sockaddr_in6);
1793    }
1794
1795    if(ipv6_array_size > 0)
1796    {
1797       cmMemcpy((U8*)(address_array + ipv4_array_size), (U8*)addrs6, ipv6_array_size); 
1798    }
1799 #endif /* IPV6_SUPPORTED */
1800
1801
1802 #ifdef SUN_KSCTP
1803    ret = bind(sockFd->fd, sockAddrPtr, sockAddrLen); 
1804    if (ret == INET_ERR)
1805    {
1806
1807 #ifdef CMINETDBG
1808 #ifndef ALIGN_64BIT
1809       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1810       /* cm_inet_c_001.main_62:Warning fix */
1811       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1812             " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1813       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1814 #else
1815       /* cm_inet_c_001.main_62:Warning fix */
1816       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1817             " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1818       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1819 #endif /*ALIGN_64BIT*/
1820 #endif /* CMINETDBG */
1821       RETVALUE(RFAILED);
1822    }
1823
1824    if (addrLst->count > 1)
1825    {
1826       if(((struct sockaddr*)address_array)->sa_family == AF_INET)
1827       {
1828          tempAddrPtr = address_array + (sizeof(struct sockaddr_in));
1829       }
1830       else if(((struct sockaddr*)address_array)->sa_family == AF_INET6)
1831       {
1832          tempAddrPtr = address_array + (sizeof(struct sockaddr_in6));
1833       }
1834       else
1835       {
1836 #ifdef CMINETDBG
1837 #ifndef ALIGN_64BIT
1838          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1839          /* cm_inet_c_001.main_62:Warning fix */
1840          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1841                " sockFd->fd(%ld),  error(%d), port(%d)\n ",
1842                INET_ERR_CODE, port, sockFd->fd);
1843          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1844 #else
1845          /* cm_inet_c_001.main_62:Warning fix */
1846          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1847                " sockFd->fd(%d), error(%d), port(%d)\n ", 
1848                INET_ERR_CODE, port, sockFd->fd);
1849          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1850 #endif /*ALIGN_64BIT*/
1851 #endif /* CMINETDBG */
1852          RETVALUE(RFAILED);
1853       }
1854
1855       ret = sctp_bindx(sockFd->fd, (Void*)tempAddrPtr, addrLst->count - 1, SCTP_BINDX_ADD_ADDR); 
1856    }
1857 #else
1858    /* linux */
1859    ret = sctp_bindx(sockFd->fd, (struct sockaddr*)address_array, addrLst->count, SCTP_BINDX_ADD_ADDR); 
1860 #endif
1861    if (ret == INET_ERR)
1862    {
1863 #ifdef CMINETDBG
1864 #ifndef ALIGN_64BIT
1865       /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1866       /* cm_inet_c_001.main_62:Warning fix */
1867       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1868             " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1869       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1870 #else
1871       /* cm_inet_c_001.main_62:Warning fix */
1872       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1873             " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1874       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1875 #endif /*ALIGN_64BIT*/
1876 #endif /* CMINETDBG */
1877       RETVALUE(RFAILED);
1878    }
1879
1880    RETVALUE(ROK); 
1881 }
1882
1883 /*
1884 *
1885 *      Fun:   cmInetSctpConnectx 
1886 *
1887 *      Desc:  Establishes a sctp connection with remote addresses
1888 *
1889 *      Ret:   ROK     - successful
1890 *             RFAILED - failed
1891 *
1892 *      Notes: None.
1893 *
1894 *      File:  cm_inet.c
1895 *
1896 */
1897 #ifdef ANSI
1898 PUBLIC S16 cmInetSctpConnectx
1899 (
1900 CmInetFd          *sockFd,       /* socket file descriptor */ 
1901 CmInetNetAddr     *primAddr,     /* primary destination Internet address */
1902 CmInetNetAddrLst  *addrLst,      /* destination Internet address list */
1903 U16                port          /* port number */
1904 )
1905 #else
1906 PUBLIC S16 cmInetSctpConnectx(sockFd, primAddr, addrLst, port)
1907 CmInetFd          *sockFd;       /* socket file descriptor */ 
1908 CmInetNetAddr     *primAddr;     /* primary destination Internet address */
1909 CmInetNetAddrLst  *addrLst;      /* destination Internet address list */
1910 U16                port;         /* port number */
1911 #endif
1912 {
1913    S32   ret;   
1914    U32   cnt;
1915    /* cm_inet_c_001.main_46: Removed SS_LINUX flag */
1916    S32   idx;
1917
1918 /* cm_inet_c_001.main_64: New variable used as an argument for sctp_connectx */
1919 #ifdef SCTP_CONNECTX_NEW
1920    U32 assocId = 0;
1921 #endif   
1922    U32    addresses_array_size = 0;
1923    U32    idx4 = 0;
1924    struct sockaddr_in  addrs[CM_INET_NUM_NET_ADDR];
1925    U32    ipv4_array_size = 0;
1926
1927 #ifndef IPV6_SUPPORTED
1928    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1929 #else
1930    Data   address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1931 #endif /* IPV6_SUPPORTED */
1932
1933 #ifdef IPV6_SUPPORTED
1934 #ifdef SUN_KSCTP
1935    S8     *addrString = NULLP;
1936    U32    addrLen = 0;
1937    S8     ipv4Format[23] = "::ffff:";
1938    CmInetIpAddr ipv4NetAddr;
1939 #endif /* SUN_KSCTP */
1940    U32    idx6 = 0;
1941    struct sockaddr_in6  addrs6[CM_INET_NUM_NET_ADDR];
1942    U32    ipv6_array_size = 0;
1943 #endif /* IPV6_SUPPORTED */
1944 #ifndef SS_LINUX
1945    U32    sockAddrLen = 0;
1946 #endif /* sockAddrLen */
1947
1948 #ifndef SS_LINUX
1949    CmInetSockAddr *sockAddrPtr = NULLP;
1950 #endif /* SS_LINUX */
1951 #if (ERRCLASS & ERRCLS_INT_PAR)
1952    /* error check on parameters */
1953    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1954          (primAddr == NULLP))
1955    {
1956       RETVALUE(RFAILED);
1957    }
1958     /* cm_inet_c_001.main_58 : Added check for addrLst to fix klockwork issue */
1959    if (addrLst == NULLP)
1960    {
1961       RETVALUE(RFAILED);
1962    }
1963    /* cm_inet_c_001.main_46: Included check for no of address aginst max */
1964    if( addrLst->count > CM_INET_NUM_NET_ADDR )
1965    {
1966 #ifdef CMINETDBG
1967 #ifndef ALIGN_64BIT
1968       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1969       /* cm_inet_c_001.main_62:Warning fix */
1970       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1971             " sockFd->fd(%ld)\n", 
1972             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1973       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1974 #else
1975       /* cm_inet_c_001.main_62:Warning fix */
1976       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1977             " sockFd->fd(%d)\n", 
1978             addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1979       CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1980 #endif /*ALIGN_64BIT*/
1981 #endif /* CMINETDBG */
1982       RETVALUE(RFAILED);
1983    }
1984 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1985
1986
1987    cmMemset((U8*)&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1988 #ifdef IPV6_SUPPORTED
1989    cmMemset((U8*)&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1990 #endif /* IPV6_SUPPORTED */
1991
1992    cnt = 0;
1993
1994 #ifdef IPV6_SUPPORTED 
1995    if (primAddr->type == CM_INET_IPV6ADDR_TYPE)
1996    {
1997       if (sockFd->protType == AF_INET)
1998       {
1999 #ifdef CMINETDBG
2000 #ifndef ALIGN_64BIT
2001          /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2002          /* cm_inet_c_001.main_62:Warning fix */
2003          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2004                " sockFd->fd(%ld)\n", sockFd->fd);
2005          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
2006 #else
2007          /* cm_inet_c_001.main_62:Warning fix */
2008          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2009                " sockFd->fd(%d)\n",  sockFd->fd);
2010          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
2011 #endif /*ALIGN_64BIT*/
2012 #endif /* CMINETDBG */
2013          RETVALUE(RFAILED);
2014       }
2015
2016       addrs6[idx6].sin6_family      = AF_INET6;
2017       addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2018       CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr), &(primAddr->u.ipv6NetAddr));
2019       addresses_array_size += sizeof(struct sockaddr_in6);
2020       ipv6_array_size += sizeof(struct sockaddr_in6);
2021       idx6++;
2022    }
2023    else 
2024    {
2025 #ifdef SUN_KSCTP
2026       if (sockFd->protType == AF_INET)
2027       {
2028 #ifdef CMINETDBG
2029 #ifndef ALIGN_64BIT
2030          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2031          /* cm_inet_c_001.main_62:Warning fix */
2032          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2033                " sockFd->fd(%ld)\n", sockFd->fd);
2034          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
2035 #else
2036          /* cm_inet_c_001.main_62:Warning fix */
2037          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2038                " sockFd->fd(%d)\n", sockFd->fd);
2039          CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
2040 #endif /*ALIGN_64BIT*/
2041 #endif /* CMINETDBG */
2042          RETVALUE(RFAILED);
2043       }
2044       addrs6[idx6].sin6_family      = AF_INET6;
2045       addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2046       ipv4NetAddr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2047       cmInetNtoa(ipv4NetAddr, &addrString);
2048       addrLen = cmStrlen((U8*)addrString);
2049       cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2050       ipv4Format[7+addrLen] = '\0';
2051       cmInetPton6((CmInetIpAddr6*)&(addrs6[idx6].sin6_addr), ipv4Format);
2052       addresses_array_size += sizeof(struct sockaddr_in6);
2053       ipv6_array_size += sizeof(struct sockaddr_in6);
2054       idx6++;
2055 #else
2056       addrs[idx4].sin_family      = AF_INET;
2057       addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2058       addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2059       addresses_array_size += sizeof(struct sockaddr_in);
2060       ipv4_array_size += sizeof(struct sockaddr_in);
2061       idx4++;
2062 #endif 
2063    }
2064 #else 
2065    addrs[idx4].sin_family      = AF_INET;
2066    addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2067    addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2068    addresses_array_size += sizeof(struct sockaddr_in);
2069    ipv4_array_size += sizeof(struct sockaddr_in);
2070    idx4++;
2071 #endif /* IPV6_SUPPORTED */
2072
2073    cnt++;
2074
2075    /* cm_inet_c_001.main_46: Moved the SS_LINUX flag down, 
2076     * copy addresses in Solaris also */
2077    if (addrLst != NULLP)
2078    {
2079       for (idx = 0; idx < addrLst->count; idx++)
2080       {
2081
2082          /* cm_inet_c_001.main_46: Don't include the primary address 
2083           * if its prersent in list */
2084          if ( addrLst->addrs[idx].type == CM_INET_IPV4ADDR_TYPE )
2085          {
2086             if ( addrLst->addrs[idx].u.ipv4NetAddr == primAddr->u.ipv4NetAddr )
2087             {
2088                continue;
2089             }
2090          }
2091 #ifdef IPV6_SUPPORTED
2092          else if ( addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE )
2093          {
2094             if (( cmMemcmp(addrLst->addrs[idx].u.ipv6NetAddr,
2095                    primAddr->u.ipv6NetAddr, sizeof(CmInetIpAddr6) )) == 0 )
2096             {
2097                continue;
2098             }
2099          }
2100
2101          if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
2102          {
2103             if (sockFd->protType == AF_INET)
2104             {
2105 #ifdef CMINETDBG
2106 #ifndef ALIGN_64BIT
2107                /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2108                /* cm_inet_c_001.main_62:Warning fix */
2109                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2110                      " sockFd->fd(%ld)\n", sockFd->fd);
2111                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
2112 #else
2113                /* cm_inet_c_001.main_62:Warning fix */
2114                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2115                      " sockFd->fd(%d)\n", sockFd->fd);
2116                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
2117 #endif /*ALIGN_64BIT*/
2118 #endif /* CMINETDBG */
2119                RETVALUE(RFAILED);
2120             }
2121
2122             addrs6[idx6].sin6_family      = AF_INET6;
2123             addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2124             CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr),
2125                                   &(addrLst->addrs[idx].u.ipv6NetAddr));
2126             addresses_array_size += sizeof(struct sockaddr_in6);
2127             ipv6_array_size += sizeof(struct sockaddr_in6);
2128             idx6++;
2129          }
2130          else 
2131          {
2132 #ifdef SUN_KSCTP
2133             if (sockFd->protType == AF_INET)
2134             {
2135 #ifdef CMINETDBG
2136 #ifndef ALIGN_64BIT
2137                /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2138                /* cm_inet_c_001.main_62:Warning fix */
2139                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2140                      " sockFd->fd(%ld)\n", sockFd->fd);
2141                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2142 #else
2143                /* cm_inet_c_001.main_62:Warning fix */
2144                snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2145                      " sockFd->fd(%d)\n", sockFd->fd);
2146                CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2147 #endif /*ALIGN_64BIT*/
2148 #endif /* CMINETDBG */
2149                RETVALUE(RFAILED);
2150             }
2151             addrs6[idx6].sin6_family      = AF_INET6;
2152             addrs6[idx6].sin6_port        = CM_INET_HTON_U16(port);
2153             ipv4NetAddr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2154             cmInetNtoa(ipv4NetAddr, &addrString);
2155             addrLen = cmStrlen((U8*)addrString);
2156             cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2157             ipv4Format[7+addrLen] = '\0';
2158             cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
2159             addresses_array_size += sizeof(struct sockaddr_in6);
2160             ipv6_array_size += sizeof(struct sockaddr_in6);
2161             idx6++;
2162 #else
2163             addrs[idx4].sin_family      = AF_INET;
2164             addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2165             addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2166             addresses_array_size += sizeof(struct sockaddr_in);
2167             ipv4_array_size += sizeof(struct sockaddr_in);
2168             idx4++;
2169 #endif /* SUN_KSCTP */
2170          }
2171 #else 
2172          addrs[idx4].sin_family      = AF_INET;
2173          addrs[idx4].sin_port        = CM_INET_HTON_U16(port);
2174          addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2175          addresses_array_size += sizeof(struct sockaddr_in);
2176          ipv4_array_size += sizeof(struct sockaddr_in);
2177          idx4++;
2178 #endif /* IPV6_SUPPORTED */
2179          /*cm_inet_c_001.main_39 */
2180          cnt++;
2181       }
2182    }
2183
2184    /* cm_inet_c_001.main_46: Moved SS_LINUX flag to here */
2185 #ifdef SS_LINUX
2186    /*cm_inet_c_001.main_58 : Added check array_size to fix klockwork issue */
2187    if((ipv4_array_size > 0) && (ipv4_array_size <= (CM_INET_NUM_NET_ADDR * \
2188                sizeof(struct sockaddr_in))))
2189    {
2190       cmMemcpy((U8*)address_array, (U8*)&addrs[0], ipv4_array_size); 
2191    }
2192    else
2193    {
2194       RETVALUE(RFAILED);
2195    }
2196 /* HLAL */
2197 #if 0
2198 #ifdef IPV6_SUPPORTED
2199    if((ipv6_array_size > 0) && (ipv6_array_size <= (CM_INET_NUM_NET_ADDR * \
2200                sizeof(struct sockaddr_in))))
2201    {
2202       cmMemcpy((U8*)(address_array + ipv4_array_size), (U8*)addrs6, ipv6_array_size); 
2203    }
2204    else
2205    {
2206       RETVALUE(RFAILED);
2207    }
2208 #endif /* IPV6_SUPPORTED */
2209 #endif
2210 /* cm_inet_c_001.main_64: Support for new definition of sctp_connectx */
2211 #ifndef SCTP_CONNECTX_NEW   
2212    ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt);
2213 #else
2214    ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt, (sctp_assoc_t *)&assocId);
2215 #endif
2216
2217 #else
2218    /* solaris */
2219    /* cm_inet_c_001.main_46: Use next provided address to connect if 
2220     * first one fails */
2221
2222 #ifdef CMINET_SUN_CONNECTX
2223    idx4 = 0;
2224 #ifdef IPV6_SUPPORTED
2225    idx6 = 0;
2226 #endif /* IPV6_SUPPORTED */
2227    for (idx = 0; idx < cnt; idx++)
2228    {
2229       if( addrs[idx4].sin_family == AF_INET)
2230       {
2231         sockAddrPtr = (CmInetSockAddr *)&addrs[idx4];
2232         sockAddrLen = sizeof(struct sockaddr_in);
2233         idx4++;
2234       }
2235 #ifdef IPV6_SUPPORTED
2236       else 
2237       {
2238         sockAddrPtr = (CmInetSockAddr *)&addrs6[idx6];
2239         sockAddrLen = sizeof(struct sockaddr_in6);
2240         idx6++;
2241       }
2242 #endif/* IPV6_SUPPORTED */
2243
2244       ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2245
2246         if ( ret != INET_ERR )
2247         {
2248             break;
2249         }
2250 #ifdef CMINETDBG
2251 #ifndef ALIGN_64BIT
2252       /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2253       /* cm_inet_c_001.main_62:Warning fix */
2254       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2255             " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2256       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2257 #else
2258       /* cm_inet_c_001.main_62:Warning fix */
2259       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2260             " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2261       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2262 #endif /*ALIGN_64BIT*/
2263 #endif /* CMINETDBG */
2264
2265    }
2266 #else
2267
2268    if( addrs[0].sin_family == AF_INET)
2269    {
2270      sockAddrPtr = (CmInetSockAddr*)&addrs[0];
2271      sockAddrLen = sizeof(struct sockaddr_in);
2272      idx4++;
2273    }
2274 #ifdef IPV6_SUPPORTED
2275    else 
2276    {
2277      sockAddrPtr = (CmInetSockAddr*)&addrs6[0];
2278      sockAddrLen = sizeof(struct sockaddr_in6);
2279      idx6++;
2280    }
2281 #endif/* IPV6_SUPPORTED */
2282
2283    ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2284
2285 #endif /* CMINET_SUN_CONNECTX */
2286 #endif /* SS_LINUX */
2287
2288    if (ret == INET_ERR)
2289    {
2290 #ifdef CMINETDBG
2291 #ifndef ALIGN_64BIT
2292       /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2293       /* cm_inet_c_001.main_62:Warning fix */
2294       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2295             " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2296       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
2297 #else
2298       /* cm_inet_c_001.main_62:Warning fix */
2299       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2300             " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2301       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
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       /* cm_inet_c_001.main_62:Warning fix */
2781       snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2782             " sockFd->fd(%d)\n",  INET_ERR_CODE, sockFd->fd);
2783       CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2784 #endif /*ALIGN_64BIT*/
2785 #endif /* CMINETDBG */
2786
2787       RETVALUE(RFAILED);
2788    }
2789
2790    /* save the length of the received message */
2791    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2792    *len = (MsgLen)ret;
2793
2794 #ifdef IPV6_SUPPORTED 
2795    if (addr.ss_family == AF_INET6)
2796    {
2797        U8 ipv4Format[12] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff};
2798        pAddr6 = (struct sockaddr_in6*)&addr;
2799        *port = CM_INET_NTOH_U16(pAddr6->sin6_port);
2800
2801       if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
2802       {
2803          srcAddr->type          = CM_INET_IPV4ADDR_TYPE;
2804          cmMemcpy((U8*)&srcAddr->u.ipv4NetAddr, (U8*)((pAddr6->sin6_addr.s6_addr) + 12), sizeof(U32));
2805          srcAddr->u.ipv4NetAddr = CM_INET_HTON_U32(srcAddr->u.ipv4NetAddr);
2806       }
2807
2808       else
2809       {
2810          srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2811          CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr); 
2812       }
2813    }
2814    else 
2815    {
2816       pAddr = (struct sockaddr_in*)&addr;
2817       *port = CM_INET_NTOH_U16(pAddr->sin_port);
2818       srcAddr->type          = CM_INET_IPV4ADDR_TYPE;
2819       srcAddr->u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2820    }
2821 #else 
2822    pAddr = (struct sockaddr_in*)&addr;
2823    *port = CM_INET_NTOH_U16(pAddr->sin_port);
2824    srcAddr->type          = CM_INET_IPV4ADDR_TYPE;
2825    srcAddr->u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2826 #endif /* IPV6_SUPPORTED */
2827
2828    /* fill sndrcv info */
2829    sinfo->stream     = info.sinfo_stream;
2830    sinfo->ssn        = info.sinfo_ssn;
2831    sinfo->flags      = info.sinfo_flags;
2832    /*cm_inet_c_001.main_54: converting ppid to host*/
2833    sinfo->ppid       = CM_INET_NTOH_U32(info.sinfo_ppid);
2834    sinfo->context    = info.sinfo_context;
2835    sinfo->timetolive = info.sinfo_timetolive;
2836    sinfo->tsn        = info.sinfo_tsn;
2837    sinfo->cumtsn     = info.sinfo_cumtsn;
2838    sinfo->assocId    = info.sinfo_assoc_id;
2839
2840    /* fill message flags */
2841    *flag = 0;
2842    if ((msgFlags & MSG_EOR) != 0)
2843       *flag |= CM_INET_SCTP_MSG_EOR;
2844
2845    if ((msgFlags & MSG_NOTIFICATION) != 0)
2846    {
2847       *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2848       *mBuf = NULLP;
2849
2850       sctpNtfy = (union sctp_notification*)recvbuf;
2851
2852       ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2853       ntfy->header.nLen   = sctpNtfy->sn_header.sn_length;
2854
2855       switch(sctpNtfy->sn_header.sn_type)
2856       {
2857          case SCTP_ASSOC_CHANGE:
2858             ntfy->header.nType  = CM_INET_SCTP_ASSOC_CHANGE;
2859             switch(sctpNtfy->sn_assoc_change.sac_state)
2860             {
2861                 case SCTP_COMM_UP:
2862                      ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2863                      break;
2864                 case SCTP_COMM_LOST:
2865                      ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2866                      break;
2867                 case SCTP_RESTART:
2868                      ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2869                      break;
2870                 case SCTP_SHUTDOWN_COMP:
2871                      ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2872                      break;
2873                 case SCTP_CANT_STR_ASSOC:
2874                      ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
2875                      break;
2876                 default:
2877                      break;
2878             }
2879             ntfy->u.assocChange.error      = sctpNtfy->sn_assoc_change.sac_error;
2880             ntfy->u.assocChange.outStreams = sctpNtfy->sn_assoc_change.sac_outbound_streams;
2881             ntfy->u.assocChange.inStreams  = sctpNtfy->sn_assoc_change.sac_inbound_streams;
2882             ntfy->u.assocChange.assocId    = sctpNtfy->sn_assoc_change.sac_assoc_id;
2883 #ifdef SS_LINUX
2884             ntfy->u.assocChange.info       = sctpNtfy->sn_assoc_change.sac_info;
2885 #endif
2886             break;
2887          case SCTP_PEER_ADDR_CHANGE:
2888             ntfy->header.nType  = CM_INET_SCTP_PEER_ADDR_CHANGE;
2889             switch(sctpNtfy->sn_paddr_change.spc_state)
2890             {
2891                 case SCTP_ADDR_AVAILABLE:
2892                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2893                      break;
2894                 case SCTP_ADDR_UNREACHABLE:
2895                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2896                      break;
2897                 case SCTP_ADDR_REMOVED:
2898                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2899                      break;
2900                 case SCTP_ADDR_ADDED:
2901                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2902                      break;
2903                 case SCTP_ADDR_MADE_PRIM:
2904                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2905                      break;
2906 #ifdef SS_LINUX
2907                 case SCTP_ADDR_CONFIRMED:
2908                      ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2909                      break;
2910 #endif
2911                 default:
2912                 break;
2913             }
2914
2915 #ifdef IPV6_SUPPORTED 
2916             if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
2917             {
2918                pAddr6 = (struct sockaddr_in6*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2919                ntfy->u.paddrChange.addr.type = CM_INET_IPV6ADDR_TYPE;
2920                CM_INET_COPY_IPV6ADDR(&ntfy->u.paddrChange.addr.u.ipv6NetAddr, 
2921                                                     &pAddr6->sin6_addr.s6_addr); 
2922             }
2923             else 
2924             {
2925                pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2926                ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2927                ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2928             }
2929 #else 
2930             pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2931             ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2932             ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2933 #endif /* IPV6_SUPPORTED */
2934
2935             ntfy->u.paddrChange.error   = sctpNtfy->sn_paddr_change.spc_error;
2936             ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2937             break;
2938          case SCTP_REMOTE_ERROR:
2939             ntfy->header.nType  = CM_INET_SCTP_REMOTE_ERROR;
2940
2941             ntfy->u.remoteErr.error   = sctpNtfy->sn_remote_error.sre_error;
2942             ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2943 #ifdef SS_LINUX
2944             /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2945             datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2946
2947             ret = SGetSBuf( meminfo->region, meminfo->pool, \
2948                   &ntfy->u.remoteErr.data, datlen );
2949             if( ret != ROK )
2950             {
2951                ntfy->u.remoteErr.data = NULLP;
2952                break;
2953             }
2954             cmMemcpy(ntfy->u.remoteErr.data,\
2955                   sctpNtfy->sn_remote_error.sre_data, datlen);
2956 #endif
2957             break;
2958          case SCTP_SEND_FAILED:
2959             ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2960
2961             ntfy->u.sndFailed.error           = sctpNtfy->sn_send_failed.ssf_error;
2962             ntfy->u.sndFailed.assocId         = sctpNtfy->sn_send_failed.ssf_assoc_id;
2963 #ifdef SS_LINUX
2964             /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2965             datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2966
2967             ret = SGetSBuf( meminfo->region, meminfo->pool, \
2968                   &ntfy->u.sndFailed.data, datlen );
2969             if( ret != ROK )
2970             {
2971                ntfy->u.sndFailed.data = NULLP;
2972                break;
2973             }
2974             cmMemcpy(ntfy->u.sndFailed.data,\
2975                   sctpNtfy->sn_send_failed.ssf_data, datlen );
2976 #endif
2977             ntfy->u.sndFailed.info.stream     = sctpNtfy->sn_send_failed.ssf_info.sinfo_stream;
2978             ntfy->u.sndFailed.info.ssn        = sctpNtfy->sn_send_failed.ssf_info.sinfo_ssn;
2979             ntfy->u.sndFailed.info.flags      = sctpNtfy->sn_send_failed.ssf_info.sinfo_flags;
2980             ntfy->u.sndFailed.info.ppid       = sctpNtfy->sn_send_failed.ssf_info.sinfo_ppid;
2981             ntfy->u.sndFailed.info.context    = sctpNtfy->sn_send_failed.ssf_info.sinfo_context;
2982             ntfy->u.sndFailed.info.timetolive = sctpNtfy->sn_send_failed.ssf_info.sinfo_timetolive;
2983             ntfy->u.sndFailed.info.tsn        = sctpNtfy->sn_send_failed.ssf_info.sinfo_tsn;
2984             ntfy->u.sndFailed.info.cumtsn     = sctpNtfy->sn_send_failed.ssf_info.sinfo_cumtsn;
2985             ntfy->u.sndFailed.info.assocId    = sctpNtfy->sn_send_failed.ssf_info.sinfo_assoc_id;
2986             break;
2987          case SCTP_SHUTDOWN_EVENT:
2988             ntfy->header.nType  = CM_INET_SCTP_SHUTDOWN_EVENT;
2989
2990             ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2991             break;
2992 #ifdef SUN_KSCTP
2993          case SCTP_ADAPTION_INDICATION :
2994 #else
2995             /* linux */
2996          case SCTP_ADAPTATION_INDICATION :
2997 #endif
2998             ntfy->header.nType  = CM_INET_SCTP_ADAPTATION_INDICATION;
2999
3000 #ifdef SUN_KSCTP
3001             ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
3002             ntfy->u.adaptationEvt.assocId       = sctpNtfy->sn_adaption_event.sai_assoc_id;
3003 #else
3004             /* linux */
3005             ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
3006             ntfy->u.adaptationEvt.assocId       = sctpNtfy->sn_adaptation_event.sai_assoc_id;
3007 #endif
3008             break;
3009          case SCTP_PARTIAL_DELIVERY_EVENT:
3010             ntfy->header.nType  = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
3011
3012             ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
3013             ntfy->u.pdapiEvt.assocId    = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
3014             break;
3015          default:
3016             break;
3017       }
3018    }
3019    else
3020    {
3021       /* get a message buffer */
3022       ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
3023       if (ret != ROK)
3024       {
3025          SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3026          RETVALUE(RFAILED);
3027       }
3028
3029       ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
3030       if (ret != ROK)
3031       {
3032          SPutMsg(*mBuf);
3033          SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3034          RETVALUE(RFAILED);
3035       }
3036    }
3037
3038    /* cleanup */
3039    SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);       
3040
3041    RETVALUE(ROK);
3042 }
3043
3044 /*
3045 *
3046 *      Fun:   cmInetSctpGetPAddrs 
3047 *
3048 *      Desc:  returns the list of peer addresses 
3049 *
3050 *      Ret:   ROK     - successful
3051 *             RFAILED - failed
3052 *
3053 *      Notes: None.
3054 *
3055 *      File:  cm_inet.c
3056 *
3057 */
3058 #ifdef ANSI
3059 PUBLIC S16 cmInetSctpGetPAddrs
3060 (
3061 CmInetFd             *sockFd,       /* socket file descriptor */ 
3062 U32                   assocId,      /* association id */
3063 CmInetNetAddrLst     *addrlst       /* peer address list */
3064 )
3065 #else
3066 PUBLIC S16 cmInetSctpGetPAddrs(sockFd, assocId, addrlst)
3067 CmInetFd             *sockFd;       /* socket file descriptor */ 
3068 U32                   assocId;      /* association id */
3069 CmInetNetAddrLst     *addrlst;      /* peer address list */
3070 #endif
3071 {
3072    /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
3073    S32   cnt;
3074    S32   idx;
3075    U8    *byteAddress;   
3076    struct sockaddr    *peerAddrList;
3077    struct sockaddr_in *pAddr;
3078 #ifdef IPV6_SUPPORTED
3079    struct sockaddr_in6 *pAddr6;
3080 #endif /* IPV6_SUPPORTED */
3081
3082 #ifdef SUN_KSCTP
3083    if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
3084 #else
3085       if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
3086 #endif
3087       {
3088 #ifdef CMINETDBG
3089 #ifndef ALIGN_64BIT
3090          /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3091          /* cm_inet_c_001.main_62:Warning fix */
3092          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
3093                " sockFd->fd(%ld), assocId(%ld)\n", 
3094                INET_ERR_CODE, sockFd->fd, assocId);
3095          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
3096 #else
3097       /* cm_inet_c_001.main_55: Fix for compilation warning */
3098       /* cm_inet_c_001.main_62:Warning fix */
3099          snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
3100                " sockFd->fd(%d),assocId(%d)\n", 
3101                INET_ERR_CODE, sockFd->fd, assocId);
3102          CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
3103 #endif /*ALIGN_64BIT*/
3104 #endif /* CMINETDBG */
3105
3106          RETVALUE(RFAILED);
3107       }
3108
3109    byteAddress = (U8*)peerAddrList;
3110    for (idx = 0; idx < cnt; idx++)
3111    {
3112 #ifdef IPV6_SUPPORTED 
3113
3114       if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
3115       {
3116          if (sockFd->protType == AF_INET)
3117          {
3118 #ifdef CMINETDBG
3119 #ifndef ALIGN_64BIT
3120             /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3121             sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
3122                   " sockFd->fd(%ld)", sockFd->fd);
3123             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
3124 #else
3125             sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
3126                   " sockFd->fd(%d)", sockFd->fd);
3127             CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
3128 #endif /*ALIGN_64BIT*/
3129 #endif /* CMINETDBG */
3130
3131             sctp_freepaddrs(peerAddrList);
3132             RETVALUE(RFAILED);
3133          }
3134
3135          pAddr6 = (struct sockaddr_in6*)byteAddress;
3136
3137          addrlst->addrs[idx].type = CM_INET_IPV6ADDR_TYPE;
3138          CM_INET_COPY_IPV6ADDR(&(addrlst->addrs[idx].u.ipv6NetAddr), &(pAddr6->sin6_addr.s6_addr));
3139          byteAddress += sizeof(struct sockaddr_in6);
3140       }
3141       else 
3142       {
3143          pAddr = (struct sockaddr_in*)byteAddress;
3144          addrlst->addrs[idx].type          = CM_INET_IPV4ADDR_TYPE;
3145          addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3146          byteAddress += sizeof(struct sockaddr_in);
3147       }
3148 #else 
3149       pAddr = (struct sockaddr_in*)byteAddress;
3150       addrlst->addrs[idx].type          = CM_INET_IPV4ADDR_TYPE;
3151       addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3152       byteAddress += sizeof(struct sockaddr_in);
3153 #endif /* IPV6_SUPPORTED */
3154    }
3155
3156    /* cm_inet_c_001.main_58 : Fix for klockwork issue */
3157    addrlst->count = (U8)cnt;   
3158
3159    sctp_freepaddrs(peerAddrList);
3160
3161    RETVALUE(ROK);
3162 }
3163
3164 /*
3165 *
3166 *      Fun:    cmInetGetOpt 
3167 *
3168 *      Desc:   invokes socket API to retrive specified socket options
3169 *
3170 *      Ret:   ROK     - successful
3171 *             RFAILED - failed
3172 *
3173 *      Notes:
3174 *
3175 *      File:   cm_inet.c
3176 *
3177 */
3178 #ifdef ANSI
3179 PUBLIC S16 cmInetGetOpt
3180 (
3181 CmInetFd *sockFd,               /* socket file descriptor */ 
3182 U32       level,                /* option level */
3183 U32       type,                 /* option type */
3184 Ptr       value                 /* option value */ 
3185
3186 #else
3187 PUBLIC S16 cmInetGetOpt(sockFd, level, type, value)
3188 CmInetFd *sockFd;               /* socket file descriptor */ 
3189 U32       level;                /* option level */
3190 U32       type;                 /* option type */
3191 Ptr       value;                /* option value */
3192 #endif
3193 {
3194    socklen_t                len;
3195    struct sctp_status       status;
3196    struct sctp_paddrinfo    addrInfo;
3197    struct sockaddr_in      *pAddr;
3198 #ifdef IPV6_SUPPORTED
3199    struct sockaddr_in6     *pAddr6;
3200 #endif /* IPV6_SUPPORTED */
3201    struct sctp_assocparams  assocParams;
3202 /*cm_inet_c_001.main_40 Updated for the support of configurable RTO parameters, 
3203                         HBeat value Max retransmissions (Init, Path, Association)*/
3204    struct sctp_initmsg      initMsg;
3205    struct sctp_rtoinfo      rtoInfo;
3206    struct sctp_paddrparams  addrParams;
3207    CmInetSctpStatus        *pSctpStatus;
3208    CmInetSctpPeerAddrInfo  *pPeerAddrInfo;
3209    CmInetSctpInitMsg       *pInitMsg;
3210    CmInetSctpAssocParams   *pAssocParams;
3211    CmInetSctpRtoInfo       *pRtoInfo;
3212    CmInetSctpPeerAddrParams *pPeerAddrParams;
3213    /*cm_inet_c_001.main_58  : fix for klockwork issue */
3214    S32                     ret;
3215
3216    TRC2(cmInetGetOpt);
3217
3218 #if (ERRCLASS & ERRCLS_INT_PAR)
3219    /* error check on parameters */
3220    if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3221    {
3222       RETVALUE(RFAILED);
3223    }
3224 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3225
3226    switch (type) 
3227    {
3228       case CM_INET_OPT_SCTP_GET_ASSOC_STA:
3229          pSctpStatus = (CmInetSctpStatus*)value;
3230          cmMemset((U8*)&status, 0, sizeof(struct sctp_status));
3231          len = sizeof(status);
3232          status.sstat_assoc_id = pSctpStatus->assocId;
3233
3234          ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
3235
3236          pSctpStatus->rwnd      = status.sstat_rwnd;
3237          pSctpStatus->unackdata = status.sstat_unackdata;
3238          pSctpStatus->penddata  = status.sstat_penddata;
3239          pSctpStatus->instrms   = status.sstat_instrms;
3240          pSctpStatus->outstrms  = status.sstat_outstrms;
3241          pSctpStatus->fragPoint = status.sstat_fragmentation_point; 
3242
3243          switch (status.sstat_state)
3244          {
3245 #ifdef SUN_KSCTP
3246             case SCTPS_IDLE:
3247             case SCTPS_BOUND:
3248             case SCTPS_LISTEN:
3249 #else
3250             case SCTP_EMPTY:
3251 #endif
3252                {
3253                   pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3254                }
3255                break;
3256
3257 #ifdef SS_LINUX
3258             case SCTP_CLOSED:
3259                {
3260                   pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3261                }
3262                break;
3263 #endif
3264
3265 #ifdef SUN_KSCTP
3266             case SCTPS_COOKIE_WAIT:
3267 #else
3268             case SCTP_COOKIE_WAIT:
3269 #endif
3270                {
3271                   pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3272                }
3273                break;
3274
3275 #ifdef SUN_KSCTP
3276             case SCTPS_COOKIE_ECHOED:
3277 #else
3278             case SCTP_COOKIE_ECHOED:
3279 #endif
3280                {
3281                   pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3282                }
3283                break;
3284
3285 #ifdef SUN_KSCTP
3286             case SCTPS_ESTABLISHED:
3287 #else
3288             case SCTP_ESTABLISHED:
3289 #endif
3290                {
3291                   pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3292                }
3293                break;
3294
3295 #ifdef SUN_KSCTP
3296             case SCTPS_SHUTDOWN_PENDING:
3297 #else
3298             case SCTP_SHUTDOWN_PENDING:
3299 #endif
3300                {
3301                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3302                }
3303                break;
3304
3305 #ifdef SUN_KSCTP
3306             case SCTPS_SHUTDOWN_SENT:
3307 #else
3308             case SCTP_SHUTDOWN_SENT:
3309 #endif
3310                {
3311                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3312                }
3313                break;
3314
3315 #ifdef SUN_KSCTP
3316             case SCTPS_SHUTDOWN_RECEIVED:
3317 #else
3318             case SCTP_SHUTDOWN_RECEIVED:
3319 #endif
3320                {
3321                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3322                }
3323                break;
3324
3325 #ifdef SUN_KSCTP
3326             case SCTPS_SHUTDOWN_ACK_SENT:
3327 #else
3328             case SCTP_SHUTDOWN_ACK_SENT:
3329 #endif
3330                {
3331                   pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3332                }
3333                break;
3334
3335             default:
3336                {
3337                   RETVALUE(RFAILED);
3338                }
3339                break;
3340          }
3341
3342 #ifdef IPV6_SUPPORTED 
3343          if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3344          {
3345             pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3346             pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr6->sin6_port);
3347
3348             pSctpStatus->primary.addr.type = CM_INET_IPV6ADDR_TYPE;
3349             CM_INET_COPY_IPV6ADDR(&pSctpStatus->primary.addr.u.ipv6NetAddr, 
3350                   &pAddr6->sin6_addr.s6_addr); 
3351          }
3352          else 
3353          {
3354             pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3355             pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr->sin_port);
3356             pSctpStatus->primary.addr.type          = CM_INET_IPV4ADDR_TYPE;
3357             pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3358          }
3359 #else 
3360          pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3361          pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr->sin_port);
3362          pSctpStatus->primary.addr.type          = CM_INET_IPV4ADDR_TYPE;
3363          pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3364 #endif /* IPV6_SUPPORTED */
3365
3366          pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3367          if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3368              pSctpStatus->primary.isActive = TRUE;
3369          else
3370              pSctpStatus->primary.isActive = FALSE;
3371              pSctpStatus->primary.cwnd = status.sstat_primary.spinfo_cwnd;
3372              pSctpStatus->primary.srtt = status.sstat_primary.spinfo_srtt;
3373              pSctpStatus->primary.rto  = status.sstat_primary.spinfo_rto;
3374              pSctpStatus->primary.mtu  = status.sstat_primary.spinfo_mtu;
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 **********************************************************************/