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