1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
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 #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
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 *******************************************************************************/
20 /********************************************************************20**
22 Name: common Internet socket library
26 Desc: common library for Internet sockets,
27 always link this library with following libraries:
33 *********************************************************************21*/
37 * This software may be combined with the following TRILLIUM
40 * part no. description
41 * -------- ----------------------------------------------
42 * 1000151 TCAP over TCP/IP
46 /* header include files (.h) */
48 #include "envopt.h" /* environment options */
49 #include "envdep.h" /* environment dependent */
50 #include "envind.h" /* environment independent */
52 #include "gen.h" /* general */
53 #include "ssi.h" /* system services interface */
54 #include "cm_inet.h" /* socket library file */
56 /*cm_inet_c_001.main_35 : Updated for C++ compilation */
59 #endif /* __cplusplus */
61 /* environment dependent include files */
73 #if (!defined(SS_VW) && !defined(SS_PS))
80 #include <sys/types.h>
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
88 #include <sys/times.h>
91 #include <selectLib.h>
94 #if (!defined (SS_PS) && !defined(HPOS))
95 #include <sys/select.h>
100 #include <sys/filio.h>
101 #endif /* SS_LINUX */
102 #endif /* SS_PS && HPOS */
104 #include <sys/time.h>
108 #include <netinet/in.h>
109 #include <arpa/inet.h>
110 #include <netinet/tcp.h>
111 #ifdef IPV6_SUPPORTED
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>
119 #include <netinet/icmp6.h>
122 #endif /* IPV6_SUPPORTED */
126 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
128 #include <netinet/sctp.h>
131 /* cm_inet_c_001.main_58: Added new header files to support filteration
132 * of ICMP messages */
134 #ifdef CM_ICMP_FILTER_SUPPORT
135 #include <asm/types.h>
136 #include <linux/icmp.h>
139 /* cm_inet_c_001.main_62:Warning fix */
140 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
145 #endif /* __cplusplus */
146 /* header/extern include files (.x) */
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 */
159 /* BSD and Winsock error handling is different */
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
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 */
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
210 #define MIN_BACK_LOG 0
212 /* added a win2k specific defines in. */
215 #ifndef SIO_UDP_CONNRESET
216 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
219 #define MAX_BACK_LOG 1
221 #define MAX_BACK_LOG 5
224 #ifdef IPV6_OPTS_SUPPORTED
225 #ifndef IPV6_SUPPORTED
226 #error "Enable IPV6_SUPPORTED flag if IPV6_OPTS_SUPPORTED is defined."
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 */
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 */
243 /* forward references */
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[],
254 /* cm_inet_c_001.main_50 - Added parameter to get length of dbufs packed for partial
257 PRIVATE S16 buildSendIovec ARGS((Buffer *mBuf, MsgLen msgLen,
258 CmInetIovec txArr[], S16 numDBuf,
259 S16 *numIovElems, U32 *strtEndDBufNum,
261 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
263 /* prototypes of new functions needed to send and
264 * process after receiving the extension headers through ancillary data */
266 #ifdef IPV6_SUPPORTED
267 #ifdef IPV6_OPTS_SUPPORTED
268 PRIVATE S16 cmInet6BuildSendHBHOpts ARGS((CmInetIpv6HBHHdrArr *hbhOptsArr,
269 U8 *cmsgBuf, U32 *curMsgIdx,
271 PRIVATE S16 cmInet6BuildSendRouteOpts ARGS((CmInetIpv6RtHdr *rtOptsArr,
272 U8 *cmsgBuf, U32 *curMsgIdx));
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));
285 PRIVATE S16 cmInetBuildSendHoplimit ARGS((U32 hoplimit, U8 *cmsgBuf,
287 #endif /* SS_LINUX */
289 PRIVATE S16 cmInet6BuildSendPktinfo ARGS((CmInetIpAddr6 *srcAddr,
290 U8 *cmsgBuf, U32 *curMsgIdx,
292 #endif /* LOCAL_INTF */
293 #endif /* IPV6_OPTS_SUPPORTED */
294 #endif /* IPV6_SUPPORTED */
296 /* public variable declarations */
298 /* private variable declarations */
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 */
306 /* cm_inet_c_001.main_60 POLL Specific Functions defined */
312 * Desc: Poll on pollfdarr
314 * Ret: Number of File Descriptor Selected
323 PUBLIC S16 cmInetPoll
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 */
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 */
344 if(numFds > CM_INET_POLL_MAXFDSUPP)
347 /* cm_inet_c_001.main_62:Warning fix */
349 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%lu) invalid \n",numFds);
351 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%u) invalid \n",numFds);
353 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
354 #endif /* CMINETDBG */
358 #if (ERRCLASS & ERRCLS_INT_PAR)
359 /* error check on parameters */
360 if (pollFdArr == NULLP)
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 */
369 #endif /* ERRCLASS & ERRCLS_INT_PAR */
371 ret = poll(pollFdArr,numFds,timeout);
378 switch(INET_ERR_CODE)
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);
389 #endif /* CMINETDBG */
392 } /* end of switch */
395 *numRdyFds = (S16)ret;
403 * Fun: cmInetPollSetFd
405 * Desc: Set the selected fd in pollFdArr with event eventMask
407 * Ret: RFAILED : if file descriptor is out of range
408 * ROK : if pollFdArr is set.
417 PUBLIC S16 cmInetPollSetFd
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 */
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 */
433 TRC2(cmInetPollSetFd);
435 if ((idx) >= CM_INET_POLL_MAXFDSUPP || (idx) < 0)
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 */
446 #if (ERRCLASS & ERRCLS_INT_PAR)
447 /* error check on parameters */
448 if (pollFdArr == NULLP)
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 */
457 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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);
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 */
474 /* Setting fd and events with eventMask */
475 pollFdArr[idx].fd = sockFd->fd;
476 pollFdArr[idx].events |= eventMask;
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);
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 */
500 * Fun: cmInetPollFdIsSet
502 * Desc: Checks whether fd is selected
504 * Ret: TRUE : If Fd is Selected
505 * FALSE: If Fd is not Selected
514 PUBLIC S16 cmInetPollFdIsSet
516 CmInetPollFd *pollFdArr, /* poll FD Array */
517 S16 idx, /* poll Fd Array Index */
518 U16 eventMask /* Event Mask to be set */
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 */
529 TRC2(cmInetPollFdIsSet);
531 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
534 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Index (%d) \n",idx);
535 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
536 #endif /* CMINETDBG */
540 #if (ERRCLASS & ERRCLS_INT_PAR)
541 /* error check on parameters */
542 if (pollFdArr == NULLP)
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 */
551 #endif /* ERRCLASS & ERRCLS_INT_PAR */
553 ret = (pollFdArr[idx].revents & eventMask);
560 * Fun: cmInetPollClearFdREvent
562 * Desc: clears the reventMask in revent of the givent FD.
574 PUBLIC S16 cmInetPollClearFdREvent
576 CmInetPollFd *pollFdArr, /* poll FD Array */
577 S16 idx, /* poll Fd Array Index */
578 U16 eventMask /* Event Mask to be set */
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 */
588 TRC2(cmInetPollClearFdREvent);
591 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
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 */
601 #if (ERRCLASS & ERRCLS_INT_PAR)
602 /* error check on parameters */
603 if (pollFdArr == NULLP)
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 */
612 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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);
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 */
628 /* Clearing the events with eventMask */
629 pollFdArr[idx].revents = (pollFdArr[idx].revents & (~(eventMask)));
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);
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 */
652 * Fun: cmInetPollClearFdEvent
654 * Desc: clears the eventMask in event of the givent FD.
666 PUBLIC S16 cmInetPollClearFdEvent
668 CmInetPollFd *pollFdArr, /* poll FD Array */
669 S16 idx, /* poll Fd Array Index */
670 U16 eventMask /* Event Mask to be set */
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 */
680 TRC2(cmInetPollClearFdEvent);
683 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
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 */
693 #if (ERRCLASS & ERRCLS_INT_PAR)
694 /* error check on parameters */
695 if (pollFdArr == NULLP)
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 */
704 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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);
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 */
720 /* Clearing events with eventMask */
721 pollFdArr[idx].events = (pollFdArr[idx].events & (~(eventMask)));
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);
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 */
744 * Fun: cmInetPollDelFd
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.
750 * It deletes fd from array by swapping lastIdx pollFd
751 * values to index to be deleted and deinitializes the
757 * Notes: It does not decrement the lastIdx and it has to be
758 * decremented by the caller of this function.
765 PUBLIC S16 cmInetPollDelFd
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 */
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 */
779 TRC2(cmInetPollDelFd);
781 if(lastIdx < delIdx || lastIdx < 0 || delIdx < 0)
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 */
792 #if (ERRCLASS & ERRCLS_INT_PAR)
793 /* error check on parameters */
794 if (pollFdArr == NULLP)
797 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Parameter (pollFdArr is NULL)");
798 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
799 #endif /* CMINETDBG */
802 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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);
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 */
818 pollFdArr[delIdx].fd = pollFdArr[lastIdx].fd;
819 pollFdArr[delIdx].events = pollFdArr[lastIdx].events;
820 pollFdArr[delIdx].revents = pollFdArr[lastIdx].revents;
822 pollFdArr[lastIdx].fd = -1;
823 pollFdArr[lastIdx].events = 0;
824 pollFdArr[lastIdx].revents = 0;
832 * Fun: cmInetPollInitFdArr
834 * Desc: Cleans all elements of fd array.
839 * Notes: It does not allocates/deallocates memory for Poll Fd Array.
840 * Caller of function has to allocate/deallocate memory for
848 PUBLIC S16 cmInetPollInitFdArr
850 CmInetPollFd *pollFdArr /* poll FD Array */
853 PUBLIC S16 cmInetPollInitFdArr(pollFdArr)
854 CmInetPollFd *pollFdArr; /* poll FD Array */
859 TRC2(cmInetPollInitFdArr);
860 /* Sets each element of pollFdArr to initial value
865 #if (ERRCLASS & ERRCLS_INT_PAR)
866 /* error check on parameters */
867 if (pollFdArr == NULLP)
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 */
876 #endif /* ERRCLASS & ERRCLS_INT_PAR */
878 for(idx=0; idx < CM_INET_POLL_MAXFDSUPP; idx++)
880 pollFdArr[idx].fd = -1;
881 pollFdArr[idx].events = 0;
882 pollFdArr[idx].revents = 0;
887 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
892 * Desc: Allocates dBufs to receive an entire message.
894 * Ret: ROK - successful
896 * ROUTRES - failed, out of resources
905 PRIVATE S16 buildRecvBuf
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 */
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 */
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 */
938 /* Initialise ret and part of msg here */
941 /* added defined(_XPG4_2) */
942 /* Moved initialisation of msg here. */
944 #if (defined(SS_LINUX) || defined(_XPG4_2))
945 msg->msg_control = NULLP;
946 msg->msg_controllen = 0;
948 msg->msg_accrights = NULLP;
949 msg->msg_accrightslen = 0;
950 #endif /* SS_LINUX */
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. */
956 #ifdef T2K_MEM_LEAK_DBG
957 char * file = __FILE__;
959 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
961 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
966 /* Get the data part */
967 ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
970 numBuf++; /* because of cleanup */
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))
981 numBuf++; /* because of cleanup */
987 rxArr[numBuf].iov_base = (Void*)dPtr;
988 rxArr[numBuf].iov_len = (U32)dLen;
990 rxArr[numBuf].iov_base = (S8*)dPtr;
991 rxArr[numBuf].iov_len = dLen;
992 #endif /* SS_LINUX */
997 /* allocate buffer space for entire message length */
1000 if (numBuf >= maxSize)
1002 /* to big to fit in gather vector array */
1006 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
1011 ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
1014 numBuf++; /* because of cleanup */
1018 rxArr[numBuf].iov_base = (Void*)dPtr;
1019 rxArr[numBuf].iov_len = (U32)dLen;
1021 rxArr[numBuf].iov_base = (S8*)dPtr;
1022 rxArr[numBuf].iov_len = dLen;
1023 #endif /* SS_LINUX */
1028 /* adjust last buffer length */
1029 /* check if we broke out because numBuf >= maxSize */
1031 rxArr[numBuf - 1].iov_len = dLen;
1033 rxArr[numBuf - 1].iov_len = dLen - (bufLen - len);
1035 /* setup recvmsg() message header */
1036 msg->msg_iov = rxArr;
1037 msg->msg_iovlen = numBuf;
1043 for (i = 0; i < numBuf; i++)
1044 SPutDBuf(info->region, info->pool, dBuf[i]);
1046 msg->msg_iovlen = 0;
1049 } /* end of buildRecvBuf */
1055 * Desc: Builds a message out of the received dBufs.
1057 * Ret: ROK - successful
1059 * ROUTRES - failed, out of resources
1068 PRIVATE S16 buildRecvMsg
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 */
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 */
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 */
1097 ret = SGetMsg(info->region, info->pool, &mBuf);
1103 /* link buffers to message */
1106 /* cm_inet_c_001.main_58: fix for klockwork issue */
1107 bufLen = (MsgLen)rxArr[i].iov_len;
1108 if (msgLen < bufLen)
1112 ret = SUpdMsg(mBuf, dBufs[i], bufLen);
1130 /* cleanup unused buffers */
1133 #ifdef T2K_MEM_LEAK_DBG
1134 char * file = __FILE__;
1135 U32 line = __LINE__;
1136 SPutDBuf(info->region, info->pool, dBufs[i]);
1138 SPutDBuf(info->region, info->pool, dBufs[i]);
1144 } /* end of buildRecvMsg */
1150 * Fun: buildSendIovec
1152 * Desc: Builds a io vector to send a message.
1154 * Ret: ROK - successful
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.
1167 PRIVATE S16 buildSendIovec
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 */
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 */
1197 /* Initialisations */
1202 /* cm_inet_c_001.main_50 - Intialize the newly added parameter */
1205 /* Set up vector for gathering send */
1206 ret = SInitNxtDBuf(mBuf);
1213 txArr[iovIdx].iov_len = 0;
1215 if ((*strtEndDBufNum != 0))
1217 /* Skip through the required number of dBufs */
1218 dBufsToSkip = *strtEndDBufNum;
1222 ret = SGetNxtDBuf(mBuf, &dBuf);
1231 ret = SGetNxtDBuf(mBuf, &dBuf);
1234 ret = SGetDataTx(dBuf, &dPtr, &dLen);
1241 txArr[iovIdx].iov_base = (S8 *)dPtr;
1242 txArr[iovIdx].iov_len = dLen;
1246 else if (ret == ROKDNA)
1259 if (iovIdx >= numDBufs)
1261 if (allocLen >= msgLen)
1269 (*numIovElems) = iovIdx;
1270 (*strtEndDBufNum) += iovIdx;
1272 /* cm_inet_c_001.main_50 - Assign the value of dbufs packed in IO-vector */
1277 } /* end of buildSendIovec */
1278 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
1285 * Desc: Creates an Internet socket descriptor.
1286 * On default the socket is non-blocking ( can be changed
1287 * with the function cmInetSetOpt()).
1290 * CM_INET_STREAM (TCP)
1291 * CM_INET_DGRAM (UDP)
1293 * Ret: ROK - successful
1303 #ifdef IPV6_SUPPORTED
1304 PUBLIC S16 cmInetSocket
1306 U8 type, /* socket type */
1307 CmInetFd *sockFd, /* socket file descriptor */
1308 U8 protocol, /* protocol value */
1309 U8 domain /* domain */
1312 PUBLIC S16 cmInetSocket
1314 U8 type, /* socket type */
1315 CmInetFd *sockFd, /* socket file descriptor */
1316 U8 protocol /* protocol value */
1318 #endif /* IPV6_SUPPORTED */
1319 #else /* CM_INET2 */
1320 PUBLIC S16 cmInetSocket
1322 U8 type, /* socket type */
1323 CmInetFd *sockFd /* socket file descriptor */
1325 #endif /* 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 */
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 */
1347 S32 ret; /* temporary return value */
1351 #if (defined(WIN32) && defined(WIN2K))
1354 #endif /* WIN2K && WIN32 */
1358 #if (defined(WIN32) && defined(WIN2K))
1360 bNewBehavior = FALSE;
1361 #endif /* WIN32 && WIN2K */
1365 #ifdef IPV6_SUPPORTED
1366 sockFd->fd = socket(domain, type, protocol);
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))
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);
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;
1393 /* set socket type */
1394 sockFd->type = type;
1396 /* set socket protocol type (IPv4/IPv6) */
1397 #ifdef IPV6_SUPPORTED
1398 sockFd->protType = domain;
1399 #endif /* IPV6_SUPPORTED */
1401 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1403 if (protocol != IPPROTO_SCTP)
1406 /* set default options */
1407 optVal = CM_INET_OPT_DISABLE;
1408 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1411 ret = cmInetClose(sockFd);
1416 #ifndef CMINET_BSDCOMPAT
1417 optVal = CM_INET_OPT_ENABLE;
1418 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BSD_COMPAT, (Ptr)&optVal);
1421 ret = cmInetClose(sockFd);
1424 #endif /* CMINET_BSDCOMPAT */
1425 #endif /* SS_LINUX */
1427 #if (defined(WIN32) && defined(WIN2K))
1428 if(type == CM_INET_DGRAM)
1430 ret = WSAIoctl(sockFd->fd, SIO_UDP_CONNRESET, &bNewBehavior,
1431 sizeof(bNewBehavior), NULLP, 0, &bytesReturned,
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);
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);
1453 #endif /* WIN2K && WIN32 */
1454 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1457 #ifdef CM_LKSCTP_NONBLOCK
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
1464 optVal = CM_INET_OPT_DISABLE;
1465 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1468 ret = cmInetClose(sockFd);
1472 #endif /* CM_LKSCTP_NONBLOCK ends */
1475 } /* end of cmInetSocket */
1482 * Desc: Binds a socket file descriptor to a local Internet
1485 * Ret: ROK - successful
1495 PUBLIC S16 cmInetBind
1497 CmInetFd *sockFd, /* socket file descriptor */
1498 CmInetAddr *myAddr /* locale Internet address/port */
1501 PUBLIC S16 cmInetBind(sockFd, myAddr)
1502 CmInetFd *sockFd; /* socket file descriptor */
1503 CmInetAddr *myAddr; /* locale Internet address/port */
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 */
1512 #endif /* CMINETDBG */
1513 #endif /* IPV6_SUPPORTED */
1514 U32 sizeOfAddr; /* sizeof address passed to the bind call */
1515 CmInetSockAddr *sockAddrPtr;
1519 #if (ERRCLASS & ERRCLS_INT_PAR)
1520 /* error check on parameters */
1521 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1526 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1528 #ifdef IPV6_SUPPORTED
1529 if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
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;
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;
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 */
1557 ret = bind(sockFd->fd, sockAddrPtr, sizeOfAddr);
1558 if (ret == INET_ERR)
1561 #ifdef IPV6_SUPPORTED
1562 if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1563 port = myAddr->u.ipv6Addr.port;
1565 port = myAddr->u.ipv4Addr.port;
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);
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*/
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);
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 */
1600 } /* end of cmInetBind */
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 */
1607 * Fun: cmInetSctpBindx
1609 * Desc: Binds a SCTP socket file descriptor to local Internet
1612 * Ret: ROK - successful
1621 PUBLIC S16 cmInetSctpBindx
1623 CmInetFd *sockFd, /* socket file descriptor */
1624 CmInetNetAddrLst *addrLst, /* local Internet address list */
1625 U16 port /* port number */
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 */
1634 S32 ret; /* temporary return value */
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))];
1642 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1643 #endif /* IPV6_SUPPORTED */
1646 Data *tempAddrPtr = NULLP;
1648 U32 addresses_array_size = 0;
1649 #ifdef IPV6_SUPPORTED
1651 S8 *addrString = NULLP;
1653 S8 ipv4Format[23] = "::ffff:";
1654 #endif /* SUN_KSCTP */
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;
1662 #if (ERRCLASS & ERRCLS_INT_PAR)
1663 /* error check on parameters */
1664 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1670 if(addrLst->count > CM_INET_NUM_NET_ADDR)
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);
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 */
1690 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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 */
1697 for (idx = 0; idx < addrLst->count; idx++)
1699 #ifdef IPV6_SUPPORTED
1700 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1702 ipv6_array_size += sizeof(struct sockaddr_in6);
1703 addresses_array_size += sizeof(struct sockaddr_in6);
1704 if (sockFd->protType == AF_INET)
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);
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 */
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));
1732 ipv6_array_size += sizeof(struct sockaddr_in6);
1733 addresses_array_size += sizeof(struct sockaddr_in6);
1734 if (sockFd->protType == AF_INET)
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);
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 */
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);
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);
1769 #endif /* SUN_KSCTP */
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);
1778 #endif /* IPV6_SUPPORTED */
1782 if(ipv4_array_size > 0)
1784 sockAddrPtr = (struct sockaddr*)address_array;
1785 sockAddrLen = sizeof(struct sockaddr_in);
1786 cmMemcpy((U8*)address_array, (U8*)addrs, ipv4_array_size);
1788 #ifdef IPV6_SUPPORTED
1791 sockAddrPtr = (struct sockaddr*)address_array;
1792 sockAddrLen = sizeof(struct sockaddr_in6);
1795 if(ipv6_array_size > 0)
1797 cmMemcpy((U8*)(address_array + ipv4_array_size), (U8*)addrs6, ipv6_array_size);
1799 #endif /* IPV6_SUPPORTED */
1803 ret = bind(sockFd->fd, sockAddrPtr, sockAddrLen);
1804 if (ret == INET_ERR)
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);
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 */
1824 if (addrLst->count > 1)
1826 if(((struct sockaddr*)address_array)->sa_family == AF_INET)
1828 tempAddrPtr = address_array + (sizeof(struct sockaddr_in));
1830 else if(((struct sockaddr*)address_array)->sa_family == AF_INET6)
1832 tempAddrPtr = address_array + (sizeof(struct sockaddr_in6));
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);
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 */
1855 ret = sctp_bindx(sockFd->fd, (Void*)tempAddrPtr, addrLst->count - 1, SCTP_BINDX_ADD_ADDR);
1859 ret = sctp_bindx(sockFd->fd, (struct sockaddr*)address_array, addrLst->count, SCTP_BINDX_ADD_ADDR);
1861 if (ret == INET_ERR)
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);
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 */
1885 * Fun: cmInetSctpConnectx
1887 * Desc: Establishes a sctp connection with remote addresses
1889 * Ret: ROK - successful
1898 PUBLIC S16 cmInetSctpConnectx
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 */
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 */
1915 /* cm_inet_c_001.main_46: Removed SS_LINUX flag */
1918 U32 addresses_array_size = 0;
1920 struct sockaddr_in addrs[CM_INET_NUM_NET_ADDR];
1921 U32 ipv4_array_size = 0;
1923 #ifndef IPV6_SUPPORTED
1924 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1926 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1927 #endif /* IPV6_SUPPORTED */
1929 #ifdef IPV6_SUPPORTED
1931 S8 *addrString = NULLP;
1933 S8 ipv4Format[23] = "::ffff:";
1934 CmInetIpAddr ipv4NetAddr;
1935 #endif /* SUN_KSCTP */
1937 struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1938 U32 ipv6_array_size = 0;
1939 #endif /* IPV6_SUPPORTED */
1941 U32 sockAddrLen = 0;
1942 #endif /* sockAddrLen */
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))
1954 /* cm_inet_c_001.main_58 : Added check for addrLst to fix klockwork issue */
1955 if (addrLst == NULLP)
1959 /* cm_inet_c_001.main_46: Included check for no of address aginst max */
1960 if( addrLst->count > CM_INET_NUM_NET_ADDR )
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);
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 */
1980 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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 */
1990 #ifdef IPV6_SUPPORTED
1991 if (primAddr->type == CM_INET_IPV6ADDR_TYPE)
1993 if (sockFd->protType == AF_INET)
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);
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 */
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);
2022 if (sockFd->protType == AF_INET)
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);
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 */
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);
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);
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);
2067 #endif /* IPV6_SUPPORTED */
2071 /* cm_inet_c_001.main_46: Moved the SS_LINUX flag down,
2072 * copy addresses in Solaris also */
2073 if (addrLst != NULLP)
2075 for (idx = 0; idx < addrLst->count; idx++)
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 )
2082 if ( addrLst->addrs[idx].u.ipv4NetAddr == primAddr->u.ipv4NetAddr )
2087 #ifdef IPV6_SUPPORTED
2088 else if ( addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE )
2090 if (( cmMemcmp(addrLst->addrs[idx].u.ipv6NetAddr,
2091 primAddr->u.ipv6NetAddr, sizeof(CmInetIpAddr6) )) == 0 )
2097 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
2099 if (sockFd->protType == AF_INET)
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);
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 */
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);
2129 if (sockFd->protType == AF_INET)
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);
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 */
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);
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);
2165 #endif /* SUN_KSCTP */
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);
2174 #endif /* IPV6_SUPPORTED */
2175 /*cm_inet_c_001.main_39 */
2180 /* cm_inet_c_001.main_46: Moved SS_LINUX flag to here */
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))))
2186 cmMemcpy((U8*)address_array, (U8*)&addrs[0], ipv4_array_size);
2192 #ifdef IPV6_SUPPORTED
2193 if((ipv6_array_size > 0) && (ipv6_array_size <= (CM_INET_NUM_NET_ADDR * \
2194 sizeof(struct sockaddr_in))))
2196 cmMemcpy((U8*)(address_array + ipv4_array_size), (U8*)addrs6, ipv6_array_size);
2202 #endif /* IPV6_SUPPORTED */
2204 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt);
2208 /* cm_inet_c_001.main_46: Use next provided address to connect if
2209 * first one fails */
2211 #ifdef CMINET_SUN_CONNECTX
2213 #ifdef IPV6_SUPPORTED
2215 #endif /* IPV6_SUPPORTED */
2216 for (idx = 0; idx < cnt; idx++)
2218 if( addrs[idx4].sin_family == AF_INET)
2220 sockAddrPtr = (CmInetSockAddr *)&addrs[idx4];
2221 sockAddrLen = sizeof(struct sockaddr_in);
2224 #ifdef IPV6_SUPPORTED
2227 sockAddrPtr = (CmInetSockAddr *)&addrs6[idx6];
2228 sockAddrLen = sizeof(struct sockaddr_in6);
2231 #endif/* IPV6_SUPPORTED */
2233 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2235 if ( ret != INET_ERR )
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);
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 */
2257 if( addrs[0].sin_family == AF_INET)
2259 sockAddrPtr = (CmInetSockAddr*)&addrs[0];
2260 sockAddrLen = sizeof(struct sockaddr_in);
2263 #ifdef IPV6_SUPPORTED
2266 sockAddrPtr = (CmInetSockAddr*)&addrs6[0];
2267 sockAddrLen = sizeof(struct sockaddr_in6);
2270 #endif/* IPV6_SUPPORTED */
2272 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2274 #endif /* CMINET_SUN_CONNECTX */
2275 #endif /* SS_LINUX */
2277 if (ret == INET_ERR)
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);
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 */
2294 switch (INET_ERR_CODE)
2296 /* non-blocking: connection is in progress */
2297 case ERR_INPROGRESS:
2298 RETVALUE(RINPROGRESS);
2302 * non-blocking: connection is established
2303 * blocking : connection is already established
2309 /* resource temporarily unavailable */
2310 case ERR_WOULDBLOCK:
2314 /* non-blocking: connection is in progress */
2316 RETVALUE(RINPROGRESS);
2320 RETVALUE(RINPROGRESS);
2323 /* Check for connection refused and timeout errors */
2324 case ERR_CONNREFUSED:
2329 /* it is a real error */
2341 * Fun: cmInetSctpPeelOff
2343 * Desc: Branches an existing sctp association off to a seperate socket
2345 * Ret: ROK - successful
2354 PUBLIC S16 cmInetSctpPeelOff
2356 CmInetFd *sockFd, /* socket file descriptor */
2357 U32 assocId, /* association id */
2358 CmInetFdType *assocFd /* association fd */
2361 PUBLIC S16 cmInetSctpPeelOff(sockFd, assocId, assocFd)
2362 CmInetFd *sockFd; /* socket file descriptor */
2363 U32 assocId; /* association id */
2364 CmInetFdType *assocFd; /* association fd */
2369 #if (ERRCLASS & ERRCLS_INT_PAR)
2370 /* error check on parameters */
2371 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) || (assocFd == NULLP))
2375 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2378 ret = sctp_peeloff(sockFd->fd, assocId);
2379 if (ret == INET_ERR)
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);
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 */
2407 * Fun: cmInetSctpSendMsg
2409 * Desc: invokes sctp socket API to send message to the remote addresses
2411 * Ret: ROK - successful
2420 PUBLIC S16 cmInetSctpSendMsg
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 */
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 */
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 */
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
2462 S8 *addrString = NULLP;
2464 S8 ipv4Format[23] = "::ffff:";
2465 CmInetIpAddr ipv4NetAddr;
2466 #endif /* SUN_KSCTP */
2467 struct sockaddr_in6 addr6;
2468 #endif /* IPV6_SUPPORTED */
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))
2477 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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 */
2485 /* copy message to a flat buffer */
2486 ret = SFndLenMsg(mBuf, &bufLen);
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))
2497 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
2502 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
2503 if ((ret != ROK) || (msgLen != bufLen))
2505 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2509 if ( dstAddr != NULLP)
2511 #ifdef IPV6_SUPPORTED
2512 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
2514 if (sockFd->protType == AF_INET)
2516 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
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);
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 */
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;
2544 if (sockFd->protType == AF_INET)
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);
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 */
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;
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 */
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 */
2594 sockAddrPtr = (CmInetSockAddr*)&addr;
2596 /* cm_inet_c_001.main_58 : initialized sockAddrLen properly */
2597 #ifdef IPV6_SUPPORTED
2598 sockAddrLen = sizeof(struct sockaddr_in6);
2600 sockAddrLen = sizeof(struct sockaddr_in);
2604 /* Not validating the address, whether addr is a valid address or not */
2609 if (unorderFlg == TRUE)
2612 flags |= MSG_UNORDERED;
2615 flags |= SCTP_UNORDERED;
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)
2625 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
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);
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 */
2644 if ((INET_ERR_CODE == ERR_AGAIN) || (INET_ERR_CODE == ERR_WOULDBLOCK))
2645 RETVALUE(RWOULDBLOCK);
2646 else if (INET_ERR_CODE == ERR_PIPE)
2652 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2656 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2663 * Fun: cmInetSctpRecvMsg
2665 * Desc: invokes sctp API to get the message received at sctp socket
2667 * Ret: ROK - successful
2676 PUBLIC S16 cmInetSctpRecvMsg
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 */
2689 PUBLIC S16 cmInetSctpRecvMsg(sockFd, srcAddr, port, meminfo, mBuf, len,
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 */
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;
2711 Data *recvbuf = NULLP;
2713 union sctp_notification *sctpNtfy = NULLP;
2714 /* cm_inet_c_001.main_46: Defined new variable to store length of data */
2717 #endif /* SS_LINUX */
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))
2727 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2732 cmMemset((U8*)ntfy, 0, sizeof(CmInetSctpNotification));
2734 buflen = CM_INET_MAX_MSG_LEN;
2736 /* allocate flat receive buffer */
2737 ret = SGetSBuf(meminfo->region, meminfo->pool, &recvbuf, buflen);
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 */
2749 addrlen = sizeof(struct sockaddr_storage);
2751 cmMemset((U8*)&addr, 0, sizeof(struct sockaddr_storage));
2752 cmMemset((U8*)&info, 0, sizeof(struct sctp_sndrcvinfo));
2754 ret = sctp_recvmsg(sockFd->fd, (Void *)recvbuf, (size_t)buflen,
2755 (struct sockaddr*)&addr, &addrlen, &info,
2757 if (ret == INET_ERR)
2760 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
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);
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 */
2779 /* save the length of the received message */
2780 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2783 #ifdef IPV6_SUPPORTED
2784 if (addr.ss_family == AF_INET6)
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);
2790 if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
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);
2799 srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2800 CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr);
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);
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 */
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;
2829 /* fill message flags */
2831 if ((msgFlags & MSG_EOR) != 0)
2832 *flag |= CM_INET_SCTP_MSG_EOR;
2834 if ((msgFlags & MSG_NOTIFICATION) != 0)
2836 *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2839 sctpNtfy = (union sctp_notification*)recvbuf;
2841 ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2842 ntfy->header.nLen = sctpNtfy->sn_header.sn_length;
2844 switch(sctpNtfy->sn_header.sn_type)
2846 case SCTP_ASSOC_CHANGE:
2847 ntfy->header.nType = CM_INET_SCTP_ASSOC_CHANGE;
2848 switch(sctpNtfy->sn_assoc_change.sac_state)
2851 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2853 case SCTP_COMM_LOST:
2854 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2857 ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2859 case SCTP_SHUTDOWN_COMP:
2860 ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2862 case SCTP_CANT_STR_ASSOC:
2863 ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
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;
2873 ntfy->u.assocChange.info = sctpNtfy->sn_assoc_change.sac_info;
2876 case SCTP_PEER_ADDR_CHANGE:
2877 ntfy->header.nType = CM_INET_SCTP_PEER_ADDR_CHANGE;
2878 switch(sctpNtfy->sn_paddr_change.spc_state)
2880 case SCTP_ADDR_AVAILABLE:
2881 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2883 case SCTP_ADDR_UNREACHABLE:
2884 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2886 case SCTP_ADDR_REMOVED:
2887 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2889 case SCTP_ADDR_ADDED:
2890 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2892 case SCTP_ADDR_MADE_PRIM:
2893 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2896 case SCTP_ADDR_CONFIRMED:
2897 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2904 #ifdef IPV6_SUPPORTED
2905 if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
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);
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);
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 */
2924 ntfy->u.paddrChange.error = sctpNtfy->sn_paddr_change.spc_error;
2925 ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2927 case SCTP_REMOTE_ERROR:
2928 ntfy->header.nType = CM_INET_SCTP_REMOTE_ERROR;
2930 ntfy->u.remoteErr.error = sctpNtfy->sn_remote_error.sre_error;
2931 ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2933 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2934 datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2936 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2937 &ntfy->u.remoteErr.data, datlen );
2940 ntfy->u.remoteErr.data = NULLP;
2943 cmMemcpy(ntfy->u.remoteErr.data,\
2944 sctpNtfy->sn_remote_error.sre_data, datlen);
2947 case SCTP_SEND_FAILED:
2948 ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2950 ntfy->u.sndFailed.error = sctpNtfy->sn_send_failed.ssf_error;
2951 ntfy->u.sndFailed.assocId = sctpNtfy->sn_send_failed.ssf_assoc_id;
2953 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2954 datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2956 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2957 &ntfy->u.sndFailed.data, datlen );
2960 ntfy->u.sndFailed.data = NULLP;
2963 cmMemcpy(ntfy->u.sndFailed.data,\
2964 sctpNtfy->sn_send_failed.ssf_data, datlen );
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;
2976 case SCTP_SHUTDOWN_EVENT:
2977 ntfy->header.nType = CM_INET_SCTP_SHUTDOWN_EVENT;
2979 ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2982 case SCTP_ADAPTION_INDICATION :
2985 case SCTP_ADAPTATION_INDICATION :
2987 ntfy->header.nType = CM_INET_SCTP_ADAPTATION_INDICATION;
2990 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
2991 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaption_event.sai_assoc_id;
2994 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
2995 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaptation_event.sai_assoc_id;
2998 case SCTP_PARTIAL_DELIVERY_EVENT:
2999 ntfy->header.nType = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
3001 ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
3002 ntfy->u.pdapiEvt.assocId = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
3010 /* get a message buffer */
3011 ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
3014 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3018 ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
3022 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3028 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3035 * Fun: cmInetSctpGetPAddrs
3037 * Desc: returns the list of peer addresses
3039 * Ret: ROK - successful
3048 PUBLIC S16 cmInetSctpGetPAddrs
3050 CmInetFd *sockFd, /* socket file descriptor */
3051 U32 assocId, /* association id */
3052 CmInetNetAddrLst *addrlst /* peer address list */
3055 PUBLIC S16 cmInetSctpGetPAddrs(sockFd, assocId, addrlst)
3056 CmInetFd *sockFd; /* socket file descriptor */
3057 U32 assocId; /* association id */
3058 CmInetNetAddrLst *addrlst; /* peer address list */
3061 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
3065 struct sockaddr *peerAddrList;
3066 struct sockaddr_in *pAddr;
3067 #ifdef IPV6_SUPPORTED
3068 struct sockaddr_in6 *pAddr6;
3069 #endif /* IPV6_SUPPORTED */
3072 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
3074 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
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);
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 */
3098 byteAddress = (U8*)peerAddrList;
3099 for (idx = 0; idx < cnt; idx++)
3101 #ifdef IPV6_SUPPORTED
3103 if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
3105 if (sockFd->protType == AF_INET)
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);
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 */
3120 sctp_freepaddrs(peerAddrList);
3124 pAddr6 = (struct sockaddr_in6*)byteAddress;
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);
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);
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 */
3145 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
3146 addrlst->count = (U8)cnt;
3148 sctp_freepaddrs(peerAddrList);
3157 * Desc: invokes socket API to retrive specified socket options
3159 * Ret: ROK - successful
3168 PUBLIC S16 cmInetGetOpt
3170 CmInetFd *sockFd, /* socket file descriptor */
3171 U32 level, /* option level */
3172 U32 type, /* option type */
3173 Ptr value /* option value */
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 */
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 */
3207 #if (ERRCLASS & ERRCLS_INT_PAR)
3208 /* error check on parameters */
3209 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3213 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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;
3223 ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
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;
3232 switch (status.sstat_state)
3242 pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3249 pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3255 case SCTPS_COOKIE_WAIT:
3257 case SCTP_COOKIE_WAIT:
3260 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3265 case SCTPS_COOKIE_ECHOED:
3267 case SCTP_COOKIE_ECHOED:
3270 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3275 case SCTPS_ESTABLISHED:
3277 case SCTP_ESTABLISHED:
3280 pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3285 case SCTPS_SHUTDOWN_PENDING:
3287 case SCTP_SHUTDOWN_PENDING:
3290 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3295 case SCTPS_SHUTDOWN_SENT:
3297 case SCTP_SHUTDOWN_SENT:
3300 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3305 case SCTPS_SHUTDOWN_RECEIVED:
3307 case SCTP_SHUTDOWN_RECEIVED:
3310 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3315 case SCTPS_SHUTDOWN_ACK_SENT:
3317 case SCTP_SHUTDOWN_ACK_SENT:
3320 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3331 #ifdef IPV6_SUPPORTED
3332 if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3334 pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3335 pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr6->sin6_port);
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);
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);
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 */
3355 pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3356 if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3357 pSctpStatus->primary.isActive = TRUE;
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;
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;
3372 #ifdef IPV6_SUPPORTED
3373 if (pPeerAddrInfo->addr.type == CM_INET_IPV6ADDR_TYPE)
3375 if (sockFd->protType == AF_INET)
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);
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 */
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);
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);
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 */
3413 /* Not validating the address, whether Addr is a valid address or not */
3415 ret = getsockopt(sockFd->fd, level, SCTP_GET_PEER_ADDR_INFO, &addrInfo, &len);
3417 if (addrInfo.spinfo_state == SCTP_ACTIVE)
3418 pPeerAddrInfo->isActive = TRUE;
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;
3427 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
3429 pPeerAddrParams = (CmInetSctpPeerAddrParams *)value;
3431 cmMemset((U8*)&addrParams, 0, sizeof(struct sctp_paddrparams));
3433 addrParams.spp_assoc_id = pPeerAddrParams->assocId;
3435 if (pPeerAddrParams->s.addrPres == TRUE)
3437 #ifdef IPV6_SUPPORTED
3438 if (pPeerAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
3440 if (sockFd->protType == AF_INET)
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",
3448 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3450 /* cm_inet_c_001.main_62:Warning fix */
3451 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%d)\n",
3453 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3454 #endif /*ALIGN_64BIT*/
3455 #endif /* CMINETDBG */
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);
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);
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 */
3480 #ifdef IPV6_SUPPORTED
3481 if (sockFd->protType == AF_INET6)
3482 addrParams.spp_address.ss_family = AF_INET6;
3484 addrParams.spp_address.ss_family = AF_INET;
3486 addrParams.spp_address.ss_family = AF_INET;
3490 len = sizeof(addrParams);
3492 ret = getsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, &len);
3493 /* cm_inet_c_001.main_41 : Fixed the Solaris compilation problem */
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;
3502 if (addrParams.spp_flags & SPP_HB_ENABLE)
3503 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_ENABLE;
3505 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_DISABLE;
3507 if (addrParams.spp_flags & SPP_PMTUD_ENABLE)
3508 pPeerAddrParams->pmtudFlag = CM_INET_OPT_ENABLE;
3510 pPeerAddrParams->pmtudFlag = CM_INET_OPT_DISABLE;
3512 if (addrParams.spp_flags & SPP_SACKDELAY_ENABLE)
3513 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_ENABLE;
3515 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_DISABLE;
3520 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
3522 pAssocParams = (CmInetSctpAssocParams *)value;
3524 cmMemset((U8*)&assocParams, 0, sizeof(struct sctp_assocparams));
3526 assocParams.sasoc_assoc_id = pAssocParams->assocId;
3528 len = sizeof(assocParams);
3530 ret = getsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, &len);
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;
3541 case CM_INET_OPT_SCTP_RTO_INFO:
3543 pRtoInfo = (CmInetSctpRtoInfo *)value;
3545 cmMemset((U8*)&rtoInfo, 0, sizeof(struct sctp_rtoinfo));
3547 len = sizeof(rtoInfo);
3549 ret = getsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoInfo, &len);
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;
3558 case CM_INET_OPT_SCTP_INIT_MSG:
3560 pInitMsg = (CmInetSctpInitMsg *)value;
3562 cmMemset((U8*)&initMsg, 0, sizeof(struct sctp_initmsg));
3564 len = sizeof(initMsg);
3566 ret = getsockopt(sockFd->fd, level, SCTP_INITMSG, &initMsg, &len);
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;
3579 if (ret == INET_ERR)
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);
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 */
3601 /* cm_inet_c_001.main_54: Added new function cmInetShutDownSctp()*/
3604 * Fun: cmInetShutDownSctp
3606 * Desc: Shutdown the SCTP association gracefully.
3608 * Ret: ROK - successful
3617 PUBLIC S16 cmInetShutDownSctp
3619 CmInetFd *sockFd /* socket file descriptor */
3622 PUBLIC S16 cmInetShutDownSctp(sockFd)
3623 CmInetFd *sockFd; /* socket file descriptor */
3626 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3628 struct sctp_sndrcvinfo sndRcvInfo;
3630 TRC2(cmInetShutDownSctp);
3632 cmMemset((U8*)&sndRcvInfo, 0, sizeof(sndRcvInfo));
3635 sndRcvInfo.sinfo_flags = MSG_EOF;
3637 sndRcvInfo.sinfo_flags = SCTP_EOF;
3640 /* Call the sctp_send with flag set to termiante the association */
3642 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
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);
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 */
3666 /* cm_inet_c_001.main_61: Added new function cmInetAbortSctpAssoc()*/
3669 * Fun: cmInetAbortSctpAssoc
3671 * Desc: ABORT the association.
3673 * Ret: ROK - successful
3682 PUBLIC S16 cmInetAbortSctpAssoc
3684 CmInetFd *sockFd, /* socket file descriptor */
3685 UConnId assocId /* Association ID */
3688 PUBLIC S16 cmInetAbortSctpAssoc(sockFd, assocId)
3689 CmInetFd *sockFd; /* socket file descriptor */
3690 UConnId assocId; /* Association ID */
3694 struct sctp_sndrcvinfo sndRcvInfo;
3696 TRC2(cmInetAbortSctpAssoc);
3698 cmMemset((U8*)&sndRcvInfo, 0, sizeof(sndRcvInfo));
3701 sndRcvInfo.sinfo_flags = MSG_ABORT;
3703 sndRcvInfo.sinfo_flags = SCTP_ABORT;
3706 sndRcvInfo.sinfo_assoc_id = assocId;
3708 /* Call the sctp_send with flag set to termiante the association */
3710 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
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);
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 */
3739 * Fun: cmInetConnect
3741 * Desc: Establishs a connection to a foreign address (TCP) or associates
3742 * a UDP socket to a foreign address.
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)
3757 PUBLIC S16 cmInetConnect
3759 CmInetFd *sockFd, /* socket file descriptor */
3760 CmInetAddr *servAddr /* foreign Internet address/port */
3763 PUBLIC S16 cmInetConnect(sockFd, servAddr)
3764 CmInetFd *sockFd; /* socket file descriptor */
3765 CmInetAddr *servAddr; /* foreign Internet address/port */
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 */
3774 #endif /* CMINETDBG */
3775 #endif /* IPV6_SUPPORTED */
3777 CmInetSockAddr *sockAddrPtr;
3779 TRC2(cmInetConnect);
3781 #if (ERRCLASS & ERRCLS_INT_PAR)
3782 /* error check on parameters */
3783 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3784 (servAddr == NULLP))
3788 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3790 #ifdef IPV6_SUPPORTED
3791 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
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;
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;
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 */
3819 ret = connect(sockFd->fd, sockAddrPtr, sizeOfAddr);
3820 if (ret == INET_ERR)
3822 switch (INET_ERR_CODE)
3824 /* non-blocking: connection is in progress */
3825 case ERR_INPROGRESS:
3826 RETVALUE(RINPROGRESS);
3830 * non-blocking: connection is established
3831 * blocking : connection is already established
3837 /* resource temporarily unavailable */
3838 case ERR_WOULDBLOCK:
3842 /* non-blocking: connection is in progress */
3844 RETVALUE(RINPROGRESS);
3848 RETVALUE(RINPROGRESS);
3851 /* Check for connection refused and timeout errors */
3852 case ERR_CONNREFUSED:
3857 /* it is a real error */
3860 #ifdef IPV6_SUPPORTED
3861 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3862 port = servAddr->u.ipv6Addr.port;
3864 port = servAddr->u.ipv4Addr.port;
3866 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
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);
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*/
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);
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 */
3901 } /* end of cmInetConnect */
3908 * Desc: Indicates the willingness of a socket to listen for incomming
3909 * connection requests.
3911 * Ret: ROK - successful
3914 * Notes: The backLog value has to be within 0..5
3921 PUBLIC S16 cmInetListen
3923 CmInetFd *sockFd, /* socket file descriptor */
3924 S16 backLog /* max. number of outstandig connections 0..5 */
3927 PUBLIC S16 cmInetListen(sockFd, backLog)
3928 CmInetFd *sockFd; /* socket file descriptor */
3929 S16 backLog; /* max. number of outstandig connections 0..5 */
3932 S32 ret; /* temporary return value */
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))
3943 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3945 ret = listen(sockFd->fd, backLog);
3946 if (ret == INET_ERR)
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);
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 */
3966 } /* end of cmInetListen */
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().
3977 * Ret: ROK - successful
3978 * ROKDNA - there is no connection present to accept (only
3989 PUBLIC S16 cmInetAccept
3991 CmInetFd *sockFd, /* socket file descriptor */
3992 CmInetAddr *fromAddr, /* calling Internet address/port */
3993 CmInetFd *newSockFd /* socket file descriptor for new connection*/
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*/
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;
4009 CmInetSockAddr sockAddr;
4010 #endif /* IPV6_SUPPORTED */
4017 #if (ERRCLASS & ERRCLS_INT_PAR)
4018 /* error check on parameters */
4019 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
4023 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4025 /* change CmInetSockAddr to sockAddr */
4026 addrLen = sizeof(sockAddr);
4029 #if ( defined(SUNOS) || defined(SS_LINUX))
4030 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
4031 (socklen_t *)&addrLen);
4033 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
4035 #endif /* SUNOS || SS_LINUX */
4037 /* cm_inet_c_001.main_58: Moved setting of protType below */
4039 if (CM_INET_INV_SOCK_FD(newSockFd))
4041 if (INET_ERR_CODE == ERR_WOULDBLOCK)
4043 /* no connection present to accept */
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);
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 */
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;
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);
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 */
4089 #endif /* IPV6_SUPPORTED */
4091 /* set the new socket file descriptor type */
4092 newSockFd->type = CM_INET_STREAM;
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);
4099 ret = cmInetClose(newSockFd);
4103 #ifdef IPV6_SUPPORTED
4104 cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
4105 if (addrLen == sizeof(struct sockaddr_in))
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);
4113 else if (addrLen == sizeof(struct sockaddr_in6))
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);
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 */
4127 } /* end of cmInetAccept */
4132 * Fun: cmInet4FillTos
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.
4147 PRIVATE S16 cmInet4FillTos
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 */
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 */
4160 struct cmsghdr *tempHdr;
4163 TRC2(cmInet4FillTos)
4168 /* cmsghdr struc will appear before data in the ancillary data object.
4169 * So put cmsghdr struc in flat buffer first. */
4171 /* cmsghdr struc points to flat buffer's starting address */
4172 tempHdr = (struct cmsghdr *)cmsgBuf;
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);
4181 /* fill up the length of cmsghdr structure */
4182 tempHdr->cmsg_len = len;
4187 }/* end of cmInet4FillTos */
4190 * Fun: cmInetSendDscpMsg
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
4198 * Values for flag parameter:
4200 * CM_INET_NO_FLAG - no additional control flag
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
4208 * Notes: The successful completion of a send call does not indicate that
4209 * the data has been successfully delivered!
4211 * This function does not free any sent buffers.
4219 PUBLIC S16 cmInetSendDscpMsg
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 */
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 */
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 */
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 */
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 */
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 */
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))
4287 TRC2(cmInetSendDscpMsg)
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))
4298 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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 */
4306 #endif /* WIN32 | CMINETFLATBUF */
4308 msgLen = 0; /* need by CC to pass without warning */
4309 sockAddrPtr = NULLP;
4312 /* setup remote address */
4313 if (dstAddr != NULLP)
4315 #ifdef IPV6_SUPPORTED
4316 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
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;
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;
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 */
4346 #if (defined(WIN32) || defined(CMINETFLATBUF))
4347 /* copy message to a flat buffer */
4348 ret = SFndLenMsg(mBuf, &bufLen);
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))
4359 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4364 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4365 if ((ret != ROK) || (msgLen != bufLen))
4368 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4372 if (dstAddr == NULLP)
4374 /* VxWorks sendto has some problem
4375 * with connected UDP socket, use send */
4377 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4380 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4381 #endif /* end of SS_VW */
4384 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4386 #if (defined(SS_VW) && defined(SS_VW6_7))
4387 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4389 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4392 #endif /* end of SS_VW6_7 and SS_VW */
4394 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4395 sockAddrPtr, sizeOfAddr);
4398 if (ret == INET_ERR)
4401 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4403 if(INET_ERR_CODE == ERR_AGAIN)
4406 RETVALUE(RWOULDBLOCK);
4409 /* Check for ERR_WOULDBLOCK */
4410 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4413 RETVALUE(RWOULDBLOCK);
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);
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 */
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))
4435 RETVALUE(RNETFAILED);
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))
4453 /* check if entire message could be sent */
4458 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4459 RETVALUE(RWOULDBLOCK);
4463 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4465 #else /* end of Win NT/flat buffer specific part */
4466 ret = SFndLenMsg(mBuf, &msgLen);
4473 /* cmMemset((U8*)&msg, 0, sizeof(msg)); */
4476 if (dstAddr != NULLP)
4479 msg.msg_name = (Void*)sockAddrPtr;
4482 msg.msg_name = (char *)sockAddrPtr;
4484 msg.msg_name = (caddr_t)sockAddrPtr;
4486 #endif /* SS_LINUX */
4487 msg.msg_namelen = sizeOfAddr;
4491 msg.msg_name = NULLP;
4492 msg.msg_namelen = 0;
4494 /* added defined(_XPG4_2) */
4495 #if (defined(SS_LINUX) || defined(_XPG4_2))
4496 msg.msg_control = NULLP;
4497 msg.msg_controllen = 0;
4499 msg.msg_accrights = 0;
4500 msg.msg_accrightslen = NULLP;
4501 #endif /* SS_LINUX */
4503 /* allocate scatter vector */
4504 numDBufs = CM_INET_MAX_DBUF;
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))
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 */
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))
4524 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4526 cmInetBuildSendHoplimit((U32)ipHdrParams->u.ipv6HdrParm.ttl.val,
4527 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
4529 #endif /* SS_LINUX */
4532 /* have to decide how to get the src addr to add in in6_pktinfo */
4533 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4535 cmInet6BuildSendPktinfo(
4536 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4537 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx,
4540 #endif /* LOCAL_INTF */
4542 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4543 * cmsgData one by one. */
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);
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);
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);
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 */
4573 #endif /* IPV6_OPTS_SUPPORTED */
4575 /* Loop till all the data is sent or till the sendmsg call cannot send
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);
4588 /* Incase of UDP/RAW messages call SCompressMsg. */
4589 if (sockFd->type != CM_INET_STREAM)
4591 /* Compress the message into a single dBuf */
4592 ret = SCompressMsg(mBuf);
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);
4611 msg.msg_iov = txArr;
4617 extern int ntl_hLib;
4618 if ( sockFd->fd >= 0xD001)
4619 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4621 ret = sendmsg(sockFd->fd, &msg, 0);
4624 ret = sendmsg(sockFd->fd, &msg, 0);
4626 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4627 if (ret == INET_ERR)
4629 if((INET_ERR_CODE == ERR_AGAIN) ||
4630 (INET_ERR_CODE == ERR_WOULDBLOCK))
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);
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);
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 */
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))
4655 RETVALUE(RNETFAILED);
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))
4669 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
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
4676 RETVALUE(RWOULDBLOCK);
4680 } while (*len < msgLen);
4681 #endif /* WIN32 | CMINETFLATBUF */
4685 } /* end of cmInetSendDscpMsg */
4689 * Fun: cmInetSendMsg
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
4697 * Values for flag parameter:
4699 * CM_INET_NO_FLAG - no additional control flag
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
4707 * Notes: The successful completion of a send call does not indicate that
4708 * the data has been successfully delivered!
4710 * This function does not free any sent buffers.
4718 PUBLIC S16 cmInetSendMsg
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 */
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 */
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 */
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 */
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 */
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 */
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 */
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))
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))
4810 #endif /* ERRCLASS & ERRCLS_INT_PAR */
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
4819 #endif /* IPV6_SUPPORTED */
4820 #endif /* WIN32 | CMINETFLATBUF */
4822 msgLen = 0; /* need by CC to pass without warning */
4823 sockAddrPtr = NULLP;
4826 /* setup remote address */
4827 if (dstAddr != NULLP)
4829 #ifdef IPV6_SUPPORTED
4830 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
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;
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;
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 */
4860 #if (defined(WIN32) || defined(CMINETFLATBUF))
4861 /* copy message to a flat buffer */
4862 ret = SFndLenMsg(mBuf, &bufLen);
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))
4873 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4878 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4879 if ((ret != ROK) || (msgLen != bufLen))
4882 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4886 if (dstAddr == NULLP)
4888 /* VxWorks sendto has some problem
4889 * with connected UDP socket, use send */
4891 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4894 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4895 #endif /* end of SS_VW */
4898 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4900 #if (defined(SS_VW) && defined(SS_VW6_7))
4901 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4903 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4906 #endif /* end of SS_VW6_7 and SS_VW */
4908 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4909 sockAddrPtr, sizeOfAddr);
4912 if (ret == INET_ERR)
4915 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4917 if(INET_ERR_CODE == ERR_AGAIN)
4920 RETVALUE(RWOULDBLOCK);
4923 /* Check for ERR_WOULDBLOCK */
4924 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4927 RETVALUE(RWOULDBLOCK);
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);
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 */
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))
4949 RETVALUE(RNETFAILED);
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))
4967 /* check if entire message could be sent */
4972 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4973 RETVALUE(RWOULDBLOCK);
4977 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4979 #else /* end of Win NT/flat buffer specific part */
4980 ret = SFndLenMsg(mBuf, &msgLen);
4987 /* cmMemset((U8*)&msg, 0, sizeof(msg)); */
4990 if (dstAddr != NULLP)
4993 msg.msg_name = (Void*)sockAddrPtr;
4996 msg.msg_name = (char *)sockAddrPtr;
4998 msg.msg_name = (caddr_t)sockAddrPtr;
5000 #endif /* SS_LINUX */
5001 msg.msg_namelen = sizeOfAddr;
5005 msg.msg_name = NULLP;
5006 msg.msg_namelen = 0;
5008 /* added defined(_XPG4_2) */
5009 #if (defined(SS_LINUX) || defined(_XPG4_2))
5010 msg.msg_control = NULLP;
5011 msg.msg_controllen = 0;
5013 msg.msg_accrights = 0;
5014 msg.msg_accrightslen = NULLP;
5015 #endif /* SS_LINUX */
5017 /* allocate scatter vector */
5018 numDBufs = CM_INET_MAX_DBUF;
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))
5030 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
5032 cmInetBuildSendHoplimit((U32)ipHdrParams->u.ipv6HdrParm.ttl.val,
5033 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
5035 #endif /* SS_LINUX */
5038 /* have to decide how to get the src addr to add in in6_pktinfo */
5039 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
5041 cmInet6BuildSendPktinfo(
5042 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
5043 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx,
5046 #endif /* LOCAL_INTF */
5048 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
5049 * cmsgData one by one. */
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);
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);
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);
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 */
5079 #endif /* IPV6_OPTS_SUPPORTED */
5081 /* Loop till all the data is sent or till the sendmsg call cannot send
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);
5094 /* Incase of UDP/RAW messages call SCompressMsg. */
5095 if (sockFd->type != CM_INET_STREAM)
5097 /* Compress the message into a single dBuf */
5098 ret = SCompressMsg(mBuf);
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);
5117 msg.msg_iov = txArr;
5123 extern int ntl_hLib;
5124 if ( sockFd->fd >= 0xD001)
5125 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
5127 ret = sendmsg(sockFd->fd, &msg, 0);
5130 ret = sendmsg(sockFd->fd, &msg, 0);
5132 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
5133 if (ret == INET_ERR)
5135 if((INET_ERR_CODE == ERR_AGAIN) ||
5136 (INET_ERR_CODE == ERR_WOULDBLOCK))
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);
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);
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 */
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))
5161 RETVALUE(RNETFAILED);
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))
5175 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
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
5182 RETVALUE(RWOULDBLOCK);
5186 } while (*len < msgLen);
5187 #endif /* WIN32 | CMINETFLATBUF */
5191 } /* end of cmInetSendMsg */
5194 /* added new functions for IPv6 extension headers */
5195 #ifdef IPV6_OPTS_SUPPORTED
5199 * Fun: cmInet6BuildSendPktinfo
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.
5214 PRIVATE S16 cmInet6BuildSendPktinfo
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 */
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 */
5229 struct cmsghdr *tempHdr;
5230 struct in6_pktinfo *ipv6Pktinfo;
5231 struct in6_addr lpBkAddr;
5234 TRC2(cmInet6BuildSendPktinfo)
5238 lpBkAddr = in6addr_loopback;
5240 /* cmsghdr struc will appear before data in the ancillary data object.
5241 * So put cmsghdr struc in flat buffer first. */
5243 /* cmsghdr struc points to flat buffer's starting address */
5244 tempHdr = (struct cmsghdr *)cmsgBuf;
5246 /* fill up level & type of cmsghdr structure */
5247 if (protType == AF_INET6)
5249 tempHdr->cmsg_level = IPPROTO_IPV6;
5250 tempHdr->cmsg_type = IPV6_PKTINFO;
5253 else if(protType == AF_INET)
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);
5263 /* skip length of cmsghdr structure - 12 bytes */
5264 len += sizeof(struct cmsghdr);
5266 if(protType == AF_INET6)
5267 ipv6Pktinfo = (struct in6_pktinfo *)(cmsgBuf + len);
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);
5279 /* insert the hoplimit. This will override the kernel's
5280 * default hoplimit value */
5281 if(protType == AF_INET6)
5283 /* store ipv6 src addr */
5284 cmMemcpy((U8 *)&(ipv6Pktinfo->ipi6_addr), (U8 *)srcAddr, 16);
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;
5295 else if(protType == AF_INET)
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);
5305 /* fill up the length of cmsghdr structure */
5306 tempHdr->cmsg_len = len;
5311 }/* end of cmInet6BuildSendPktinfo */
5312 #endif /* LOCAL_INTF */
5318 * Fun: cmInetBuildSendHoplimit
5320 * Desc: This function inserts hoplimit value to be sent out by ancillary
5321 * data by calling sendmsg()function.
5332 PRIVATE S16 cmInetBuildSendHoplimit
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 */
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 */
5345 struct cmsghdr *tempHdr;
5348 TRC2(cmInetBuildSendHoplimit)
5352 /* cmsghdr struc will appear before data in the ancillary data object.
5353 * So put cmsghdr struc in flat buffer first. */
5355 /* cmsghdr struc points to flat buffer's starting address */
5356 tempHdr = (struct cmsghdr *)cmsgBuf;
5358 /* fill up level & type of cmsghdr structure */
5359 tempHdr->cmsg_level = IPPROTO_IPV6;
5360 tempHdr->cmsg_type = IPV6_HOPLIMIT;
5362 /* skip cmsghdr struc (length of cmsghdr structure) */
5363 len += sizeof(struct cmsghdr);
5365 /* insert the hoplimit. This will override the kernel's
5366 * default hoplimit value */
5367 *(cmsgBuf + len) = hoplimit;
5368 len += sizeof(hoplimit);
5370 /* fill up the length of cmsghdr structure */
5371 tempHdr->cmsg_len = len;
5375 } /* end of cmInetBuildSendHoplimit */
5376 #endif /* SS_LINUX */
5381 * Fun: cmInet6BuildSendHBHOpts
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.
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()
5396 * Notes: This function will also be used for Destination options
5403 PRIVATE S16 cmInet6BuildSendHBHOpts
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 */
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 */
5418 struct cmsghdr *tempHdr;
5422 TRC2(cmInet6BuildSendHBHOpts)
5427 /* cmsghdr struc will appear before data in the ancillary data object.
5428 * So put cmsghdr struc in flat buffer first. */
5430 /* cmsghdr struc points to flat buffer's starting address */
5431 tempHdr = (struct cmsghdr *)cmsgBuf;
5433 /* fill up level & type of cmsghdr structure */
5436 tempHdr->cmsg_level = IPPROTO_IPV6;
5437 tempHdr->cmsg_type = IPV6_HOPOPTS;
5439 else if (hdrId == 1)
5441 tempHdr->cmsg_level = IPPROTO_IPV6;
5442 tempHdr->cmsg_type = IPV6_DSTOPTS;
5445 /* skip cmsghdr struc (length of cmsghdr structure) */
5446 len += (sizeof(tempHdr->cmsg_level) + sizeof(tempHdr->cmsg_len) +
5447 sizeof(tempHdr->cmsg_type));
5449 /* Next Hdr: will be fill up accordingly by Kernel */
5450 *(cmsgBuf + len) = 0x00;
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;
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;
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);
5468 /* copy length field of every HBH/dest option */
5469 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].length;
5470 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].length);
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;
5479 /* cuMsgIdx will have the total length of HBH options array */
5480 /* add this length to the length of cmsgHdr struc */
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. */
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 */
5493 *(cmsgBuf + len) = 0x01;
5495 *(cmsgBuf + len) = 0x00;
5499 /* fill up the length of cmsghdr structure */
5500 tempHdr->cmsg_len = len;
5504 } /* end of cmInet6BuildSendHBHOpts */
5509 * Fun: cmInet6BuildSendRouteOpts
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
5526 PRIVATE S16 cmInet6BuildSendRouteOpts
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 */
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 */
5539 struct cmsghdr *tempHdr;
5540 CmInetIpv6RtHdr0 *tempRtHdr;
5544 TRC2(cmInet6BuildSendRouteOpts);
5549 /* cmsghdr struc will appear before data in the ancillary data object.
5550 * So put cmsghdr struc in flat buffer first */
5552 /* cmsghdr struc points to flat buffer */
5553 tempHdr = (struct cmsghdr *)(cmsgBuf);
5555 tempHdr->cmsg_level = IPPROTO_IPV6;
5556 tempHdr->cmsg_type = IPV6_RTHDR;
5558 /* skip cmsghdr structure */
5559 len += sizeof(struct cmsghdr);
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);
5565 /* attach route hdr type 0 after cmsghdr structure */
5566 tempRtHdr = (CmInetIpv6RtHdr0 *)(cmsgBuf + len);
5568 /* fill up fields of route hdr type 0 */
5570 /* will be filled up by Kernel */
5571 tempRtHdr->ip6r0_nextHdr = 0x00;
5573 tempRtHdr->ip6r0_hdrExtLen = (2 * rtOptsArr->numAddrs);
5575 /* only type supported today */
5576 tempRtHdr->ip6r0_type = 0x00;
5578 tempRtHdr->ip6r0_segLeft = rtOptsArr->numAddrs;
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 */
5585 tempRtHdr->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5587 /* move pointer in the flat buffer to the end of this structure */
5588 len += sizeof(CmInetIpv6RtHdr0);
5590 /* fill up all IPV6 addresses from rtOptsArr in the flat buffer */
5591 for (addrIdx = 0; addrIdx < rtOptsArr->numAddrs; addrIdx++)
5593 cmMemcpy((U8 *)(cmsgBuf + len),
5594 (U8 *)(rtOptsArr->ipv6Addrs[addrIdx]), 16);
5600 } /* end of cmInet6BuildSendRouteOpts */
5605 * Fun: cmInet6BuildRecvHopOptsArr
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.
5612 * Ret: ROK - successful
5622 PRIVATE S16 cmInet6BuildRecvHopOptsArr
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 */
5631 PRIVATE S16 cmInet6BuildRecvHopOptsArr(cmsgData, hbhDataLen, hbhOptsArr, hdrId,
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 */
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 */
5647 TRC2(cmInet6BuildRecvHopOptsArr)
5649 /* get length of actual hbh ancillary data */
5650 hbhDataLen -= sizeof(struct cmsghdr);
5656 /* skip Next Hdr byte & Hdr Ext Length byte */
5659 /* First find out how many hop-by-hop headers we need to allocate */
5662 /* break when all HBH data is copied to hbhOptsArr */
5663 if (curDataIdx >= hbhDataLen)
5669 tempType = *(U8 *)(cmsgData + curDataIdx);
5672 /* take care of pad1 option */
5675 /* not considering the pad1 as valid option */
5681 tempLen = *(U8 *)(cmsgData + curDataIdx);
5683 /* 1 is to skip length. tempLen to skip the value field */
5684 curDataIdx += (1 + tempLen);
5686 /* considering the padN as valid option for Dest Opt Hdr!!! As this is
5687 * the "only" valid option today. Ignore for HBH hdr */
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));
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 */
5711 /* skip Next Hdr byte & Hdr Ext Length byte */
5714 hbhOptsArr->numHBHOpts = numOpts;
5716 /* fill up HBH/dest opt array from recvd ancillary data */
5719 /* break when all HBH data is copied to hbhOptsArr */
5720 if (curDataIdx >= hbhDataLen)
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. */
5727 /* get the type of current HBH/dest option */
5728 tempType = *(cmsgData + curDataIdx);
5731 /* ignore PAD1 for both HBH/dest by skipping to next option */
5735 /* calculate how much to skip for padN in case of HBH */
5740 /* get the length field of padN option */
5741 tempLen = *(cmsgData + curDataIdx);
5744 /* move pointer forward to skip value field */
5745 curDataIdx += tempLen;
5749 hbhOptsArr->hbhOpts[optsIdx].type = tempType;
5751 /* copy the length */
5752 hbhOptsArr->hbhOpts[optsIdx].length = *(cmsgData + curDataIdx);
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;
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);
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 --)
5778 if (hbhOptsArr->hbhOpts[optsIdx - 1].value != NULLP)
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);
5791 /* clean up all CmInetIpv6HBHHdr structures allocated for all
5792 * arrived HBH options OR numOpts CmInetIpv6HBHHdr structures
5793 * allocated after counting numOpts */
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;
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;
5813 /* get next option */
5817 } /* end of cmInet6BuildRecvHopOptsArr() */
5822 * Fun: cmInet6BuildRecvRtHdr
5824 * Desc: This function fills up the Route Header in the cmInetIpv6HdrParm
5825 * from the recvd ancillary data from recvmsg system call.
5827 * Ret: ROK - successful
5837 PRIVATE S16 cmInet6BuildRecvRtHdr
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 */
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 */
5854 U32 curDataIdx; /* to keep track where we are in hbh Data */
5855 U8 i; /* loop counter */
5856 S16 ret; /* temporary return value */
5858 TRC2(cmInet6BuildRecvRtHdr)
5860 /* byte len of actual rtHdr ancil data */
5861 rtDataLen -= sizeof(struct cmsghdr);
5863 /* start from beginning */
5866 /* copy next header byte */
5867 rtHdr0->ip6r0_nextHdr = *(cmsgData + curDataIdx);
5870 /* copy header extension length byte */
5871 rtHdr0->ip6r0_hdrExtLen = *(cmsgData + curDataIdx);
5874 /* copy type byte (always 0) */
5875 rtHdr0->ip6r0_type = 0x00;
5878 /* copy segment left byte */
5879 rtHdr0->ip6r0_segLeft = *(cmsgData + curDataIdx);
5882 /* copy 1 reserve byte + 3 strict/loose bytes */
5883 cmMemcpy((U8 *)(&rtOptsArr->slMap),
5884 (U8 *)(cmsgData + curDataIdx), 4);
5887 /* also save reserv byte + 3 sl bytes to rtHdro struc */
5888 rtHdr0->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5890 /* subtract 8 bytes for Next Hdr, Hdr Ext Len, .... + SL bit map */
5891 rtOptsArr->numAddrs = (rtDataLen - 8)/16;
5893 ret = SGetSBuf(info->region, info->pool,
5894 (Data **)&rtOptsArr->ipv6Addrs,
5895 (Size)rtOptsArr->numAddrs * 16);
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 */
5907 /* copy all the ipv6 addresses */
5908 for(i=0; i < rtOptsArr->numAddrs; i++)
5910 cmMemcpy((U8 *)(rtOptsArr->ipv6Addrs[i]),
5911 (U8 *)(cmsgData + curDataIdx), 16);
5916 } /* end of cmInet6BuildRecvRtHdr() */
5921 * Fun: cmInet6GetHopLimitValue
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.
5927 * Ret: ROK - successful
5936 PRIVATE S16 cmInet6GetHopLimitValue
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 */
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 */
5949 U16 curDataIdx; /* to keep track where we are in the ancillary Data */
5950 U32 *hopLimitValue; /* ttl/hoplimit value */
5952 hopLimitValue = NULL;
5955 /* get length of actual hbh ancillary data */
5956 hopLimitDataLen -= sizeof(struct cmsghdr);
5958 /* go to the first byte of hop limit which present after cmsghdr struc */
5959 curDataIdx += sizeof(struct cmsghdr);
5961 /* mark that hoplimit(ttl) is present */
5962 ipv6HdrParam->ttl.pres = TRUE;
5964 /* the first byte will be the HopLimit value */
5965 hopLimitValue = (U32 *)(cmsgData);
5966 ipv6HdrParam->ttl.val = (U8)(*hopLimitValue);
5970 #endif /* IPV6_OPTS_SUPPORTED */
5975 * Fun: cmInetRecvMsg
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
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:
5987 * CM_INET_NO_FLAG - no additional control flag
5988 * CM_INET_MSG_PEEK - do not destroy data on receive buffer
5990 * Ret: ROK - successful
5991 * ROKDNA - ok, data not available
5992 * RCLOSED - connection closed by peer
5993 * ROUTRES - failed, out of resources
6002 PUBLIC S16 cmInetRecvMsg
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 */
6014 CmInetLocalInf *localIf, /* local interface on which pkt was recvd */
6015 #endif /* LOCAL_INTF */
6016 S32 flags /* additional control flags */
6019 /* added for IPv6 */
6020 #ifdef IPV6_OPTS_SUPPORTED
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 */
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 */
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 */
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 */
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 */
6079 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6080 #endif /* IPV6_SUPPORTED */
6082 S32 ret; /* temporary return value */
6083 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
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 */
6096 /* cm_inet_c_001.main_55: As remAddrLen is only being used when
6097 * WIN32 or CMINETFLATBUF is defined, then Removed variable
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 */
6109 struct in6_pktinfo *pkt6Info; /* IPv6 IP_PKTINFO */
6110 #endif /* LOCAL_INTF */
6112 #if (defined(SS_LINUX) || defined(_XPG4_2))
6113 U8 ancillData[CM_INET_IPV6_ANCIL_DATA];
6114 /* from stack for IPv6 ancill data */
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 */
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 */
6129 struct in_pktinfo *pkt4Info; /* IPv4 IP_PKTINFO */
6131 #endif /* SS_LINUX */
6132 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6133 struct cmsghdr *cmsgptr;/* pointer to struct cmsghdr */
6135 #endif /* WIN32 | CMINETFLATBUF */
6136 /* used by getsockopt */
6138 /* cm_inet_c_001.main_55:Removed unused variables errValue and optLen */
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))
6149 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6153 /*cm_inet_c_001.main_48 variables declaration */
6154 #if !((defined(WIN32) || defined(CMINETFLATBUF)))
6159 #if (defined(WIN32) || defined(CMINETFLATBUF))
6161 #ifdef IPV6_SUPPORTED
6163 #endif /* IPV6_SUPPORTED */
6165 #ifdef IPV6_SUPPORTED
6168 #endif /* IPV6_SUPPORTED */
6170 #if (defined(SS_LINUX) || defined(_XPG4_2))
6171 cmMemset((U8*)ancillData, 0, sizeof(ancillData));
6172 #endif /* SS_LINUX || _XPG4_2 */
6174 #endif /* (WIN32 | CMINETFLATBUF) */
6176 /* clear the structure */
6177 cmMemset((U8*)&remSockAddr, 0, sizeof(remSockAddr));
6179 /* get number of pending data */
6180 /* removed 3rd arg memInfo. MemInfo is no longer
6181 needed as we call ioctl for all sockets */
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
6187 if(sockFd->type == CM_INET_STREAM)
6189 ret = cmInetGetNumRead(sockFd, &pendLen);
6192 /* ret may be RFAILED or ROUTRES */
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.
6204 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE+1;
6208 /* check if connection got closed */
6211 if (sockFd->type == CM_INET_STREAM)
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 */
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
6226 ret = cmInetPeekNew(sockFd, NULLP, info, 0, 1, readBuf);
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. */
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))
6245 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6246 *len = (MsgLen)pendLen;
6249 /* check if there are enough pending data to read */
6250 if ((*len == CM_INET_READ_ANY) || ((U32)*len <= pendLen))
6252 if (*len == CM_INET_READ_ANY)
6254 /* added check for TCP socket. Pending data length in
6255 the socket recv buffer is determined by ioctl call in
6257 For TCP it can't be > CM_INET_MAX_MSG_LEN. */
6258 if (sockFd->type == CM_INET_STREAM)
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;
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.
6269 /* read all pending data */
6270 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6271 bufLen = (MsgLen)pendLen;
6272 *len = (MsgLen)pendLen;
6276 /* cm_inet_c_001.main_45- Returning CM_INET_MAX_MSG_LEN when input is larger than
6279 /* max message length is limited to control the memory usage */
6280 if ((*len) > CM_INET_MAX_MSG_LEN)
6282 (*len) = CM_INET_MAX_MSG_LEN;
6285 /* read data length given by user */
6289 #if (defined(WIN32) || defined(CMINETFLATBUF))
6291 /* set destination Internet address structure */
6292 if (fromAddr != NULLP)
6294 remAddrLen = sizeof(remSockAddr);
6301 /* allocate flat receive buffer */
6302 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6311 * maybe needs more than one recvfrom() call to read an entire
6312 * message from a stream socket (TCP)
6316 /* added separate recvfrom calls different OS */
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))
6322 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6323 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
6325 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6326 NULLP, (int *)&remAddrLen);
6328 #if ( defined(SUNOS) || defined(SS_LINUX))
6330 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6331 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
6333 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6334 NULLP, (socklen_t *)&remAddrLen);
6337 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6338 &remSockAddr, (S32 *)&remAddrLen);
6340 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6341 NULLP, (S32 *)&remAddrLen);
6343 #endif /* defined(SUNOS) || defined(SS_LINUX) */
6344 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
6346 if (recvLen == INET_ERR)
6349 /* moved cleanup here */
6350 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6352 /* added check ERR_WOULDBLOCK */
6353 if ((INET_ERR_CODE == ERR_AGAIN) ||
6354 (INET_ERR_CODE == ERR_WOULDBLOCK))
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))
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);
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 */
6392 * a message is always read atomically on a datagram socket,
6393 * therefore it's ok to read less than pending data!
6396 if ((sockFd->type == CM_INET_RAW) ||
6397 (sockFd->type == CM_INET_DGRAM))
6402 #else /* CM_INET2 */
6403 if (sockFd->type == CM_INET_DGRAM)
6408 #endif /* CM_INET2 */
6409 } /* while (curLen > 0) (only for stream sockets) */
6411 /* For UDP, it is possible to receive
6412 * a 0 byte datagram, in this case just return ROKDNA.
6415 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6418 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6421 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6425 /* cm_inet_c_001.main_48 : If Received
6426 * len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6430 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6431 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6433 if ((sockFd->type == CM_INET_DGRAM)
6434 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
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);
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*/
6453 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6457 /* cm_inet_c_001.main_48 : copy data to a message structure */
6458 ret = SGetMsg(info->region, info->pool, &mBuf);
6462 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6467 if ((sockFd->type == CM_INET_DGRAM) ||
6468 (sockFd->type == CM_INET_RAW))
6470 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6474 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6477 #else /* CM_INET2 */
6478 if (sockFd->type == CM_INET_DGRAM)
6480 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6484 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6486 #endif /* CM_INET2 */
6490 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6496 /* setup return destination Internet address */
6497 /* added the check of (remAddrLen > 0) */
6498 if ((fromAddr != NULLP) && (remAddrLen > 0))
6500 #ifdef IPV6_SUPPORTED
6501 if (remAddrLen == sizeof(struct sockaddr_in6))
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);
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);
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 */
6524 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6526 #else /* end of Win NT/flat buffer specific part */
6528 /* Initialise variable */
6529 allocFlatBuf = FALSE;
6532 * maybe needs more than one recvmsg() call to read entire message
6533 * on a stream socket
6537 /* allocate gather vector, it's a dynamic array */
6538 numDBufs = CM_INET_MAX_DBUF;
6540 ret = SGetSBuf(info->region, info->pool, (Data**)&dBufs,
6541 numDBufs*sizeof(Buffer*));
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,
6553 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6557 /* check if the function returned RNA */
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++ */
6567 #ifdef T2K_MEM_LEAK_DBG
6568 char * file = __FILE__;
6569 U32 line = __LINE__;
6572 /* cleanup the dBuf array */
6573 for (i = 0; i < msg.msg_iovlen; i++)
6574 SPutDBuf(info->region, info->pool, dBufs[i]);
6576 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6577 numDBufs * sizeof(Buffer*));
6579 /* allocate flat receive buffer */
6580 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6584 allocFlatBuf = TRUE;
6586 /* update the message structure */
6588 rxArr[0].iov_base = (Void*)recvBuf;
6589 rxArr[0].iov_len = (U32)bufLen;
6591 rxArr[0].iov_base = (S8*)recvBuf;
6592 rxArr[0].iov_len = bufLen;
6593 #endif /* SS_LINUX */
6594 msg.msg_iov = rxArr;
6600 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6601 numDBufs*sizeof(Buffer*));
6606 numBuf = msg.msg_iovlen;
6608 /* setup destination Internet address structure */
6609 if (fromAddr != NULLP)
6612 msg.msg_name = (Void*)&remSockAddr;
6615 msg.msg_name = (char *)&remSockAddr;
6617 msg.msg_name = (caddr_t)&remSockAddr;
6619 #endif /* SS_LINUX */
6620 msg.msg_namelen = sizeof(remSockAddr);
6624 msg.msg_name = NULLP;
6625 msg.msg_namelen = 0;
6628 /* added defined(_XPG4_2). Also changed the
6630 #if (defined(SS_LINUX) || defined(_XPG4_2))
6631 msg.msg_control = ancillData;
6632 msg.msg_controllen = sizeof(ancillData);
6634 msg.msg_accrights = NULLP;
6635 msg.msg_accrightslen = 0;
6636 #endif /* SS_LINUX */
6638 recvLen = recvmsg(sockFd->fd, &msg, flags);
6639 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
6641 /* Moved up the cleanup precedures here before returning */
6642 /* Cleanup flat buffer if allocated */
6644 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6648 for (i = 0; i < numBuf; i++)
6650 #ifdef T2K_MEM_LEAK_DBG
6651 char * file = __FILE__;
6652 U32 line = __LINE__;
6655 SPutDBuf(info->region, info->pool, dBufs[i]);
6657 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6658 numDBufs*sizeof(Buffer*));
6661 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6662 * it has partially received data
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))
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
6679 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6680 * it has partially received data
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);
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 */
6701 /* If this happens then cmInetRecvMsg must return RCLOSED.
6702 * Needed for getting icmp msgs */
6703 if (INET_ERR_CODE == ERR_CONNABORTED)
6713 /* added for IPv6 extn headers */
6714 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
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)
6721 cmsgptr = CMSG_FIRSTHDR(&msg);
6727 #endif /* SS_LINUX || _XPG4_2 */
6729 if (cmsgptr != NULLP)
6731 #ifdef IPV6_OPTS_SUPPORTED
6732 if(ipHdrParams != NULLP)
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;
6739 /* get all ancillary data objects recvd one by one */
6740 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6741 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6743 if (cmsgptr->cmsg_level == IPPROTO_IPV6)
6745 /* Initialise ipHdrParams properly */
6746 ipHdrParams->type = CM_INET_IPV6ADDR_TYPE;
6748 if (cmsgptr->cmsg_type == IPV6_HOPOPTS)
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,
6757 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt =
6761 else if(cmsgptr->cmsg_type == IPV6_DSTOPTS)
6763 else if ((cmsgptr->cmsg_type == IPV6_DSTOPTS) ||
6764 (cmsgptr->cmsg_type == IPV6_RTHDRDSTOPTS))
6765 #endif /* SS_LINUX */
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,
6774 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt =
6777 else if (cmsgptr->cmsg_type == IPV6_RTHDR)
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,
6786 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt =
6789 else if(cmsgptr->cmsg_type == IPV6_HOPLIMIT)
6791 /* get the received hoplimit */
6792 ret = cmInet6GetHopLimitValue((U8 *)CMSG_DATA(cmsgptr),
6793 cmsgptr->cmsg_len, &ipHdrParams->u.ipv6HdrParm);
6800 #endif /* IPV6_OPTS_SUPPORTED */
6802 #ifdef IPV6_SUPPORTED
6804 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6805 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6807 if(cmsgptr->cmsg_type == IPV6_PKTINFO)
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);
6817 #endif /* LOCAL_INTF */
6820 #if (defined(SS_LINUX) && defined(LOCAL_INTF))
6821 #ifdef IPV6_SUPPORTED
6822 if(sockFd->protType == AF_INET)
6825 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
6826 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6828 if (cmsgptr->cmsg_level == IPPROTO_IP &&
6829 cmsgptr->cmsg_type == IP_PKTINFO)
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);
6839 #ifdef IPV6_SUPPORTED
6842 #endif /* SS_LINUX */
6844 #endif /* IPV6_OPTS_SUPPORTED || LOCAL_INTF */
6846 /* setup return destination Internet address */
6847 if (fromAddr != NULLP)
6849 #ifdef IPV6_SUPPORTED
6850 if (msg.msg_namelen == sizeof(struct sockaddr_in6))
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);
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);
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 */
6874 /* Incase a flat buffer was allocated get
6875 * a message to pass up */
6881 ret = SGetMsg(info->region, info->pool, &tempMsg);
6885 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6889 /* cm_inet_c_001.main_48 : A 0 len UDP packet could be received */
6892 ret = SAddPstMsgMult(recvBuf, recvLen, tempMsg);
6895 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
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
6908 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6909 *len = (MsgLen)recvLen;
6914 /* build message out of dBufs */
6915 ret = buildRecvMsg(info, rxArr, numBuf, recvLen, dBufs, &tempMsg);
6918 /* Deallocate previously allocated
6922 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6923 numDBufs*sizeof(Buffer*));
6930 /* it's first recvmsg() call */
6935 /* concatenate messages */
6936 ret = SCatMsg(*mPtr, tempMsg, M1M2);
6942 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6943 numDBufs*sizeof(Buffer*));
6949 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6950 numDBufs*sizeof(Buffer*));
6953 * a message is always read atomically on a datagram socket,
6954 * therefore it's ok to read less than pending data!
6957 if ((sockFd->type == CM_INET_DGRAM) ||
6958 (sockFd->type == CM_INET_RAW))
6960 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6961 *len = (MsgLen)recvLen;
6964 #else /* CM_INET2 */
6965 if (sockFd->type == CM_INET_DGRAM)
6967 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6968 *len = (MsgLen)recvLen;
6971 #endif /* CM_INET2 */
6972 } /* while(bufLen > 0) (only for stream sockets) */
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
6979 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6982 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6994 /* Received len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6999 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
7000 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
7002 if ((sockFd->type == CM_INET_DGRAM)
7003 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
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);
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);
7032 #endif /* WIN32 | CMINETFLATBUF */
7036 /* not enough data pending yet */
7041 } /* end of cmInetRecvMsg */
7044 /* cm_inet_c_001.main_56: Added new function cmInetPeekNew() */
7048 * Fun: cmInetPeekNew
7050 * Desc: Reads some data from the socket without destroying the socket
7052 * The data is specified by the byte positon (first byte is at
7053 * position 0) and the length.
7055 * Ret: ROK - successful
7056 * ROKDNA - ok, data not available
7057 * RCLOSED - connection closed by peer
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.
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.
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.
7081 PUBLIC S16 cmInetPeekNew
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 */
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 */
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 */
7108 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
7109 #endif /* IPV6_SUPPORTED */
7111 TRC2(cmInetPeeknew);
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))
7121 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7123 /* check if fromAddr is present or not */
7124 if (fromAddr != NULLP)
7126 remAddrLen = sizeof(remSockAddr);
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))
7137 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
7138 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7140 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
7141 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7143 #if ( defined(SUNOS) || defined(SS_LINUX))
7145 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
7146 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7147 (socklen_t *)&remAddrLen);
7149 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
7150 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7153 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
7154 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
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) */
7161 /* removed the check of returned remAddrLen */
7162 if (recvLen == INET_ERR)
7164 /* added check ERR_WOULDBLOCK */
7165 if ((INET_ERR_CODE == ERR_AGAIN) ||
7166 (INET_ERR_CODE == ERR_WOULDBLOCK))
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))
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);
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);
7193 #endif /* CMINETDBG */
7197 else if (recvLen == 0)
7202 /* cm_inet_c_001.main_57 - Fix for validation */
7203 if (recvLen < (S32)dataLen) /* maybe happen */
7208 /* setup return destination Internet address */
7209 /* added the check of (remAddLen > 0) */
7210 if ((fromAddr != NULLP) && (remAddrLen > 0))
7212 #ifdef IPV6_SUPPORTED
7213 cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
7214 if (remAddrLen == sizeof(struct sockaddr_in6))
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);
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);
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 */
7239 } /* end of cmInetPeeknew */
7246 * Desc: Reads some data from the socket without destroying the socket
7248 * The data is specified by the byte positon (first byte is at
7249 * position 0) and the length.
7251 * Ret: ROK - successful
7252 * ROKDNA - ok, data not available
7253 * RCLOSED - connection closed by peer
7263 PUBLIC S16 cmInetPeek
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 */
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 */
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 */
7302 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
7303 #endif /* IPV6_SUPPORTED */
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))
7315 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7317 /* check if there are some datas */
7318 if (sockFd->blocking)
7325 /* poll (non-blocking) */
7327 timeoutPtr = &timeout;
7329 CM_INET_FD_ZERO(&readFdS);
7330 CM_INET_FD_SET(sockFd, &readFdS);
7332 ret = cmInetSelect(&readFdS, NULLP, timeoutPtr, &numFdS);
7333 if (CM_INET_FD_ISSET(sockFd, &readFdS))
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);
7341 /* cm_inet_c_001.main_50
7342 * Return RCLOSED if cmInetGetNumRead returns RCLOSED. For other
7343 * errors just return RFAILED.
7351 /* check if connection got closed */
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
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)
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 */
7378 if (pendLen > CM_INET_MAX_UDPRAW_MSGSIZE)
7379 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE;
7381 remAddrLen = sizeof(CmInetSockAddr);
7384 /* check if there are enough pending data to read */
7385 bufLen = dataPos + dataLen;
7387 /* check if fromAddr is present or not */
7388 if (fromAddr != NULLP)
7390 remAddrLen = sizeof(remSockAddr);
7397 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
7398 if ((MsgLen)pendLen >= bufLen)
7400 /* allocate receive buffer (flat structure) */
7401 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
7407 /* added different recvfrom calls with
7408 * different 6th arg for different OS */
7410 /* If remAddrLen is 0, pass NULLP */
7411 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7413 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7414 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7416 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7417 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7419 #if ( defined(SUNOS) || defined(SS_LINUX))
7421 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7422 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7423 (socklen_t *)&remAddrLen);
7425 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7426 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7429 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7430 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
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) */
7437 /* removed the check of returned remAddrLen */
7438 if (recvLen == INET_ERR)
7441 /* moved cleanup here */
7442 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7444 /* added check ERR_WOULDBLOCK */
7445 if ((INET_ERR_CODE == ERR_AGAIN) ||
7446 (INET_ERR_CODE == ERR_WOULDBLOCK))
7452 /* moved up the cleanup */
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);
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);
7467 #endif /* CMINETDBG */
7469 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7470 (INET_ERR_CODE == ERR_CONNRESET))
7478 if (recvLen < (S32)bufLen) /* maybe happen */
7481 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7486 for (j = 0, i = dataPos; i < bufLen; j++, i++)
7487 data[j] = recvBuf[i];
7489 /* setup return destination Internet address */
7490 /* added the check of (remAddLen > 0) */
7491 if ((fromAddr != NULLP) && (remAddrLen > 0))
7493 #ifdef IPV6_SUPPORTED
7494 cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
7495 if (remAddrLen == sizeof(struct sockaddr_in6))
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);
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);
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 */
7520 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7524 /* not enough data pending yet */
7530 /* no data pending */
7535 } /* end of cmInetPeek */
7542 * Desc: Close a socket gracefully.
7544 * Ret: ROK - successful
7554 PUBLIC S16 cmInetClose
7556 CmInetFd *sockFd /* socket file descriptor */
7559 PUBLIC S16 cmInetClose(sockFd)
7560 CmInetFd *sockFd; /* socket file descriptor */
7563 S32 ret; /* temporary return value */
7567 #if (ERRCLASS & ERRCLS_INT_PAR)
7568 /* error check on parameters */
7569 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7573 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7576 ret = closesocket(sockFd->fd);
7578 ret = close(sockFd->fd);
7580 if (ret == INET_ERR)
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);
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 */
7600 } /* end of cmInetClose */
7605 * Fun: cmInetShutdown
7607 * Desc: Close an Internet connection with more control over the data of
7608 * the full-duplex connection.
7609 * Values for the howTo parameter:
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
7615 * Ret: ROK - successful
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
7628 PUBLIC S16 cmInetShutdown
7630 CmInetFd *sockFd, /* socket file descriptor */
7631 S32 howTo /* operation flag */
7634 PUBLIC S16 cmInetShutdown(sockFd, howTo)
7635 CmInetFd *sockFd; /* socket file descriptor */
7636 S32 howTo; /* operation flag */
7639 S32 ret; /* temporary return value */
7641 TRC2(cmInetShutdown);
7643 #if (ERRCLASS & ERRCLS_INT_PAR)
7644 /* error check on parameters */
7645 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7649 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7651 ret = shutdown(sockFd->fd, howTo);
7652 if (ret == INET_ERR)
7654 if (INET_ERR_CODE == ERR_NOTCONN)
7656 /* socket is not connected */
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);
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 */
7681 } /* end of cmInetShutdown */
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
7695 * Ret: ROK - successful
7696 * RTIMEOUT - timout expired
7706 PUBLIC S16 cmInetSelect
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 */
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 */
7721 S32 ret; /* temporary return value */
7722 struct timeval timeout; /* timeout structure */
7723 struct timeval *timeoutPtr;
7726 #if (ERRCLASS & ERRCLS_INT_PAR)
7727 /* error check on parameters */
7728 if (numFdS == NULLP)
7732 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7736 if (mSecTimeout != NULLP)
7738 timeout.tv_sec = *mSecTimeout / 1000;
7739 timeout.tv_usec = (*mSecTimeout % 1000) * 1000;
7740 timeoutPtr = &timeout;
7744 /* infinite timeout */
7750 timeout.tv_usec = 1;
7753 /* cm_inet_c_001.main_53 - Removed do-while loop */
7754 ret = select(FD_SETSIZE, readFdS, writeFdS, (fd_set*)0, timeoutPtr);
7756 /* cm_inet_c_001.main_53 - Return ROKDNA in case select was interrupted */
7757 if ((ret == INET_ERR) && (INET_ERR_CODE == ERR_EINTR))
7762 /* timeout occured */
7768 if (ret == INET_ERR)
7770 /* asa: Added a check for ERR_INVAL to return ROK
7771 * readFdS and writeFdS may be passed as NULL to
7772 * cmInetSelect() call
7774 switch(errCode = INET_ERR_CODE)
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",
7785 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET039, 0, prntBuf);
7786 #endif /* CMINETDBG */
7789 } /* end of switch */
7792 /* return number of ready file descriptors */
7793 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7797 } /* end of cmInetSelect */
7804 * Desc: Sets a socket option.
7805 * The function supports following options:
7807 * CM_INET_OPT_BLOCK:
7808 * value: CM_INET_OPT_DISABLE non-blocking
7809 * value: CM_INET_OPT_ENABLE blocking
7811 * CM_INET_OPT_REUSEADDR:
7812 * value: CM_INET_OPT_ENABLE reuse address
7814 * CM_INET_OPT_BROADCAST:
7815 * value: CM_INET_OPT_DISABLE
7816 * value: CM_INET_OPT_ENABLE
7818 * CM_INET_OPT_KEEPALIVE:
7819 * value: CM_INET_OPT_DISABLE
7820 * value: CM_INET_OPT_ENABLE
7822 * CM_INET_OPT_RX_BUF_SIZE:
7823 * value: receive buffer size in bytes
7825 * CM_INET_OPT_TX_BUF_SIZE:
7826 * value: transmitter buffer size in bytes
7828 * CM_INET_OPT_ADD_MCAST_MBR:
7829 * value: address of CmInetMCastInf structure
7831 * CM_INET_OPT_DRP_MCAST_MBR:
7832 * value: address of CmInetMCastInf structure
7834 * CM_INET_OPT_TCP_NODELAY:
7835 * value: CM_INET_OPT_DISABLE
7836 * value: CM_INET_OPT_ENABLE
7838 * CM_INET_OPT_BSD_COMPAT: For Linux only
7839 * value: CM_INET_OPT_ENABLE
7840 * value: CM_INET_OPT_DISABLE
7842 * CM_INET_OPT_HDR_INCLD:
7843 * value: CM_INET_ENABLE
7844 * value: CM_INET_DISABLE
7846 * CM_INET_OPT_DONT_FRAGMENT:
7847 * value: CM_INET_OPT_ENABLE
7848 * value: CM_INET_DISABLE
7851 * value: Type of Service.
7854 * value: Time To Live.
7856 * CM_INET_OPT_IP_OPTIONS:
7857 * value: IPv4 header option value
7860 * CM_INET_OPT_IP_ROUTER_ALERT:
7861 * value: CM_INET_OPT_DISABLE
7862 * value: CM_INET_OPT_ENABLE
7864 * CM_INET_OPT_IPV4_PKTINFO
7865 * value: CM_INET_OPT_ENABLE
7866 * value: CM_INET_OPT_DISABLE
7868 * CM_INET_OPT_MCAST_LOOP:
7869 * value: CM_INET_OPT_DISABLE
7870 * value: CM_INET_OPT_ENABLE
7872 * CM_INET_OPT_MCAST_IF:
7873 * value: Address of interface.
7875 * CM_INET_OPT_MCAST_TTL:
7876 * value: TTL of the outgoing multicast packet.
7878 * The next options are defined only if IPV6 is
7881 * CM_INET_OPT_ADD_MCAST6_MBR:
7882 * value: address of CmInetMCastInf6 structure
7884 * CM_INET_OPT_DRP_MCAST6_MBR:
7885 * value: address of CmInetMCastInf6 structure
7887 * CM_INET_OPT_MCAST6_LOOP:
7888 * value: CM_INET_OPT_DISABLE
7889 * value: CM_INET_OPT_ENABLE
7891 * CM_INET_OPT_MCAST6_IF:
7892 * value: Interface index
7894 * CM_INET_OPT_MCAST6_HOPS:
7895 * value: multicast hop limit
7897 * CM_INET_OPT_RECVIPV6_HOPLIM:
7898 * value: CM_INET_OPT_ENABLE hop limit will be returned
7900 * value: CM_INET_OPT_DISABLE hop limit wont be returned
7903 * CM_INET_OPT_RECVIPV6_HBHOPTS:
7904 * value: CM_INET_OPT_ENABLE HBH Options will be returned
7906 * value: CM_INET_OPT_DISABLE HBH Options wont be returned
7909 * CM_INET_OPT_RECVIPV6_DSTOPTS:
7910 * value: CM_INET_OPT_ENABLE Dest Options will be returned
7912 * value: CM_INET_OPT_DISABLE Dest Options wont be returned
7915 * CM_INET_OPT_RECVIPV6_RTHDR:
7916 * value: CM_INET_OPT_ENABLE Route Hdr Opt will be turned
7918 * value: CM_INET_OPT_DISABLE Route Hdr Opt will be turned
7919 * OFF on the socket.
7921 * CM_INET_OPT_IP_ROUTER_ALERT6
7922 * value: CM_INET_OPT_ENABLE
7923 * value: CM_INET_OPT_DISABLE
7925 * CM_INET_OPT_IPV6_PKTINFO
7926 * value: CM_INET_OPT_ENABLE Enable sending and receiving
7928 * value: CM_INET_OPT_DISABLE Disable sending and receiving
7931 * CM_INET_OPT_LINGER
7932 * value: address of CmInetSockLinger structure
7934 * CM_INET_OPT_SCTP_EVENTS
7935 * value: address of CmInetSctpSockEvent structure
7937 * CM_INET_OPT_SCTP_PRIM_ADDR
7938 * value: address of CmInetSctpPrimAddr structure
7940 * CM_INET_OPT_SCTP_PEERADDR_PARAMS
7941 * value: address of CmInetSctpPeerAddrParams structure
7944 * Ret: ROK - successful
7946 * RNA - failed, option not available
7947 * (Only when CM_INET2 is defined)
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
7958 PUBLIC S16 cmInetSetOpt
7960 CmInetFd *sockFd, /* socket file descriptor */
7961 U32 level, /* option level */
7962 U32 type, /* option type */
7963 Ptr value /* option value */
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 */
7973 S32 ret = ROK; /* temporary return value */
7974 U32 disable = 0; /* disable option */
7975 U32 enable = 1; /* enable option */
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 */
7986 #endif /* IPV4_OPTS_SUPPORTED */
7988 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST)\
7990 U8 lpEnable = 1; /* multicast loop enable */
7991 U8 lpDisable = 0; /* multicast loop disable */
7992 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7995 BOOL boolEnable = TRUE; /* enable option */
7996 BOOL boolDisable = FALSE; /* disable option */
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 */
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 */
8019 /* cm_inet_c_001.main_58 : Added new local variables to support filteration
8020 * of ICMP messages */
8022 #ifdef CM_ICMP_FILTER_SUPPORT
8023 struct icmp_filter icmpFilter;
8027 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
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 */
8041 CmInetSockLinger *pSockLinger;
8042 CmInetSctpSockEvent *pSctpEvent;
8043 CmInetSctpPrimAddr *pSctpPrimAddr;
8044 CmInetSctpPeerAddrParams *pSctpPAddrParams;
8045 CmInetSctpRtoInfo *pSctpRtoInfo;
8046 CmInetSctpInitMsg *pSctpInitMsg;
8047 CmInetSctpAssocParams *pSctpAssocParams;
8054 /* cm_inet_c_001.main_58 : Added NULL check for value field */
8060 #if (ERRCLASS & ERRCLS_INT_PAR)
8061 /* error check on parameters */
8062 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
8066 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8070 case CM_INET_OPT_BLOCK:
8071 optVal = (U32*)value;
8074 case CM_INET_OPT_ENABLE:
8077 /* cm_inet_c_001.main_59: Fix for compilation warning */
8078 ret = ioctlsocket(sockFd->fd, FIONBIO, (U32 *)&disable);
8081 ret = ioctl(sockFd->fd, FIONBIO, (char*)&disable);
8084 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&disable);
8086 ret = ioctl(sockFd->fd, (S32)FIONBIO, &disable);
8091 sockFd->blocking = 1;
8094 case CM_INET_OPT_DISABLE:
8096 /* cm_inet_c_001.main_59: Fix for compilation warning */
8097 ret = ioctlsocket(sockFd->fd, FIONBIO, (U32 *)&enable);
8100 ret = ioctl(sockFd->fd, FIONBIO, (char*)&enable);
8103 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&enable);
8105 ret = ioctl(sockFd->fd, (S32)FIONBIO, &enable);
8109 sockFd->blocking = 0;
8119 case CM_INET_OPT_REUSEADDR:
8120 optVal = (U32*)value;
8121 if (*optVal == CM_INET_OPT_ENABLE)
8124 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8125 (char*)&boolEnable, sizeof(boolEnable));
8127 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8128 (char*)&enable, sizeof(enable));
8130 setsockopt(sockFd->fd, level, SO_REUSEPORT,
8131 (char*)&enable, sizeof(enable));
8135 else if (*optVal == CM_INET_OPT_DISABLE)
8138 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8139 (char*)&boolDisable, sizeof(boolDisable));
8141 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8142 (char*)&disable, sizeof(disable));
8144 ret = setsockopt(sockFd->fd, level, SO_REUSEPORT,
8145 (char*)&disable, sizeof(disable));
8151 case CM_INET_OPT_BROADCAST:
8152 optVal = (U32*)value;
8153 if (*optVal == CM_INET_OPT_ENABLE)
8156 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8157 (char*)&boolEnable, sizeof(boolEnable));
8159 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8160 (char*)&enable, sizeof(enable));
8163 else if (*optVal == CM_INET_OPT_DISABLE)
8166 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8167 (char*)&boolDisable, sizeof(boolDisable));
8169 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8170 (char*)&disable, sizeof(disable));
8175 case CM_INET_OPT_KEEPALIVE:
8176 optVal = (U32*)value;
8177 if (*optVal == CM_INET_OPT_ENABLE)
8180 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8181 (char*)&boolEnable, sizeof(boolEnable));
8183 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8184 (char*)&enable, sizeof(enable));
8187 else if (*optVal == CM_INET_OPT_DISABLE)
8190 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8191 (char*)&boolDisable, sizeof(boolDisable));
8193 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8194 (char*)&disable, sizeof(disable));
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));
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));
8211 case CM_INET_OPT_TCP_NODELAY:
8212 optVal = (U32*)value;
8213 if (*optVal == CM_INET_OPT_ENABLE)
8217 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8218 (char*)&boolEnable, sizeof(boolEnable));
8219 #endif /* SS_WINCE */
8221 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8222 (char*)&enable, sizeof(enable));
8225 else if (*optVal == CM_INET_OPT_DISABLE)
8229 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8230 (char*)&boolDisable, sizeof(boolDisable));
8231 #endif /* SS_WINCE */
8233 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8234 (char*)&disable, sizeof(disable));
8239 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || \
8240 defined(SS_VW_MCAST) || defined(HPOS))
8242 case CM_INET_OPT_ADD_MCAST_MBR:
8243 mCast = (CmInetMCastInf*)value;
8245 /* Copy the addresses to stMreq structure */
8247 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8249 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8251 stMreq.imr_interface.s_addr = CM_INET_HTON_U32(mCast->localAddr);
8253 ret = setsockopt(sockFd->fd, level, IP_ADD_MEMBERSHIP,
8254 (char*)&stMreq, sizeof(stMreq));
8257 case CM_INET_OPT_DRP_MCAST_MBR:
8258 mCast = (CmInetMCastInf*)value;
8260 /* Copy the addresses to stMreq structure */
8262 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8264 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8266 stMreq.imr_interface.s_addr = CM_INET_HTON_U32(mCast->localAddr);
8268 ret = setsockopt(sockFd->fd, level, IP_DROP_MEMBERSHIP,
8269 (char*)&stMreq, sizeof(stMreq));
8272 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
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)
8282 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
8283 &enable, sizeof(enable));
8285 else if (*optVal == CM_INET_OPT_DISABLE)
8287 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
8288 &disable, sizeof(disable));
8291 #endif /* CMINET_BSDCOMPAT */
8292 #endif /* SS_LINUX */
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) \
8299 case CM_INET_OPT_HDR_INCLD:
8300 optVal = (U32*)value;
8301 if (*optVal == CM_INET_OPT_ENABLE)
8306 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
8307 (char*)&enable, sizeof(enable));
8310 else if (*optVal == CM_INET_OPT_DISABLE)
8315 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
8316 (char*)&disable, sizeof(disable));
8321 /* added new options */
8322 #ifdef IPV4_OPTS_SUPPORTED
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)
8332 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
8333 (char*)&enable, sizeof(enable));
8337 else if (*optVal == CM_INET_OPT_DISABLE)
8339 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
8340 (char*)&disable, sizeof(disable));
8345 #endif /* SS_LINUX */
8347 /* set Router Alert socket option */
8348 case CM_INET_OPT_IP_OPTIONS:
8349 #if (defined (SS_VW) || defined(SS_LINUX))
8352 tempTknStr64=(TknStr64 *)value;
8353 if (tempTknStr64->pres == TRUE)
8355 if (tempTknStr64->len == 0)
8357 /* disable the IP_OPTIONS for Router Alert. */
8359 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
8360 (CONSTANT char *)&disableOpt, sizeof(int));
8362 ret = setsockopt(sockFd->fd, level, IP_OPTIONS, NULL, 0);
8366 /* enable the IP_OPTIONS for Router Alert */
8367 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
8368 (char *)tempTknStr64->val, tempTknStr64->len);
8371 RETVALUE(RFAILED); /* Trying to set IPv4 Hdr option
8372 * without giving option values*/
8373 #endif /* SS_VW || SS_LINUX */
8375 #endif /* IPV4_OPTS_SUPPORTED */
8377 /* added new options */
8378 #if (defined(SS_LINUX) && (!defined(SS_VW) && !defined(WIN32)))
8380 case CM_INET_OPT_IPV4_PKTINFO:
8381 optVal = (U32*)value;
8382 if (*optVal == CM_INET_OPT_ENABLE)
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));
8391 else if (*optVal == CM_INET_OPT_DISABLE)
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));
8401 #endif /* LOCAL_INTF */
8402 #endif /* SS_LINUX */
8404 #endif /* SUNOS || WIN32 || SS_PS || SS_VW || HPOS */
8406 case CM_INET_OPT_DONTFRAGMENT:
8407 optVal = (U32*)value;
8408 if (*optVal == CM_INET_OPT_ENABLE)
8411 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8412 (char*)&boolEnable, sizeof(boolEnable));
8415 else if (*optVal == CM_INET_OPT_DISABLE)
8418 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8419 (char*)&boolDisable, sizeof(boolDisable));
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));
8432 case CM_INET_OPT_TTL:
8433 optVal = (U32*)value;
8434 ret = setsockopt(sockFd->fd, level, IP_TTL,
8435 (char*)optVal, sizeof(*optVal));
8437 #endif /* SUNOS || WIN32 || HPOS || SS_VW */
8438 #endif /* CM_INET2 */
8440 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST) \
8442 case CM_INET_OPT_MCAST_LOOP:
8443 optVal = (U32*)value;
8444 if (*optVal == CM_INET_OPT_ENABLE)
8447 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8448 (char *)&lpEnable, sizeof(lpEnable));
8450 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8451 (CONSTANT char *)&lpEnable, sizeof(lpEnable));
8457 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8458 (char *)&lpDisable, sizeof(lpDisable));
8460 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8461 (CONSTANT char *)&lpDisable, sizeof(lpDisable));
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));
8473 case CM_INET_OPT_MCAST_TTL:
8474 optVal = (U32*)value;
8475 /* remove CONSTANT in setsockopt for VW */
8477 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8478 (char *)optVal, sizeof(U8));
8480 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8481 (CONSTANT char *)optVal, sizeof(U8));
8484 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
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));
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));
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));
8505 case CM_INET_OPT_MCAST6_LOOP:
8506 optVal = (U32*)value;
8507 if (*optVal == CM_INET_OPT_ENABLE)
8509 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8510 &loopEna, sizeof(loopEna));
8514 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8515 &loopDis, sizeof(loopDis));
8519 case CM_INET_OPT_MCAST6_IF:
8520 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_IF,
8521 (U32 *)value, sizeof(U32));
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));
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));
8541 #endif /* ICMPV6_FILTER_SUPPORTED */
8543 /* added new options */
8544 #ifdef IPV6_OPTS_SUPPORTED
8545 case CM_INET_OPT_RECVIPV6_HOPLIM:
8546 optVal = (U32*)value;
8548 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8549 (char *)optVal, sizeof(U32));
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 */
8560 case CM_INET_OPT_RECVIPV6_HBHOPTS:
8561 optVal = (U32*)value;
8563 ret = setsockopt(sockFd->fd, level, IPV6_HOPOPTS,
8564 (char *)optVal, sizeof(U32));
8566 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPOPTS,
8567 (char *)optVal, sizeof(U32));
8568 #endif /* SS_LINUX */
8571 case CM_INET_OPT_RECVIPV6_DSTOPTS:
8572 optVal = (U32*)value;
8574 ret = setsockopt(sockFd->fd, level, IPV6_DSTOPTS,
8575 (char *)optVal, sizeof(U32));
8577 ret = setsockopt(sockFd->fd, level, IPV6_RECVDSTOPTS,
8578 (char *)optVal, sizeof(U32));
8579 #endif /* SS_LINUX */
8582 case CM_INET_OPT_RECVIPV6_RTHDR:
8583 optVal = (U32*)value;
8585 ret = setsockopt(sockFd->fd, level, IPV6_RTHDR,
8586 (char *)optVal, sizeof(U32));
8588 ret = setsockopt(sockFd->fd, level, IPV6_RECVRTHDR,
8589 (char *)optVal, sizeof(U32));
8590 #endif /* SS_LINUX */
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
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 */
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));
8606 ret = setsockopt(sockFd->fd, level, IPV6_ROUTER_ALERT,
8607 (char *)&disable, sizeof(disable));
8610 #endif /* SS_LINUX */
8611 #endif /* IPV6_OPTS_SUPPORTED */
8614 case CM_INET_OPT_IPV6_PKTINFO:
8615 optVal = (U32*)value;
8617 ret = setsockopt(sockFd->fd, level, IPV6_PKTINFO,
8618 (char *)optVal, sizeof(U32));
8620 ret = setsockopt(sockFd->fd, level, IPV6_RECVPKTINFO,
8621 (char *)&enable, sizeof(enable));
8622 #endif /* SS_LINUX */
8624 #endif /* LOCAL_INTF */
8626 #endif /* IPV6_SUPPORTED */
8628 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8630 case CM_INET_OPT_LINGER:
8631 pSockLinger = (CmInetSockLinger *)value;
8633 cmMemset((U8*)&lngr, 0, sizeof(struct linger));
8635 if (pSockLinger->enable == TRUE)
8640 lngr.l_linger = pSockLinger->lingerTime;
8641 ret = setsockopt(sockFd->fd, level, SO_LINGER, &lngr, sizeof(lngr));
8644 case CM_INET_OPT_SCTP_EVENTS:
8645 pSctpEvent = (CmInetSctpSockEvent *)value;
8647 cmMemset((U8*)&event, 0, sizeof(struct sctp_event_subscribe));
8649 if (pSctpEvent->dataIoEvent == TRUE)
8650 event.sctp_data_io_event = 1;
8652 if (pSctpEvent->associationEvent == TRUE)
8653 event.sctp_association_event = 1;
8655 if (pSctpEvent->addressEvent == TRUE)
8656 event.sctp_address_event = 1;
8658 if (pSctpEvent->sendFailureEvent == TRUE)
8659 event.sctp_send_failure_event = 1;
8661 if (pSctpEvent->peerErrorEvent == TRUE)
8662 event.sctp_peer_error_event = 1;
8664 if (pSctpEvent->shutdownEvent == TRUE)
8665 event.sctp_shutdown_event = 1;
8667 if (pSctpEvent->partialDeliveryEvent == TRUE)
8668 event.sctp_partial_delivery_event = 1;
8670 if (pSctpEvent->adaptationLayerEvent == TRUE)
8672 event.sctp_adaption_layer_event = 1;
8674 event.sctp_adaptation_layer_event = 1;
8677 ret = setsockopt(sockFd->fd, level, SCTP_EVENTS, &event, sizeof(event));
8680 case CM_INET_OPT_SCTP_PRIM_ADDR:
8681 pSctpPrimAddr = (CmInetSctpPrimAddr *)value;
8683 cmMemset((U8*)&setPrim, 0, sizeof(struct sctp_setprim));
8685 #ifdef IPV6_SUPPORTED
8686 if (pSctpPrimAddr->addr.type == CM_INET_IPV6ADDR_TYPE)
8688 if (sockFd->protType == AF_INET)
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);
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 */
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);
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);
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 */
8726 setPrim.ssp_assoc_id = pSctpPrimAddr->assocId;
8728 ret = setsockopt(sockFd->fd, level, SCTP_PRIMARY_ADDR, &setPrim, sizeof(setPrim));
8731 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
8732 pSctpPAddrParams = (CmInetSctpPeerAddrParams *)value;
8734 cmMemset((U8*)&addrParams, 0, sizeof(struct sctp_paddrparams));
8737 if (pSctpPAddrParams->s.addrPres == TRUE)
8739 #ifdef IPV6_SUPPORTED
8740 if (pSctpPAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
8742 if (sockFd->protType == AF_INET)
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);
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 */
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);
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);
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 */
8783 #ifdef IPV6_SUPPORTED
8784 if (sockFd->protType == AF_INET6)
8785 addrParams.spp_address.ss_family = AF_INET6;
8787 addrParams.spp_address.ss_family = AF_INET;
8789 addrParams.spp_address.ss_family = AF_INET;
8793 /* Not validating the address, whether addr is a valid address or not */
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;
8799 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8800 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8802 addrParams.spp_hbinterval = 0;
8805 addrParams.spp_flags = 0;
8807 if (pSctpPAddrParams->pmtudFlag == CM_INET_OPT_ENABLE)
8809 addrParams.spp_flags |= SPP_PMTUD_ENABLE;
8810 addrParams.spp_pathmtu = pSctpPAddrParams->pathMtu;
8812 else if(pSctpPAddrParams->pmtudFlag == CM_INET_OPT_DISABLE)
8813 addrParams.spp_flags |= SPP_PMTUD_DISABLE;
8815 if (pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_ENABLE)
8817 addrParams.spp_flags |= SPP_SACKDELAY_ENABLE;
8818 addrParams.spp_sackdelay = pSctpPAddrParams->sackDelay;
8820 else if(pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_DISABLE)
8821 addrParams.spp_flags |= SPP_SACKDELAY_DISABLE;
8823 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8825 addrParams.spp_flags |= SPP_HB_ENABLE;
8826 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8828 else if(pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_DISABLE)
8829 addrParams.spp_flags |= SPP_HB_DISABLE;
8831 ret = setsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, sizeof(addrParams));
8834 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
8835 pSctpAssocParams = (CmInetSctpAssocParams *)value;
8837 cmMemset((U8*)&assocParams, 0, sizeof(struct sctp_assocparams));
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;
8846 ret = setsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams));
8849 case CM_INET_OPT_SCTP_RTO_INFO:
8850 pSctpRtoInfo = (CmInetSctpRtoInfo *)value;
8852 cmMemset((U8*)&rtoinfo, 0, sizeof(struct sctp_rtoinfo));
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;
8859 ret = setsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
8862 case CM_INET_OPT_SCTP_INIT_MSG:
8863 pSctpInitMsg = (CmInetSctpInitMsg *)value;
8865 cmMemset((U8*)&initmsg, 0, sizeof(struct sctp_initmsg));
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;
8872 ret = setsockopt(sockFd->fd, level, SCTP_INITMSG, &initmsg, sizeof(initmsg));
8875 #endif /*CM_LKSCTP*/
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 */
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));
8891 /* wrong socket option type */
8896 if (ret == INET_ERR)
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);
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 */
8915 } /* end of cmInetSetOpt */
8921 * Fun: cmInetGetNumRead
8923 * Desc: Gives the number of pending octets in the socket receive buffer.
8925 * Ret: ROK - successful
8935 PUBLIC S16 cmInetGetNumRead
8937 CmInetFd *sockFd, /* socket file descriptor */
8938 U32 *dataLen /* number of pending octets */
8939 /* removed 3rd argument memInfo */
8942 PUBLIC S16 cmInetGetNumRead(sockFd, dataLen)
8943 CmInetFd *sockFd; /* socket file descriptor */
8944 U32 *dataLen; /* number of pending octets */
8945 /* removed 3rd argument memInfo */
8948 S32 ret; /* temporary return value */
8950 /* removed local variables added for recvfrom call */
8952 TRC2(cmInetGetNumRead);
8954 #if (ERRCLASS & ERRCLS_INT_PAR)
8955 /* error check on parameters */
8956 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
8963 /* use ioctl call for all types of socket to get length of
8964 pending data in the socket recv buffer */
8966 /* cm_inet_c_001.main_59: Fix for compilation warning */
8967 ret = ioctlsocket(sockFd->fd, FIONREAD, (U32 *)dataLen);
8970 ret = ioctl(sockFd->fd, FIOREAD, (char*)dataLen);
8973 ret = ioctl(sockFd->fd, FIONREAD, (S32)dataLen);
8975 ret = ioctl(sockFd->fd, FIONREAD, dataLen);
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. */
8984 if (ret == INET_ERR)
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))
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.
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))
9020 /* cm_inet_c_001.main_45: Change 2048 to CM_INET_MAX_UDPRAW_MSGSIZE */
9021 *dataLen = CM_INET_MAX_UDPRAW_MSGSIZE;
9023 #endif /* SS_LINUX */
9025 /* removed error debug printing added for recvfrom call. */
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);
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 */
9045 } /* end of cmInetGetNumRead */
9051 * Fun: cmInetGetHostByName
9053 * Desc: Resolves a host name into the appropriate 4 byte Internet
9056 * Ret: ROK - successful
9066 PUBLIC S16 cmInetGetHostByName
9068 S8 *hostName, /* host name */
9069 CmInetIpAddrTbl *addrTbl /* Address Table of IPV4 Addresses */
9072 PUBLIC S16 cmInetGetHostByName (hostName, addrTbl)
9073 S8 *hostName; /* host name */
9074 CmInetIpAddrTbl *addrTbl; /* Address Table of IPV4 Addresses */
9078 U8 numAddrs; /* Number of Addresses */
9081 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
9082 struct hostent *hostid; /* pointer to host information */
9085 struct hostent hostid; /* host information */
9086 S8 infoBuf[CM_INET_MAX_INFO]; /* info buffer */
9087 S32 err; /* error code */
9089 #endif /* WIN32 || SS_LINUX || HPOS */
9091 TRC2(cmInetGetHostByName)
9093 #if (ERRCLASS & ERRCLS_INT_PAR)
9094 /* error check on parameters */
9095 if ((hostName == NULLP) || (addrTbl == NULLP))
9099 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9108 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
9109 hostid = gethostbyname(hostName);
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 */
9121 if (hostid->h_addrtype != AF_INET)
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 */
9135 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9136 (hostid->h_addr_list[numAddrs] != NULLP))
9138 addrTbl->netAddr[addrTbl->count++] =
9139 CM_INET_NTOH_U32 (*((U32 *) hostid->h_addr_list[numAddrs]));
9149 vwIpAddr = hostGetByName(hostName);
9150 if (vwIpAddr == INET_ERR)
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 */
9161 CM_COPY_VWIPADDR(vwIpAddr, &(addrTbl->netAddr[addrTbl->count]));
9166 err = 0; /* err is not reset by gethostnyname_r()! */
9168 gethostbyname_r(hostName, &hostid, infoBuf, CM_INET_MAX_INFO, (int*)&err);
9169 if ((hostid.h_addrtype != AF_INET) || (err < 0))
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 */
9182 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9183 (hostid.h_addr_list[numAddrs] != NULLP))
9185 addrTbl->netAddr[addrTbl->count++] =
9186 CM_INET_NTOH_U32 (*((U32 *) hostid.h_addr_list[numAddrs]));
9192 #endif /* WIN32 || SS_LINUX || HPOS */
9196 } /* end of cmInetGetHostByName */
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 */
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. */
9209 * Fun: cmInetGetIpNodeByName
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.
9216 * Ret: ROK - successful
9225 PUBLIC S16 cmInetGetIpNodeByName
9227 S8 *hostName, /* host name */
9228 CmInetIpAddrArr *addrArr /* Array of addressed filled in */
9231 PUBLIC S16 cmInetGetIpNodeByName(hostName, addrArr)
9232 S8 *hostName; /* host name */
9233 CmInetIpAddrArr *addrArr; /* Array of addressed filled in */
9236 /* for return value from cmInetGetHostByName */
9237 #ifndef IPV6_SUPPORTED
9242 U8 numAddrs=0; /* Number of addresses */
9243 int err=0; /* error code */
9244 struct hostent *hostid; /* host information */
9245 #endif /* SS_LINUX */
9247 #endif /* IPV6_SUPPORTED */
9249 TRC2(cmInetGetIpNodeByName)
9252 #if (ERRCLASS & ERRCLS_INT_PAR)
9253 /* error check on parameters */
9254 if ((hostName == NULLP) || (addrArr == NULLP))
9258 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9260 #ifdef IPV6_SUPPORTED
9264 #ifdef IPV6_SUPPORTED
9265 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
9266 hostid = getipnodebyname(hostName, AF_INET6, 0, &err);
9268 #endif /* IPV6_SUPPORTED */
9269 hostid = getipnodebyname(hostName, AF_INET, 0, &err);
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 */
9283 #ifdef IPV6_SUPPORTED
9284 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
9286 if (hostid->h_addrtype == AF_INET6)
9288 while ((numAddrs < CM_INET_IPV6_NUM_ADDR) &&
9289 (hostid->h_addr_list[numAddrs] != NULLP))
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++;
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 */
9312 #endif /* IPV6_SUPPORTED */
9314 if (hostid->h_addrtype == AF_INET)
9316 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9317 (hostid->h_addr_list[numAddrs] != NULLP))
9319 addrArr->u.ipv4AddrArr.count ++;
9320 addrArr->u.ipv4AddrArr.netAddr[numAddrs] =
9321 CM_INET_NTOH_U32 (*((U32 *) hostid->h_addr_list[numAddrs]));
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 */
9338 #endif /* SS_LINUX */
9343 ret = cmInetGetHostByName(hostName, &addrArr->u.ipv4AddrArr);
9345 #endif /* IPV6_SUPPORTED */
9347 } /* end of cmInetGetIpNodeByName */
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.
9358 * Ret: ROK - successful
9368 PUBLIC S16 cmInetAddr(
9369 S8 *asciiAddr, /* ascii address representation */
9370 CmInetIpAddr *address /* 4 byte interent address */
9373 PUBLIC S16 cmInetAddr(asciiAddr, address)
9374 S8 *asciiAddr; /* ascii address representation */
9375 CmInetIpAddr *address; /* 4 byte interent address */
9380 #if (ERRCLASS & ERRCLS_INT_PAR)
9381 /* error check on parameters */
9382 if (asciiAddr == NULLP)
9386 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9388 *address = inet_addr(asciiAddr);
9389 if (*address == (U32)ERR_INADDRNONE)
9391 /* asciiAddr does not contain a valid internet address */
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.
9407 * Ret: ROK - successful
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!
9419 PUBLIC S16 cmInetNtoa(
9420 CmInetIpAddr address, /* 4 byte interent address */
9421 S8 **asciiAddr /* ascii address representation */
9424 PUBLIC S16 cmInetNtoa(address, asciiAddr)
9425 CmInetIpAddr address; /* 4 byte interent address */
9426 S8 **asciiAddr; /* ascii address representation */
9429 struct in_addr inetAddr; /* internet address structure */
9433 #if (ERRCLASS & ERRCLS_INT_PAR)
9434 /* error check on parameters */
9435 if (asciiAddr == NULLP)
9439 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9441 inetAddr.s_addr = address;
9443 *asciiAddr = inet_ntoa(inetAddr);
9444 if (*asciiAddr == NULL)
9455 * Desc: Converts an network address into a string.
9456 * This function is a wrapper for the inet_ntop() call.
9458 * Ret: ROK - successful
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.
9470 PUBLIC S16 cmInetNtop(
9471 U8 type, /* ip address type */
9472 Void *address, /* 4/16 byte interent address */
9473 S8 *asciiAddr, /* ascii adress representation */
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 */
9488 #if (ERRCLASS & ERRCLS_INT_PAR)
9489 /* error check on parameters */
9490 if (asciiAddr == NULLP || address == NULLP || len == 0 )
9495 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9498 case CM_INET_IPV4ADDR_TYPE :
9501 case CM_INET_IPV6ADDR_TYPE :
9505 if(inet_ntop(domain,address,asciiAddr,len) == NULL)
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
9525 * Desc: Converts a IP address string to address.
9527 * Ret: ROK - successful
9537 PUBLIC S16 cmInetPton(
9538 CmInetIpAddr *address, /* 4 byte interent address */
9539 S8 *asciiAddr /* ascii address representation */
9542 PUBLIC S16 cmInetPton(address, asciiAddr)
9543 CmInetIpAddr *address; /* 4 byte interent address */
9544 S8 *asciiAddr; /* ascii address representation */
9551 #if (ERRCLASS & ERRCLS_INT_PAR)
9552 /* error check on parameters */
9553 if ((asciiAddr == NULLP) || (address == NULLP))
9557 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9559 ret = inet_pton(AF_INET, asciiAddr, (void *)address);
9566 } /* end of cmInetPton */
9568 #endif /* IPV6_SUPPORTED */
9570 #ifdef IPV6_SUPPORTED
9576 * Desc: Converts a IP address string to IPV6 address suitable
9577 * to be used in bind.
9579 * Ret: ROK - successful
9588 PUBLIC S16 cmInetPton6(
9589 CmInetIpAddr6 *address6, /* 16 byte interent address */
9590 S8 *asciiAddr /* ascii address representation */
9593 PUBLIC S16 cmInetPton6(address6, asciiAddr)
9594 CmInetIpAddr6 *address6; /* 16 byte interent address */
9595 S8 *asciiAddr; /* ascii address representation */
9601 struct sockaddr_storage ss;
9602 U32 sslen = sizeof(ss);
9606 #if (ERRCLASS & ERRCLS_INT_PAR)
9607 /* error check on parameters */
9608 if ((asciiAddr == NULLP) || (address6 == NULLP))
9612 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9615 ret = inet_pton(AF_INET6, asciiAddr, (void *)address6);
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));
9628 } /* end of cmInetPton6 */
9629 #endif /* IPV6_SUPPORTED */
9635 * Fun: cmInetGetMemSize
9637 * Desc: This function gives the max number of static buffer space that
9638 * the internet library will allocate.
9640 * Ret: ROK - successful
9649 PUBLIC S16 cmInetGetMemSize(
9650 S32 *size /* max used memory size */
9653 PUBLIC S16 cmInetGetMemSize(size)
9654 S32 *size; /* max used memory size */
9658 /* max static memory size depends on max flat buffer size */
9659 *size = CM_INET_MAX_MSG_LEN;
9661 /* max static memory size depends on max flat buffer or iovect size */
9662 *size = CM_INET_MAX_MSG_LEN;
9674 * Desc: This function initializes the socket library.
9676 * Ret: ROK - successful
9678 * Notes: Required only for Winsock and not for 4.3BSD
9685 PUBLIC S16 cmInetInit(
9689 PUBLIC S16 cmInetInit(Void)
9697 version = MAKEWORD(CM_INET_HIGH_VER, CM_INET_LOW_VER);
9698 err = WSAStartup(version, &data);
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
9718 * Ret: ROK - successful
9720 * Notes: Required only for Winsock and not for 4.3BSD
9727 PUBLIC S16 cmInetDeInit(
9731 PUBLIC S16 cmInetDeInit(Void)
9745 }/* end of cmInetDeInit() */
9750 * Fun: cmInetGetSockName
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.
9756 * Ret: ROK - successful
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.
9768 PUBLIC S16 cmInetGetSockName
9770 CmInetFd *sockFd, /* socket file descriptor */
9774 PUBLIC S16 cmInetGetSockName(sockFd, locAddr)
9775 CmInetFd *sockFd; /* socket file descriptor */
9776 CmInetAddr *locAddr;
9779 struct sockaddr_in *sockAddr;
9780 #ifdef IPV6_SUPPORTED
9781 struct sockaddr_in6 *sockAddr6;
9782 struct sockaddr_in6 lclSockAddr;
9784 CmInetSockAddr lclSockAddr;
9785 #endif /* IPV6_SUPPORTED */
9790 #endif /* SS_LINUX */
9792 /*cm_inet_c_001.main_58 : fix for klockwork issue */
9795 TRC2(cmInetGetSockName);
9797 #if (ERRCLASS & ERRCLS_INT_PAR)
9798 /* error check on parameters */
9799 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
9804 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9806 cmMemset((U8*)&lclSockAddr, 0, sizeof(lclSockAddr));
9807 size = sizeof(lclSockAddr);
9810 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr,
9811 (socklen_t *)&size);
9813 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, (int*)&size);
9814 #endif /* SS_LINUX */
9818 switch(errCode = INET_ERR_CODE)
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);
9826 locAddr->port = CM_INET_NTOH_U16(sockAddr->sin_port);
9827 #endif /* IPV6_SUPPORTED */
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);
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 */
9846 }/* end of switch */
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))
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);
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);
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 */
9875 }/* end of cmInetGetSockName() */
9877 /* New functions to peek into the file descriptor
9879 #if (defined(SUNOS) || defined(WIN32) || defined(SS_LINUX) || defined(SS_VW) \
9884 * Fun: cmInetFdSetInfoInit
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
9890 * Ret: ROK - successful
9900 PUBLIC S16 cmInetFdSetInfoInit
9902 CmInetFdSetInfo *fdSetInfo
9905 PUBLIC S16 cmInetFdSetInfoInit(fdSetInfo)
9906 CmInetFdSetInfo *fdSetInfo;
9909 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW) || defined(HPOS))
9914 #endif /* SUNOS || SS_LINUX || SS_VW */
9916 #if (ERRCLASS & ERRCLS_INT_PAR)
9917 if (fdSetInfo == NULLP)
9919 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9921 if (fdSetInfo->initDone == TRUE)
9925 fdSetInfo->numFds = 0;
9928 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW)|| defined(HPOS))
9929 /* Check if we are on a big endian machine */
9932 fdSetInfo->bigEndian = FALSE;
9934 fdSetInfo->bigEndian = TRUE;
9936 fdSetInfo->arIdx = 0;
9937 fdSetInfo->ar[0] = 0xff;
9939 /* Initialise the array */
9940 /* The array contains bit positions for the first bit
9941 * for each integer from 1 to 2^8.
9943 for (arIdx = 1; arIdx < 256; arIdx++)
9945 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9946 curByte = (U8)arIdx;
9953 fdSetInfo->ar[arIdx] = bitPos;
9957 curByte = curByte >> 1;
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]);
9964 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->fds_bits[0]);
9965 #endif /* SS_LINUX */
9966 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9968 fdSetInfo->initDone = TRUE;
9970 }/* end of cmInetFdSetInfoInit() */
9977 * Desc: This function is used to get the file descriptor from the
9978 * file descriptor set.
9980 * Ret: ROK - successful
9981 * ROKDNA - socket not found
9983 * RNA - failed, initialisation not done
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.
9995 PUBLIC S16 cmInetGetFd
9997 CmInetFdSetInfo *fdSetInfo,
9999 CmInetFdType *sockFd
10002 PUBLIC S16 cmInetGetFd(fdSetInfo, fdSet, sockFd)
10003 CmInetFdSetInfo *fdSetInfo;
10004 CmInetFdSet *fdSet;
10005 CmInetFdType *sockFd;
10008 /*cm_inet_c_001.main_58 : Fix for klockwork issue */
10009 #if (!defined (WIN32))
10010 U32 sizOfFdSetArElem;
10016 #endif /* !defined (WIN32) */
10018 #if (ERRCLASS & ERRCLS_INT_PAR)
10019 if ((fdSetInfo == NULLP) || (fdSet == NULLP) || (sockFd == NULLP))
10022 if (fdSetInfo->initDone != TRUE)
10024 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10027 #if (ERRCLASS & ERRCLS_DEBUG)
10028 if (fdSetInfo->numFds > FD_SETSIZE)
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)
10036 *sockFd = fdSet->fd_array[fdSetInfo->numFds];
10037 fdSetInfo->numFds += 1;
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;
10047 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
10048 sizOfFdSetArElem = sizeof(fdSet->__fds_bits[0]);
10050 sizOfFdSetArElem = sizeof(fdSet->fds_bits[0]);
10051 #endif /* SS_LINUX */
10053 for (curIdx = fdSetInfo->arIdx; curIdx < fdSetInfo->numArElems;
10056 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
10057 if (fdSet->__fds_bits[curIdx])
10059 if (fdSet->fds_bits[curIdx])
10060 #endif /* SS_LINUX */
10062 /* Walk through the bytes in this element */
10063 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
10064 tempByte = (U8 *)&fdSet->__fds_bits[curIdx];
10066 tempByte = (U8 *)&fdSet->fds_bits[curIdx];
10067 #endif /* SS_LINUX */
10069 /* Set the starting byte offset */
10070 if (fdSetInfo->bigEndian)
10071 tempByte += sizOfFdSetArElem - 1;
10073 for (bytesScanned = 0; bytesScanned < sizOfFdSetArElem;
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);
10088 if (fdSetInfo->bigEndian)
10101 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
10102 } /* end of cmInetGetFd */
10104 #endif /* SUNOS || WIN32 || SS_LINUX || SS_VW || HPOS */
10107 /* add cmInetConvertStrToIpAddr and
10108 * cmInetAsciiToIpv4 functions */
10111 * Fun: cmInetConvertStrToIpAddr
10113 * Desc: This function parses the input string for an IPV4/IPV6 address.
10115 * 1) IPV4 in dot number format:
10117 * 2) IPV6, in uncompressed, compressed, and IPV4 embedded format
10118 * 10:20:30:40:502:610:70C:80ad
10120 * 45::AB:34:123.34.5.667
10122 * Ret: ROK - SUCCESS
10123 * RFAILED - FAILURE
10132 PUBLIC S16 cmInetConvertStrToIpAddr
10134 U16 len, /* Length of IP address */
10135 U8 *val, /* Domain Name String */
10136 CmInetNetAddr *address /* IP Address */
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 */
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*/
10161 TRC2(cmInetConvertStrToIpAddr)
10164 #ifdef IPV6_SUPPORTED
10167 compressed = 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*/
10174 cmMemset((U8 *)ipv4, 0, CM_INET_IPV4ADDR_SIZE);
10176 /* Check for IP Address */
10177 while ((val[idx] != '.') && (val[idx] != ':') &&
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')))
10188 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10190 /* Convert Ascii to integer */
10191 CM_INET_ATOI(ipv4[0], val[idx]);
10193 #ifdef IPV6_SUPPORTED
10194 /* convert Ascii to hex */
10195 CM_INET_ATOH(ipv6[0], val[idx]);
10196 #endif /* IPV6_SUPPORTED */
10198 idx++; /* move to the next character */
10199 } /* while, try to determine IPV4 or IPV6 */
10201 #if (ERRCLASS & ERRCLS_DEBUG)
10202 if ((val[idx] != '.') && (val[idx] != ':'))
10206 } /* if, couldn't determine IPV4 or IPV6 */
10207 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10210 if (val[idx] == '.')
10213 cmInetAsciiToIpv4(3, &(ipv4[1]), (U16)(len - idx), &(val[idx]));
10215 address->type = CM_INET_IPV4ADDR_TYPE;
10216 CM_INET_GET_IPV4_ADDR_FRM_STRING(address->u.ipv4NetAddr, ipv4);
10218 #ifdef IPV6_SUPPORTED
10221 numBlk = 1; /* already converted the 1st block */
10223 while ((val[idx] != '\0') && (idx < len) && (numBlk <= 8))
10225 idx++; /* go to the next char, either a number or the 2nd : */
10226 if (val[idx] == ':')
10228 #if (ERRCLASS & ERRCLS_DEBUG)
10229 if (compressed == TRUE)
10231 /* can't have 2 :: */
10234 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10237 idx++; /* skip the : */
10240 } /* if, IPV6 in compressed format :: */
10244 } /* else, uncompressed, convert next block */
10246 numBlk++; /* increase number of blocks */
10248 /* assign the index the beginning of the block */
10251 while(val[idx] != ':' && val[idx] != '\0' && idx < len)
10253 if (val[idx] == '.')
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
10268 } /* if, '.' means IPV4 address embedded in IPV6 */
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')))
10278 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10280 /* Convert Ascii to integer */
10281 CM_INET_ATOH(ipv6[ipv6Idx], val[idx]);
10283 /* move to the next index */
10285 } /* while, convert a block of 16 bits Hex number */
10286 if (embedIPV4 == TRUE)
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)
10294 if (embedIPV4 == TRUE)
10296 numBlk = 5; /* the last 2 blocks are IPV4 */
10297 } /* if, IPV4 embedded */
10300 numBlk = 7; /* copy from the last block */
10301 } /* else, no embedded IPV4 */
10303 /* type cast U8 over -1 becasue we want to copy the last block,
10306 for (i = ipv6Idx; i != (U8) (-1); i --)
10308 ipv6Reg[numBlk] = ipv6Cmp[i];
10310 } /* for, copying compress IPV6 to regular IPV6 */
10311 } /* if, compressed format */
10313 if (embedIPV4 == TRUE)
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 */
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);
10326 #endif /* IPV6_SUPPORTED */
10329 } /* cmInetConvertStrToIpAddr */
10334 * Fun: cmInetAsciiToIpv4
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
10346 * Ret: ROK - SUCCESS
10347 * RFAILED - FAILURE
10355 PUBLIC S16 cmInetAsciiToIpv4
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 */
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 */
10370 U8 byteCount; /* Byte Count */
10371 U8 idx; /* Index for string*/
10373 TRC2(cmInetAsciiToIpv4)
10376 for (byteCount = 0; byteCount < numBytes; byteCount++)
10378 while((val[idx] != '.') && (idx < len))
10380 #if (ERRCLASS & ERRCLS_DEBUG)
10381 if (val[idx] < '0' || val[idx] > '9')
10386 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10388 /* Convert Ascii to integer */
10389 CM_INET_ATOI(ipv4Addr[byteCount], val[idx]);
10391 /* move to the next index */
10398 } /* cmInetAsciiToIpv4 */
10400 /* cm_inet_c_001.main_34:Added wrapper function for getaddrinfo and freeaddrinfo */
10401 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
10405 * Fun: cmInetGetAddrInfo
10407 * Desc: a socket file descriptor to a local Internet
10410 * Ret: Value returned by getaddrinfo
10419 PUBLIC S32 cmInetGetAddrInfo
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 */
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 */
10435 TRC2(cmInetGetAddrInfo);
10438 #if (ERRCLASS & ERRCLS_INT_PAR)
10439 /* error check on parameters */
10440 if ((node == NULLP) || (hints == NULLP))
10444 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10446 ret = getaddrinfo(node,service,hints,res);
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);
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 */
10466 } /* end of cmInetGetAddrInfo */
10471 * Fun: cmInetFreeAddrInfo
10473 * Desc: Free the dynamically allocated addrinfo structure
10484 PUBLIC Void cmInetFreeAddrInfo
10486 CmInetAddrInfo *res /* Link list of addrInfo structure */
10489 PUBLIC Void cmInetFreeAddrInfo(res)
10490 CmInetAddrInfo *res; /* Link list of addrInfo structure */
10493 TRC2(cmInetFreeAddrInfo);
10495 #if (ERRCLASS & ERRCLS_INT_PAR)
10496 /* error check on parameters */
10499 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10502 } /* end of cmInetFreeAddrInfo */
10504 #endif /* SS_VW | SS_PS | WIN32*/
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
10512 * Fun: cmInetFlushRcvBuf
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.
10517 * Ret: ROK - successful
10518 * ROKDNA - ok, data not available
10519 * RCLOSED - connection closed by peer
10520 * ROUTRES - failed, out of resources
10529 PUBLIC S16 cmInetFlushRecvBuf
10531 CmInetFd *sockFd, /* socket file descriptor */
10532 MsgLen *len, /* number of octects to be flushed */
10533 S32 flags /* additional control flags */
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 */
10543 Data recvTempBuf[CM_INET_MAX_BYTES_READ];
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 */
10555 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
10556 #endif /* IPV6_SUPPORTED */
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 */
10568 #if (defined(SS_LINUX) || defined(_XPG4_2))
10569 U8 ancillData[CM_INET_IPV6_ANCIL_DATA];
10570 /* from stack for IPv6 ancill data */
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 */
10578 #endif /* IPV6_SUPPORTED */
10579 #endif /* WIN32 | CMINETFLATBUF */
10581 /* used by getsockopt */
10582 U32 errValue; /* error value */
10583 U32 optLen; /* option length */
10585 TRC2(cmInetFlushRcvBuf)
10587 #if (ERRCLASS & ERRCLS_INT_PAR)
10588 /* error check on parameters */
10589 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
10593 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10596 #if (defined(WIN32) || defined(CMINETFLATBUF))
10598 #endif /* (WIN32 | CMINETFLATBUF) */
10600 /* clear the structure */
10601 cmMemset((U8*)&remSockAddr, 0, sizeof(remSockAddr));
10603 /* get number of pending data */
10604 ret = cmInetGetNumRead(sockFd, &pendLen);
10607 /* ret may be RFAILED or ROUTRES */
10611 /* check if connection got closed */
10614 if (sockFd->type == CM_INET_STREAM)
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
10627 /* clear error if there is any, because if there is internal error
10628 * here it will cause infinite loop in TUCL */
10631 optLen = sizeof(int);
10633 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10634 (char*)&errValue, (socklen_t *)&optLen);
10636 #if (defined(SS_VW) || defined(SS_PS))
10637 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10638 (char*)&errValue, (int *)&optLen);
10641 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10642 (char*)&errValue, (int *)&optLen);
10643 #endif /* SS_WINCE */
10645 #endif /* SS_LINUX */
10646 if (ret == INET_ERR)
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);
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 */
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);
10672 #if ( defined(SUNOS) || defined(SS_LINUX))
10673 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10674 NULLP, (socklen_t *)&remAddrLen);
10676 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10677 NULLP, (S32 *)&remAddrLen);
10679 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10680 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10685 }/* if (pendLen == 0)*/
10688 if((*len == CM_INET_READ_THROW) || (*len >= CM_INET_MAX_BYTES_READ))
10690 curLen = CM_INET_MAX_BYTES_READ;
10694 curLen = *len; /*set to given number of messasges to be flushed */
10697 if((*len != CM_INET_READ_THROW) && (*len < pendLen))
10702 #if (defined(WIN32) || defined(CMINETFLATBUF))
10706 * maybe needs more than one recvfrom() call to read an entire
10711 cmMemset((U8*)recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10712 /* added separate recvfrom calls different OS */
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);
10718 #if ( defined(SUNOS) || defined(SS_LINUX))
10719 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10720 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
10722 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempbuf, curLen, 0,
10723 &remSockAddr, (S32 *)&remAddrLen);
10725 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10726 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10728 if (recvLen == INET_ERR)
10731 /* added check ERR_WOULDBLOCK */
10732 if ((INET_ERR_CODE == ERR_AGAIN) ||
10733 (INET_ERR_CODE == ERR_WOULDBLOCK))
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))
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);
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 */
10768 if(recvLen < curLen)
10771 pendLen -= recvLen;
10773 if(pendLen < curLen)
10776 } /* while (curLen > 0) */
10778 #else /* end of Win NT/flat buffer specific part */
10781 * maybe needs more than one recvmsg() call to read entire message
10782 * on a stream socket
10786 cmMemset((U8*)recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10787 /* update the message structure */
10789 rxArr[0].iov_base = (Void*)recvTempBuf;
10790 rxArr[0].iov_len = (U32)curLen;
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;
10798 msg.msg_name = NULLP;
10799 msg.msg_namelen = 0;
10801 /* added defined(_XPG4_2). Also changed the
10803 #if (defined(SS_LINUX) || defined(_XPG4_2))
10804 msg.msg_control = ancillData;
10805 msg.msg_controllen = sizeof(ancillData);
10808 msg.msg_accrights = NULLP;
10809 msg.msg_accrightslen = 0;
10810 #endif /* SS_LINUX */
10812 recvLen = recvmsg(sockFd->fd, &msg, flags);
10813 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
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))
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);
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 */
10839 /* If this happens then cmInetFlushRecvBuf must return RCLOSED.
10840 * Needed for getting icmp msgs */
10841 if (INET_ERR_CODE == ERR_CONNABORTED)
10847 }/* if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))*/
10849 if(recvLen < curLen)
10852 pendLen -= recvLen;
10854 if(pendLen < curLen)
10857 } /* while(curLen > 0) */
10859 #endif /* WIN32 | CMINETFLATBUF */
10863 } /* end of cmInetFlushRecvBuf */
10865 #endif /* CM_INET_FLUSH_RECV_BUF*/
10867 /**********************************************************************
10869 **********************************************************************/