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