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 /* cm_inet_c_001.main_64: New variable used as an argument for sctp_connectx */
1919 #ifdef SCTP_CONNECTX_NEW
1922 U32 addresses_array_size = 0;
1924 struct sockaddr_in addrs[CM_INET_NUM_NET_ADDR];
1925 U32 ipv4_array_size = 0;
1927 #ifndef IPV6_SUPPORTED
1928 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1930 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1931 #endif /* IPV6_SUPPORTED */
1933 #ifdef IPV6_SUPPORTED
1935 S8 *addrString = NULLP;
1937 S8 ipv4Format[23] = "::ffff:";
1938 CmInetIpAddr ipv4NetAddr;
1939 #endif /* SUN_KSCTP */
1941 struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1942 U32 ipv6_array_size = 0;
1943 #endif /* IPV6_SUPPORTED */
1945 U32 sockAddrLen = 0;
1946 #endif /* sockAddrLen */
1949 CmInetSockAddr *sockAddrPtr = NULLP;
1950 #endif /* SS_LINUX */
1951 #if (ERRCLASS & ERRCLS_INT_PAR)
1952 /* error check on parameters */
1953 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1954 (primAddr == NULLP))
1958 /* cm_inet_c_001.main_58 : Added check for addrLst to fix klockwork issue */
1959 if (addrLst == NULLP)
1963 /* cm_inet_c_001.main_46: Included check for no of address aginst max */
1964 if( addrLst->count > CM_INET_NUM_NET_ADDR )
1968 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1969 /* cm_inet_c_001.main_62:Warning fix */
1970 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1971 " sockFd->fd(%ld)\n",
1972 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1973 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1975 /* cm_inet_c_001.main_62:Warning fix */
1976 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1977 " sockFd->fd(%d)\n",
1978 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1979 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1980 #endif /*ALIGN_64BIT*/
1981 #endif /* CMINETDBG */
1984 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1987 cmMemset((U8*)&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1988 #ifdef IPV6_SUPPORTED
1989 cmMemset((U8*)&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1990 #endif /* IPV6_SUPPORTED */
1994 #ifdef IPV6_SUPPORTED
1995 if (primAddr->type == CM_INET_IPV6ADDR_TYPE)
1997 if (sockFd->protType == AF_INET)
2001 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2002 /* cm_inet_c_001.main_62:Warning fix */
2003 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2004 " sockFd->fd(%ld)\n", sockFd->fd);
2005 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
2007 /* cm_inet_c_001.main_62:Warning fix */
2008 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2009 " sockFd->fd(%d)\n", sockFd->fd);
2010 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
2011 #endif /*ALIGN_64BIT*/
2012 #endif /* CMINETDBG */
2016 addrs6[idx6].sin6_family = AF_INET6;
2017 addrs6[idx6].sin6_port = CM_INET_HTON_U16(port);
2018 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr), &(primAddr->u.ipv6NetAddr));
2019 addresses_array_size += sizeof(struct sockaddr_in6);
2020 ipv6_array_size += sizeof(struct sockaddr_in6);
2026 if (sockFd->protType == AF_INET)
2030 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2031 /* cm_inet_c_001.main_62:Warning fix */
2032 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2033 " sockFd->fd(%ld)\n", sockFd->fd);
2034 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
2036 /* cm_inet_c_001.main_62:Warning fix */
2037 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2038 " sockFd->fd(%d)\n", sockFd->fd);
2039 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
2040 #endif /*ALIGN_64BIT*/
2041 #endif /* CMINETDBG */
2044 addrs6[idx6].sin6_family = AF_INET6;
2045 addrs6[idx6].sin6_port = CM_INET_HTON_U16(port);
2046 ipv4NetAddr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2047 cmInetNtoa(ipv4NetAddr, &addrString);
2048 addrLen = cmStrlen((U8*)addrString);
2049 cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2050 ipv4Format[7+addrLen] = '\0';
2051 cmInetPton6((CmInetIpAddr6*)&(addrs6[idx6].sin6_addr), ipv4Format);
2052 addresses_array_size += sizeof(struct sockaddr_in6);
2053 ipv6_array_size += sizeof(struct sockaddr_in6);
2056 addrs[idx4].sin_family = AF_INET;
2057 addrs[idx4].sin_port = CM_INET_HTON_U16(port);
2058 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2059 addresses_array_size += sizeof(struct sockaddr_in);
2060 ipv4_array_size += sizeof(struct sockaddr_in);
2065 addrs[idx4].sin_family = AF_INET;
2066 addrs[idx4].sin_port = CM_INET_HTON_U16(port);
2067 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(primAddr->u.ipv4NetAddr);
2068 addresses_array_size += sizeof(struct sockaddr_in);
2069 ipv4_array_size += sizeof(struct sockaddr_in);
2071 #endif /* IPV6_SUPPORTED */
2075 /* cm_inet_c_001.main_46: Moved the SS_LINUX flag down,
2076 * copy addresses in Solaris also */
2077 if (addrLst != NULLP)
2079 for (idx = 0; idx < addrLst->count; idx++)
2082 /* cm_inet_c_001.main_46: Don't include the primary address
2083 * if its prersent in list */
2084 if ( addrLst->addrs[idx].type == CM_INET_IPV4ADDR_TYPE )
2086 if ( addrLst->addrs[idx].u.ipv4NetAddr == primAddr->u.ipv4NetAddr )
2091 #ifdef IPV6_SUPPORTED
2092 else if ( addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE )
2094 if (( cmMemcmp(addrLst->addrs[idx].u.ipv6NetAddr,
2095 primAddr->u.ipv6NetAddr, sizeof(CmInetIpAddr6) )) == 0 )
2101 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
2103 if (sockFd->protType == AF_INET)
2107 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2108 /* cm_inet_c_001.main_62:Warning fix */
2109 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2110 " sockFd->fd(%ld)\n", sockFd->fd);
2111 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
2113 /* cm_inet_c_001.main_62:Warning fix */
2114 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
2115 " sockFd->fd(%d)\n", sockFd->fd);
2116 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
2117 #endif /*ALIGN_64BIT*/
2118 #endif /* CMINETDBG */
2122 addrs6[idx6].sin6_family = AF_INET6;
2123 addrs6[idx6].sin6_port = CM_INET_HTON_U16(port);
2124 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr),
2125 &(addrLst->addrs[idx].u.ipv6NetAddr));
2126 addresses_array_size += sizeof(struct sockaddr_in6);
2127 ipv6_array_size += sizeof(struct sockaddr_in6);
2133 if (sockFd->protType == AF_INET)
2137 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2138 /* cm_inet_c_001.main_62:Warning fix */
2139 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2140 " sockFd->fd(%ld)\n", sockFd->fd);
2141 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2143 /* cm_inet_c_001.main_62:Warning fix */
2144 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2145 " sockFd->fd(%d)\n", sockFd->fd);
2146 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2147 #endif /*ALIGN_64BIT*/
2148 #endif /* CMINETDBG */
2151 addrs6[idx6].sin6_family = AF_INET6;
2152 addrs6[idx6].sin6_port = CM_INET_HTON_U16(port);
2153 ipv4NetAddr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2154 cmInetNtoa(ipv4NetAddr, &addrString);
2155 addrLen = cmStrlen((U8*)addrString);
2156 cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2157 ipv4Format[7+addrLen] = '\0';
2158 cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
2159 addresses_array_size += sizeof(struct sockaddr_in6);
2160 ipv6_array_size += sizeof(struct sockaddr_in6);
2163 addrs[idx4].sin_family = AF_INET;
2164 addrs[idx4].sin_port = CM_INET_HTON_U16(port);
2165 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2166 addresses_array_size += sizeof(struct sockaddr_in);
2167 ipv4_array_size += sizeof(struct sockaddr_in);
2169 #endif /* SUN_KSCTP */
2172 addrs[idx4].sin_family = AF_INET;
2173 addrs[idx4].sin_port = CM_INET_HTON_U16(port);
2174 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_U32(addrLst->addrs[idx].u.ipv4NetAddr);
2175 addresses_array_size += sizeof(struct sockaddr_in);
2176 ipv4_array_size += sizeof(struct sockaddr_in);
2178 #endif /* IPV6_SUPPORTED */
2179 /*cm_inet_c_001.main_39 */
2184 /* cm_inet_c_001.main_46: Moved SS_LINUX flag to here */
2186 /*cm_inet_c_001.main_58 : Added check array_size to fix klockwork issue */
2187 if((ipv4_array_size > 0) && (ipv4_array_size <= (CM_INET_NUM_NET_ADDR * \
2188 sizeof(struct sockaddr_in))))
2190 cmMemcpy((U8*)address_array, (U8*)&addrs[0], ipv4_array_size);
2198 #ifdef IPV6_SUPPORTED
2199 if((ipv6_array_size > 0) && (ipv6_array_size <= (CM_INET_NUM_NET_ADDR * \
2200 sizeof(struct sockaddr_in))))
2202 cmMemcpy((U8*)(address_array + ipv4_array_size), (U8*)addrs6, ipv6_array_size);
2208 #endif /* IPV6_SUPPORTED */
2210 /* cm_inet_c_001.main_64: Support for new definition of sctp_connectx */
2211 #ifndef SCTP_CONNECTX_NEW
2212 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt);
2214 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt, (sctp_assoc_t *)&assocId);
2219 /* cm_inet_c_001.main_46: Use next provided address to connect if
2220 * first one fails */
2222 #ifdef CMINET_SUN_CONNECTX
2224 #ifdef IPV6_SUPPORTED
2226 #endif /* IPV6_SUPPORTED */
2227 for (idx = 0; idx < cnt; idx++)
2229 if( addrs[idx4].sin_family == AF_INET)
2231 sockAddrPtr = (CmInetSockAddr *)&addrs[idx4];
2232 sockAddrLen = sizeof(struct sockaddr_in);
2235 #ifdef IPV6_SUPPORTED
2238 sockAddrPtr = (CmInetSockAddr *)&addrs6[idx6];
2239 sockAddrLen = sizeof(struct sockaddr_in6);
2242 #endif/* IPV6_SUPPORTED */
2244 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2246 if ( ret != INET_ERR )
2252 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2253 /* cm_inet_c_001.main_62:Warning fix */
2254 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2255 " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2256 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2258 /* cm_inet_c_001.main_62:Warning fix */
2259 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2260 " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2261 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2262 #endif /*ALIGN_64BIT*/
2263 #endif /* CMINETDBG */
2268 if( addrs[0].sin_family == AF_INET)
2270 sockAddrPtr = (CmInetSockAddr*)&addrs[0];
2271 sockAddrLen = sizeof(struct sockaddr_in);
2274 #ifdef IPV6_SUPPORTED
2277 sockAddrPtr = (CmInetSockAddr*)&addrs6[0];
2278 sockAddrLen = sizeof(struct sockaddr_in6);
2281 #endif/* IPV6_SUPPORTED */
2283 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2285 #endif /* CMINET_SUN_CONNECTX */
2286 #endif /* SS_LINUX */
2288 if (ret == INET_ERR)
2292 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2293 /* cm_inet_c_001.main_62:Warning fix */
2294 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2295 " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2296 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
2298 /* cm_inet_c_001.main_62:Warning fix */
2299 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2300 " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2301 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
2302 #endif /*ALIGN_64BIT*/
2303 #endif /* CMINETDBG */
2305 switch (INET_ERR_CODE)
2307 /* non-blocking: connection is in progress */
2308 case ERR_INPROGRESS:
2309 RETVALUE(RINPROGRESS);
2313 * non-blocking: connection is established
2314 * blocking : connection is already established
2320 /* resource temporarily unavailable */
2321 case ERR_WOULDBLOCK:
2325 /* non-blocking: connection is in progress */
2327 RETVALUE(RINPROGRESS);
2331 RETVALUE(RINPROGRESS);
2334 /* Check for connection refused and timeout errors */
2335 case ERR_CONNREFUSED:
2340 /* it is a real error */
2352 * Fun: cmInetSctpPeelOff
2354 * Desc: Branches an existing sctp association off to a seperate socket
2356 * Ret: ROK - successful
2365 PUBLIC S16 cmInetSctpPeelOff
2367 CmInetFd *sockFd, /* socket file descriptor */
2368 U32 assocId, /* association id */
2369 CmInetFdType *assocFd /* association fd */
2372 PUBLIC S16 cmInetSctpPeelOff(sockFd, assocId, assocFd)
2373 CmInetFd *sockFd; /* socket file descriptor */
2374 U32 assocId; /* association id */
2375 CmInetFdType *assocFd; /* association fd */
2380 #if (ERRCLASS & ERRCLS_INT_PAR)
2381 /* error check on parameters */
2382 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) || (assocFd == NULLP))
2386 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2389 ret = sctp_peeloff(sockFd->fd, assocId);
2390 if (ret == INET_ERR)
2394 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2395 /* cm_inet_c_001.main_62:Warning fix */
2396 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%ld),"
2397 " sockFd->fd(%ld)\n", INET_ERR_CODE, assocId, sockFd->fd);
2398 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2400 /* cm_inet_c_001.main_55: Fix for compilation warning */
2401 /* cm_inet_c_001.main_62:Warning fix */
2402 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%d),"
2403 " sockFd->fd(%d)\n", INET_ERR_CODE, assocId, sockFd->fd);
2404 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2405 #endif /*ALIGN_64BIT*/
2406 #endif /* CMINETDBG */
2418 * Fun: cmInetSctpSendMsg
2420 * Desc: invokes sctp socket API to send message to the remote addresses
2422 * Ret: ROK - successful
2431 PUBLIC S16 cmInetSctpSendMsg
2433 CmInetFd *sockFd, /* socket file descriptor */
2434 CmInetNetAddr *dstAddr, /* destination Internet address/port */
2435 U16 port, /* destination port no. */
2436 CmInetMemInfo *info, /* buffer allocation info */
2437 Buffer *mBuf, /* buffer structure to send */
2438 MsgLen *len, /* number of actually sent octets */
2439 U16 strmId, /* sctp stream identifier */
2440 Bool unorderFlg, /* flag to enable the unordered delivery */
2441 U16 ttl, /* time to live */
2442 U32 ppId, /* opaque value passed along with the message */
2443 U32 context /* value to be passed back, if error occurs */
2446 PUBLIC S16 cmInetSctpSendMsg(sockFd, dstAddr, port, info, mBuf, len, strmId,
2447 unorderFlg, ttl, ppId, context)
2448 CmInetFd *sockFd; /* socket file descriptor */
2449 CmInetNetAddr *dstAddr; /* destination Internet address/port */
2450 U16 port; /* destination port no. */
2451 CmInetMemInfo *info; /* buffer allocation info */
2452 Buffer *mBuf; /* buffer structure to send */
2453 MsgLen *len; /* number of actually sent octets */
2454 U16 strmId; /* sctp stream identifier */
2455 Bool unorderFlg; /* flag to enable the unordered delivery */
2456 U16 ttl; /* time to live */
2457 U32 ppId; /* opaque value passed along with the message */
2458 U32 context; /* value to be passed back, if error occurs */
2462 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2463 MsgLen msgLen = 0; /* message length */
2464 MsgLen bufLen = 0; /* send buffer length */
2465 Data *sendBuf = NULLP; /* plain send buffer */
2467 CmInetSockAddr *sockAddrPtr = NULLP;
2468 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2469 MsgLen sockAddrLen = 0;
2470 struct sockaddr_in addr;
2471 #ifdef IPV6_SUPPORTED
2473 S8 *addrString = NULLP;
2475 S8 ipv4Format[23] = "::ffff:";
2476 CmInetIpAddr ipv4NetAddr;
2477 #endif /* SUN_KSCTP */
2478 struct sockaddr_in6 addr6;
2479 #endif /* IPV6_SUPPORTED */
2481 #if (ERRCLASS & ERRCLS_INT_PAR)
2482 /* error check on parameters */
2483 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd)
2484 || (info == NULLP) || (mBuf == NULLP) || (len == NULLP))
2488 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2491 cmMemset((U8*)&addr, 0, sizeof(struct sockaddr_in));
2492 #ifdef IPV6_SUPPORTED
2493 cmMemset((U8*)&addr6, 0, sizeof(struct sockaddr_in6));
2494 #endif /* IPV6_SUPPORTED */
2496 /* copy message to a flat buffer */
2497 ret = SFndLenMsg(mBuf, &bufLen);
2502 /* max message length is limited to control the memory usage */
2503 /* casting bufLen to avoid warnings */
2504 if ((bufLen > 0) && ((U32)bufLen > CM_INET_MAX_MSG_LEN))
2508 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
2513 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
2514 if ((ret != ROK) || (msgLen != bufLen))
2516 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2520 if ( dstAddr != NULLP)
2522 #ifdef IPV6_SUPPORTED
2523 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
2525 if (sockFd->protType == AF_INET)
2527 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2530 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2531 /* cm_inet_c_001.main_62:Warning fix */
2532 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2533 " IPV4 socket, sockFd->fd(%ld)\n", sockFd->fd);
2534 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2536 /* cm_inet_c_001.main_62:Warning fix */
2537 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2538 " IPV4 socket, sockFd->fd(%d)\n", sockFd->fd);
2539 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2540 #endif /*ALIGN_64BIT*/
2541 #endif /* CMINETDBG */
2545 addr6.sin6_family = AF_INET6;
2546 addr6.sin6_port = CM_INET_HTON_U16(port);
2547 CM_INET_COPY_IPV6ADDR(&addr6.sin6_addr.s6_addr, &dstAddr->u.ipv6NetAddr);
2548 sockAddrLen = sizeof(struct sockaddr_in6);
2549 sockAddrPtr = (CmInetSockAddr*)&addr6;
2555 if (sockFd->protType == AF_INET)
2559 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2560 /* cm_inet_c_001.main_62:Warning fix */
2561 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2562 " socket, sockFd->fd(%ld)\n", sockFd->fd);
2563 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2565 /* cm_inet_c_001.main_62:Warning fix */
2566 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2567 " socket, sockFd->fd(%d)\n", sockFd->fd);
2568 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2569 #endif /*ALIGN_64BIT*/
2570 #endif /* CMINETDBG */
2573 addr6.sin6_family = AF_INET6;
2574 addr6.sin6_port = CM_INET_HTON_U16(port);
2575 ipv4NetAddr = CM_INET_HTON_U32(dstAddr->u.ipv4NetAddr);
2576 cmInetNtoa(ipv4NetAddr, &addrString);
2577 addrLen = cmStrlen((U8*)addrString);
2578 cmMemcpy((U8*)(ipv4Format+7), (U8*)addrString, addrLen);
2579 ipv4Format[7+addrLen] = '\0';
2580 cmInetPton6((CmInetIpAddr6*)(addr6.sin6_addr.s6_addr), ipv4Format);
2581 sockAddrLen = sizeof(struct sockaddr_in6);
2582 sockAddrPtr = (CmInetSockAddr*)&addr6;
2584 addr.sin_family = AF_INET;
2585 addr.sin_port = CM_INET_HTON_U16(port);
2586 addr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->u.ipv4NetAddr);
2587 sockAddrLen = sizeof(struct sockaddr_in);
2588 sockAddrPtr = (CmInetSockAddr*)&addr;
2589 #endif /* SUN_KSCTP */
2592 addr.sin_family = AF_INET;
2593 addr.sin_port = CM_INET_HTON_U16(port);
2594 addr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->u.ipv4NetAddr);
2595 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2596 sockAddrLen = (MsgLen)sizeof(struct sockaddr_in);
2597 sockAddrPtr = (CmInetSockAddr*)&addr;
2598 #endif /* IPV6_SUPPORTED */
2605 sockAddrPtr = (CmInetSockAddr*)&addr;
2607 /* cm_inet_c_001.main_58 : initialized sockAddrLen properly */
2608 #ifdef IPV6_SUPPORTED
2609 sockAddrLen = sizeof(struct sockaddr_in6);
2611 sockAddrLen = sizeof(struct sockaddr_in);
2615 /* Not validating the address, whether addr is a valid address or not */
2620 if (unorderFlg == TRUE)
2623 flags |= MSG_UNORDERED;
2626 flags |= SCTP_UNORDERED;
2629 /*cm_inet_c_001.main_54: converting ppid to network*/
2630 ppId = CM_INET_HTON_U32(ppId);
2631 ret = sctp_sendmsg(sockFd->fd, (Void*)sendBuf, bufLen,
2632 (struct sockaddr*)sockAddrPtr, (size_t)sockAddrLen,
2633 ppId, flags, strmId, ttl, context);
2634 if (ret == INET_ERR)
2636 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2639 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2640 /* cm_inet_c_001.main_62:Warning fix */
2641 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%ld),"
2642 " strmId(%u),sockFd->fd(%ld)\n",
2643 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2644 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2646 /* cm_inet_c_001.main_55: Fix for compilation warning */
2647 /* cm_inet_c_001.main_62:Warning fix */
2648 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%d),"
2649 " strmId(%u),sockFd->fd(%d)\n",
2650 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2651 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2652 #endif /*ALIGN_64BIT*/
2653 #endif /* CMINETDBG */
2655 if ((INET_ERR_CODE == ERR_AGAIN) || (INET_ERR_CODE == ERR_WOULDBLOCK))
2656 RETVALUE(RWOULDBLOCK);
2657 else if (INET_ERR_CODE == ERR_PIPE)
2663 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2667 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2674 * Fun: cmInetSctpRecvMsg
2676 * Desc: invokes sctp API to get the message received at sctp socket
2678 * Ret: ROK - successful
2687 PUBLIC S16 cmInetSctpRecvMsg
2689 CmInetFd *sockFd, /* socket file descriptor */
2690 CmInetNetAddr *srcAddr, /* source Internet address/port */
2691 U16 *port, /* source port no. */
2692 CmInetMemInfo *meminfo, /* buffer allocation info */
2693 Buffer **mBuf, /* buffer structure received */
2694 MsgLen *len, /* number of octets received */
2695 CmInetSctpSndRcvInfo *sinfo, /* sctp send-receive info */
2696 U32 *flag, /* flags */
2697 CmInetSctpNotification *ntfy /* notification parameters */
2700 PUBLIC S16 cmInetSctpRecvMsg(sockFd, srcAddr, port, meminfo, mBuf, len,
2702 CmInetFd *sockFd; /* socket file descriptor */
2703 CmInetNetAddr *srcAddr; /* source Internet address/port */
2704 U16 *port; /* source port no. */
2705 CmInetMemInfo *meminfo; /* buffer allocation info */
2706 Buffer **mBuf; /* buffer structure received */
2707 MsgLen *len; /* number of octets received */
2708 CmInetSctpSndRcvInfo *sinfo; /* sctp send-receive info */
2709 U32 *flag; /* flags */
2710 CmInetSctpNotification *ntfy; /* notification parameters */
2715 struct sctp_sndrcvinfo info;
2716 struct sockaddr_storage addr;
2717 struct sockaddr_in *pAddr = NULLP;
2718 #ifdef IPV6_SUPPORTED
2719 struct sockaddr_in6 *pAddr6 = NULLP;
2722 Data *recvbuf = NULLP;
2724 union sctp_notification *sctpNtfy = NULLP;
2725 /* cm_inet_c_001.main_46: Defined new variable to store length of data */
2728 #endif /* SS_LINUX */
2730 #if (ERRCLASS & ERRCLS_INT_PAR)
2731 /* error check on parameters */
2732 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
2733 (srcAddr == NULLP) || (port == NULLP) || (meminfo == NULLP) ||
2734 (mBuf == NULLP) || (len == NULLP) || (sinfo == NULLP) || (flag == NULLP))
2738 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2743 cmMemset((U8*)ntfy, 0, sizeof(CmInetSctpNotification));
2745 buflen = CM_INET_MAX_MSG_LEN;
2747 /* allocate flat receive buffer */
2748 ret = SGetSBuf(meminfo->region, meminfo->pool, &recvbuf, buflen);
2752 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2753 /* cm_inet_c_001.main_62:Warning fix */
2754 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failed to allocate memory\n");
2755 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET065, 0, prntBuf);
2756 #endif /* CMINETDBG */
2760 addrlen = sizeof(struct sockaddr_storage);
2762 cmMemset((U8*)&addr, 0, sizeof(struct sockaddr_storage));
2763 cmMemset((U8*)&info, 0, sizeof(struct sctp_sndrcvinfo));
2765 ret = sctp_recvmsg(sockFd->fd, (Void *)recvbuf, (size_t)buflen,
2766 (struct sockaddr*)&addr, &addrlen, &info,
2768 if (ret == INET_ERR)
2771 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2774 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2775 /* cm_inet_c_001.main_62:Warning fix */
2776 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2777 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
2778 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2780 /* cm_inet_c_001.main_62:Warning fix */
2781 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2782 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
2783 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2784 #endif /*ALIGN_64BIT*/
2785 #endif /* CMINETDBG */
2790 /* save the length of the received message */
2791 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2794 #ifdef IPV6_SUPPORTED
2795 if (addr.ss_family == AF_INET6)
2797 U8 ipv4Format[12] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff};
2798 pAddr6 = (struct sockaddr_in6*)&addr;
2799 *port = CM_INET_NTOH_U16(pAddr6->sin6_port);
2801 if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
2803 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2804 cmMemcpy((U8*)&srcAddr->u.ipv4NetAddr, (U8*)((pAddr6->sin6_addr.s6_addr) + 12), sizeof(U32));
2805 srcAddr->u.ipv4NetAddr = CM_INET_HTON_U32(srcAddr->u.ipv4NetAddr);
2810 srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2811 CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr);
2816 pAddr = (struct sockaddr_in*)&addr;
2817 *port = CM_INET_NTOH_U16(pAddr->sin_port);
2818 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2819 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2822 pAddr = (struct sockaddr_in*)&addr;
2823 *port = CM_INET_NTOH_U16(pAddr->sin_port);
2824 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2825 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2826 #endif /* IPV6_SUPPORTED */
2828 /* fill sndrcv info */
2829 sinfo->stream = info.sinfo_stream;
2830 sinfo->ssn = info.sinfo_ssn;
2831 sinfo->flags = info.sinfo_flags;
2832 /*cm_inet_c_001.main_54: converting ppid to host*/
2833 sinfo->ppid = CM_INET_NTOH_U32(info.sinfo_ppid);
2834 sinfo->context = info.sinfo_context;
2835 sinfo->timetolive = info.sinfo_timetolive;
2836 sinfo->tsn = info.sinfo_tsn;
2837 sinfo->cumtsn = info.sinfo_cumtsn;
2838 sinfo->assocId = info.sinfo_assoc_id;
2840 /* fill message flags */
2842 if ((msgFlags & MSG_EOR) != 0)
2843 *flag |= CM_INET_SCTP_MSG_EOR;
2845 if ((msgFlags & MSG_NOTIFICATION) != 0)
2847 *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2850 sctpNtfy = (union sctp_notification*)recvbuf;
2852 ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2853 ntfy->header.nLen = sctpNtfy->sn_header.sn_length;
2855 switch(sctpNtfy->sn_header.sn_type)
2857 case SCTP_ASSOC_CHANGE:
2858 ntfy->header.nType = CM_INET_SCTP_ASSOC_CHANGE;
2859 switch(sctpNtfy->sn_assoc_change.sac_state)
2862 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2864 case SCTP_COMM_LOST:
2865 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2868 ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2870 case SCTP_SHUTDOWN_COMP:
2871 ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2873 case SCTP_CANT_STR_ASSOC:
2874 ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
2879 ntfy->u.assocChange.error = sctpNtfy->sn_assoc_change.sac_error;
2880 ntfy->u.assocChange.outStreams = sctpNtfy->sn_assoc_change.sac_outbound_streams;
2881 ntfy->u.assocChange.inStreams = sctpNtfy->sn_assoc_change.sac_inbound_streams;
2882 ntfy->u.assocChange.assocId = sctpNtfy->sn_assoc_change.sac_assoc_id;
2884 ntfy->u.assocChange.info = sctpNtfy->sn_assoc_change.sac_info;
2887 case SCTP_PEER_ADDR_CHANGE:
2888 ntfy->header.nType = CM_INET_SCTP_PEER_ADDR_CHANGE;
2889 switch(sctpNtfy->sn_paddr_change.spc_state)
2891 case SCTP_ADDR_AVAILABLE:
2892 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2894 case SCTP_ADDR_UNREACHABLE:
2895 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2897 case SCTP_ADDR_REMOVED:
2898 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2900 case SCTP_ADDR_ADDED:
2901 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2903 case SCTP_ADDR_MADE_PRIM:
2904 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2907 case SCTP_ADDR_CONFIRMED:
2908 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2915 #ifdef IPV6_SUPPORTED
2916 if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
2918 pAddr6 = (struct sockaddr_in6*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2919 ntfy->u.paddrChange.addr.type = CM_INET_IPV6ADDR_TYPE;
2920 CM_INET_COPY_IPV6ADDR(&ntfy->u.paddrChange.addr.u.ipv6NetAddr,
2921 &pAddr6->sin6_addr.s6_addr);
2925 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2926 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2927 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2930 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2931 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2932 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
2933 #endif /* IPV6_SUPPORTED */
2935 ntfy->u.paddrChange.error = sctpNtfy->sn_paddr_change.spc_error;
2936 ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2938 case SCTP_REMOTE_ERROR:
2939 ntfy->header.nType = CM_INET_SCTP_REMOTE_ERROR;
2941 ntfy->u.remoteErr.error = sctpNtfy->sn_remote_error.sre_error;
2942 ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2944 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2945 datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2947 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2948 &ntfy->u.remoteErr.data, datlen );
2951 ntfy->u.remoteErr.data = NULLP;
2954 cmMemcpy(ntfy->u.remoteErr.data,\
2955 sctpNtfy->sn_remote_error.sre_data, datlen);
2958 case SCTP_SEND_FAILED:
2959 ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2961 ntfy->u.sndFailed.error = sctpNtfy->sn_send_failed.ssf_error;
2962 ntfy->u.sndFailed.assocId = sctpNtfy->sn_send_failed.ssf_assoc_id;
2964 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2965 datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2967 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2968 &ntfy->u.sndFailed.data, datlen );
2971 ntfy->u.sndFailed.data = NULLP;
2974 cmMemcpy(ntfy->u.sndFailed.data,\
2975 sctpNtfy->sn_send_failed.ssf_data, datlen );
2977 ntfy->u.sndFailed.info.stream = sctpNtfy->sn_send_failed.ssf_info.sinfo_stream;
2978 ntfy->u.sndFailed.info.ssn = sctpNtfy->sn_send_failed.ssf_info.sinfo_ssn;
2979 ntfy->u.sndFailed.info.flags = sctpNtfy->sn_send_failed.ssf_info.sinfo_flags;
2980 ntfy->u.sndFailed.info.ppid = sctpNtfy->sn_send_failed.ssf_info.sinfo_ppid;
2981 ntfy->u.sndFailed.info.context = sctpNtfy->sn_send_failed.ssf_info.sinfo_context;
2982 ntfy->u.sndFailed.info.timetolive = sctpNtfy->sn_send_failed.ssf_info.sinfo_timetolive;
2983 ntfy->u.sndFailed.info.tsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_tsn;
2984 ntfy->u.sndFailed.info.cumtsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_cumtsn;
2985 ntfy->u.sndFailed.info.assocId = sctpNtfy->sn_send_failed.ssf_info.sinfo_assoc_id;
2987 case SCTP_SHUTDOWN_EVENT:
2988 ntfy->header.nType = CM_INET_SCTP_SHUTDOWN_EVENT;
2990 ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2993 case SCTP_ADAPTION_INDICATION :
2996 case SCTP_ADAPTATION_INDICATION :
2998 ntfy->header.nType = CM_INET_SCTP_ADAPTATION_INDICATION;
3001 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
3002 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaption_event.sai_assoc_id;
3005 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
3006 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaptation_event.sai_assoc_id;
3009 case SCTP_PARTIAL_DELIVERY_EVENT:
3010 ntfy->header.nType = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
3012 ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
3013 ntfy->u.pdapiEvt.assocId = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
3021 /* get a message buffer */
3022 ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
3025 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3029 ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
3033 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3039 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
3046 * Fun: cmInetSctpGetPAddrs
3048 * Desc: returns the list of peer addresses
3050 * Ret: ROK - successful
3059 PUBLIC S16 cmInetSctpGetPAddrs
3061 CmInetFd *sockFd, /* socket file descriptor */
3062 U32 assocId, /* association id */
3063 CmInetNetAddrLst *addrlst /* peer address list */
3066 PUBLIC S16 cmInetSctpGetPAddrs(sockFd, assocId, addrlst)
3067 CmInetFd *sockFd; /* socket file descriptor */
3068 U32 assocId; /* association id */
3069 CmInetNetAddrLst *addrlst; /* peer address list */
3072 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
3076 struct sockaddr *peerAddrList;
3077 struct sockaddr_in *pAddr;
3078 #ifdef IPV6_SUPPORTED
3079 struct sockaddr_in6 *pAddr6;
3080 #endif /* IPV6_SUPPORTED */
3083 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
3085 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
3090 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3091 /* cm_inet_c_001.main_62:Warning fix */
3092 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
3093 " sockFd->fd(%ld), assocId(%ld)\n",
3094 INET_ERR_CODE, sockFd->fd, assocId);
3095 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
3097 /* cm_inet_c_001.main_55: Fix for compilation warning */
3098 /* cm_inet_c_001.main_62:Warning fix */
3099 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
3100 " sockFd->fd(%d),assocId(%d)\n",
3101 INET_ERR_CODE, sockFd->fd, assocId);
3102 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
3103 #endif /*ALIGN_64BIT*/
3104 #endif /* CMINETDBG */
3109 byteAddress = (U8*)peerAddrList;
3110 for (idx = 0; idx < cnt; idx++)
3112 #ifdef IPV6_SUPPORTED
3114 if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
3116 if (sockFd->protType == AF_INET)
3120 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3121 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
3122 " sockFd->fd(%ld)", sockFd->fd);
3123 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
3125 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
3126 " sockFd->fd(%d)", sockFd->fd);
3127 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
3128 #endif /*ALIGN_64BIT*/
3129 #endif /* CMINETDBG */
3131 sctp_freepaddrs(peerAddrList);
3135 pAddr6 = (struct sockaddr_in6*)byteAddress;
3137 addrlst->addrs[idx].type = CM_INET_IPV6ADDR_TYPE;
3138 CM_INET_COPY_IPV6ADDR(&(addrlst->addrs[idx].u.ipv6NetAddr), &(pAddr6->sin6_addr.s6_addr));
3139 byteAddress += sizeof(struct sockaddr_in6);
3143 pAddr = (struct sockaddr_in*)byteAddress;
3144 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
3145 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3146 byteAddress += sizeof(struct sockaddr_in);
3149 pAddr = (struct sockaddr_in*)byteAddress;
3150 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
3151 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3152 byteAddress += sizeof(struct sockaddr_in);
3153 #endif /* IPV6_SUPPORTED */
3156 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
3157 addrlst->count = (U8)cnt;
3159 sctp_freepaddrs(peerAddrList);
3168 * Desc: invokes socket API to retrive specified socket options
3170 * Ret: ROK - successful
3179 PUBLIC S16 cmInetGetOpt
3181 CmInetFd *sockFd, /* socket file descriptor */
3182 U32 level, /* option level */
3183 U32 type, /* option type */
3184 Ptr value /* option value */
3187 PUBLIC S16 cmInetGetOpt(sockFd, level, type, value)
3188 CmInetFd *sockFd; /* socket file descriptor */
3189 U32 level; /* option level */
3190 U32 type; /* option type */
3191 Ptr value; /* option value */
3195 struct sctp_status status;
3196 struct sctp_paddrinfo addrInfo;
3197 struct sockaddr_in *pAddr;
3198 #ifdef IPV6_SUPPORTED
3199 struct sockaddr_in6 *pAddr6;
3200 #endif /* IPV6_SUPPORTED */
3201 struct sctp_assocparams assocParams;
3202 /*cm_inet_c_001.main_40 Updated for the support of configurable RTO parameters,
3203 HBeat value Max retransmissions (Init, Path, Association)*/
3204 struct sctp_initmsg initMsg;
3205 struct sctp_rtoinfo rtoInfo;
3206 struct sctp_paddrparams addrParams;
3207 CmInetSctpStatus *pSctpStatus;
3208 CmInetSctpPeerAddrInfo *pPeerAddrInfo;
3209 CmInetSctpInitMsg *pInitMsg;
3210 CmInetSctpAssocParams *pAssocParams;
3211 CmInetSctpRtoInfo *pRtoInfo;
3212 CmInetSctpPeerAddrParams *pPeerAddrParams;
3213 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3218 #if (ERRCLASS & ERRCLS_INT_PAR)
3219 /* error check on parameters */
3220 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3224 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3228 case CM_INET_OPT_SCTP_GET_ASSOC_STA:
3229 pSctpStatus = (CmInetSctpStatus*)value;
3230 cmMemset((U8*)&status, 0, sizeof(struct sctp_status));
3231 len = sizeof(status);
3232 status.sstat_assoc_id = pSctpStatus->assocId;
3234 ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
3236 pSctpStatus->rwnd = status.sstat_rwnd;
3237 pSctpStatus->unackdata = status.sstat_unackdata;
3238 pSctpStatus->penddata = status.sstat_penddata;
3239 pSctpStatus->instrms = status.sstat_instrms;
3240 pSctpStatus->outstrms = status.sstat_outstrms;
3241 pSctpStatus->fragPoint = status.sstat_fragmentation_point;
3243 switch (status.sstat_state)
3253 pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3260 pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3266 case SCTPS_COOKIE_WAIT:
3268 case SCTP_COOKIE_WAIT:
3271 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3276 case SCTPS_COOKIE_ECHOED:
3278 case SCTP_COOKIE_ECHOED:
3281 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3286 case SCTPS_ESTABLISHED:
3288 case SCTP_ESTABLISHED:
3291 pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3296 case SCTPS_SHUTDOWN_PENDING:
3298 case SCTP_SHUTDOWN_PENDING:
3301 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3306 case SCTPS_SHUTDOWN_SENT:
3308 case SCTP_SHUTDOWN_SENT:
3311 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3316 case SCTPS_SHUTDOWN_RECEIVED:
3318 case SCTP_SHUTDOWN_RECEIVED:
3321 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3326 case SCTPS_SHUTDOWN_ACK_SENT:
3328 case SCTP_SHUTDOWN_ACK_SENT:
3331 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3342 #ifdef IPV6_SUPPORTED
3343 if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3345 pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3346 pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr6->sin6_port);
3348 pSctpStatus->primary.addr.type = CM_INET_IPV6ADDR_TYPE;
3349 CM_INET_COPY_IPV6ADDR(&pSctpStatus->primary.addr.u.ipv6NetAddr,
3350 &pAddr6->sin6_addr.s6_addr);
3354 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3355 pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr->sin_port);
3356 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3357 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3360 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3361 pSctpStatus->primary.port = CM_INET_NTOH_U16(pAddr->sin_port);
3362 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3363 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_U32(pAddr->sin_addr.s_addr);
3364 #endif /* IPV6_SUPPORTED */
3366 pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3367 if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3368 pSctpStatus->primary.isActive = TRUE;
3370 pSctpStatus->primary.isActive = FALSE;
3371 pSctpStatus->primary.cwnd = status.sstat_primary.spinfo_cwnd;
3372 pSctpStatus->primary.srtt = status.sstat_primary.spinfo_srtt;
3373 pSctpStatus->primary.rto = status.sstat_primary.spinfo_rto;
3374 pSctpStatus->primary.mtu = status.sstat_primary.spinfo_mtu;
3377 case CM_INET_OPT_SCTP_GET_PADDR_INFO:
3378 pPeerAddrInfo = (CmInetSctpPeerAddrInfo*)value;
3379 cmMemset((U8*)&addrInfo, 0, sizeof(struct sctp_paddrinfo));
3380 len = sizeof(addrInfo);
3381 addrInfo.spinfo_assoc_id = pPeerAddrInfo->assocId;
3383 #ifdef IPV6_SUPPORTED
3384 if (pPeerAddrInfo->addr.type == CM_INET_IPV6ADDR_TYPE)
3386 if (sockFd->protType == AF_INET)
3390 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3391 /* cm_inet_c_001.main_62:Warning fix */
3392 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3393 " sockFd->fd(%ld)\n", sockFd->fd);
3394 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3396 /* cm_inet_c_001.main_62:Warning fix */
3397 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3398 " sockFd->fd(%d)\n", sockFd->fd);
3399 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3400 #endif /*ALIGN_64BIT*/
3401 #endif /* CMINETDBG */
3405 pAddr6 = (struct sockaddr_in6*)&(addrInfo.spinfo_address);
3406 pAddr6->sin6_family = AF_INET6;
3407 pAddr6->sin6_port = CM_INET_HTON_U16(pPeerAddrInfo->port);
3408 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrInfo->addr.u.ipv6NetAddr);
3412 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3413 pAddr->sin_family = AF_INET;
3414 pAddr->sin_port = CM_INET_HTON_U16(pPeerAddrInfo->port);
3415 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3418 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3419 pAddr->sin_family = AF_INET;
3420 pAddr->sin_port = CM_INET_HTON_U16(pPeerAddrInfo->port);
3421 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3422 #endif /* IPV6_SUPPORTED */
3424 /* Not validating the address, whether Addr is a valid address or not */
3426 ret = getsockopt(sockFd->fd, level, SCTP_GET_PEER_ADDR_INFO, &addrInfo, &len);
3428 if (addrInfo.spinfo_state == SCTP_ACTIVE)
3429 pPeerAddrInfo->isActive = TRUE;
3431 pPeerAddrInfo->isActive = FALSE;
3432 pPeerAddrInfo->cwnd = addrInfo.spinfo_cwnd;
3433 pPeerAddrInfo->srtt = addrInfo.spinfo_srtt;
3434 pPeerAddrInfo->rto = addrInfo.spinfo_rto;
3435 pPeerAddrInfo->mtu = addrInfo.spinfo_mtu;
3438 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
3440 pPeerAddrParams = (CmInetSctpPeerAddrParams *)value;
3442 cmMemset((U8*)&addrParams, 0, sizeof(struct sctp_paddrparams));
3444 addrParams.spp_assoc_id = pPeerAddrParams->assocId;
3446 if (pPeerAddrParams->s.addrPres == TRUE)
3448 #ifdef IPV6_SUPPORTED
3449 if (pPeerAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
3451 if (sockFd->protType == AF_INET)
3455 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3456 /* cm_inet_c_001.main_62:Warning fix */
3457 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%ld)\n",
3459 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3461 /* cm_inet_c_001.main_62:Warning fix */
3462 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%d)\n",
3464 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3465 #endif /*ALIGN_64BIT*/
3466 #endif /* CMINETDBG */
3470 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
3471 pAddr6->sin6_family = AF_INET6;
3472 pAddr6->sin6_port = CM_INET_HTON_U16(pPeerAddrParams->s.port);
3473 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrParams->s.addr.u.ipv6NetAddr);
3477 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3478 pAddr->sin_family = AF_INET;
3479 pAddr->sin_port = CM_INET_HTON_U16(pPeerAddrParams->s.port);
3480 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3483 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3484 pAddr->sin_family = AF_INET;
3485 pAddr->sin_port = CM_INET_HTON_U16(pPeerAddrParams->s.port);
3486 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3487 #endif /* IPV6_SUPPORTED */
3491 #ifdef IPV6_SUPPORTED
3492 if (sockFd->protType == AF_INET6)
3493 addrParams.spp_address.ss_family = AF_INET6;
3495 addrParams.spp_address.ss_family = AF_INET;
3497 addrParams.spp_address.ss_family = AF_INET;
3501 len = sizeof(addrParams);
3503 ret = getsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, &len);
3504 /* cm_inet_c_001.main_41 : Fixed the Solaris compilation problem */
3507 pPeerAddrParams->hbInterval = addrParams.spp_hbinterval;
3508 pPeerAddrParams->pathMaxRxt = addrParams.spp_pathmaxrxt;
3509 pPeerAddrParams->assocId = addrParams.spp_assoc_id;
3510 pPeerAddrParams->pathMtu = addrParams.spp_pathmtu;
3511 pPeerAddrParams->sackDelay = addrParams.spp_sackdelay;
3513 if (addrParams.spp_flags & SPP_HB_ENABLE)
3514 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_ENABLE;
3516 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_DISABLE;
3518 if (addrParams.spp_flags & SPP_PMTUD_ENABLE)
3519 pPeerAddrParams->pmtudFlag = CM_INET_OPT_ENABLE;
3521 pPeerAddrParams->pmtudFlag = CM_INET_OPT_DISABLE;
3523 if (addrParams.spp_flags & SPP_SACKDELAY_ENABLE)
3524 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_ENABLE;
3526 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_DISABLE;
3531 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
3533 pAssocParams = (CmInetSctpAssocParams *)value;
3535 cmMemset((U8*)&assocParams, 0, sizeof(struct sctp_assocparams));
3537 assocParams.sasoc_assoc_id = pAssocParams->assocId;
3539 len = sizeof(assocParams);
3541 ret = getsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, &len);
3543 pAssocParams->assocMaxReTx = assocParams.sasoc_asocmaxrxt;
3544 pAssocParams->cookieLife = assocParams.sasoc_cookie_life;
3545 pAssocParams->assocId = assocParams.sasoc_assoc_id;
3546 pAssocParams->numberOfPeerDest = assocParams.sasoc_number_peer_destinations;
3547 pAssocParams->peerRwnd = assocParams.sasoc_peer_rwnd;
3548 pAssocParams->localRwnd = assocParams.sasoc_local_rwnd;
3552 case CM_INET_OPT_SCTP_RTO_INFO:
3554 pRtoInfo = (CmInetSctpRtoInfo *)value;
3556 cmMemset((U8*)&rtoInfo, 0, sizeof(struct sctp_rtoinfo));
3558 len = sizeof(rtoInfo);
3560 ret = getsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoInfo, &len);
3562 pRtoInfo->assocId = rtoInfo.srto_assoc_id;
3563 pRtoInfo->rtoInitial = rtoInfo.srto_initial;
3564 pRtoInfo->rtoMax = rtoInfo.srto_max;
3565 pRtoInfo->rtoMin = rtoInfo.srto_min;
3569 case CM_INET_OPT_SCTP_INIT_MSG:
3571 pInitMsg = (CmInetSctpInitMsg *)value;
3573 cmMemset((U8*)&initMsg, 0, sizeof(struct sctp_initmsg));
3575 len = sizeof(initMsg);
3577 ret = getsockopt(sockFd->fd, level, SCTP_INITMSG, &initMsg, &len);
3579 pInitMsg->maxInitReTx = initMsg.sinit_max_attempts;
3580 pInitMsg->maxInitTimeout = initMsg.sinit_max_init_timeo;
3581 pInitMsg->numOstreams = initMsg.sinit_num_ostreams;
3582 pInitMsg->maxInstreams = initMsg.sinit_max_instreams;
3590 if (ret == INET_ERR)
3594 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3595 /* cm_inet_c_001.main_62:Warning fix */
3596 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3597 " error(%d), sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3598 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3600 /* cm_inet_c_001.main_62:Warning fix */
3601 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3602 " error(%d), sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3603 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3604 #endif /*ALIGN_64BIT*/
3605 #endif /* CMINETDBG */
3612 /* cm_inet_c_001.main_54: Added new function cmInetShutDownSctp()*/
3615 * Fun: cmInetShutDownSctp
3617 * Desc: Shutdown the SCTP association gracefully.
3619 * Ret: ROK - successful
3628 PUBLIC S16 cmInetShutDownSctp
3630 CmInetFd *sockFd /* socket file descriptor */
3633 PUBLIC S16 cmInetShutDownSctp(sockFd)
3634 CmInetFd *sockFd; /* socket file descriptor */
3637 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3639 struct sctp_sndrcvinfo sndRcvInfo;
3641 TRC2(cmInetShutDownSctp);
3643 cmMemset((U8*)&sndRcvInfo, 0, sizeof(sndRcvInfo));
3646 sndRcvInfo.sinfo_flags = MSG_EOF;
3648 sndRcvInfo.sinfo_flags = SCTP_EOF;
3651 /* Call the sctp_send with flag set to termiante the association */
3653 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3659 /* cm_inet_c_001.main_62:Warning fix */
3660 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%ld)\n",
3661 INET_ERR_CODE, sockFd->fd);
3662 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3664 /* cm_inet_c_001.main_62:Warning fix */
3665 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%d)\n",
3666 INET_ERR_CODE, sockFd->fd);
3667 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3668 #endif /*ALIGN_64BIT*/
3669 #endif /* CMINETDBG */
3677 /* cm_inet_c_001.main_61: Added new function cmInetAbortSctpAssoc()*/
3680 * Fun: cmInetAbortSctpAssoc
3682 * Desc: ABORT the association.
3684 * Ret: ROK - successful
3693 PUBLIC S16 cmInetAbortSctpAssoc
3695 CmInetFd *sockFd, /* socket file descriptor */
3696 UConnId assocId /* Association ID */
3699 PUBLIC S16 cmInetAbortSctpAssoc(sockFd, assocId)
3700 CmInetFd *sockFd; /* socket file descriptor */
3701 UConnId assocId; /* Association ID */
3705 struct sctp_sndrcvinfo sndRcvInfo;
3707 TRC2(cmInetAbortSctpAssoc);
3709 cmMemset((U8*)&sndRcvInfo, 0, sizeof(sndRcvInfo));
3712 sndRcvInfo.sinfo_flags = MSG_ABORT;
3714 sndRcvInfo.sinfo_flags = SCTP_ABORT;
3717 sndRcvInfo.sinfo_assoc_id = assocId;
3719 /* Call the sctp_send with flag set to termiante the association */
3721 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3727 /* cm_inet_c_001.main_62:Warning fix */
3728 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%ld)\n",
3729 INET_ERR_CODE, sockFd->fd);
3730 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3732 /* cm_inet_c_001.main_62:Warning fix */
3733 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%d)\n",
3734 INET_ERR_CODE, sockFd->fd);
3735 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3736 #endif /*ALIGN_64BIT*/
3737 #endif /* CMINETDBG */
3750 * Fun: cmInetConnect
3752 * Desc: Establishs a connection to a foreign address (TCP) or associates
3753 * a UDP socket to a foreign address.
3755 * Ret: ROK - successful
3756 * ROKDNA - resource temporarily unavaiable
3757 * RINPROGRESS - connection is in progress (only non-blocking)
3758 * RISCONN - connection is established (only non-blocking)
3768 PUBLIC S16 cmInetConnect
3770 CmInetFd *sockFd, /* socket file descriptor */
3771 CmInetAddr *servAddr /* foreign Internet address/port */
3774 PUBLIC S16 cmInetConnect(sockFd, servAddr)
3775 CmInetFd *sockFd; /* socket file descriptor */
3776 CmInetAddr *servAddr; /* foreign Internet address/port */
3779 S32 ret; /* temporary return value */
3780 struct sockaddr_in dstAddr; /* foreign Internet address/port */
3781 #ifdef IPV6_SUPPORTED
3782 struct sockaddr_in6 dstAddr6; /* foreign Internet IPV6 address/port */
3785 #endif /* CMINETDBG */
3786 #endif /* IPV6_SUPPORTED */
3788 CmInetSockAddr *sockAddrPtr;
3790 TRC2(cmInetConnect);
3792 #if (ERRCLASS & ERRCLS_INT_PAR)
3793 /* error check on parameters */
3794 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3795 (servAddr == NULLP))
3799 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3801 #ifdef IPV6_SUPPORTED
3802 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3804 cmMemset((U8*)&dstAddr6, 0, sizeof(dstAddr6));
3805 dstAddr6.sin6_family = AF_INET6;
3806 dstAddr6.sin6_port = CM_INET_HTON_U16(servAddr->u.ipv6Addr.port);
3807 CM_INET_COPY_IPV6ADDR(&dstAddr6.sin6_addr,
3808 &servAddr->u.ipv6Addr.ipv6NetAddr);
3809 sizeOfAddr = sizeof(struct sockaddr_in6);
3810 sockAddrPtr = (CmInetSockAddr *)&dstAddr6;
3814 cmMemset((U8*)&dstAddr, 0, sizeof(dstAddr));
3815 dstAddr.sin_family = AF_INET;
3816 dstAddr.sin_port = CM_INET_HTON_U16(servAddr->u.ipv4Addr.port);
3817 dstAddr.sin_addr.s_addr = CM_INET_HTON_U32(servAddr->u.ipv4Addr.address);
3818 sizeOfAddr = sizeof(struct sockaddr_in);
3819 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3822 cmMemset((U8*)&dstAddr, 0, sizeof(dstAddr));
3823 dstAddr.sin_family = AF_INET;
3824 dstAddr.sin_port = CM_INET_HTON_U16(servAddr->port);
3825 dstAddr.sin_addr.s_addr = CM_INET_HTON_U32(servAddr->address);
3826 sizeOfAddr = sizeof(struct sockaddr_in);
3827 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3828 #endif /* IPV6_SUPPORTED */
3830 ret = connect(sockFd->fd, sockAddrPtr, sizeOfAddr);
3831 if (ret == INET_ERR)
3833 switch (INET_ERR_CODE)
3835 /* non-blocking: connection is in progress */
3836 case ERR_INPROGRESS:
3837 RETVALUE(RINPROGRESS);
3841 * non-blocking: connection is established
3842 * blocking : connection is already established
3848 /* resource temporarily unavailable */
3849 case ERR_WOULDBLOCK:
3853 /* non-blocking: connection is in progress */
3855 RETVALUE(RINPROGRESS);
3859 RETVALUE(RINPROGRESS);
3862 /* Check for connection refused and timeout errors */
3863 case ERR_CONNREFUSED:
3868 /* it is a real error */
3871 #ifdef IPV6_SUPPORTED
3872 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3873 port = servAddr->u.ipv6Addr.port;
3875 port = servAddr->u.ipv4Addr.port;
3877 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3879 /* cm_inet_c_001.main_62:Warning fix */
3880 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3881 " addrtype(0x%x), port(0x%1x), sockFd->fd(%ld)\n",
3882 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3883 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3885 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3886 " addrtype(0x%x), port(0x%1x), sockFd->fd(%d)\n",
3887 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3888 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3889 #endif /*ALIGN_64BIT*/
3892 /* cm_inet_c_001.main_62:Warning fix */
3893 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%lx),"
3894 "port(0x%1x), sockFd->fd(%ld)\n", INET_ERR_CODE ,
3895 servAddr->address, servAddr->port, sockFd->fd);
3896 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3898 /* cm_inet_c_001.main_62:Warning fix */
3899 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%x),"
3900 "port(0x%x), sockFd->fd(%d)\n", INET_ERR_CODE ,
3901 servAddr->address, servAddr->port, sockFd->fd);
3902 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3903 #endif /*ALIGN_64BIT*/
3904 #endif /* IPV6_SUPPORTED */
3905 #endif /* CMINETDBG */
3912 } /* end of cmInetConnect */
3919 * Desc: Indicates the willingness of a socket to listen for incomming
3920 * connection requests.
3922 * Ret: ROK - successful
3925 * Notes: The backLog value has to be within 0..5
3932 PUBLIC S16 cmInetListen
3934 CmInetFd *sockFd, /* socket file descriptor */
3935 S16 backLog /* max. number of outstandig connections 0..5 */
3938 PUBLIC S16 cmInetListen(sockFd, backLog)
3939 CmInetFd *sockFd; /* socket file descriptor */
3940 S16 backLog; /* max. number of outstandig connections 0..5 */
3943 S32 ret; /* temporary return value */
3947 #if (ERRCLASS & ERRCLS_INT_PAR)
3948 /* error check on parameters */
3949 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3950 (backLog < MIN_BACK_LOG) || (backLog > MAX_BACK_LOG))
3954 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3956 ret = listen(sockFd->fd, backLog);
3957 if (ret == INET_ERR)
3961 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3962 /* cm_inet_c_001.main_62:Warning fix */
3963 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3964 " sockFd->fd(%ld)\n", INET_ERR_CODE, backLog, sockFd->fd);
3965 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3967 /* cm_inet_c_001.main_62:Warning fix */
3968 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3969 " sockFd->fd(%d)\n", INET_ERR_CODE, backLog, sockFd->fd);
3970 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3971 #endif /*ALIGN_64BIT*/
3972 #endif /* CMINETDBG */
3977 } /* end of cmInetListen */
3984 * Desc: Accepts an incoming connection.
3985 * On default the new socket is non-blocking. The options can be
3986 * changed with the function cmInetSetOpt().
3988 * Ret: ROK - successful
3989 * ROKDNA - there is no connection present to accept (only
4000 PUBLIC S16 cmInetAccept
4002 CmInetFd *sockFd, /* socket file descriptor */
4003 CmInetAddr *fromAddr, /* calling Internet address/port */
4004 CmInetFd *newSockFd /* socket file descriptor for new connection*/
4007 PUBLIC S16 cmInetAccept(sockFd, fromAddr, newSockFd)
4008 CmInetFd *sockFd; /* socket file descriptor */
4009 CmInetAddr *fromAddr; /* calling Internet address/port */
4010 CmInetFd *newSockFd; /* socket file descriptor for new connection*/
4013 S32 ret; /* temporary return value */
4014 S32 addrLen; /* address structure length */
4015 struct sockaddr_in *peerAddr; /* calling Internet address/port */
4016 #ifdef IPV6_SUPPORTED
4017 struct sockaddr_in6 *peerAddr6; /* calling Internet address/port */
4018 struct sockaddr_in6 sockAddr;
4020 CmInetSockAddr sockAddr;
4021 #endif /* IPV6_SUPPORTED */
4028 #if (ERRCLASS & ERRCLS_INT_PAR)
4029 /* error check on parameters */
4030 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
4034 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4036 /* change CmInetSockAddr to sockAddr */
4037 addrLen = sizeof(sockAddr);
4040 #if ( defined(SUNOS) || defined(SS_LINUX))
4041 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
4042 (socklen_t *)&addrLen);
4044 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
4046 #endif /* SUNOS || SS_LINUX */
4048 /* cm_inet_c_001.main_58: Moved setting of protType below */
4050 if (CM_INET_INV_SOCK_FD(newSockFd))
4052 if (INET_ERR_CODE == ERR_WOULDBLOCK)
4054 /* no connection present to accept */
4061 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
4062 /* cm_inet_c_001.main_62:Warning fix */
4063 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
4064 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4065 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
4067 /* cm_inet_c_001.main_62:Warning fix */
4068 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
4069 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4070 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
4071 #endif /*ALIGN_64BIT*/
4072 #endif /* CMINETDBG */
4078 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
4079 /* added for IPv6/IPv4 socket distinguishing */
4080 #ifdef IPV6_SUPPORTED
4081 if (addrLen == sizeof(struct sockaddr_in))
4082 newSockFd->protType = AF_INET;
4083 else if(addrLen == sizeof(struct sockaddr_in6))
4084 newSockFd->protType = AF_INET6;
4089 /* cm_inet_c_001.main_62:Warning fix */
4090 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%ld)\n", sockFd->fd);
4091 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
4093 /* cm_inet_c_001.main_62:Warning fix */
4094 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%d)\n", sockFd->fd);
4095 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
4096 #endif /*ALIGN_64BIT*/
4097 #endif /* CMINETDBG */
4100 #endif /* IPV6_SUPPORTED */
4102 /* set the new socket file descriptor type */
4103 newSockFd->type = CM_INET_STREAM;
4105 /* set default options for new socket file descriptor */
4106 optVal = CM_INET_OPT_DISABLE;
4107 ret = cmInetSetOpt(newSockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, &optVal);
4110 ret = cmInetClose(newSockFd);
4114 #ifdef IPV6_SUPPORTED
4115 cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
4116 if (addrLen == sizeof(struct sockaddr_in))
4118 peerAddr = (struct sockaddr_in *)&sockAddr;
4119 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
4120 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(peerAddr->sin_port);
4121 fromAddr->u.ipv4Addr.address =
4122 CM_INET_NTOH_U32(peerAddr->sin_addr.s_addr);
4124 else if (addrLen == sizeof(struct sockaddr_in6))
4126 peerAddr6 = (struct sockaddr_in6 *)&sockAddr;
4127 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
4128 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_U16(peerAddr6->sin6_port);
4129 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
4130 &peerAddr6->sin6_addr);
4133 peerAddr = (struct sockaddr_in *)&sockAddr;
4134 fromAddr->port = CM_INET_NTOH_U16(peerAddr->sin_port);
4135 fromAddr->address = CM_INET_NTOH_U32(peerAddr->sin_addr.s_addr);
4136 #endif /* IPV6_SUPPORTED */
4138 } /* end of cmInetAccept */
4143 * Fun: cmInet4FillTos
4145 * Desc: This function inserts tos (into ancillary data) which
4146 * will be used to fill tos value in ip header in outgoing IP packet
4147 * when sending that packet using sendmsg()function.
4158 PRIVATE S16 cmInet4FillTos
4160 U8 tos, /* tos value to be filled in ipheader */
4161 U8 *cmsgBuf, /* flat buffer where to build ext hdrs */
4162 U32 *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4165 PRIVATE S16 cmInet4FillTos(tos, cmsgBuf, curMsgIdx, protType)
4166 U8 tos; /* tos value to be filled in ipheader */
4167 U8 *cmsgBuf; /* flat buffer where to build ext hdrs */
4168 U32 *curMsgIdx; /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4171 struct cmsghdr *tempHdr;
4174 TRC2(cmInet4FillTos)
4179 /* cmsghdr struc will appear before data in the ancillary data object.
4180 * So put cmsghdr struc in flat buffer first. */
4182 /* cmsghdr struc points to flat buffer's starting address */
4183 tempHdr = (struct cmsghdr *)cmsgBuf;
4185 /* fill up level & type of cmsghdr structure */
4186 tempHdr->cmsg_level = IPPROTO_IPV6;
4187 tempHdr->cmsg_type = IP_TOS;
4188 (*(U8*)CMSG_DATA(tempHdr)) = tos;
4189 len = CMSG_SPACE(sizeof tos);
4192 /* fill up the length of cmsghdr structure */
4193 tempHdr->cmsg_len = len;
4198 }/* end of cmInet4FillTos */
4201 * Fun: cmInetSendDscpMsg
4203 * Desc: Sends the message data hold by mBuf.
4204 * The len paramter gives the actual written octets. If the socket
4205 * is non-blocking this value can be differ from the mBuf length
4206 * because there was not enough transmit buffer space available. If
4207 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4209 * Values for flag parameter:
4211 * CM_INET_NO_FLAG - no additional control flag
4213 * Ret: ROK - successful
4214 * RWOULDBLOCK - no or not entire mBuf sent because would block
4215 * ROUTRES - failed, out of resources
4216 * RCLOSED - connection was closed by the peer
4219 * Notes: The successful completion of a send call does not indicate that
4220 * the data has been successfully delivered!
4222 * This function does not free any sent buffers.
4230 PUBLIC S16 cmInetSendDscpMsg
4232 CmInetFd *sockFd, /* socket file descriptor */
4233 CmInetAddr *dstAddr, /* destination Internet address/port */
4234 CmInetMemInfo *info, /* buffer allocation info */
4235 Buffer *mBuf, /* buffer structure to send */
4236 MsgLen *len, /* number of actually sent octets */
4237 /* added for IPv6 ext hdr */
4238 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4239 S16 flags /* additional control flags, unused */
4242 /* added for IPv6 ext hdr */
4243 PUBLIC S16 cmInetSendDscpMsg(sockFd, dstAddr, info, mBuf, len, ipHdrParams, flags)
4244 CmInetFd *sockFd; /* socket file descriptor */
4245 CmInetAddr *dstAddr; /* destination Internet address/port */
4246 CmInetMemInfo *info; /* buffer allocation info */
4247 Buffer *mBuf; /* buffer structure to send */
4248 MsgLen *len; /* number of actually sent octets */
4249 CmInetIpHdrParm *ipHdrParams; /* IPv6 extensions headers */
4250 S16 flags; /* additional control flags, unused */
4253 #if (defined(WIN32) || defined(CMINETFLATBUF))
4254 S32 ret; /* temporary return value */
4255 MsgLen msgLen; /* message length */
4256 MsgLen bufLen; /* send buffer length */
4257 Data *sendBuf; /* plain send buffer */
4259 S32 ret; /* temporary return value */
4260 S32 retVal; /* temporary return value */
4261 S16 i; /* loop index */
4262 CmInetIovec txArr[CM_INET_MAX_DBUF]; /* scatter vector */
4263 S16 numDBufs; /* number of dBufs in message */
4264 struct msghdr msg; /* sendmsg() message header */
4265 MsgLen msgLen; /* message length */
4266 U32 strtEndDBufNum; /* starting/ending DBuf number */
4267 MsgLen unSentLen; /* sent len */
4268 #ifdef IPV6_SUPPORTED
4269 U32 curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4270 /* added for IPv6 ext hdr */
4271 #if (defined(SS_LINUX) || defined(_XPG4_2))
4272 /* alloc from stack for IPv6 ancill data */
4273 U8 cmsgData[CM_INET_IPV6_ANCIL_DATA];
4274 #endif /* SS_LINUX || _XPG4_2 */
4276 U32 curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4277 #if (defined(SS_LINUX) || defined(_XPG4_2))
4278 /* alloc from stack for IPv4 ancill data */
4279 U8 cmsgData[CM_INET_IPV4_ANCIL_DATA];
4280 #endif /* SS_LINUX || _XPG4_2 */
4281 #endif /* IPV6_SUPPORTED */
4282 #endif /* WIN32 | CMINETFLATBUF */
4284 struct sockaddr_in remAddr; /* remote Internet address */
4285 #ifdef IPV6_SUPPORTED
4286 struct sockaddr_in6 remAddr6; /* remote Internet address */
4287 #endif /* IPV8_SUPPORTED */
4288 CmInetSockAddr *sockAddrPtr;
4289 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4292 /* cm_inet_c_001.main_50 - Added for partial send handling */
4293 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4294 #if (!defined(WIN32))
4298 TRC2(cmInetSendDscpMsg)
4302 #if (ERRCLASS & ERRCLS_INT_PAR)
4303 /* error check on parameters */
4304 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4305 (info == NULLP) || (len == NULLP))
4309 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4311 /* added for IPv6 ext hdr */
4312 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4313 #if (defined(SS_LINUX) || defined(_XPG4_2))
4314 /* cmMemset((U8*)cmsgData, 0, sizeof(cmsgData)); */
4315 #endif /* SS_LINUX || _XPG4_2 */
4317 #endif /* WIN32 | CMINETFLATBUF */
4319 msgLen = 0; /* need by CC to pass without warning */
4320 sockAddrPtr = NULLP;
4323 /* setup remote address */
4324 if (dstAddr != NULLP)
4326 #ifdef IPV6_SUPPORTED
4327 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4329 cmMemset((U8*)&remAddr6, 0, sizeof(remAddr6));
4330 remAddr6.sin6_family = AF_INET6;
4331 remAddr6.sin6_port = CM_INET_HTON_U16(dstAddr->u.ipv6Addr.port);
4332 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4333 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4334 sizeOfAddr = sizeof(remAddr6);
4335 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4339 cmMemset((U8*)&remAddr, 0, sizeof(remAddr));
4340 remAddr.sin_family = AF_INET;
4341 remAddr.sin_port = CM_INET_HTON_U16(dstAddr->u.ipv4Addr.port);
4342 remAddr.sin_addr.s_addr =
4343 CM_INET_HTON_U32(dstAddr->u.ipv4Addr.address);
4344 sizeOfAddr = sizeof(remAddr);
4345 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4348 /* cmMemset((U8*)&remAddr, 0, sizeof(remAddr)); */
4349 remAddr.sin_family = AF_INET;
4350 remAddr.sin_port = CM_INET_HTON_U16(dstAddr->port);
4351 remAddr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->address);
4352 sizeOfAddr = sizeof(remAddr);
4353 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4354 #endif /* IPV6_SUPPORTED */
4357 #if (defined(WIN32) || defined(CMINETFLATBUF))
4358 /* copy message to a flat buffer */
4359 ret = SFndLenMsg(mBuf, &bufLen);
4364 /* max message length is limited to control the memory usage */
4365 /* casting bufLen to avoid warnings */
4366 if ((bufLen > 0) && ((U32)bufLen > CM_INET_MAX_MSG_LEN))
4370 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4375 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4376 if ((ret != ROK) || (msgLen != bufLen))
4379 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4383 if (dstAddr == NULLP)
4385 /* VxWorks sendto has some problem
4386 * with connected UDP socket, use send */
4388 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4391 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4392 #endif /* end of SS_VW */
4395 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4397 #if (defined(SS_VW) && defined(SS_VW6_7))
4398 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4400 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4403 #endif /* end of SS_VW6_7 and SS_VW */
4405 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4406 sockAddrPtr, sizeOfAddr);
4409 if (ret == INET_ERR)
4412 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4414 if(INET_ERR_CODE == ERR_AGAIN)
4417 RETVALUE(RWOULDBLOCK);
4420 /* Check for ERR_WOULDBLOCK */
4421 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4424 RETVALUE(RWOULDBLOCK);
4429 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4430 /* cm_inet_c_001.main_62:Warning fix */
4431 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4432 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4433 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4435 /* cm_inet_c_001.main_62:Warning fix */
4436 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4437 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4438 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4439 #endif /*ALIGN_64BIT*/
4440 #endif /* CMINETDBG */
4442 /* cm_inet_c_001.main_37 network unreacheble error is added */
4443 /* check if network is reacheble*/
4444 if ((INET_ERR_CODE == ERR_NETUNREACH))
4446 RETVALUE(RNETFAILED);
4450 /* Check if connection was closed */
4451 if ((INET_ERR_CODE == ERR_PIPE) ||
4452 (INET_ERR_CODE == ERR_CONNABORTED) ||
4453 (INET_ERR_CODE == ERR_CONNRESET))
4464 /* check if entire message could be sent */
4469 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4470 RETVALUE(RWOULDBLOCK);
4474 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4476 #else /* end of Win NT/flat buffer specific part */
4477 ret = SFndLenMsg(mBuf, &msgLen);
4484 /* cmMemset((U8*)&msg, 0, sizeof(msg)); */
4487 if (dstAddr != NULLP)
4490 msg.msg_name = (Void*)sockAddrPtr;
4493 msg.msg_name = (char *)sockAddrPtr;
4495 msg.msg_name = (caddr_t)sockAddrPtr;
4497 #endif /* SS_LINUX */
4498 msg.msg_namelen = sizeOfAddr;
4502 msg.msg_name = NULLP;
4503 msg.msg_namelen = 0;
4505 /* added defined(_XPG4_2) */
4506 #if (defined(SS_LINUX) || defined(_XPG4_2))
4507 msg.msg_control = NULLP;
4508 msg.msg_controllen = 0;
4510 msg.msg_accrights = 0;
4511 msg.msg_accrightslen = NULLP;
4512 #endif /* SS_LINUX */
4514 /* allocate scatter vector */
4515 numDBufs = CM_INET_MAX_DBUF;
4521 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV4ADDR_TYPE))
4522 if((ipHdrParams->u.hdrParmIpv4.tos.pres == TRUE)&& \
4523 (ipHdrParams->u.hdrParmIpv4.tos.val != 0))
4525 cmInet4FillTos(ipHdrParams->u.hdrParmIpv4.tos.val,
4526 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
4527 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4528 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4530 /* if the sender wants to send Ipv6 exten. headers */
4531 #ifdef IPV6_OPTS_SUPPORTED
4532 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4535 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4537 cmInetBuildSendHoplimit((U32)ipHdrParams->u.ipv6HdrParm.ttl.val,
4538 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
4540 #endif /* SS_LINUX */
4543 /* have to decide how to get the src addr to add in in6_pktinfo */
4544 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4546 cmInet6BuildSendPktinfo(
4547 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4548 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx,
4551 #endif /* LOCAL_INTF */
4553 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4554 * cmsgData one by one. */
4556 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4557 /* build HBH ext header in cmsgData starting at indx 0 */
4558 cmInet6BuildSendHBHOpts(
4559 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4560 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4562 /* now copy the elements from the Destination Option array one by
4563 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4564 * which is the end of HBH hdr. */
4565 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4566 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4567 cmInet6BuildSendDestOpts(
4568 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4569 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4571 /* copy Route header to to the Flat Buffer cmsgData */
4572 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4573 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4574 cmInet6BuildSendRouteOpts(
4575 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4576 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
4578 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4579 * will be the curMsgIdx */
4580 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4581 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4584 #endif /* IPV6_OPTS_SUPPORTED */
4586 /* Loop till all the data is sent or till the sendmsg call cannot send
4590 /* build the send vector */
4591 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4592 total length of the packed dbufs */
4593 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4594 &strtEndDBufNum, &ioLen);
4599 /* Incase of UDP/RAW messages call SCompressMsg. */
4600 if (sockFd->type != CM_INET_STREAM)
4602 /* Compress the message into a single dBuf */
4603 ret = SCompressMsg(mBuf);
4608 /* Rebuild the send vector */
4609 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4610 total length of the packed dbuf */
4611 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4612 &strtEndDBufNum, &ioLen);
4622 msg.msg_iov = txArr;
4628 extern int ntl_hLib;
4629 if ( sockFd->fd >= 0xD001)
4630 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4632 ret = sendmsg(sockFd->fd, &msg, 0);
4635 ret = sendmsg(sockFd->fd, &msg, 0);
4637 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4638 if (ret == INET_ERR)
4640 if((INET_ERR_CODE == ERR_AGAIN) ||
4641 (INET_ERR_CODE == ERR_WOULDBLOCK))
4643 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4644 message was sent earlier */
4645 RETVALUE(RWOULDBLOCK);
4649 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4650 /* cm_inet_c_001.main_62:Warning fix */
4651 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4652 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4653 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4655 /* cm_inet_c_001.main_62:Warning fix */
4656 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4657 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4658 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4659 #endif /*ALIGN_64BIT*/
4660 #endif /* CMINETDBG */
4662 /* cm_inet_c_001.main_37 network unreacheble error is added */
4663 /* check if network is reacheble or not */
4664 if ((INET_ERR_CODE == ERR_NETUNREACH))
4666 RETVALUE(RNETFAILED);
4669 /* Check if connection was closed by the peer */
4670 if ((INET_ERR_CODE == ERR_PIPE) ||
4671 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4672 (INET_ERR_CODE == ERR_CONNABORTED))
4680 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4683 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4684 * to be sent, then return WOULDBLOCK
4687 RETVALUE(RWOULDBLOCK);
4691 } while (*len < msgLen);
4692 #endif /* WIN32 | CMINETFLATBUF */
4696 } /* end of cmInetSendDscpMsg */
4700 * Fun: cmInetSendMsg
4702 * Desc: Sends the message data hold by mBuf.
4703 * The len paramter gives the actual written octets. If the socket
4704 * is non-blocking this value can be differ from the mBuf length
4705 * because there was not enough transmit buffer space available. If
4706 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4708 * Values for flag parameter:
4710 * CM_INET_NO_FLAG - no additional control flag
4712 * Ret: ROK - successful
4713 * RWOULDBLOCK - no or not entire mBuf sent because would block
4714 * ROUTRES - failed, out of resources
4715 * RCLOSED - connection was closed by the peer
4718 * Notes: The successful completion of a send call does not indicate that
4719 * the data has been successfully delivered!
4721 * This function does not free any sent buffers.
4729 PUBLIC S16 cmInetSendMsg
4731 CmInetFd *sockFd, /* socket file descriptor */
4732 CmInetAddr *dstAddr, /* destination Internet address/port */
4733 CmInetMemInfo *info, /* buffer allocation info */
4734 Buffer *mBuf, /* buffer structure to send */
4735 MsgLen *len, /* number of actually sent octets */
4736 /* added for IPv6 ext hdr */
4737 #ifdef IPV6_OPTS_SUPPORTED
4738 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4739 #endif /* IPV6_OPTS_SUPPORTED */
4740 S16 flags /* additional control flags, unused */
4743 /* added for IPv6 ext hdr */
4744 #ifdef IPV6_OPTS_SUPPORTED
4745 PUBLIC S16 cmInetSendMsg(sockFd, dstAddr, info, mBuf, len, ipHdrParams, flags)
4746 CmInetFd *sockFd; /* socket file descriptor */
4747 CmInetAddr *dstAddr; /* destination Internet address/port */
4748 CmInetMemInfo *info; /* buffer allocation info */
4749 Buffer *mBuf; /* buffer structure to send */
4750 MsgLen *len; /* number of actually sent octets */
4751 CmInetIpHdrParm *ipHdrParams; /* IPv6 extensions headers */
4752 S16 flags; /* additional control flags, unused */
4754 PUBLIC S16 cmInetSendMsg(sockFd, dstAddr, info, mBuf, len, flags)
4755 CmInetFd *sockFd; /* socket file descriptor */
4756 CmInetAddr *dstAddr; /* destination Internet address/port */
4757 CmInetMemInfo *info; /* buffer allocation info */
4758 Buffer *mBuf; /* buffer structure to send */
4759 MsgLen *len; /* number of actually sent octets */
4760 S16 flags; /* additional control flags, unused */
4761 #endif /* IPV6_OPTS_SUPPORTED */
4764 #if (defined(WIN32) || defined(CMINETFLATBUF))
4765 S32 ret; /* temporary return value */
4766 MsgLen msgLen; /* message length */
4767 MsgLen bufLen; /* send buffer length */
4768 Data *sendBuf; /* plain send buffer */
4770 S32 ret; /* temporary return value */
4771 S32 retVal; /* temporary return value */
4772 S16 i; /* loop index */
4773 CmInetIovec txArr[CM_INET_MAX_DBUF]; /* scatter vector */
4774 S16 numDBufs; /* number of dBufs in message */
4775 struct msghdr msg; /* sendmsg() message header */
4776 MsgLen msgLen; /* message length */
4777 U32 strtEndDBufNum; /* starting/ending DBuf number */
4778 MsgLen unSentLen; /* sent len */
4779 #ifdef IPV6_SUPPORTED
4780 /* added for IPv6 ext hdr */
4781 #ifdef IPV6_OPTS_SUPPORTED
4782 U32 curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4783 #if (defined(SS_LINUX) || defined(_XPG4_2))
4784 /* alloc from stack for IPv6 ancill data */
4785 U8 cmsgData[CM_INET_IPV6_ANCIL_DATA];
4786 #endif /* SS_LINUX || _XPG4_2 */
4787 #endif /* IPV6_OPTS_SUPPORTED */
4789 #if (defined(SS_LINUX) || defined(_XPG4_2))
4790 /* alloc from stack for IPv4 ancill data */
4791 /* U8 cmsgData[CM_INET_IPV4_ANCIL_DATA];*/
4792 #endif /* SS_LINUX || _XPG4_2 */
4793 #endif /* IPV6_SUPPORTED */
4794 #endif /* WIN32 | CMINETFLATBUF */
4796 struct sockaddr_in remAddr; /* remote Internet address */
4797 #ifdef IPV6_SUPPORTED
4798 struct sockaddr_in6 remAddr6; /* remote Internet address */
4799 #endif /* IPV8_SUPPORTED */
4800 CmInetSockAddr *sockAddrPtr;
4801 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4804 /* cm_inet_c_001.main_50 - Added for partial send handling */
4805 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4806 #if (!defined(WIN32))
4814 #if (ERRCLASS & ERRCLS_INT_PAR)
4815 /* error check on parameters */
4816 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4817 (info == NULLP) || (len == NULLP))
4821 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4823 /* added for IPv6 ext hdr */
4824 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4825 #if (defined(SS_LINUX) || defined(_XPG4_2))
4826 /* cmMemset((U8*)cmsgData, 0, sizeof(cmsgData)); */
4827 #endif /* SS_LINUX || _XPG4_2 */
4828 #ifdef IPV6_OPTS_SUPPORTED
4830 #endif /* IPV6_SUPPORTED */
4831 #endif /* WIN32 | CMINETFLATBUF */
4833 msgLen = 0; /* need by CC to pass without warning */
4834 sockAddrPtr = NULLP;
4837 /* setup remote address */
4838 if (dstAddr != NULLP)
4840 #ifdef IPV6_SUPPORTED
4841 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4843 cmMemset((U8*)&remAddr6, 0, sizeof(remAddr6));
4844 remAddr6.sin6_family = AF_INET6;
4845 remAddr6.sin6_port = CM_INET_HTON_U16(dstAddr->u.ipv6Addr.port);
4846 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4847 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4848 sizeOfAddr = sizeof(remAddr6);
4849 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4853 cmMemset((U8*)&remAddr, 0, sizeof(remAddr));
4854 remAddr.sin_family = AF_INET;
4855 remAddr.sin_port = CM_INET_HTON_U16(dstAddr->u.ipv4Addr.port);
4856 remAddr.sin_addr.s_addr =
4857 CM_INET_HTON_U32(dstAddr->u.ipv4Addr.address);
4858 sizeOfAddr = sizeof(remAddr);
4859 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4862 /* cmMemset((U8*)&remAddr, 0, sizeof(remAddr)); */
4863 remAddr.sin_family = AF_INET;
4864 remAddr.sin_port = CM_INET_HTON_U16(dstAddr->port);
4865 remAddr.sin_addr.s_addr = CM_INET_HTON_U32(dstAddr->address);
4866 sizeOfAddr = sizeof(remAddr);
4867 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4868 #endif /* IPV6_SUPPORTED */
4871 #if (defined(WIN32) || defined(CMINETFLATBUF))
4872 /* copy message to a flat buffer */
4873 ret = SFndLenMsg(mBuf, &bufLen);
4878 /* max message length is limited to control the memory usage */
4879 /* casting bufLen to avoid warnings */
4880 if ((bufLen > 0) && ((U32)bufLen > CM_INET_MAX_MSG_LEN))
4884 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4889 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4890 if ((ret != ROK) || (msgLen != bufLen))
4893 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4897 if (dstAddr == NULLP)
4899 /* VxWorks sendto has some problem
4900 * with connected UDP socket, use send */
4902 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4905 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4906 #endif /* end of SS_VW */
4909 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4911 #if (defined(SS_VW) && defined(SS_VW6_7))
4912 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4914 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4917 #endif /* end of SS_VW6_7 and SS_VW */
4919 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4920 sockAddrPtr, sizeOfAddr);
4923 if (ret == INET_ERR)
4926 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4928 if(INET_ERR_CODE == ERR_AGAIN)
4931 RETVALUE(RWOULDBLOCK);
4934 /* Check for ERR_WOULDBLOCK */
4935 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4938 RETVALUE(RWOULDBLOCK);
4943 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4944 /* cm_inet_c_001.main_62:Warning fix */
4945 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4946 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4947 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4949 /* cm_inet_c_001.main_62:Warning fix */
4950 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4951 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4952 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4953 #endif /*ALIGN_64BIT*/
4954 #endif /* CMINETDBG */
4956 /* cm_inet_c_001.main_37 network unreacheble error is added */
4957 /* check if network is reacheble*/
4958 if ((INET_ERR_CODE == ERR_NETUNREACH))
4960 RETVALUE(RNETFAILED);
4964 /* Check if connection was closed */
4965 if ((INET_ERR_CODE == ERR_PIPE) ||
4966 (INET_ERR_CODE == ERR_CONNABORTED) ||
4967 (INET_ERR_CODE == ERR_CONNRESET))
4978 /* check if entire message could be sent */
4983 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4984 RETVALUE(RWOULDBLOCK);
4988 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4990 #else /* end of Win NT/flat buffer specific part */
4991 ret = SFndLenMsg(mBuf, &msgLen);
4998 /* cmMemset((U8*)&msg, 0, sizeof(msg)); */
5001 if (dstAddr != NULLP)
5004 msg.msg_name = (Void*)sockAddrPtr;
5007 msg.msg_name = (char *)sockAddrPtr;
5009 msg.msg_name = (caddr_t)sockAddrPtr;
5011 #endif /* SS_LINUX */
5012 msg.msg_namelen = sizeOfAddr;
5016 msg.msg_name = NULLP;
5017 msg.msg_namelen = 0;
5019 /* added defined(_XPG4_2) */
5020 #if (defined(SS_LINUX) || defined(_XPG4_2))
5021 msg.msg_control = NULLP;
5022 msg.msg_controllen = 0;
5024 msg.msg_accrights = 0;
5025 msg.msg_accrightslen = NULLP;
5026 #endif /* SS_LINUX */
5028 /* allocate scatter vector */
5029 numDBufs = CM_INET_MAX_DBUF;
5036 /* if the sender wants to send Ipv6 exten. headers */
5037 #ifdef IPV6_OPTS_SUPPORTED
5038 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
5041 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
5043 cmInetBuildSendHoplimit((U32)ipHdrParams->u.ipv6HdrParm.ttl.val,
5044 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
5046 #endif /* SS_LINUX */
5049 /* have to decide how to get the src addr to add in in6_pktinfo */
5050 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
5052 cmInet6BuildSendPktinfo(
5053 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
5054 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx,
5057 #endif /* LOCAL_INTF */
5059 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
5060 * cmsgData one by one. */
5062 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
5063 /* build HBH ext header in cmsgData starting at indx 0 */
5064 cmInet6BuildSendHBHOpts(
5065 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
5066 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
5068 /* now copy the elements from the Destination Option array one by
5069 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
5070 * which is the end of HBH hdr. */
5071 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
5072 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
5073 cmInet6BuildSendDestOpts(
5074 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
5075 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
5077 /* copy Route header to to the Flat Buffer cmsgData */
5078 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
5079 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
5080 cmInet6BuildSendRouteOpts(
5081 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
5082 (U8 *)(cmsgData + curMsgIdx), &curMsgIdx);
5084 /* msghrd struc's msg_control will point cmsgData and msg_controllen
5085 * will be the curMsgIdx */
5086 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
5087 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
5090 #endif /* IPV6_OPTS_SUPPORTED */
5092 /* Loop till all the data is sent or till the sendmsg call cannot send
5096 /* build the send vector */
5097 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
5098 total length of the packed dbufs */
5099 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
5100 &strtEndDBufNum, &ioLen);
5105 /* Incase of UDP/RAW messages call SCompressMsg. */
5106 if (sockFd->type != CM_INET_STREAM)
5108 /* Compress the message into a single dBuf */
5109 ret = SCompressMsg(mBuf);
5114 /* Rebuild the send vector */
5115 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
5116 total length of the packed dbuf */
5117 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
5118 &strtEndDBufNum, &ioLen);
5128 msg.msg_iov = txArr;
5134 extern int ntl_hLib;
5135 if ( sockFd->fd >= 0xD001)
5136 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
5138 ret = sendmsg(sockFd->fd, &msg, 0);
5141 ret = sendmsg(sockFd->fd, &msg, 0);
5143 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
5144 if (ret == INET_ERR)
5146 if((INET_ERR_CODE == ERR_AGAIN) ||
5147 (INET_ERR_CODE == ERR_WOULDBLOCK))
5149 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
5150 message was sent earlier */
5151 RETVALUE(RWOULDBLOCK);
5155 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5156 /* cm_inet_c_001.main_62:Warning fix */
5157 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
5158 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
5159 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
5161 /* cm_inet_c_001.main_62:Warning fix */
5162 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
5163 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
5164 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
5165 #endif /*ALIGN_64BIT*/
5166 #endif /* CMINETDBG */
5168 /* cm_inet_c_001.main_37 network unreacheble error is added */
5169 /* check if network is reacheble or not */
5170 if ((INET_ERR_CODE == ERR_NETUNREACH))
5172 RETVALUE(RNETFAILED);
5175 /* Check if connection was closed by the peer */
5176 if ((INET_ERR_CODE == ERR_PIPE) ||
5177 (INET_ERR_CODE == ERR_CONNREFUSED) ||
5178 (INET_ERR_CODE == ERR_CONNABORTED))
5186 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
5189 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
5190 * to be sent, then return WOULDBLOCK
5193 RETVALUE(RWOULDBLOCK);
5197 } while (*len < msgLen);
5198 #endif /* WIN32 | CMINETFLATBUF */
5202 } /* end of cmInetSendMsg */
5205 /* added new functions for IPv6 extension headers */
5206 #ifdef IPV6_OPTS_SUPPORTED
5210 * Fun: cmInet6BuildSendPktinfo
5212 * Desc: This function inserts src address (into ancillary data) which
5213 * will be used as the src addr in outgoing IP packet when sending
5214 * that packet using sendmsg()function.
5225 PRIVATE S16 cmInet6BuildSendPktinfo
5227 CmInetIpAddr6 *srcAddr, /* src ip addr to set on outgoing packet */
5228 U8 *cmsgBuf, /* flat buffer where to build ext hdrs */
5229 U32 *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5230 U8 protType /* whether IPv4/IPv6 socket */
5233 PRIVATE S16 cmInet6BuildSendPktinfo(srcAddr, cmsgBuf, curMsgIdx, protType)
5234 CmInetIpAddr6 *srcAddr; /* src ip addr to set on outgoing packet */
5235 U8 *cmsgBuf; /* flat buffer where to build ext hdrs */
5236 U32 *curMsgIdx; /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5237 U8 protType; /* whether IPv4/IPv6 socket */
5240 struct cmsghdr *tempHdr;
5241 struct in6_pktinfo *ipv6Pktinfo;
5242 struct in6_addr lpBkAddr;
5245 TRC2(cmInet6BuildSendPktinfo)
5249 lpBkAddr = in6addr_loopback;
5251 /* cmsghdr struc will appear before data in the ancillary data object.
5252 * So put cmsghdr struc in flat buffer first. */
5254 /* cmsghdr struc points to flat buffer's starting address */
5255 tempHdr = (struct cmsghdr *)cmsgBuf;
5257 /* fill up level & type of cmsghdr structure */
5258 if (protType == AF_INET6)
5260 tempHdr->cmsg_level = IPPROTO_IPV6;
5261 tempHdr->cmsg_type = IPV6_PKTINFO;
5264 else if(protType == AF_INET)
5266 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5267 /* cm_inet_c_001.main_62:Warning fix */
5268 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5269 "protType(%d)\n", protType);
5270 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET025, 0, prntBuf);
5274 /* skip length of cmsghdr structure - 12 bytes */
5275 len += sizeof(struct cmsghdr);
5277 if(protType == AF_INET6)
5278 ipv6Pktinfo = (struct in6_pktinfo *)(cmsgBuf + len);
5282 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5283 /* cm_inet_c_001.main_62:Warning fix */
5284 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5285 "protType(%d)\n", protType);
5286 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET026, 0, prntBuf);
5290 /* insert the hoplimit. This will override the kernel's
5291 * default hoplimit value */
5292 if(protType == AF_INET6)
5294 /* store ipv6 src addr */
5295 cmMemcpy((U8 *)&(ipv6Pktinfo->ipi6_addr), (U8 *)srcAddr, 16);
5298 /* store interface index */
5299 /* 0 is invalid intf indx it tells kernel to chose any intf it likes to
5300 * send this pkt. if we use nozero intf indx then kernel will send this
5301 * pkt only through that intf */
5302 ipv6Pktinfo->ipi6_ifindex = 0;
5306 else if(protType == AF_INET)
5308 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5309 /* cm_inet_c_001.main_62:Warning fix */
5310 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5311 "protType(%d)\n", protType);
5312 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET027, 0, prntBuf);
5316 /* fill up the length of cmsghdr structure */
5317 tempHdr->cmsg_len = len;
5322 }/* end of cmInet6BuildSendPktinfo */
5323 #endif /* LOCAL_INTF */
5329 * Fun: cmInetBuildSendHoplimit
5331 * Desc: This function inserts hoplimit value to be sent out by ancillary
5332 * data by calling sendmsg()function.
5343 PRIVATE S16 cmInetBuildSendHoplimit
5345 U32 hoplimit, /* the hoplimit value to be set on outgoing packet */
5346 U8 *cmsgBuf, /* flat buffer where to build ext hdrs */
5347 U32 *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5350 PRIVATE S16 cmInetBuildSendHoplimit(hoplimit, cmsgBuf, curMsgIdx)
5351 U32 hoplimit; /* the hoplimit value to be sent on outgoing packet */
5352 U8 *cmsgBuf; /* flat buffer where to build ext hdrs */
5353 U32 *curMsgIdx; /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5356 struct cmsghdr *tempHdr;
5359 TRC2(cmInetBuildSendHoplimit)
5363 /* cmsghdr struc will appear before data in the ancillary data object.
5364 * So put cmsghdr struc in flat buffer first. */
5366 /* cmsghdr struc points to flat buffer's starting address */
5367 tempHdr = (struct cmsghdr *)cmsgBuf;
5369 /* fill up level & type of cmsghdr structure */
5370 tempHdr->cmsg_level = IPPROTO_IPV6;
5371 tempHdr->cmsg_type = IPV6_HOPLIMIT;
5373 /* skip cmsghdr struc (length of cmsghdr structure) */
5374 len += sizeof(struct cmsghdr);
5376 /* insert the hoplimit. This will override the kernel's
5377 * default hoplimit value */
5378 *(cmsgBuf + len) = hoplimit;
5379 len += sizeof(hoplimit);
5381 /* fill up the length of cmsghdr structure */
5382 tempHdr->cmsg_len = len;
5386 } /* end of cmInetBuildSendHoplimit */
5387 #endif /* SS_LINUX */
5392 * Fun: cmInet6BuildSendHBHOpts
5394 * Desc: This function builds the HopByHop option which will be put
5395 * in the data portion of the ancillary data object. To build
5396 * the HopByHop option this function takes an array of
5397 * individual HopByHop option and fill them in a flat buffer.
5398 * cmsghdr struc always appear before HopBYHop Options, Dest
5399 * Options and Route header option.
5401 * The address of the flat Buffer *cmsgBuf is passed to this
5402 * function from cmInetSendMsg. This buffer will have all extension
5403 * headers. This buffer is passed as ancillary data by sendmsg()
5407 * Notes: This function will also be used for Destination options
5414 PRIVATE S16 cmInet6BuildSendHBHOpts
5416 CmInetIpv6HBHHdrArr *hbhOptsArr,/* IPv6 extensions headers HBH/Dest opts */
5417 U8 *cmsgBuf, /* flat buffer where to build ext hdrs */
5418 U32 *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5419 U8 hdrId /* 0: HBH hdr, 1:Dest Hdr */
5422 PRIVATE S16 cmInet6BuildSendHBHOpts(hbhOptsArr, cmsgBuf, curMsgIdx, hdrId)
5423 CmInetIpv6HBHHdrArr *hbhOptsArr;/* IPv6 extensions headers HBH/Dest opts */
5424 U8 *cmsgBuf; /* flat buffer where to build ext hdrs */
5425 U32 *curMsgIdx; /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5426 U8 hdrId; /* 0: HBH hdr, 1:Dest Hdr */
5429 struct cmsghdr *tempHdr;
5433 TRC2(cmInet6BuildSendHBHOpts)
5438 /* cmsghdr struc will appear before data in the ancillary data object.
5439 * So put cmsghdr struc in flat buffer first. */
5441 /* cmsghdr struc points to flat buffer's starting address */
5442 tempHdr = (struct cmsghdr *)cmsgBuf;
5444 /* fill up level & type of cmsghdr structure */
5447 tempHdr->cmsg_level = IPPROTO_IPV6;
5448 tempHdr->cmsg_type = IPV6_HOPOPTS;
5450 else if (hdrId == 1)
5452 tempHdr->cmsg_level = IPPROTO_IPV6;
5453 tempHdr->cmsg_type = IPV6_DSTOPTS;
5456 /* skip cmsghdr struc (length of cmsghdr structure) */
5457 len += (sizeof(tempHdr->cmsg_level) + sizeof(tempHdr->cmsg_len) +
5458 sizeof(tempHdr->cmsg_type));
5460 /* Next Hdr: will be fill up accordingly by Kernel */
5461 *(cmsgBuf + len) = 0x00;
5464 /* Header Ext Length: will be fill up by us. In units of 8-byte excluding
5465 * first 8 bytes starting from Next Header field. */
5466 *(cmsgBuf + len) = 0x00;
5469 /* fillup all HBH/dest options' TLV. Here, we assume that all the HBH/dest
5470 * options are packed inside 1 HBH option header. */
5471 for (optsIdx = 0; optsIdx < hbhOptsArr->numHBHOpts;
5474 /* Copy the TLV into cmsgBuf data portion */
5475 /* copy type field of every HBH/dest option */
5476 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].type;
5477 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].type);
5479 /* copy length field of every HBH/dest option */
5480 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].length;
5481 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].length);
5483 /* copy all value bytes of current HBH/dest option to the flat buffer */
5484 cmMemcpy((U8 *)(cmsgBuf + len),
5485 (U8 *)(hbhOptsArr->hbhOpts[optsIdx].value),
5486 hbhOptsArr->hbhOpts[optsIdx].length);
5487 len += hbhOptsArr->hbhOpts[optsIdx].length;
5490 /* cuMsgIdx will have the total length of HBH options array */
5491 /* add this length to the length of cmsgHdr struc */
5493 /* Padding: Different header has different padding requirement(xn+y). For
5494 * HBH Router Alert we need 2 bytes of padding. As this same function is
5495 * used for Destination option also and there is no option for it is yet
5496 * proposed, we are passing padN options - 6 bytes to make the Dest Option
5497 * hdr a multiple of 8 bytes. */
5499 /* HBH: padN of 2 bytes needed for Router Alert */
5500 /* This logic is present currently to support router alert which is the
5501 * only supported HBH option today. For other, generic method needed */
5504 *(cmsgBuf + len) = 0x01;
5506 *(cmsgBuf + len) = 0x00;
5510 /* fill up the length of cmsghdr structure */
5511 tempHdr->cmsg_len = len;
5515 } /* end of cmInet6BuildSendHBHOpts */
5520 * Fun: cmInet6BuildSendRouteOpts
5522 * Desc: This function transfers bytes from the Route hdr array to the
5523 * flat buffer. First the top cmsghdr structure will be filled in
5524 * the flat buffer, then route hdr type 0 will be added after
5525 * cmsghdr struc in the flat buffer. Then all IPV6 addresses will
5537 PRIVATE S16 cmInet6BuildSendRouteOpts
5539 CmInetIpv6RtHdr *rtOptsArr, /* IPv6 destination options array */
5540 U8 *cmsgBuf, /* flat buffer where to build ext hdrs */
5541 U32 *curMsgIdx /* idx in cmsgBuf where to start building RT hdr */
5544 PRIVATE S16 cmInet6BuildSendRouteOpts(rtOptsArr, cmsgBuf, curMsgIdx)
5545 CmInetIpv6RtHdr *rtOptsArr; /* IPv6 destination options array */
5546 U8 *cmsgBuf; /* flat buffer where to build ext hdrs */
5547 U32 *curMsgIdx; /* idx in cmsgBuf where to start building RT hd */
5550 struct cmsghdr *tempHdr;
5551 CmInetIpv6RtHdr0 *tempRtHdr;
5555 TRC2(cmInet6BuildSendRouteOpts);
5560 /* cmsghdr struc will appear before data in the ancillary data object.
5561 * So put cmsghdr struc in flat buffer first */
5563 /* cmsghdr struc points to flat buffer */
5564 tempHdr = (struct cmsghdr *)(cmsgBuf);
5566 tempHdr->cmsg_level = IPPROTO_IPV6;
5567 tempHdr->cmsg_type = IPV6_RTHDR;
5569 /* skip cmsghdr structure */
5570 len += sizeof(struct cmsghdr);
5572 /* we know the total size of Route hdr if we know the num of ipv6 addrs */
5573 tempHdr->cmsg_len = len + sizeof(CmInetIpv6RtHdr0)
5574 + rtOptsArr->numAddrs * sizeof(CmInetIpAddr6);
5576 /* attach route hdr type 0 after cmsghdr structure */
5577 tempRtHdr = (CmInetIpv6RtHdr0 *)(cmsgBuf + len);
5579 /* fill up fields of route hdr type 0 */
5581 /* will be filled up by Kernel */
5582 tempRtHdr->ip6r0_nextHdr = 0x00;
5584 tempRtHdr->ip6r0_hdrExtLen = (2 * rtOptsArr->numAddrs);
5586 /* only type supported today */
5587 tempRtHdr->ip6r0_type = 0x00;
5589 tempRtHdr->ip6r0_segLeft = rtOptsArr->numAddrs;
5591 /* Note: rfc 2292(1998) mentions 1 reserve byte & 3 strict/loose bytes
5592 * restricting total 23 ipv6 addresses can be added to the route header.
5593 * But rfc 2292(2002) mentions all 4 bytes are reserved which allows
5594 * as many ipv6 addresses as wishes to be added to the route header */
5596 tempRtHdr->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5598 /* move pointer in the flat buffer to the end of this structure */
5599 len += sizeof(CmInetIpv6RtHdr0);
5601 /* fill up all IPV6 addresses from rtOptsArr in the flat buffer */
5602 for (addrIdx = 0; addrIdx < rtOptsArr->numAddrs; addrIdx++)
5604 cmMemcpy((U8 *)(cmsgBuf + len),
5605 (U8 *)(rtOptsArr->ipv6Addrs[addrIdx]), 16);
5611 } /* end of cmInet6BuildSendRouteOpts */
5616 * Fun: cmInet6BuildRecvHopOptsArr
5618 * Desc: This function fills up the HopByHop Array of ipHdrParam from
5619 * the ancillary data received through recvmsg() call. The memory
5620 * to hold the extension headers is allocated here. All received
5621 * ext hdr info will be passed to upper user as ipHdrParam.
5623 * Ret: ROK - successful
5633 PRIVATE S16 cmInet6BuildRecvHopOptsArr
5635 U8 *cmsgData, /* flat buffer where to build ext hdrs */
5636 U32 hbhDataLen, /* byte len of cmsghdr + hbh ancil data */
5637 CmInetIpv6HBHHdrArr *hbhOptsArr, /* IPv6 extensions headers */
5638 U8 hdrId, /* 0: HBH, 1: DEST */
5639 CmInetMemInfo *info /* Memory information */
5642 PRIVATE S16 cmInet6BuildRecvHopOptsArr(cmsgData, hbhDataLen, hbhOptsArr, hdrId,
5644 U8 *cmsgData; /* flat buffer where to build ext hdrs */
5645 U32 hbhDataLen; /* byte len of cmsghdr + hbh ancil data */
5646 CmInetIpv6HBHHdrArr *hbhOptsArr; /* IPv6 extensions headers */
5647 U8 hdrId; /* 0: HBH, 1: DEST */
5648 CmInetMemInfo *info; /* Memory information */
5651 U32 curDataIdx; /* to keep track where we are in the hbh Data */
5652 U8 optsIdx; /* how many hbh opts present in data */
5653 U8 numOpts; /* number of hbh opts present in data */
5658 TRC2(cmInet6BuildRecvHopOptsArr)
5660 /* get length of actual hbh ancillary data */
5661 hbhDataLen -= sizeof(struct cmsghdr);
5667 /* skip Next Hdr byte & Hdr Ext Length byte */
5670 /* First find out how many hop-by-hop headers we need to allocate */
5673 /* break when all HBH data is copied to hbhOptsArr */
5674 if (curDataIdx >= hbhDataLen)
5680 tempType = *(U8 *)(cmsgData + curDataIdx);
5683 /* take care of pad1 option */
5686 /* not considering the pad1 as valid option */
5692 tempLen = *(U8 *)(cmsgData + curDataIdx);
5694 /* 1 is to skip length. tempLen to skip the value field */
5695 curDataIdx += (1 + tempLen);
5697 /* considering the padN as valid option for Dest Opt Hdr!!! As this is
5698 * the "only" valid option today. Ignore for HBH hdr */
5704 /* allocate mem needed to hold all HBH/Dest options */
5705 ret = SGetSBuf(info->region, info->pool,
5706 (Data **)&hbhOptsArr->hbhOpts,
5707 (Size)((sizeof(CmInetIpv6HBHHdr)) * numOpts));
5711 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5712 /* cm_inet_c_001.main_62:Warning fix */
5713 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvHopOptsArr\n");
5714 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET028, 0, prntBuf);
5715 #endif /* CMINETDBG */
5722 /* skip Next Hdr byte & Hdr Ext Length byte */
5725 hbhOptsArr->numHBHOpts = numOpts;
5727 /* fill up HBH/dest opt array from recvd ancillary data */
5730 /* break when all HBH data is copied to hbhOptsArr */
5731 if (curDataIdx >= hbhDataLen)
5734 /* only copy Router Alert HBH option part which has type 5. Otherwise,
5735 * skip it when it is a PAD1, PADN or Jumbogram option for HBH. But
5736 * consider padN as valid option for dest opt hdr. */
5738 /* get the type of current HBH/dest option */
5739 tempType = *(cmsgData + curDataIdx);
5742 /* ignore PAD1 for both HBH/dest by skipping to next option */
5746 /* calculate how much to skip for padN in case of HBH */
5751 /* get the length field of padN option */
5752 tempLen = *(cmsgData + curDataIdx);
5755 /* move pointer forward to skip value field */
5756 curDataIdx += tempLen;
5760 hbhOptsArr->hbhOpts[optsIdx].type = tempType;
5762 /* copy the length */
5763 hbhOptsArr->hbhOpts[optsIdx].length = *(cmsgData + curDataIdx);
5766 /* take care of PADN = 2 when value field empty. We also don't need
5767 * to allocate memory for empty value field */
5768 if (hbhOptsArr->hbhOpts[optsIdx].length == 0)
5769 hbhOptsArr->hbhOpts[optsIdx].value = NULLP;
5772 /* take care of all other options having valid value field
5773 * such as Router Alert, PADN >= 3 bytes and Jumbo */
5774 ret = SGetSBuf(info->region, info->pool,
5775 (Data **)&hbhOptsArr->hbhOpts[optsIdx].value,
5776 (Size)hbhOptsArr->hbhOpts[optsIdx].length);
5780 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5781 /* cm_inet_c_001.main_62:Warning fix */
5782 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 2 cmInet6BuildRecvHopOptsArr\n");
5783 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET029, 0, prntBuf);
5784 #endif /* CMINETDBG */
5785 /* now go inside every separate HBH option and free the memory
5786 * allocated for its value field */
5787 for (; optsIdx > 0; optsIdx --)
5789 if (hbhOptsArr->hbhOpts[optsIdx - 1].value != NULLP)
5792 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5793 /* cm_inet_c_001.main_62:Warning fix */
5794 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 1 in BuildRecvHopOptsArr\n");
5795 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET030, 0, prntBuf);
5796 #endif /* CMINETDBG */
5797 SPutSBuf(info->region, info->pool,
5798 (Data *)hbhOptsArr->hbhOpts[optsIdx - 1].value,
5799 (Size)hbhOptsArr->hbhOpts[optsIdx - 1].length);
5802 /* clean up all CmInetIpv6HBHHdr structures allocated for all
5803 * arrived HBH options OR numOpts CmInetIpv6HBHHdr structures
5804 * allocated after counting numOpts */
5806 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5807 /* cm_inet_c_001.main_62:Warning fix */
5808 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 2 in BuildRecvHopOptsArr\n");
5809 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET031, 0, prntBuf);
5810 #endif /* CMINETDBG */
5811 SPutSBuf(info->region, info->pool,
5812 (Data *)hbhOptsArr->hbhOpts, numOpts * sizeof(CmInetIpv6HBHHdr));
5813 hbhOptsArr->numHBHOpts = 0;
5814 hbhOptsArr->hbhOpts = NULLP;
5817 /* copy the value bytes */
5818 cmMemcpy((U8 *)hbhOptsArr->hbhOpts[optsIdx].value,
5819 (U8 *)(cmsgData + curDataIdx),
5820 hbhOptsArr->hbhOpts[optsIdx].length);
5821 curDataIdx += hbhOptsArr->hbhOpts[optsIdx].length;
5824 /* get next option */
5828 } /* end of cmInet6BuildRecvHopOptsArr() */
5833 * Fun: cmInet6BuildRecvRtHdr
5835 * Desc: This function fills up the Route Header in the cmInetIpv6HdrParm
5836 * from the recvd ancillary data from recvmsg system call.
5838 * Ret: ROK - successful
5848 PRIVATE S16 cmInet6BuildRecvRtHdr
5850 U8 *cmsgData, /* flat buffer where to build Route hdr */
5851 U32 rtDataLen, /* byte len of cmsghdr struc+rtHdr ancil data */
5852 CmInetIpv6RtHdr0 *rtHdr0, /* rtHeader0 struct that precedes IPV6 addrss */
5853 CmInetIpv6RtHdr *rtOptsArr,/* IPv6 extensions headers */
5854 CmInetMemInfo *info /* Memory information */
5857 PRIVATE S16 cmInet6BuildRecvRtHdr(cmsgData, rtDataLen, rtHdr0, rtOptsArr, info)
5858 U8 *cmsgData; /* flat buffer where to build Route hdr */
5859 U32 rtDataLen; /* byte len of cmsghdr struc+rtHdr ancil data */
5860 CmInetIpv6RtHdr0 *rtHdr0; /* rtHeader0 struct that precedes IPV6 addrss */
5861 CmInetIpv6RtHdr *rtOptsArr;/* IPv6 extensions headers */
5862 CmInetMemInfo *info; /* Memory information */
5865 U32 curDataIdx; /* to keep track where we are in hbh Data */
5866 U8 i; /* loop counter */
5867 S16 ret; /* temporary return value */
5869 TRC2(cmInet6BuildRecvRtHdr)
5871 /* byte len of actual rtHdr ancil data */
5872 rtDataLen -= sizeof(struct cmsghdr);
5874 /* start from beginning */
5877 /* copy next header byte */
5878 rtHdr0->ip6r0_nextHdr = *(cmsgData + curDataIdx);
5881 /* copy header extension length byte */
5882 rtHdr0->ip6r0_hdrExtLen = *(cmsgData + curDataIdx);
5885 /* copy type byte (always 0) */
5886 rtHdr0->ip6r0_type = 0x00;
5889 /* copy segment left byte */
5890 rtHdr0->ip6r0_segLeft = *(cmsgData + curDataIdx);
5893 /* copy 1 reserve byte + 3 strict/loose bytes */
5894 cmMemcpy((U8 *)(&rtOptsArr->slMap),
5895 (U8 *)(cmsgData + curDataIdx), 4);
5898 /* also save reserv byte + 3 sl bytes to rtHdro struc */
5899 rtHdr0->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5901 /* subtract 8 bytes for Next Hdr, Hdr Ext Len, .... + SL bit map */
5902 rtOptsArr->numAddrs = (rtDataLen - 8)/16;
5904 ret = SGetSBuf(info->region, info->pool,
5905 (Data **)&rtOptsArr->ipv6Addrs,
5906 (Size)rtOptsArr->numAddrs * 16);
5910 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5911 /* cm_inet_c_001.main_62:Warning fix */
5912 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvRtHdr\n");
5913 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET032, 0, prntBuf);
5914 #endif /* CMINETDBG */
5918 /* copy all the ipv6 addresses */
5919 for(i=0; i < rtOptsArr->numAddrs; i++)
5921 cmMemcpy((U8 *)(rtOptsArr->ipv6Addrs[i]),
5922 (U8 *)(cmsgData + curDataIdx), 16);
5927 } /* end of cmInet6BuildRecvRtHdr() */
5932 * Fun: cmInet6GetHopLimitValue
5934 * Desc: This function extracts the hop limit value(ttl) of from the
5935 * ancillary data received through recvmsg() call. Then this
5936 * hoplimit value will be passed to upper user as ipHdrParam.
5938 * Ret: ROK - successful
5947 PRIVATE S16 cmInet6GetHopLimitValue
5949 U8 *cmsgData, /* flat buffer where to build ext hdrs */
5950 U32 hopLimitDataLen, /* byte len of cmsghdr + hbh ancil data */
5951 CmInetIpv6HdrParm *ipv6HdrParam /* ipv6 header parameters */
5954 PRIVATE S16 cmInet6GetHopLimitValue(cmsgData, hopLimitDataLen, ipv6HdrParam)
5955 U8 *cmsgData; /* flat buffer where to build ext hdrs */
5956 U32 hopLimitDataLen; /* byte len of cmsghdr + hbh ancil data */
5957 CmInetIpv6HdrParm *ipv6HdrParam; /* ipv6 header parameters */
5960 U16 curDataIdx; /* to keep track where we are in the ancillary Data */
5961 U32 *hopLimitValue; /* ttl/hoplimit value */
5963 hopLimitValue = NULL;
5966 /* get length of actual hbh ancillary data */
5967 hopLimitDataLen -= sizeof(struct cmsghdr);
5969 /* go to the first byte of hop limit which present after cmsghdr struc */
5970 curDataIdx += sizeof(struct cmsghdr);
5972 /* mark that hoplimit(ttl) is present */
5973 ipv6HdrParam->ttl.pres = TRUE;
5975 /* the first byte will be the HopLimit value */
5976 hopLimitValue = (U32 *)(cmsgData);
5977 ipv6HdrParam->ttl.val = (U8)(*hopLimitValue);
5981 #endif /* IPV6_OPTS_SUPPORTED */
5986 * Fun: cmInetRecvMsg
5988 * Desc: Reads data from a socket into a message.
5989 * The buffers for the message are allocated within the
5990 * cmInetRead() function from the pool and region Id set in the
5992 * If the number of octets given by the paramter len is not
5993 * available the function immediately returns with RKDNA.
5994 * If the len parameter is set to CM_INET_READ_ANY, the currently
5995 * available data is read.
5996 * Values for flag parameter:
5998 * CM_INET_NO_FLAG - no additional control flag
5999 * CM_INET_MSG_PEEK - do not destroy data on receive buffer
6001 * Ret: ROK - successful
6002 * ROKDNA - ok, data not available
6003 * RCLOSED - connection closed by peer
6004 * ROUTRES - failed, out of resources
6013 PUBLIC S16 cmInetRecvMsg
6015 CmInetFd *sockFd, /* socket file descriptor */
6016 CmInetAddr *fromAddr, /* sender Internet address/port */
6017 CmInetMemInfo *info, /* buffer allocation info */
6018 Buffer **mPtr, /* received buffer structure */
6019 MsgLen *len, /* number of octets to read */
6020 /* added for IPv6 */
6021 #ifdef IPV6_OPTS_SUPPORTED
6022 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
6023 #endif /* IPV6_OPTS_SUPPORTED */
6025 CmInetLocalInf *localIf, /* local interface on which pkt was recvd */
6026 #endif /* LOCAL_INTF */
6027 S32 flags /* additional control flags */
6030 /* added for IPv6 */
6031 #ifdef IPV6_OPTS_SUPPORTED
6033 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len,
6034 ipHdrParams, localIf, flags)
6035 CmInetFd *sockFd; /* socket file descriptor */
6036 CmInetAddr *fromAddr; /* sender Internet address/port */
6037 CmInetMemInfo *info; /* buffer allocation info */
6038 Buffer **mPtr; /* received buffer structure */
6039 MsgLen *len; /* number of octets to read */
6040 CmInetIpHdrParm *ipHdrParams; /* IPv6 extensions headers */
6041 CmInetLocalInf *localIf; /* local interface on which pkt was recvd */
6042 S32 flags; /* additional control flags */
6044 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len, ipHdrParams, flags)
6045 CmInetFd *sockFd; /* socket file descriptor */
6046 CmInetAddr *fromAddr; /* sender Internet address/port */
6047 CmInetMemInfo *info; /* buffer allocation info */
6048 Buffer **mPtr; /* received buffer structure */
6049 MsgLen *len; /* number of octets to read */
6050 CmInetIpHdrParm *ipHdrParams; /* IPv6 extensions headers */
6051 S32 flags; /* additional control flags */
6052 #endif /* LOCAL_INTF */
6055 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len, localIf, flags)
6056 CmInetFd *sockFd; /* socket file descriptor */
6057 CmInetAddr *fromAddr; /* sender Internet address/port */
6058 CmInetMemInfo *info; /* buffer allocation info */
6059 Buffer **mPtr; /* received buffer structure */
6060 MsgLen *len; /* number of octets to read */
6061 CmInetLocalInf *localIf; /* local interface on which pkt was recvd */
6062 S32 flags; /* additional control flags */
6064 PUBLIC S16 cmInetRecvMsg(sockFd, fromAddr, info, mPtr, len, flags)
6065 CmInetFd *sockFd; /* socket file descriptor */
6066 CmInetAddr *fromAddr; /* sender Internet address/port */
6067 CmInetMemInfo *info; /* buffer allocation info */
6068 Buffer **mPtr; /* received buffer structure */
6069 MsgLen *len; /* number of octets to read */
6070 S32 flags; /* additional control flags */
6071 #endif /* LOCAL_INTF */
6072 #endif /* IPV6_OPTS_SUPPORTED */
6075 #if (defined(WIN32) || defined(CMINETFLATBUF))
6076 S32 ret; /* temporary return value */
6077 U32 pendLen; /* pending data length */
6078 S32 recvLen; /* number of received octets by recvmsg() */
6079 MsgLen bufLen; /* entire number of received octets */
6080 MsgLen curLen; /* current number of octets in buffer */
6081 Data *recvBuf; /* receive buffer */
6082 Data *bufPtr; /* current buffer position */
6083 Buffer *mBuf; /* received message */
6084 U32 remAddrLen; /* length of remote address */
6085 struct sockaddr_in *remAddr; /* remote Internet address */
6086 #ifdef IPV6_SUPPORTED
6087 struct sockaddr_in6 *remAddr6; /* remote Internet address */
6088 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6090 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6091 #endif /* IPV6_SUPPORTED */
6093 S32 ret; /* temporary return value */
6094 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
6096 U32 pendLen; /* pending data length */
6097 S32 numBuf; /* number of allocated dBufs */
6098 S32 recvLen; /* number of received octets by recvmsg() */
6099 MsgLen bufLen; /* entire number of received octets */
6100 struct msghdr msg; /* message header */
6101 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6102 Buffer *tempMsg = NULLP; /* temporary message */
6103 CmInetIovec rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
6104 Buffer **dBufs = NULLP; /* dynamic array with allocated dBufs */
6105 S16 numDBufs; /* number of allocated dBufs */
6107 /* cm_inet_c_001.main_55: As remAddrLen is only being used when
6108 * WIN32 or CMINETFLATBUF is defined, then Removed variable
6110 struct sockaddr_in *remAddr; /* remote Internet address */
6111 #ifdef IPV6_SUPPORTED
6112 struct sockaddr_in6 *remAddr6; /* remote Internet address */
6113 struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
6114 /* added for IPv6 ext headers support */
6115 #ifdef IPV6_OPTS_SUPPORTED
6116 CmInetIpv6RtHdr0 rtHdr0; /* type 0 route header */
6117 #endif /* IPV6_OPTS_SUPPORTED */
6120 struct in6_pktinfo *pkt6Info; /* IPv6 IP_PKTINFO */
6121 #endif /* LOCAL_INTF */
6123 #if (defined(SS_LINUX) || defined(_XPG4_2))
6124 U8 ancillData[CM_INET_IPV6_ANCIL_DATA];
6125 /* from stack for IPv6 ancill data */
6128 CmInetSockAddr remSockAddr; /* to get packet's src IP address */
6129 #if (defined(SS_LINUX) || defined(_XPG4_2))
6130 U8 ancillData[CM_INET_IPV4_ANCIL_DATA];
6131 /* from stack for IPv4 ancill data */
6133 #endif /* IPV6_SUPPORTED */
6134 /* added new definitions */
6135 Bool allocFlatBuf; /* allocate a flat buffer */
6136 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6137 Data *recvBuf = NULLP; /* receive buffer */
6140 struct in_pktinfo *pkt4Info; /* IPv4 IP_PKTINFO */
6142 #endif /* SS_LINUX */
6143 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6144 struct cmsghdr *cmsgptr;/* pointer to struct cmsghdr */
6146 #endif /* WIN32 | CMINETFLATBUF */
6147 /* used by getsockopt */
6149 /* cm_inet_c_001.main_55:Removed unused variables errValue and optLen */
6153 #if (ERRCLASS & ERRCLS_INT_PAR)
6154 /* error check on parameters */
6155 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6156 (info == NULLP) || (mPtr == NULLP) || (len == NULLP))
6160 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6164 /*cm_inet_c_001.main_48 variables declaration */
6165 #if !((defined(WIN32) || defined(CMINETFLATBUF)))
6170 #if (defined(WIN32) || defined(CMINETFLATBUF))
6172 #ifdef IPV6_SUPPORTED
6174 #endif /* IPV6_SUPPORTED */
6176 #ifdef IPV6_SUPPORTED
6179 #endif /* IPV6_SUPPORTED */
6181 #if (defined(SS_LINUX) || defined(_XPG4_2))
6182 cmMemset((U8*)ancillData, 0, sizeof(ancillData));
6183 #endif /* SS_LINUX || _XPG4_2 */
6185 #endif /* (WIN32 | CMINETFLATBUF) */
6187 /* clear the structure */
6188 cmMemset((U8*)&remSockAddr, 0, sizeof(remSockAddr));
6190 /* get number of pending data */
6191 /* removed 3rd arg memInfo. MemInfo is no longer
6192 needed as we call ioctl for all sockets */
6194 /* cm_inet_c_001.main_48 : call ioctl only for STREAM
6195 * sockets now. For Non-Stream sockets(Raw & UDP), fix
6196 * pending length to CM_INET_MAX_UDPRAW_MSGSIZE
6198 if(sockFd->type == CM_INET_STREAM)
6200 ret = cmInetGetNumRead(sockFd, &pendLen);
6203 /* ret may be RFAILED or ROUTRES */
6209 /* cm_inet_c_001.main_48 : pendLen is set 1 greater
6210 * than the #defined value. If recvFrom/recvMsg
6211 * returns the len == pendLen, we would drop the
6212 * message as the msg len is larger than the largest
6213 * msg we are willing to accept.
6215 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE+1;
6219 /* check if connection got closed */
6222 if (sockFd->type == CM_INET_STREAM)
6224 /* cm_inet_c_001.main_50:
6225 * cm_inet_c_001.main_56: Removed comment for cm_inet_c_001.main_50 as
6226 * the current patch changes its functionality */
6227 U8 readBuf[1]; /* declaration of variable for Peek */
6230 * cm_inet_c_001.main_56:
6231 * We are peeking the socket buffer again with peek as on some machines
6232 * like solaris, there is a latency observed in ioctl. In such cases,
6233 * ioctl may return 0, even though there are bytes available to read.
6234 * We reconfirm through peek whether 0 means EOF or its ioctl latency
6237 ret = cmInetPeekNew(sockFd, NULLP, info, 0, 1, readBuf);
6242 /* cm_inet_c_001.main_56:
6243 * Returning ROKDNA even cmInetPeekNew returns ROK. Because currently
6244 * we are not sure about pending length. Anyway socket FD already set,
6245 * we do another iteration to get exact pendLen value. We cannot call
6246 * cmInetGetNumRead at this point because of latency between the ioctl
6247 * call and recvfrom call issues on some machines ioctl call may
6248 * return ZERO even their a data to read. */
6252 /* cm_inet_c_001.main_52: Support for partial reception */
6253 /* cm_inet_c_001.main_59: Fix for compilation warning */
6254 if ((sockFd->type == CM_INET_STREAM) && (*len > (MsgLen)pendLen))
6256 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6257 *len = (MsgLen)pendLen;
6260 /* check if there are enough pending data to read */
6261 if ((*len == CM_INET_READ_ANY) || ((U32)*len <= pendLen))
6263 if (*len == CM_INET_READ_ANY)
6265 /* added check for TCP socket. Pending data length in
6266 the socket recv buffer is determined by ioctl call in
6268 For TCP it can't be > CM_INET_MAX_MSG_LEN. */
6269 if (sockFd->type == CM_INET_STREAM)
6271 /* max message length is limited to control the memory usage */
6272 if (pendLen > CM_INET_MAX_MSG_LEN)
6273 pendLen = CM_INET_MAX_MSG_LEN;
6275 /* cm_inet_c_001.main_48 : removed the check for
6276 * Non Stream sockets (pendLen < MAX_UDPRAW_MSGSIZE)
6277 * as we are hardcoding pendLen for Non-Stream sockets.
6280 /* read all pending data */
6281 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6282 bufLen = (MsgLen)pendLen;
6283 *len = (MsgLen)pendLen;
6287 /* cm_inet_c_001.main_45- Returning CM_INET_MAX_MSG_LEN when input is larger than
6290 /* max message length is limited to control the memory usage */
6291 if ((*len) > CM_INET_MAX_MSG_LEN)
6293 (*len) = CM_INET_MAX_MSG_LEN;
6296 /* read data length given by user */
6300 #if (defined(WIN32) || defined(CMINETFLATBUF))
6302 /* set destination Internet address structure */
6303 if (fromAddr != NULLP)
6305 remAddrLen = sizeof(remSockAddr);
6312 /* allocate flat receive buffer */
6313 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6322 * maybe needs more than one recvfrom() call to read an entire
6323 * message from a stream socket (TCP)
6327 /* added separate recvfrom calls different OS */
6329 /*cm_inet_c_001.main_42 1. In Vx-Works the 5th and 6th parameter of recvfrom
6330 system call are either NULL or should be valid pointer.*/
6331 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
6333 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6334 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
6336 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6337 NULLP, (int *)&remAddrLen);
6339 #if ( defined(SUNOS) || defined(SS_LINUX))
6341 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6342 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
6344 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6345 NULLP, (socklen_t *)&remAddrLen);
6348 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6349 &remSockAddr, (S32 *)&remAddrLen);
6351 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
6352 NULLP, (S32 *)&remAddrLen);
6354 #endif /* defined(SUNOS) || defined(SS_LINUX) */
6355 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
6357 if (recvLen == INET_ERR)
6360 /* moved cleanup here */
6361 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6363 /* added check ERR_WOULDBLOCK */
6364 if ((INET_ERR_CODE == ERR_AGAIN) ||
6365 (INET_ERR_CODE == ERR_WOULDBLOCK))
6372 /* In Windows the recvfrom function fails
6373 * with error code which maps to either WSAECONNABORTED. If
6374 * this happens then cmInetRecvMsg must return RCLOSED */
6375 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
6376 (INET_ERR_CODE == ERR_CONNRESET))
6384 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6385 /* cm_inet_c_001.main_62:Warning fix */
6386 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6387 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6388 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6390 /* cm_inet_c_001.main_62:Warning fix */
6391 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6392 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6393 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6394 #endif /*ALIGN_64BIT*/
6395 #endif /* CMINETDBG */
6403 * a message is always read atomically on a datagram socket,
6404 * therefore it's ok to read less than pending data!
6407 if ((sockFd->type == CM_INET_RAW) ||
6408 (sockFd->type == CM_INET_DGRAM))
6413 #else /* CM_INET2 */
6414 if (sockFd->type == CM_INET_DGRAM)
6419 #endif /* CM_INET2 */
6420 } /* while (curLen > 0) (only for stream sockets) */
6422 /* For UDP, it is possible to receive
6423 * a 0 byte datagram, in this case just return ROKDNA.
6426 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6429 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6432 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6436 /* cm_inet_c_001.main_48 : If Received
6437 * len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6441 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6442 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6444 if ((sockFd->type == CM_INET_DGRAM)
6445 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6450 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6451 /* cm_inet_c_001.main_62:Warning fix */
6452 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6453 " > than allowed(%lu), sockFd->fd(%ld) \n",
6454 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6455 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6457 /* cm_inet_c_001.main_62:Warning fix */
6458 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6459 " > than allowed(%lu), sockFd->fd(%d) \n",
6460 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6461 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6462 #endif /*ALIGN_64BIT*/
6464 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6468 /* cm_inet_c_001.main_48 : copy data to a message structure */
6469 ret = SGetMsg(info->region, info->pool, &mBuf);
6473 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6478 if ((sockFd->type == CM_INET_DGRAM) ||
6479 (sockFd->type == CM_INET_RAW))
6481 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6485 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6488 #else /* CM_INET2 */
6489 if (sockFd->type == CM_INET_DGRAM)
6491 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6495 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6497 #endif /* CM_INET2 */
6501 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6507 /* setup return destination Internet address */
6508 /* added the check of (remAddrLen > 0) */
6509 if ((fromAddr != NULLP) && (remAddrLen > 0))
6511 #ifdef IPV6_SUPPORTED
6512 if (remAddrLen == sizeof(struct sockaddr_in6))
6514 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6515 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6516 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_U16(remAddr6->sin6_port);
6517 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6518 &remAddr6->sin6_addr);
6522 remAddr = (struct sockaddr_in *)&remSockAddr;
6523 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6524 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
6525 fromAddr->u.ipv4Addr.address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6528 remAddr = (struct sockaddr_in *)&remSockAddr;
6529 fromAddr->port = CM_INET_NTOH_U16(remAddr->sin_port);
6530 fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6531 #endif /* IPV6_SUPPORTED */
6535 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6537 #else /* end of Win NT/flat buffer specific part */
6539 /* Initialise variable */
6540 allocFlatBuf = FALSE;
6543 * maybe needs more than one recvmsg() call to read entire message
6544 * on a stream socket
6548 /* allocate gather vector, it's a dynamic array */
6549 numDBufs = CM_INET_MAX_DBUF;
6551 ret = SGetSBuf(info->region, info->pool, (Data**)&dBufs,
6552 numDBufs*sizeof(Buffer*));
6558 /* Allocate dBufs for gather read */
6559 /* allocate dBufs for gathering read */
6560 if (sockFd->type == CM_INET_STREAM)
6561 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6564 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6568 /* check if the function returned RNA */
6571 /* Incase of UDP/RAW messages allocate a flat buffer. Incase
6572 * of TCP ignore this error condition. The user will call
6573 * cmInetRecvMsg again */
6574 /* cm_inet_c_001.main_62:Warning fix */
6575 if (sockFd->type != (U8)CM_INET_STREAM)/* G++ */
6578 #ifdef T2K_MEM_LEAK_DBG
6579 char * file = __FILE__;
6580 U32 line = __LINE__;
6583 /* cleanup the dBuf array */
6584 for (i = 0; i < msg.msg_iovlen; i++)
6585 SPutDBuf(info->region, info->pool, dBufs[i]);
6587 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6588 numDBufs * sizeof(Buffer*));
6590 /* allocate flat receive buffer */
6591 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6595 allocFlatBuf = TRUE;
6597 /* update the message structure */
6599 rxArr[0].iov_base = (Void*)recvBuf;
6600 rxArr[0].iov_len = (U32)bufLen;
6602 rxArr[0].iov_base = (S8*)recvBuf;
6603 rxArr[0].iov_len = bufLen;
6604 #endif /* SS_LINUX */
6605 msg.msg_iov = rxArr;
6611 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6612 numDBufs*sizeof(Buffer*));
6617 numBuf = msg.msg_iovlen;
6619 /* setup destination Internet address structure */
6620 if (fromAddr != NULLP)
6623 msg.msg_name = (Void*)&remSockAddr;
6626 msg.msg_name = (char *)&remSockAddr;
6628 msg.msg_name = (caddr_t)&remSockAddr;
6630 #endif /* SS_LINUX */
6631 msg.msg_namelen = sizeof(remSockAddr);
6635 msg.msg_name = NULLP;
6636 msg.msg_namelen = 0;
6639 /* added defined(_XPG4_2). Also changed the
6641 #if (defined(SS_LINUX) || defined(_XPG4_2))
6642 msg.msg_control = ancillData;
6643 msg.msg_controllen = sizeof(ancillData);
6645 msg.msg_accrights = NULLP;
6646 msg.msg_accrightslen = 0;
6647 #endif /* SS_LINUX */
6649 recvLen = recvmsg(sockFd->fd, &msg, flags);
6650 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
6652 /* Moved up the cleanup precedures here before returning */
6653 /* Cleanup flat buffer if allocated */
6655 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6659 for (i = 0; i < numBuf; i++)
6661 #ifdef T2K_MEM_LEAK_DBG
6662 char * file = __FILE__;
6663 U32 line = __LINE__;
6666 SPutDBuf(info->region, info->pool, dBufs[i]);
6668 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6669 numDBufs*sizeof(Buffer*));
6672 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6673 * it has partially received data
6675 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
6676 added check ERR_WOULDBLOCK */
6677 if ((INET_ERR_CODE == ERR_AGAIN) ||
6678 (INET_ERR_CODE == ERR_WOULDBLOCK))
6680 /* cm_inet_c_001.main_50 : If message is read partially then just return
6681 * OK without freeing the mPtr. This will gaurd us
6682 * against unexpected WOULDBLOCKS observed in solaris
6690 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6691 * it has partially received data
6699 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6700 /* cm_inet_c_001.main_62:Warning fix */
6701 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6702 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6703 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6705 /* cm_inet_c_001.main_62:Warning fix */
6706 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6707 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6708 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6709 #endif /*ALIGN_64BIT*/
6710 #endif /* CMINETDBG */
6712 /* If this happens then cmInetRecvMsg must return RCLOSED.
6713 * Needed for getting icmp msgs */
6714 if (INET_ERR_CODE == ERR_CONNABORTED)
6724 /* added for IPv6 extn headers */
6725 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6727 /* check if ancillary data has been received.
6728 * Return the allocated memory when no ancillary data received */
6729 #if (defined(SS_LINUX) || defined(_XPG4_2))
6730 if (msg.msg_controllen)
6732 cmsgptr = CMSG_FIRSTHDR(&msg);
6738 #endif /* SS_LINUX || _XPG4_2 */
6740 if (cmsgptr != NULLP)
6742 #ifdef IPV6_OPTS_SUPPORTED
6743 if(ipHdrParams != NULLP)
6745 ipHdrParams->u.ipv6HdrParm.ttl.pres = FALSE;
6746 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt = FALSE;
6747 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt = FALSE;
6748 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt = FALSE;
6750 /* get all ancillary data objects recvd one by one */
6751 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6752 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6754 if (cmsgptr->cmsg_level == IPPROTO_IPV6)
6756 /* Initialise ipHdrParams properly */
6757 ipHdrParams->type = CM_INET_IPV6ADDR_TYPE;
6759 if (cmsgptr->cmsg_type == IPV6_HOPOPTS)
6761 /* build up HBH opt array from recvd ancillary data */
6762 ret = cmInet6BuildRecvHopOptsArr(
6763 (U8 *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6764 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
6768 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt =
6772 else if(cmsgptr->cmsg_type == IPV6_DSTOPTS)
6774 else if ((cmsgptr->cmsg_type == IPV6_DSTOPTS) ||
6775 (cmsgptr->cmsg_type == IPV6_RTHDRDSTOPTS))
6776 #endif /* SS_LINUX */
6778 /* build up Dest opt array from recvd ancillary data */
6779 ret = cmInet6BuildRecvDstOptsArr(
6780 (U8 *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6781 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr,
6785 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt =
6788 else if (cmsgptr->cmsg_type == IPV6_RTHDR)
6790 /* build up Route Hdr from recvd ancillary data */
6791 ret = cmInet6BuildRecvRtHdr(
6792 (U8 *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, &rtHdr0,
6793 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
6797 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt =
6800 else if(cmsgptr->cmsg_type == IPV6_HOPLIMIT)
6802 /* get the received hoplimit */
6803 ret = cmInet6GetHopLimitValue((U8 *)CMSG_DATA(cmsgptr),
6804 cmsgptr->cmsg_len, &ipHdrParams->u.ipv6HdrParm);
6811 #endif /* IPV6_OPTS_SUPPORTED */
6813 #ifdef IPV6_SUPPORTED
6815 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6816 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6818 if(cmsgptr->cmsg_type == IPV6_PKTINFO)
6820 pkt6Info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
6821 localIf->intfPrsnt = TRUE;
6822 localIf->localIf = pkt6Info->ipi6_ifindex;
6823 localIf->localIfAddr.type = CM_INET_IPV6ADDR_TYPE;
6824 cmMemcpy((U8 *)&localIf->localIfAddr.u.ipv6NetAddr,
6825 (U8 *)(int *)&pkt6Info->ipi6_addr, 16);
6828 #endif /* LOCAL_INTF */
6831 #if (defined(SS_LINUX) && defined(LOCAL_INTF))
6832 #ifdef IPV6_SUPPORTED
6833 if(sockFd->protType == AF_INET)
6836 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
6837 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6839 if (cmsgptr->cmsg_level == IPPROTO_IP &&
6840 cmsgptr->cmsg_type == IP_PKTINFO)
6842 pkt4Info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
6843 localIf->intfPrsnt = TRUE;
6844 localIf->localIf = pkt4Info->ipi_ifindex;
6845 localIf->localIfAddr.type = CM_INET_IPV4ADDR_TYPE;
6846 localIf->localIfAddr.u.ipv4NetAddr =
6847 ntohl(*(int *)&pkt4Info->ipi_addr);
6850 #ifdef IPV6_SUPPORTED
6853 #endif /* SS_LINUX */
6855 #endif /* IPV6_OPTS_SUPPORTED || LOCAL_INTF */
6857 /* setup return destination Internet address */
6858 if (fromAddr != NULLP)
6860 #ifdef IPV6_SUPPORTED
6861 if (msg.msg_namelen == sizeof(struct sockaddr_in6))
6863 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6864 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6865 fromAddr->u.ipv6Addr.port =
6866 CM_INET_NTOH_U16(remAddr6->sin6_port);
6867 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6868 &remAddr6->sin6_addr);
6872 remAddr = (struct sockaddr_in *)&remSockAddr;
6873 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6874 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
6875 fromAddr->u.ipv4Addr.address =
6876 CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6879 remAddr = (struct sockaddr_in *)&remSockAddr;
6880 fromAddr->port = CM_INET_NTOH_U16(remAddr->sin_port);
6881 fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
6882 #endif /* IPV6_SUPPORTED */
6885 /* Incase a flat buffer was allocated get
6886 * a message to pass up */
6892 ret = SGetMsg(info->region, info->pool, &tempMsg);
6896 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6900 /* cm_inet_c_001.main_48 : A 0 len UDP packet could be received */
6903 ret = SAddPstMsgMult(recvBuf, recvLen, tempMsg);
6906 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6914 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6915 /* cm_inet_c_001.main_48 :flat buffers are allocated
6916 * for non -TCP sockets. On these sockets we can receive
6917 * only one message at a time
6919 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6920 *len = (MsgLen)recvLen;
6925 /* build message out of dBufs */
6926 ret = buildRecvMsg(info, rxArr, numBuf, recvLen, dBufs, &tempMsg);
6929 /* Deallocate previously allocated
6933 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6934 numDBufs*sizeof(Buffer*));
6941 /* it's first recvmsg() call */
6946 /* concatenate messages */
6947 ret = SCatMsg(*mPtr, tempMsg, M1M2);
6953 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6954 numDBufs*sizeof(Buffer*));
6960 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6961 numDBufs*sizeof(Buffer*));
6964 * a message is always read atomically on a datagram socket,
6965 * therefore it's ok to read less than pending data!
6968 if ((sockFd->type == CM_INET_DGRAM) ||
6969 (sockFd->type == CM_INET_RAW))
6971 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6972 *len = (MsgLen)recvLen;
6975 #else /* CM_INET2 */
6976 if (sockFd->type == CM_INET_DGRAM)
6978 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6979 *len = (MsgLen)recvLen;
6982 #endif /* CM_INET2 */
6983 } /* while(bufLen > 0) (only for stream sockets) */
6985 /* cm_inet_c_001.main_48 : For UDP, it is possible to receive
6986 * a 0 byte datagram, in this case just return ROKDNA
6990 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6993 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
7005 /* Received len == CM_INET_MAX_UDPRAW_MSGSIZE+1
7010 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
7011 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
7013 if ((sockFd->type == CM_INET_DGRAM)
7014 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
7025 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7026 /* cm_inet_c_001.main_62:Warning fix */
7027 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
7028 " allowed(%d),sockFd->fd(%ld)\n",
7029 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
7030 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
7032 /* cm_inet_c_001.main_62:Warning fix */
7033 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
7034 " allowed(%d),sockFd->fd(%d)\n",
7035 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
7036 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
7043 #endif /* WIN32 | CMINETFLATBUF */
7047 /* not enough data pending yet */
7052 } /* end of cmInetRecvMsg */
7055 /* cm_inet_c_001.main_56: Added new function cmInetPeekNew() */
7059 * Fun: cmInetPeekNew
7061 * Desc: Reads some data from the socket without destroying the socket
7063 * The data is specified by the byte positon (first byte is at
7064 * position 0) and the length.
7066 * Ret: ROK - successful
7067 * ROKDNA - ok, data not available
7068 * RCLOSED - connection closed by peer
7071 * Notes: Following are the differences from the cmInetPeek to cmInetPeekNew.
7072 * This primitive does not call the select function as this is already
7073 * taken care by the called primitive. This primitive will not use any
7074 * ioctl calls, because on some machines due to latency in ioctl call
7075 * length may return as ZERO, even there is some data to be read from
7076 * the socket and this primitive only peek buffer using recvfrom.
7078 * Caller of this function need to allocate the sufficient memory to hold
7079 * the data peeked from the socket i.e. dataPos + dataLen. Socket data
7080 * will be copied in the "data" starting from dataPos offset.
7082 * For example, caller passed the following values to this function.
7083 * dataPos = 2 and dataLen = 10,then size of data buffer received should
7084 * be minimum of (dataPos + dataLen)12 bytes and socket data will be
7085 * copied in the data buffer from offset 2 (dataPos) onwards.
7092 PUBLIC S16 cmInetPeekNew
7094 CmInetFd *sockFd, /* socket file descriptor */
7095 CmInetAddr *fromAddr, /* sender Internet address/port */
7096 CmInetMemInfo *info, /* buffer allocation info */
7097 MsgLen dataPos, /* position of data */
7098 MsgLen dataLen, /* length of read data */
7099 Data *data /* read data */
7102 PUBLIC S16 cmInetPeekNew(sockFd, fromAddr, info, dataPos, dataLen, data)
7103 CmInetFd *sockFd; /* socket file descriptor */
7104 CmInetAddr *fromAddr; /* sender Internet address/port */
7105 CmInetMemInfo *info; /* buffer allocation info */
7106 MsgLen dataPos; /* position of data */
7107 MsgLen dataLen; /* length of read data */
7108 Data *data; /* read data */
7111 /* cm_inet_c_001.main_57 - Fix for validation and compilation warning */
7112 S32 recvLen; /* number of received octets */
7113 S32 remAddrLen; /* length of remote address length */
7114 struct sockaddr_in *remAddr; /* remote Internet address */
7115 #ifdef IPV6_SUPPORTED
7116 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
7117 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
7119 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
7120 #endif /* IPV6_SUPPORTED */
7122 TRC2(cmInetPeeknew);
7124 #if (ERRCLASS & ERRCLS_INT_PAR)
7125 /* error check on parameters */
7126 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
7127 (info == NULLP) || (data == NULLP) ||
7128 (dataPos < 0) || (dataLen < 0))
7132 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7134 /* check if fromAddr is present or not */
7135 if (fromAddr != NULLP)
7137 remAddrLen = sizeof(remSockAddr);
7144 /* added different recvfrom calls with different 6th arg for
7145 * different OS If remAddrLen is 0, pass NULLP */
7146 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7148 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
7149 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7151 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
7152 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7154 #if ( defined(SUNOS) || defined(SS_LINUX))
7156 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
7157 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7158 (socklen_t *)&remAddrLen);
7160 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
7161 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7164 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
7165 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7167 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
7168 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7169 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7170 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7172 /* removed the check of returned remAddrLen */
7173 if (recvLen == INET_ERR)
7175 /* added check ERR_WOULDBLOCK */
7176 if ((INET_ERR_CODE == ERR_AGAIN) ||
7177 (INET_ERR_CODE == ERR_WOULDBLOCK))
7182 /* cm_inet_c_001.main_61: added host unreachable check */
7183 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7184 (INET_ERR_CODE == ERR_CONNRESET) ||
7185 (INET_ERR_CODE == ERR_HOSTUNREACH) ||
7186 (INET_ERR_CODE == ERR_CONNREFUSED))
7193 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7194 /* cm_inet_c_001.main_62:Warning fix */
7195 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%ld)\n",
7196 INET_ERR_CODE, sockFd->fd);
7197 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
7199 /* cm_inet_c_001.main_62:Warning fix */
7200 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%d)\n",
7201 INET_ERR_CODE, sockFd->fd);
7202 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
7204 #endif /* CMINETDBG */
7208 else if (recvLen == 0)
7213 /* cm_inet_c_001.main_57 - Fix for validation */
7214 if (recvLen < (S32)dataLen) /* maybe happen */
7219 /* setup return destination Internet address */
7220 /* added the check of (remAddLen > 0) */
7221 if ((fromAddr != NULLP) && (remAddrLen > 0))
7223 #ifdef IPV6_SUPPORTED
7224 cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
7225 if (remAddrLen == sizeof(struct sockaddr_in6))
7227 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7228 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7229 fromAddr->u.ipv6Addr.port =
7230 CM_INET_NTOH_U16(remAddr6->sin6_port);
7231 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
7232 &remAddr6->sin6_addr);
7236 remAddr = (struct sockaddr_in *)&remSockAddr;
7237 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7238 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
7239 fromAddr->u.ipv4Addr.address =
7240 CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7243 remAddr = (struct sockaddr_in *)&remSockAddr;
7244 fromAddr->port = CM_INET_NTOH_U16(remAddr->sin_port);
7245 fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7246 #endif /* IPV6_SUPPORTED */
7250 } /* end of cmInetPeeknew */
7257 * Desc: Reads some data from the socket without destroying the socket
7259 * The data is specified by the byte positon (first byte is at
7260 * position 0) and the length.
7262 * Ret: ROK - successful
7263 * ROKDNA - ok, data not available
7264 * RCLOSED - connection closed by peer
7274 PUBLIC S16 cmInetPeek
7276 CmInetFd *sockFd, /* socket file descriptor */
7277 CmInetAddr *fromAddr, /* sender Internet address/port */
7278 CmInetMemInfo *info, /* buffer allocation info */
7279 MsgLen dataPos, /* position of data */
7280 MsgLen dataLen, /* length of read data */
7281 Data *data /* read data */
7284 PUBLIC S16 cmInetPeek(sockFd, fromAddr, info, dataPos, dataLen, data)
7285 CmInetFd *sockFd; /* socket file descriptor */
7286 CmInetAddr *fromAddr; /* sender Internet address/port */
7287 CmInetMemInfo *info; /* buffer allocation info */
7288 MsgLen dataPos; /* position of data */
7289 MsgLen dataLen; /* length of read data */
7290 Data *data; /* read data */
7293 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7294 Data *recvBuf = NULLP; /* plain receive buffer */
7295 /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
7296 MsgLen bufLen; /* buffer length */
7297 MsgLen i; /* index */
7298 MsgLen j; /* index */
7299 S32 ret; /* temporary return value */
7300 U32 timeout; /* timeout for cmInetSelect() */
7301 U32 *timeoutPtr; /* pointer to timeout */
7302 S16 numFdS; /* number of ready descriptors */
7303 /* cm_inet_c_001.main_45 - fixing the UMR issue in 64bit linux */
7304 U32 pendLen = 0; /* pending data length */
7305 S32 recvLen; /* number of received octets */
7306 S32 remAddrLen; /* length of remote address length */
7307 CmInetFdSet readFdS; /* socket file descriptor set */
7308 struct sockaddr_in *remAddr; /* remote Internet address */
7309 #ifdef IPV6_SUPPORTED
7310 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
7311 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
7313 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
7314 #endif /* IPV6_SUPPORTED */
7318 #if (ERRCLASS & ERRCLS_INT_PAR)
7319 /* error check on parameters */
7320 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
7321 (info == NULLP) || (data == NULLP) ||
7322 (dataPos < 0) || (dataLen < 0))
7326 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7328 /* check if there are some datas */
7329 if (sockFd->blocking)
7336 /* poll (non-blocking) */
7338 timeoutPtr = &timeout;
7340 CM_INET_FD_ZERO(&readFdS);
7341 CM_INET_FD_SET(sockFd, &readFdS);
7343 ret = cmInetSelect(&readFdS, NULLP, timeoutPtr, &numFdS);
7344 if (CM_INET_FD_ISSET(sockFd, &readFdS))
7346 /* get number of pending data */
7347 /* removed 3rd arg memInfo. MemInfo is no longer needed as we
7348 call ioctl for all sockets */
7349 ret = cmInetGetNumRead(sockFd, &pendLen);
7352 /* cm_inet_c_001.main_50
7353 * Return RCLOSED if cmInetGetNumRead returns RCLOSED. For other
7354 * errors just return RFAILED.
7362 /* check if connection got closed */
7366 /* cm_inet_c_001.main_50
7367 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
7368 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
7369 * socket that select says is ready to read. This should not be
7370 * considered as connection closed. So return ROKDNA instead of
7371 * RCLOSED even for TCP sockets
7375 /* added check for TCP/UDP socket. Pending data len in the socket
7376 recv buffer is determined by ioctl call in cmInetGetNumRead.
7377 For TCP it can't be > CM_INET_MAX_MSG_LEN.
7378 For UDP it can't be > CM_INET_MAX_UDPRAW_MSGSIZE. */
7379 if (sockFd->type == CM_INET_STREAM)
7381 /* max message length is limited to control the memory usage */
7382 if (pendLen > CM_INET_MAX_MSG_LEN)
7383 pendLen = CM_INET_MAX_MSG_LEN;
7384 /* In STREAM remote address is not required */
7389 if (pendLen > CM_INET_MAX_UDPRAW_MSGSIZE)
7390 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE;
7392 remAddrLen = sizeof(CmInetSockAddr);
7395 /* check if there are enough pending data to read */
7396 bufLen = dataPos + dataLen;
7398 /* check if fromAddr is present or not */
7399 if (fromAddr != NULLP)
7401 remAddrLen = sizeof(remSockAddr);
7408 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
7409 if ((MsgLen)pendLen >= bufLen)
7411 /* allocate receive buffer (flat structure) */
7412 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
7418 /* added different recvfrom calls with
7419 * different 6th arg for different OS */
7421 /* If remAddrLen is 0, pass NULLP */
7422 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7424 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7425 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7427 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7428 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7430 #if ( defined(SUNOS) || defined(SS_LINUX))
7432 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7433 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7434 (socklen_t *)&remAddrLen);
7436 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7437 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7440 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7441 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7443 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7444 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7445 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7446 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7448 /* removed the check of returned remAddrLen */
7449 if (recvLen == INET_ERR)
7452 /* moved cleanup here */
7453 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7455 /* added check ERR_WOULDBLOCK */
7456 if ((INET_ERR_CODE == ERR_AGAIN) ||
7457 (INET_ERR_CODE == ERR_WOULDBLOCK))
7463 /* moved up the cleanup */
7467 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7468 /* cm_inet_c_001.main_62:Warning fix */
7469 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%ld)\n",
7470 INET_ERR_CODE, sockFd->fd);
7471 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7473 /* cm_inet_c_001.main_62:Warning fix */
7474 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%d)\n",
7475 INET_ERR_CODE, sockFd->fd);
7476 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7478 #endif /* CMINETDBG */
7480 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7481 (INET_ERR_CODE == ERR_CONNRESET))
7489 if (recvLen < (S32)bufLen) /* maybe happen */
7492 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7497 for (j = 0, i = dataPos; i < bufLen; j++, i++)
7498 data[j] = recvBuf[i];
7500 /* setup return destination Internet address */
7501 /* added the check of (remAddLen > 0) */
7502 if ((fromAddr != NULLP) && (remAddrLen > 0))
7504 #ifdef IPV6_SUPPORTED
7505 cmMemset((U8*)fromAddr, 0, sizeof(fromAddr));
7506 if (remAddrLen == sizeof(struct sockaddr_in6))
7508 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7509 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7510 fromAddr->u.ipv6Addr.port =
7511 CM_INET_NTOH_U16(remAddr6->sin6_port);
7512 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
7513 &remAddr6->sin6_addr);
7517 remAddr = (struct sockaddr_in *)&remSockAddr;
7518 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7519 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(remAddr->sin_port);
7520 fromAddr->u.ipv4Addr.address =
7521 CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7524 remAddr = (struct sockaddr_in *)&remSockAddr;
7525 fromAddr->port = CM_INET_NTOH_U16(remAddr->sin_port);
7526 fromAddr->address = CM_INET_NTOH_U32(remAddr->sin_addr.s_addr);
7527 #endif /* IPV6_SUPPORTED */
7531 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7535 /* not enough data pending yet */
7541 /* no data pending */
7546 } /* end of cmInetPeek */
7553 * Desc: Close a socket gracefully.
7555 * Ret: ROK - successful
7565 PUBLIC S16 cmInetClose
7567 CmInetFd *sockFd /* socket file descriptor */
7570 PUBLIC S16 cmInetClose(sockFd)
7571 CmInetFd *sockFd; /* socket file descriptor */
7574 S32 ret; /* temporary return value */
7578 #if (ERRCLASS & ERRCLS_INT_PAR)
7579 /* error check on parameters */
7580 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7584 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7587 ret = closesocket(sockFd->fd);
7589 ret = close(sockFd->fd);
7591 if (ret == INET_ERR)
7595 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7596 /* cm_inet_c_001.main_62:Warning fix */
7597 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%ld)\n",
7598 INET_ERR_CODE, sockFd->fd);
7599 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7601 /* cm_inet_c_001.main_62:Warning fix */
7602 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%d)\n",
7603 INET_ERR_CODE, sockFd->fd);
7604 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7605 #endif /*ALIGN_64BIT*/
7606 #endif /* CMINETDBG */
7611 } /* end of cmInetClose */
7616 * Fun: cmInetShutdown
7618 * Desc: Close an Internet connection with more control over the data of
7619 * the full-duplex connection.
7620 * Values for the howTo parameter:
7622 * CM_INET_SHTDWN_RECV - discard data in receive buffer
7623 * CM_INET_SHTDWN_SEND - discard data in transmit buffer
7624 * CM_INET_SHTDWN_BOTH - discard data in receive and transmit buffer
7626 * Ret: ROK - successful
7629 * Notes: This function does not free the socket descriptor but only closes the
7630 * connection (cmInetClose() has to be called afterwards).
7631 * No error is returned if the socket is not connected while calling
7639 PUBLIC S16 cmInetShutdown
7641 CmInetFd *sockFd, /* socket file descriptor */
7642 S32 howTo /* operation flag */
7645 PUBLIC S16 cmInetShutdown(sockFd, howTo)
7646 CmInetFd *sockFd; /* socket file descriptor */
7647 S32 howTo; /* operation flag */
7650 S32 ret; /* temporary return value */
7652 TRC2(cmInetShutdown);
7654 #if (ERRCLASS & ERRCLS_INT_PAR)
7655 /* error check on parameters */
7656 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7660 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7662 ret = shutdown(sockFd->fd, howTo);
7663 if (ret == INET_ERR)
7665 if (INET_ERR_CODE == ERR_NOTCONN)
7667 /* socket is not connected */
7675 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7676 /* cm_inet_c_001.main_62:Warning fix */
7677 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7678 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
7679 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7681 /* cm_inet_c_001.main_62:Warning fix */
7682 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7683 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
7684 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7685 #endif /*ALIGN_64BIT*/
7686 #endif /* CMINETDBG */
7692 } /* end of cmInetShutdown */
7699 * Desc: Allows multiplex i/o requests among multiple sockets.
7700 * If the parameter mSecTimeout points to a value of zero the
7701 * call immediatley returns (poll), if it is a null pointer, the
7702 * timeout is set to infinit.
7703 * numFdS returns the number of ready file descriptors contained
7704 * in the file descriptor sets
7706 * Ret: ROK - successful
7707 * RTIMEOUT - timout expired
7717 PUBLIC S16 cmInetSelect
7719 CmInetFdSet *readFdS, /* read socket descriptor file set */
7720 CmInetFdSet *writeFdS, /* write socket descriptor file set */
7721 U32 *mSecTimeout, /* timeout in msecs */
7722 S16 *numFdS /* number of ready descriptors */
7725 PUBLIC S16 cmInetSelect(readFdS, writeFdS, mSecTimeout, numFdS)
7726 CmInetFdSet *readFdS; /* read socket descriptor file set */
7727 CmInetFdSet *writeFdS; /* write socket descriptor file set */
7728 U32 *mSecTimeout; /* timeout in msecs */
7729 S16 *numFdS; /* number of ready descriptors */
7732 S32 ret; /* temporary return value */
7733 struct timeval timeout; /* timeout structure */
7734 struct timeval *timeoutPtr;
7737 #if (ERRCLASS & ERRCLS_INT_PAR)
7738 /* error check on parameters */
7739 if (numFdS == NULLP)
7743 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7747 if (mSecTimeout != NULLP)
7749 timeout.tv_sec = *mSecTimeout / 1000;
7750 timeout.tv_usec = (*mSecTimeout % 1000) * 1000;
7751 timeoutPtr = &timeout;
7755 /* infinite timeout */
7761 timeout.tv_usec = 1;
7764 /* cm_inet_c_001.main_53 - Removed do-while loop */
7765 ret = select(FD_SETSIZE, readFdS, writeFdS, (fd_set*)0, timeoutPtr);
7767 /* cm_inet_c_001.main_53 - Return ROKDNA in case select was interrupted */
7768 if ((ret == INET_ERR) && (INET_ERR_CODE == ERR_EINTR))
7773 /* timeout occured */
7779 if (ret == INET_ERR)
7781 /* asa: Added a check for ERR_INVAL to return ROK
7782 * readFdS and writeFdS may be passed as NULL to
7783 * cmInetSelect() call
7785 switch(errCode = INET_ERR_CODE)
7792 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7793 /* cm_inet_c_001.main_62:Warning fix */
7794 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSelect() Failed : error(%d)\n",
7796 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET039, 0, prntBuf);
7797 #endif /* CMINETDBG */
7800 } /* end of switch */
7803 /* return number of ready file descriptors */
7804 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7808 } /* end of cmInetSelect */
7815 * Desc: Sets a socket option.
7816 * The function supports following options:
7818 * CM_INET_OPT_BLOCK:
7819 * value: CM_INET_OPT_DISABLE non-blocking
7820 * value: CM_INET_OPT_ENABLE blocking
7822 * CM_INET_OPT_REUSEADDR:
7823 * value: CM_INET_OPT_ENABLE reuse address
7825 * CM_INET_OPT_BROADCAST:
7826 * value: CM_INET_OPT_DISABLE
7827 * value: CM_INET_OPT_ENABLE
7829 * CM_INET_OPT_KEEPALIVE:
7830 * value: CM_INET_OPT_DISABLE
7831 * value: CM_INET_OPT_ENABLE
7833 * CM_INET_OPT_RX_BUF_SIZE:
7834 * value: receive buffer size in bytes
7836 * CM_INET_OPT_TX_BUF_SIZE:
7837 * value: transmitter buffer size in bytes
7839 * CM_INET_OPT_ADD_MCAST_MBR:
7840 * value: address of CmInetMCastInf structure
7842 * CM_INET_OPT_DRP_MCAST_MBR:
7843 * value: address of CmInetMCastInf structure
7845 * CM_INET_OPT_TCP_NODELAY:
7846 * value: CM_INET_OPT_DISABLE
7847 * value: CM_INET_OPT_ENABLE
7849 * CM_INET_OPT_BSD_COMPAT: For Linux only
7850 * value: CM_INET_OPT_ENABLE
7851 * value: CM_INET_OPT_DISABLE
7853 * CM_INET_OPT_HDR_INCLD:
7854 * value: CM_INET_ENABLE
7855 * value: CM_INET_DISABLE
7857 * CM_INET_OPT_DONT_FRAGMENT:
7858 * value: CM_INET_OPT_ENABLE
7859 * value: CM_INET_DISABLE
7862 * value: Type of Service.
7865 * value: Time To Live.
7867 * CM_INET_OPT_IP_OPTIONS:
7868 * value: IPv4 header option value
7871 * CM_INET_OPT_IP_ROUTER_ALERT:
7872 * value: CM_INET_OPT_DISABLE
7873 * value: CM_INET_OPT_ENABLE
7875 * CM_INET_OPT_IPV4_PKTINFO
7876 * value: CM_INET_OPT_ENABLE
7877 * value: CM_INET_OPT_DISABLE
7879 * CM_INET_OPT_MCAST_LOOP:
7880 * value: CM_INET_OPT_DISABLE
7881 * value: CM_INET_OPT_ENABLE
7883 * CM_INET_OPT_MCAST_IF:
7884 * value: Address of interface.
7886 * CM_INET_OPT_MCAST_TTL:
7887 * value: TTL of the outgoing multicast packet.
7889 * The next options are defined only if IPV6 is
7892 * CM_INET_OPT_ADD_MCAST6_MBR:
7893 * value: address of CmInetMCastInf6 structure
7895 * CM_INET_OPT_DRP_MCAST6_MBR:
7896 * value: address of CmInetMCastInf6 structure
7898 * CM_INET_OPT_MCAST6_LOOP:
7899 * value: CM_INET_OPT_DISABLE
7900 * value: CM_INET_OPT_ENABLE
7902 * CM_INET_OPT_MCAST6_IF:
7903 * value: Interface index
7905 * CM_INET_OPT_MCAST6_HOPS:
7906 * value: multicast hop limit
7908 * CM_INET_OPT_RECVIPV6_HOPLIM:
7909 * value: CM_INET_OPT_ENABLE hop limit will be returned
7911 * value: CM_INET_OPT_DISABLE hop limit wont be returned
7914 * CM_INET_OPT_RECVIPV6_HBHOPTS:
7915 * value: CM_INET_OPT_ENABLE HBH Options will be returned
7917 * value: CM_INET_OPT_DISABLE HBH Options wont be returned
7920 * CM_INET_OPT_RECVIPV6_DSTOPTS:
7921 * value: CM_INET_OPT_ENABLE Dest Options will be returned
7923 * value: CM_INET_OPT_DISABLE Dest Options wont be returned
7926 * CM_INET_OPT_RECVIPV6_RTHDR:
7927 * value: CM_INET_OPT_ENABLE Route Hdr Opt will be turned
7929 * value: CM_INET_OPT_DISABLE Route Hdr Opt will be turned
7930 * OFF on the socket.
7932 * CM_INET_OPT_IP_ROUTER_ALERT6
7933 * value: CM_INET_OPT_ENABLE
7934 * value: CM_INET_OPT_DISABLE
7936 * CM_INET_OPT_IPV6_PKTINFO
7937 * value: CM_INET_OPT_ENABLE Enable sending and receiving
7939 * value: CM_INET_OPT_DISABLE Disable sending and receiving
7942 * CM_INET_OPT_LINGER
7943 * value: address of CmInetSockLinger structure
7945 * CM_INET_OPT_SCTP_EVENTS
7946 * value: address of CmInetSctpSockEvent structure
7948 * CM_INET_OPT_SCTP_PRIM_ADDR
7949 * value: address of CmInetSctpPrimAddr structure
7951 * CM_INET_OPT_SCTP_PEERADDR_PARAMS
7952 * value: address of CmInetSctpPeerAddrParams structure
7955 * Ret: ROK - successful
7957 * RNA - failed, option not available
7958 * (Only when CM_INET2 is defined)
7960 * Notes: The send and receive buffer size may be system
7961 * specific. The cmInetSetOpt() call may return
7962 * successfuly although not the entire buffer size
7969 PUBLIC S16 cmInetSetOpt
7971 CmInetFd *sockFd, /* socket file descriptor */
7972 U32 level, /* option level */
7973 U32 type, /* option type */
7974 Ptr value /* option value */
7977 PUBLIC S16 cmInetSetOpt(sockFd, level, type, value)
7978 CmInetFd *sockFd; /* socket file descriptor */
7979 U32 level; /* option level */
7980 U32 type; /* option type */
7981 Ptr value; /* option value */
7984 S32 ret = ROK; /* temporary return value */
7985 U32 disable = 0; /* disable option */
7986 U32 enable = 1; /* enable option */
7988 /* added for IPv4 options */
7989 #ifdef IPV4_OPTS_SUPPORTED
7990 #if((!defined (SS_VW)) && (!defined(SS_LINUX)))
7991 TknStr64 *tempTknStr64; /* points TknStr64 structure */
7992 /* which has value for IPv4 hdr options.*/
7993 #endif /* SS_VW && SS_LINUX */
7997 #endif /* IPV4_OPTS_SUPPORTED */
7999 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST)\
8001 U8 lpEnable = 1; /* multicast loop enable */
8002 U8 lpDisable = 0; /* multicast loop disable */
8003 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8006 BOOL boolEnable = TRUE; /* enable option */
8007 BOOL boolDisable = FALSE; /* disable option */
8010 #if (defined(SUNOS) || defined(WIN32) || defined(SS_PS) || \
8011 defined(SS_VW_MCAST) || defined(HPOS))
8012 struct ip_mreq stMreq;
8013 CmInetMCastInf *mCast;
8014 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8016 #ifdef IPV6_SUPPORTED
8017 U32 loopEna = 1; /* IPv6 multicast loop enable */
8018 U32 loopDis = 0; /* IPv6 multicast loop disable */
8019 struct ipv6_mreq *stMreq6Ptr;
8020 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
8021 this flag is gaurded under ICMPV6_FILTER_SUPPORTED. so if user want this
8022 support he has to enable the above flag.*/
8023 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8024 * to support filteration of ICMP messages */
8025 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8026 struct icmp6_filter *icmp6Filter;
8027 #endif /* ICMPV6_FILTER_SUPPORTED */
8028 #endif /* IPV6_SUPPORTED */
8030 /* cm_inet_c_001.main_58 : Added new local variables to support filteration
8031 * of ICMP messages */
8033 #ifdef CM_ICMP_FILTER_SUPPORT
8034 struct icmp_filter icmpFilter;
8038 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8041 struct sctp_event_subscribe event;
8042 struct sctp_paddrparams addrParams;
8043 struct sctp_setprim setPrim;
8044 struct sockaddr_in *pAddr;
8045 struct sctp_assocparams assocParams;
8046 struct sctp_initmsg initmsg;
8047 struct sctp_rtoinfo rtoinfo;
8048 #ifdef IPV6_SUPPORTED
8049 struct sockaddr_in6 *pAddr6;
8050 #endif /* IPV6_SUPPORTED */
8052 CmInetSockLinger *pSockLinger;
8053 CmInetSctpSockEvent *pSctpEvent;
8054 CmInetSctpPrimAddr *pSctpPrimAddr;
8055 CmInetSctpPeerAddrParams *pSctpPAddrParams;
8056 CmInetSctpRtoInfo *pSctpRtoInfo;
8057 CmInetSctpInitMsg *pSctpInitMsg;
8058 CmInetSctpAssocParams *pSctpAssocParams;
8065 /* cm_inet_c_001.main_58 : Added NULL check for value field */
8071 #if (ERRCLASS & ERRCLS_INT_PAR)
8072 /* error check on parameters */
8073 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
8077 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8081 case CM_INET_OPT_BLOCK:
8082 optVal = (U32*)value;
8085 case CM_INET_OPT_ENABLE:
8088 /* cm_inet_c_001.main_59: Fix for compilation warning */
8089 ret = ioctlsocket(sockFd->fd, FIONBIO, (U32 *)&disable);
8092 ret = ioctl(sockFd->fd, FIONBIO, (char*)&disable);
8095 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&disable);
8097 ret = ioctl(sockFd->fd, (S32)FIONBIO, &disable);
8102 sockFd->blocking = 1;
8105 case CM_INET_OPT_DISABLE:
8107 /* cm_inet_c_001.main_59: Fix for compilation warning */
8108 ret = ioctlsocket(sockFd->fd, FIONBIO, (U32 *)&enable);
8111 ret = ioctl(sockFd->fd, FIONBIO, (char*)&enable);
8114 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&enable);
8116 ret = ioctl(sockFd->fd, (S32)FIONBIO, &enable);
8120 sockFd->blocking = 0;
8130 case CM_INET_OPT_REUSEADDR:
8131 optVal = (U32*)value;
8132 if (*optVal == CM_INET_OPT_ENABLE)
8135 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8136 (char*)&boolEnable, sizeof(boolEnable));
8138 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8139 (char*)&enable, sizeof(enable));
8141 setsockopt(sockFd->fd, level, SO_REUSEPORT,
8142 (char*)&enable, sizeof(enable));
8146 else if (*optVal == CM_INET_OPT_DISABLE)
8149 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8150 (char*)&boolDisable, sizeof(boolDisable));
8152 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
8153 (char*)&disable, sizeof(disable));
8155 ret = setsockopt(sockFd->fd, level, SO_REUSEPORT,
8156 (char*)&disable, sizeof(disable));
8162 case CM_INET_OPT_BROADCAST:
8163 optVal = (U32*)value;
8164 if (*optVal == CM_INET_OPT_ENABLE)
8167 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8168 (char*)&boolEnable, sizeof(boolEnable));
8170 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8171 (char*)&enable, sizeof(enable));
8174 else if (*optVal == CM_INET_OPT_DISABLE)
8177 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8178 (char*)&boolDisable, sizeof(boolDisable));
8180 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
8181 (char*)&disable, sizeof(disable));
8186 case CM_INET_OPT_KEEPALIVE:
8187 optVal = (U32*)value;
8188 if (*optVal == CM_INET_OPT_ENABLE)
8191 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8192 (char*)&boolEnable, sizeof(boolEnable));
8194 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8195 (char*)&enable, sizeof(enable));
8198 else if (*optVal == CM_INET_OPT_DISABLE)
8201 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8202 (char*)&boolDisable, sizeof(boolDisable));
8204 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
8205 (char*)&disable, sizeof(disable));
8210 case CM_INET_OPT_RX_BUF_SIZE:
8211 optVal = (U32*)value;
8212 ret = setsockopt(sockFd->fd, level, SO_RCVBUF,
8213 (char*)optVal, sizeof(*optVal));
8216 case CM_INET_OPT_TX_BUF_SIZE:
8217 optVal = (U32*)value;
8218 ret = setsockopt(sockFd->fd, level, SO_SNDBUF,
8219 (char*)optVal, sizeof(*optVal));
8222 case CM_INET_OPT_TCP_NODELAY:
8223 optVal = (U32*)value;
8224 if (*optVal == CM_INET_OPT_ENABLE)
8228 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8229 (char*)&boolEnable, sizeof(boolEnable));
8230 #endif /* SS_WINCE */
8232 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8233 (char*)&enable, sizeof(enable));
8236 else if (*optVal == CM_INET_OPT_DISABLE)
8240 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8241 (char*)&boolDisable, sizeof(boolDisable));
8242 #endif /* SS_WINCE */
8244 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
8245 (char*)&disable, sizeof(disable));
8250 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || \
8251 defined(SS_VW_MCAST) || defined(HPOS))
8253 case CM_INET_OPT_ADD_MCAST_MBR:
8254 mCast = (CmInetMCastInf*)value;
8256 /* Copy the addresses to stMreq structure */
8258 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8260 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8262 stMreq.imr_interface.s_addr = CM_INET_HTON_U32(mCast->localAddr);
8264 ret = setsockopt(sockFd->fd, level, IP_ADD_MEMBERSHIP,
8265 (char*)&stMreq, sizeof(stMreq));
8268 case CM_INET_OPT_DRP_MCAST_MBR:
8269 mCast = (CmInetMCastInf*)value;
8271 /* Copy the addresses to stMreq structure */
8273 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8275 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_U32(mCast->mCastAddr);
8277 stMreq.imr_interface.s_addr = CM_INET_HTON_U32(mCast->localAddr);
8279 ret = setsockopt(sockFd->fd, level, IP_DROP_MEMBERSHIP,
8280 (char*)&stMreq, sizeof(stMreq));
8283 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8286 /* cm_inet_c_001.main_37 - Enable CMINET_BSDCOMPAT flag if system doesnt
8287 support CM_INET_OPT_BSD_COMPAT */
8288 #ifndef CMINET_BSDCOMPAT
8289 case CM_INET_OPT_BSD_COMPAT:
8290 optVal = (U32*)value;
8291 if (*optVal == CM_INET_OPT_ENABLE)
8293 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
8294 &enable, sizeof(enable));
8296 else if (*optVal == CM_INET_OPT_DISABLE)
8298 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
8299 &disable, sizeof(disable));
8302 #endif /* CMINET_BSDCOMPAT */
8303 #endif /* SS_LINUX */
8306 /* Added for support of Raw socket modify according to the
8307 * option available on different platform */
8308 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW) \
8310 case CM_INET_OPT_HDR_INCLD:
8311 optVal = (U32*)value;
8312 if (*optVal == CM_INET_OPT_ENABLE)
8317 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
8318 (char*)&enable, sizeof(enable));
8321 else if (*optVal == CM_INET_OPT_DISABLE)
8326 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
8327 (char*)&disable, sizeof(disable));
8332 /* added new options */
8333 #ifdef IPV4_OPTS_SUPPORTED
8335 /* Linux: set Router Alert socket option to Intercept RAW RSVP
8336 packets at the Intermediate node(Router) with Router Alert SET.
8337 This socket option is MUST be set (when this server is opened)
8338 if the RSVP server wants to intercept raw RSVP packets. */
8339 case CM_INET_OPT_IP_ROUTER_ALERT:
8340 optVal = (U32*)value;
8341 if (*optVal == CM_INET_OPT_ENABLE)
8343 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
8344 (char*)&enable, sizeof(enable));
8348 else if (*optVal == CM_INET_OPT_DISABLE)
8350 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
8351 (char*)&disable, sizeof(disable));
8356 #endif /* SS_LINUX */
8358 /* set Router Alert socket option */
8359 case CM_INET_OPT_IP_OPTIONS:
8360 #if (defined (SS_VW) || defined(SS_LINUX))
8363 tempTknStr64=(TknStr64 *)value;
8364 if (tempTknStr64->pres == TRUE)
8366 if (tempTknStr64->len == 0)
8368 /* disable the IP_OPTIONS for Router Alert. */
8370 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
8371 (CONSTANT char *)&disableOpt, sizeof(int));
8373 ret = setsockopt(sockFd->fd, level, IP_OPTIONS, NULL, 0);
8377 /* enable the IP_OPTIONS for Router Alert */
8378 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
8379 (char *)tempTknStr64->val, tempTknStr64->len);
8382 RETVALUE(RFAILED); /* Trying to set IPv4 Hdr option
8383 * without giving option values*/
8384 #endif /* SS_VW || SS_LINUX */
8386 #endif /* IPV4_OPTS_SUPPORTED */
8388 /* added new options */
8389 #if (defined(SS_LINUX) && (!defined(SS_VW) && !defined(WIN32)))
8391 case CM_INET_OPT_IPV4_PKTINFO:
8392 optVal = (U32*)value;
8393 if (*optVal == CM_INET_OPT_ENABLE)
8395 /* set IP_PKTINFO option when IP_ROUTER_ALERT is set in linux */
8396 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
8397 (char*)&enable, sizeof(enable));
8402 else if (*optVal == CM_INET_OPT_DISABLE)
8404 /* disable IP_PKTINFO when IP_ROUTER_ALERT is set in linux */
8405 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
8406 (char*)&disable, sizeof(disable));
8412 #endif /* LOCAL_INTF */
8413 #endif /* SS_LINUX */
8415 #endif /* SUNOS || WIN32 || SS_PS || SS_VW || HPOS */
8417 case CM_INET_OPT_DONTFRAGMENT:
8418 optVal = (U32*)value;
8419 if (*optVal == CM_INET_OPT_ENABLE)
8422 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8423 (char*)&boolEnable, sizeof(boolEnable));
8426 else if (*optVal == CM_INET_OPT_DISABLE)
8429 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8430 (char*)&boolDisable, sizeof(boolDisable));
8435 /* also add these 2 options for VxWorks */
8436 #if (defined(SUNOS)|| defined(WIN32) || defined(HPOS) || defined(SS_VW))
8437 case CM_INET_OPT_TOS:
8438 optVal = (U32*)value;
8439 ret = setsockopt(sockFd->fd, level, IP_TOS,
8440 (char*)optVal, sizeof(*optVal));
8443 case CM_INET_OPT_TTL:
8444 optVal = (U32*)value;
8445 ret = setsockopt(sockFd->fd, level, IP_TTL,
8446 (char*)optVal, sizeof(*optVal));
8448 #endif /* SUNOS || WIN32 || HPOS || SS_VW */
8449 #endif /* CM_INET2 */
8451 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST) \
8453 case CM_INET_OPT_MCAST_LOOP:
8454 optVal = (U32*)value;
8455 if (*optVal == CM_INET_OPT_ENABLE)
8458 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8459 (char *)&lpEnable, sizeof(lpEnable));
8461 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8462 (CONSTANT char *)&lpEnable, sizeof(lpEnable));
8468 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8469 (char *)&lpDisable, sizeof(lpDisable));
8471 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8472 (CONSTANT char *)&lpDisable, sizeof(lpDisable));
8477 case CM_INET_OPT_MCAST_IF:
8478 optVal = (U32*)value;
8479 *optVal = CM_INET_HTON_U32((U32)*optVal);
8480 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_IF,
8481 (char *)optVal, sizeof(struct in_addr));
8484 case CM_INET_OPT_MCAST_TTL:
8485 optVal = (U32*)value;
8486 /* remove CONSTANT in setsockopt for VW */
8488 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8489 (char *)optVal, sizeof(U8));
8491 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8492 (CONSTANT char *)optVal, sizeof(U8));
8495 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8497 #ifdef IPV6_SUPPORTED
8498 case CM_INET_OPT_IPV6_TTL:
8499 optVal = (U32*)value;
8500 ret = setsockopt(sockFd->fd, level, IPV6_UNICAST_HOPS,
8501 (char*)optVal, sizeof(*optVal));
8504 case CM_INET_OPT_ADD_MCAST6_MBR:
8505 stMreq6Ptr = (struct ipv6_mreq *)value;
8506 ret = setsockopt(sockFd->fd, level, IPV6_JOIN_GROUP,
8507 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8510 case CM_INET_OPT_DRP_MCAST6_MBR:
8511 stMreq6Ptr = (struct ipv6_mreq *)value;
8512 ret = setsockopt(sockFd->fd, level, IPV6_LEAVE_GROUP,
8513 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8516 case CM_INET_OPT_MCAST6_LOOP:
8517 optVal = (U32*)value;
8518 if (*optVal == CM_INET_OPT_ENABLE)
8520 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8521 &loopEna, sizeof(loopEna));
8525 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8526 &loopDis, sizeof(loopDis));
8530 case CM_INET_OPT_MCAST6_IF:
8531 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_IF,
8532 (U32 *)value, sizeof(U32));
8535 case CM_INET_OPT_MCAST6_HOPS:
8536 optVal = (U32*)value;
8537 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_HOPS,
8538 (char *)optVal, sizeof(U32));
8541 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
8542 this flag is gaurded under ICMPV6_SUPPORTED. so if user want this
8543 support he has to enable the above flag.*/
8544 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8545 * to support filteration of ICMP messages */
8546 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8547 case CM_INET_OPT_ICMP6_FILTER:
8548 icmp6Filter = (struct icmp6_filter *)value;
8549 ret = setsockopt(sockFd->fd, level, ICMP6_FILTER,
8550 (char *)icmp6Filter, sizeof(struct icmp6_filter));
8552 #endif /* ICMPV6_FILTER_SUPPORTED */
8554 /* added new options */
8555 #ifdef IPV6_OPTS_SUPPORTED
8556 case CM_INET_OPT_RECVIPV6_HOPLIM:
8557 optVal = (U32*)value;
8559 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8560 (char *)optVal, sizeof(U32));
8562 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8563 (char *)optVal, sizeof(U32));
8564 /* enable the reception of IPv6 HopLimit value as ancillary data */
8565 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPLIMIT,
8566 (char*)&enable, sizeof(enable));
8567 #endif /* SS_LINUX */
8571 case CM_INET_OPT_RECVIPV6_HBHOPTS:
8572 optVal = (U32*)value;
8574 ret = setsockopt(sockFd->fd, level, IPV6_HOPOPTS,
8575 (char *)optVal, sizeof(U32));
8577 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPOPTS,
8578 (char *)optVal, sizeof(U32));
8579 #endif /* SS_LINUX */
8582 case CM_INET_OPT_RECVIPV6_DSTOPTS:
8583 optVal = (U32*)value;
8585 ret = setsockopt(sockFd->fd, level, IPV6_DSTOPTS,
8586 (char *)optVal, sizeof(U32));
8588 ret = setsockopt(sockFd->fd, level, IPV6_RECVDSTOPTS,
8589 (char *)optVal, sizeof(U32));
8590 #endif /* SS_LINUX */
8593 case CM_INET_OPT_RECVIPV6_RTHDR:
8594 optVal = (U32*)value;
8596 ret = setsockopt(sockFd->fd, level, IPV6_RTHDR,
8597 (char *)optVal, sizeof(U32));
8599 ret = setsockopt(sockFd->fd, level, IPV6_RECVRTHDR,
8600 (char *)optVal, sizeof(U32));
8601 #endif /* SS_LINUX */
8604 /* works ONLY for IPPROTO_RAW type socket. so if it this socket
8605 * option is tried to set for IPPROTO_RSVP, then it is supposed
8606 * to fail with EINVAL according to net/ipv6/ipv6_sockglue.c
8608 * if HI_SRVC_RAW_RAW is not used during ServOpenReq as the server
8609 * type, then it will fail here due to above reason */
8611 case CM_INET_OPT_IP_ROUTER_ALERT6:
8612 optVal = (U32*)value;
8613 if(*optVal == CM_INET_OPT_ENABLE)
8614 ret = setsockopt(sockFd->fd, IPPROTO_IPV6, IPV6_ROUTER_ALERT,
8615 (char *)&enable, sizeof(enable));
8617 ret = setsockopt(sockFd->fd, level, IPV6_ROUTER_ALERT,
8618 (char *)&disable, sizeof(disable));
8621 #endif /* SS_LINUX */
8622 #endif /* IPV6_OPTS_SUPPORTED */
8625 case CM_INET_OPT_IPV6_PKTINFO:
8626 optVal = (U32*)value;
8628 ret = setsockopt(sockFd->fd, level, IPV6_PKTINFO,
8629 (char *)optVal, sizeof(U32));
8631 ret = setsockopt(sockFd->fd, level, IPV6_RECVPKTINFO,
8632 (char *)&enable, sizeof(enable));
8633 #endif /* SS_LINUX */
8635 #endif /* LOCAL_INTF */
8637 #endif /* IPV6_SUPPORTED */
8639 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8641 case CM_INET_OPT_LINGER:
8642 pSockLinger = (CmInetSockLinger *)value;
8644 cmMemset((U8*)&lngr, 0, sizeof(struct linger));
8646 if (pSockLinger->enable == TRUE)
8651 lngr.l_linger = pSockLinger->lingerTime;
8652 ret = setsockopt(sockFd->fd, level, SO_LINGER, &lngr, sizeof(lngr));
8655 case CM_INET_OPT_SCTP_EVENTS:
8656 pSctpEvent = (CmInetSctpSockEvent *)value;
8658 cmMemset((U8*)&event, 0, sizeof(struct sctp_event_subscribe));
8660 if (pSctpEvent->dataIoEvent == TRUE)
8661 event.sctp_data_io_event = 1;
8663 if (pSctpEvent->associationEvent == TRUE)
8664 event.sctp_association_event = 1;
8666 if (pSctpEvent->addressEvent == TRUE)
8667 event.sctp_address_event = 1;
8669 if (pSctpEvent->sendFailureEvent == TRUE)
8670 event.sctp_send_failure_event = 1;
8672 if (pSctpEvent->peerErrorEvent == TRUE)
8673 event.sctp_peer_error_event = 1;
8675 if (pSctpEvent->shutdownEvent == TRUE)
8676 event.sctp_shutdown_event = 1;
8678 if (pSctpEvent->partialDeliveryEvent == TRUE)
8679 event.sctp_partial_delivery_event = 1;
8681 if (pSctpEvent->adaptationLayerEvent == TRUE)
8683 event.sctp_adaption_layer_event = 1;
8685 event.sctp_adaptation_layer_event = 1;
8688 ret = setsockopt(sockFd->fd, level, SCTP_EVENTS, &event, sizeof(event));
8691 case CM_INET_OPT_SCTP_PRIM_ADDR:
8692 pSctpPrimAddr = (CmInetSctpPrimAddr *)value;
8694 cmMemset((U8*)&setPrim, 0, sizeof(struct sctp_setprim));
8696 #ifdef IPV6_SUPPORTED
8697 if (pSctpPrimAddr->addr.type == CM_INET_IPV6ADDR_TYPE)
8699 if (sockFd->protType == AF_INET)
8703 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8704 /* cm_inet_c_001.main_62:Warning fix */
8705 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8706 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8707 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8709 /* cm_inet_c_001.main_62:Warning fix */
8710 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8711 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8712 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8713 #endif /*ALIGN_64BIT*/
8714 #endif /* CMINETDBG */
8718 pAddr6 = (struct sockaddr_in6*)&(setPrim.ssp_addr);
8719 pAddr6->sin6_family = AF_INET6;
8720 pAddr6->sin6_port = CM_INET_HTON_U16(pSctpPrimAddr->port);
8721 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPrimAddr->addr.u.ipv6NetAddr);
8725 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8726 pAddr->sin_family = AF_INET;
8727 pAddr->sin_port = CM_INET_HTON_U16(pSctpPrimAddr->port);
8728 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8731 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8732 pAddr->sin_family = AF_INET;
8733 pAddr->sin_port = CM_INET_HTON_U16(pSctpPrimAddr->port);
8734 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8735 #endif /* IPV6_SUPPORTED */
8737 setPrim.ssp_assoc_id = pSctpPrimAddr->assocId;
8739 ret = setsockopt(sockFd->fd, level, SCTP_PRIMARY_ADDR, &setPrim, sizeof(setPrim));
8742 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
8743 pSctpPAddrParams = (CmInetSctpPeerAddrParams *)value;
8745 cmMemset((U8*)&addrParams, 0, sizeof(struct sctp_paddrparams));
8748 if (pSctpPAddrParams->s.addrPres == TRUE)
8750 #ifdef IPV6_SUPPORTED
8751 if (pSctpPAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
8753 if (sockFd->protType == AF_INET)
8757 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8758 /* cm_inet_c_001.main_62:Warning fix */
8759 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8760 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8761 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8763 /* cm_inet_c_001.main_62:Warning fix */
8764 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8765 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8766 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8767 #endif /*ALIGN_64BIT*/
8768 #endif /* CMINETDBG */
8773 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
8774 pAddr6->sin6_family = AF_INET6;
8775 pAddr6->sin6_port = CM_INET_HTON_U16(pSctpPAddrParams->s.port);
8776 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPAddrParams->s.addr.u.ipv6NetAddr);
8780 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8781 pAddr->sin_family = AF_INET;
8782 pAddr->sin_port = CM_INET_HTON_U16(pSctpPAddrParams->s.port);
8783 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8786 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8787 pAddr->sin_family = AF_INET;
8788 pAddr->sin_port = CM_INET_HTON_U16(pSctpPAddrParams->s.port);
8789 pAddr->sin_addr.s_addr = CM_INET_HTON_U32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8790 #endif /* IPV6_SUPPORTED */
8794 #ifdef IPV6_SUPPORTED
8795 if (sockFd->protType == AF_INET6)
8796 addrParams.spp_address.ss_family = AF_INET6;
8798 addrParams.spp_address.ss_family = AF_INET;
8800 addrParams.spp_address.ss_family = AF_INET;
8804 /* Not validating the address, whether addr is a valid address or not */
8806 addrParams.spp_assoc_id = pSctpPAddrParams->assocId;
8807 /*cm_inet_c_001.main_58 : fix for klockwork issue */
8808 addrParams.spp_pathmaxrxt = (U16)pSctpPAddrParams->pathMaxRxt;
8810 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8811 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8813 addrParams.spp_hbinterval = 0;
8816 addrParams.spp_flags = 0;
8818 if (pSctpPAddrParams->pmtudFlag == CM_INET_OPT_ENABLE)
8820 addrParams.spp_flags |= SPP_PMTUD_ENABLE;
8821 addrParams.spp_pathmtu = pSctpPAddrParams->pathMtu;
8823 else if(pSctpPAddrParams->pmtudFlag == CM_INET_OPT_DISABLE)
8824 addrParams.spp_flags |= SPP_PMTUD_DISABLE;
8826 if (pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_ENABLE)
8828 addrParams.spp_flags |= SPP_SACKDELAY_ENABLE;
8829 addrParams.spp_sackdelay = pSctpPAddrParams->sackDelay;
8831 else if(pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_DISABLE)
8832 addrParams.spp_flags |= SPP_SACKDELAY_DISABLE;
8834 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8836 addrParams.spp_flags |= SPP_HB_ENABLE;
8837 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8839 else if(pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_DISABLE)
8840 addrParams.spp_flags |= SPP_HB_DISABLE;
8842 ret = setsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, sizeof(addrParams));
8845 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
8846 pSctpAssocParams = (CmInetSctpAssocParams *)value;
8848 cmMemset((U8*)&assocParams, 0, sizeof(struct sctp_assocparams));
8850 assocParams.sasoc_cookie_life = pSctpAssocParams->cookieLife;
8851 assocParams.sasoc_asocmaxrxt = pSctpAssocParams->assocMaxReTx;
8852 assocParams.sasoc_assoc_id = pSctpAssocParams->assocId;
8853 assocParams.sasoc_number_peer_destinations = pSctpAssocParams->numberOfPeerDest;
8854 assocParams.sasoc_peer_rwnd = pSctpAssocParams->peerRwnd;
8855 assocParams.sasoc_local_rwnd = pSctpAssocParams->localRwnd;
8857 ret = setsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams));
8860 case CM_INET_OPT_SCTP_RTO_INFO:
8861 pSctpRtoInfo = (CmInetSctpRtoInfo *)value;
8863 cmMemset((U8*)&rtoinfo, 0, sizeof(struct sctp_rtoinfo));
8865 rtoinfo.srto_assoc_id = pSctpRtoInfo->assocId;
8866 rtoinfo.srto_initial = pSctpRtoInfo->rtoInitial;
8867 rtoinfo.srto_max = pSctpRtoInfo->rtoMax;
8868 rtoinfo.srto_min = pSctpRtoInfo->rtoMin;
8870 ret = setsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
8873 case CM_INET_OPT_SCTP_INIT_MSG:
8874 pSctpInitMsg = (CmInetSctpInitMsg *)value;
8876 cmMemset((U8*)&initmsg, 0, sizeof(struct sctp_initmsg));
8878 initmsg.sinit_max_attempts = pSctpInitMsg->maxInitReTx;
8879 initmsg.sinit_max_init_timeo = pSctpInitMsg->maxInitTimeout;
8880 initmsg.sinit_num_ostreams = pSctpInitMsg->numOstreams;
8881 initmsg.sinit_max_instreams = pSctpInitMsg->maxInstreams;
8883 ret = setsockopt(sockFd->fd, level, SCTP_INITMSG, &initmsg, sizeof(initmsg));
8886 #endif /*CM_LKSCTP*/
8888 /* cm_inet_c_001.main_58 : Added to support filteration of ICMP
8889 * messages and protected under CM_ICMP_FILTER_SUPPORT flag. Its a
8890 * partial implementaion for icmp filter done for TUCL */
8892 #ifdef CM_ICMP_FILTER_SUPPORT
8893 case CM_INET_OPT_ICMP_FILTER:
8894 optVal = (U32*)value;
8895 ret = setsockopt(sockFd->fd, level, ICMP_FILTER,
8896 optVal, sizeof(icmpFilter));
8902 /* wrong socket option type */
8907 if (ret == INET_ERR)
8911 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8912 /* cm_inet_c_001.main_62:Warning fix */
8913 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%ld)\n",
8914 INET_ERR_CODE, sockFd->fd);
8915 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8917 /* cm_inet_c_001.main_62:Warning fix */
8918 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%d)\n",
8919 INET_ERR_CODE, sockFd->fd);
8920 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8921 #endif /*ALIGN_64BIT*/
8922 #endif /* CMINETDBG */
8926 } /* end of cmInetSetOpt */
8932 * Fun: cmInetGetNumRead
8934 * Desc: Gives the number of pending octets in the socket receive buffer.
8936 * Ret: ROK - successful
8946 PUBLIC S16 cmInetGetNumRead
8948 CmInetFd *sockFd, /* socket file descriptor */
8949 U32 *dataLen /* number of pending octets */
8950 /* removed 3rd argument memInfo */
8953 PUBLIC S16 cmInetGetNumRead(sockFd, dataLen)
8954 CmInetFd *sockFd; /* socket file descriptor */
8955 U32 *dataLen; /* number of pending octets */
8956 /* removed 3rd argument memInfo */
8959 S32 ret; /* temporary return value */
8961 /* removed local variables added for recvfrom call */
8963 TRC2(cmInetGetNumRead);
8965 #if (ERRCLASS & ERRCLS_INT_PAR)
8966 /* error check on parameters */
8967 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
8974 /* use ioctl call for all types of socket to get length of
8975 pending data in the socket recv buffer */
8977 /* cm_inet_c_001.main_59: Fix for compilation warning */
8978 ret = ioctlsocket(sockFd->fd, FIONREAD, (U32 *)dataLen);
8981 ret = ioctl(sockFd->fd, FIOREAD, (char*)dataLen);
8984 ret = ioctl(sockFd->fd, FIONREAD, (S32)dataLen);
8986 ret = ioctl(sockFd->fd, FIONREAD, dataLen);
8991 /* For UDP socket assign the length of pending data in the
8992 socket recv buffer to largest datagram size.
8993 Removed recvfrom call & necessary processing for it. */
8995 if (ret == INET_ERR)
8997 /* removed error check CONABORTED added for recvfrom call.
8998 Also return value changed from RCLOSED to ROK */
8999 /* Check for reset connection */
9000 /* cm_inet_c_001.main_45: Close the TCP connection only when err is one of these*/
9001 if ((INET_ERR_CODE == ERR_CONNREFUSED) ||
9002 (INET_ERR_CODE == ERR_CONNABORTED) ||
9003 (INET_ERR_CODE == ERR_TIMEDOUT))
9007 /* cm_inet_c_001.main_50
9008 * Return RCLOSED instead of ROK to initiate connection closure.
9009 * ROK will be returned only if the ioctl call above returns ROK.
9010 * The routines calling this function have been modified to not
9011 * return RCLOSED when this function returns ROK with pending data
9012 * length value of 0. This modification is needed because:
9013 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
9014 * returns successfully with pend length as 0 on a TCP socket that
9015 * select says is ready to read. This should not be considered as
9016 * connection closed.
9021 /* removed error check ERR_WOULDBLOCK */
9022 /* cm_inet_c_001.main_45: Dont close the connection in case of ERR_CONNRESET */
9023 if ((INET_ERR_CODE == ERR_AGAIN) ||
9024 (INET_ERR_CODE == ERR_CONNRESET))
9031 /* cm_inet_c_001.main_45: Change 2048 to CM_INET_MAX_UDPRAW_MSGSIZE */
9032 *dataLen = CM_INET_MAX_UDPRAW_MSGSIZE;
9034 #endif /* SS_LINUX */
9036 /* removed error debug printing added for recvfrom call. */
9040 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9041 /* cm_inet_c_001.main_62:Warning fix */
9042 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
9043 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9044 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
9046 /* cm_inet_c_001.main_62:Warning fix */
9047 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
9048 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9049 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
9050 #endif /*ALIGN_64BIT*/
9051 #endif /* CMINETDBG */
9056 } /* end of cmInetGetNumRead */
9062 * Fun: cmInetGetHostByName
9064 * Desc: Resolves a host name into the appropriate 4 byte Internet
9067 * Ret: ROK - successful
9077 PUBLIC S16 cmInetGetHostByName
9079 S8 *hostName, /* host name */
9080 CmInetIpAddrTbl *addrTbl /* Address Table of IPV4 Addresses */
9083 PUBLIC S16 cmInetGetHostByName (hostName, addrTbl)
9084 S8 *hostName; /* host name */
9085 CmInetIpAddrTbl *addrTbl; /* Address Table of IPV4 Addresses */
9089 U8 numAddrs; /* Number of Addresses */
9092 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
9093 struct hostent *hostid; /* pointer to host information */
9096 struct hostent hostid; /* host information */
9097 S8 infoBuf[CM_INET_MAX_INFO]; /* info buffer */
9098 S32 err; /* error code */
9100 #endif /* WIN32 || SS_LINUX || HPOS */
9102 TRC2(cmInetGetHostByName)
9104 #if (ERRCLASS & ERRCLS_INT_PAR)
9105 /* error check on parameters */
9106 if ((hostName == NULLP) || (addrTbl == NULLP))
9110 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9119 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
9120 hostid = gethostbyname(hostName);
9124 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9125 /* cm_inet_c_001.main_62:Warning fix */
9126 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9127 " hostName(%p)\n", INET_ERR_CODE, hostName);
9128 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET044, 0, prntBuf);
9129 #endif /* CMINETDBG */
9132 if (hostid->h_addrtype != AF_INET)
9135 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9136 /* cm_inet_c_001.main_62:Warning fix */
9137 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetHostByName() Failed : error(%d),"
9138 " hostName(%p), hostid->h_addrtype(%d)\n",
9139 INET_ERR_CODE, hostName, hostid->h_addrtype);
9140 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET045, 0, prntBuf);
9141 #endif /* CMINETDBG */
9146 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9147 (hostid->h_addr_list[numAddrs] != NULLP))
9149 addrTbl->netAddr[addrTbl->count++] =
9150 CM_INET_NTOH_U32 (*((U32 *) hostid->h_addr_list[numAddrs]));
9160 vwIpAddr = hostGetByName(hostName);
9161 if (vwIpAddr == INET_ERR)
9164 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9165 /* cm_inet_c_001.main_62:Warning fix */
9166 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9167 " hostName(%p)\n", INET_ERR_CODE, hostName);
9168 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET046, 0, prntBuf);
9169 #endif /* CMINETDBG */
9172 CM_COPY_VWIPADDR(vwIpAddr, &(addrTbl->netAddr[addrTbl->count]));
9177 err = 0; /* err is not reset by gethostnyname_r()! */
9179 gethostbyname_r(hostName, &hostid, infoBuf, CM_INET_MAX_INFO, (int*)&err);
9180 if ((hostid.h_addrtype != AF_INET) || (err < 0))
9183 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9184 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d), hostName(%p),"
9185 " hostid.h_addrtype(%d)\n",
9186 INET_ERR_CODE, hostName, hostid.h_addrtype);
9187 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET047, 0, prntBuf);
9188 #endif /* CMINETDBG */
9193 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9194 (hostid.h_addr_list[numAddrs] != NULLP))
9196 addrTbl->netAddr[addrTbl->count++] =
9197 CM_INET_NTOH_U32 (*((U32 *) hostid.h_addr_list[numAddrs]));
9203 #endif /* WIN32 || SS_LINUX || HPOS */
9207 } /* end of cmInetGetHostByName */
9210 /* The getipnodebyname is not supported on all the Solaris Operating system
9211 * versions. This has to be supported on operating systems that support IPV6
9212 * as per the RFC on the IPV6 socket interface. Hence this function is moved
9213 * under the IPV6_SUPPORTED flag */
9215 /* This function now can be called for both IPv4 and IPv6. However, we will
9216 * call cmInetGetHostByName inside for IPv4. Move all flag dependencies
9217 * inside this function. */
9220 * Fun: cmInetGetIpNodeByName
9222 * Desc: Resolves a host name into the appropriate 4 byte Internet
9223 * address or into the appropriate 16 byte IPV6 address.
9224 * This function is expected to be thread safe and should be used
9225 * instead of the cmInetGetHostByName function.
9227 * Ret: ROK - successful
9236 PUBLIC S16 cmInetGetIpNodeByName
9238 S8 *hostName, /* host name */
9239 CmInetIpAddrArr *addrArr /* Array of addressed filled in */
9242 PUBLIC S16 cmInetGetIpNodeByName(hostName, addrArr)
9243 S8 *hostName; /* host name */
9244 CmInetIpAddrArr *addrArr; /* Array of addressed filled in */
9247 /* for return value from cmInetGetHostByName */
9248 #ifndef IPV6_SUPPORTED
9253 U8 numAddrs=0; /* Number of addresses */
9254 int err=0; /* error code */
9255 struct hostent *hostid; /* host information */
9256 #endif /* SS_LINUX */
9258 #endif /* IPV6_SUPPORTED */
9260 TRC2(cmInetGetIpNodeByName)
9263 #if (ERRCLASS & ERRCLS_INT_PAR)
9264 /* error check on parameters */
9265 if ((hostName == NULLP) || (addrArr == NULLP))
9269 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9271 #ifdef IPV6_SUPPORTED
9275 #ifdef IPV6_SUPPORTED
9276 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
9277 hostid = getipnodebyname(hostName, AF_INET6, 0, &err);
9279 #endif /* IPV6_SUPPORTED */
9280 hostid = getipnodebyname(hostName, AF_INET, 0, &err);
9284 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9285 /* cm_inet_c_001.main_62:Warning fix */
9286 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetIpNodeByName() Failed : error(%d),"
9287 " hostName(%p), addrArr->type(%d)n",
9288 err, hostName, addrArr->type);
9289 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET048, 0, prntBuf);
9290 #endif /* CMINETDBG */
9294 #ifdef IPV6_SUPPORTED
9295 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
9297 if (hostid->h_addrtype == AF_INET6)
9299 while ((numAddrs < CM_INET_IPV6_NUM_ADDR) &&
9300 (hostid->h_addr_list[numAddrs] != NULLP))
9302 /* Use the cminet fill macro here */
9303 CM_INET_COPY_IPV6ADDR(&addrArr->u.ipv6AddrArr.netAddr[numAddrs],
9304 hostid->h_addr_list[numAddrs]);
9305 addrArr->u.ipv6AddrArr.count++;
9312 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9313 /* cm_inet_c_001.main_62:Warning fix */
9314 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
9315 " hostName(%p), addrArr->type(%d),hostid->h_addrtype(%d) \n",
9316 err, hostName, addrArr->type, hostid->h_addrtype);
9317 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET049, 0, prntBuf);
9318 #endif /* CMINETDBG */
9323 #endif /* IPV6_SUPPORTED */
9325 if (hostid->h_addrtype == AF_INET)
9327 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
9328 (hostid->h_addr_list[numAddrs] != NULLP))
9330 addrArr->u.ipv4AddrArr.count ++;
9331 addrArr->u.ipv4AddrArr.netAddr[numAddrs] =
9332 CM_INET_NTOH_U32 (*((U32 *) hostid->h_addr_list[numAddrs]));
9339 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9340 /* cm_inet_c_001.main_62:Warning fix */
9341 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
9342 " hostName(%p), hostid->h_addrtype(%d), addrArr->type(%d)\n",
9343 err, hostName, hostid->h_addrtype, addrArr->type);
9344 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET050, 0, prntBuf);
9345 #endif /* CMINETDBG */
9349 #endif /* SS_LINUX */
9354 ret = cmInetGetHostByName(hostName, &addrArr->u.ipv4AddrArr);
9356 #endif /* IPV6_SUPPORTED */
9358 } /* end of cmInetGetIpNodeByName */
9365 * Desc: Converts an ASCII string containig an internet address
9366 * ("xxx.xxx.xxx.xxx") into a CmInetIpAddr (U32) format.
9367 * This function is a wrapper for the inet_addr() call.
9369 * Ret: ROK - successful
9379 PUBLIC S16 cmInetAddr(
9380 S8 *asciiAddr, /* ascii address representation */
9381 CmInetIpAddr *address /* 4 byte interent address */
9384 PUBLIC S16 cmInetAddr(asciiAddr, address)
9385 S8 *asciiAddr; /* ascii address representation */
9386 CmInetIpAddr *address; /* 4 byte interent address */
9391 #if (ERRCLASS & ERRCLS_INT_PAR)
9392 /* error check on parameters */
9393 if (asciiAddr == NULLP)
9397 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9399 *address = inet_addr(asciiAddr);
9400 if (*address == (U32)ERR_INADDRNONE)
9402 /* asciiAddr does not contain a valid internet address */
9414 * Desc: Converts an CmInetIPAddr based IP address into a string
9415 * of the format "xxx.xxx.xxx.xxx".
9416 * This function is a wrapper for the inet_ntoa() call.
9418 * Ret: ROK - successful
9421 * Notes: This function delivers a pointer to a static buffer
9422 * within the system. Therefore the string has to be copied
9423 * by the caller before another call is made!
9430 PUBLIC S16 cmInetNtoa(
9431 CmInetIpAddr address, /* 4 byte interent address */
9432 S8 **asciiAddr /* ascii address representation */
9435 PUBLIC S16 cmInetNtoa(address, asciiAddr)
9436 CmInetIpAddr address; /* 4 byte interent address */
9437 S8 **asciiAddr; /* ascii address representation */
9440 struct in_addr inetAddr; /* internet address structure */
9444 #if (ERRCLASS & ERRCLS_INT_PAR)
9445 /* error check on parameters */
9446 if (asciiAddr == NULLP)
9450 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9452 inetAddr.s_addr = address;
9454 *asciiAddr = inet_ntoa(inetAddr);
9455 if (*asciiAddr == NULL)
9466 * Desc: Converts an network address into a string.
9467 * This function is a wrapper for the inet_ntop() call.
9469 * Ret: ROK - successful
9472 * Notes: This function copies the resulting string to the buffer pointed to
9473 * by asciiaddr,which must be a non NULL pointer.The caller specifies
9474 * the number of bytes available in this buffer in the argument len.
9481 PUBLIC S16 cmInetNtop(
9482 U8 type, /* ip address type */
9483 Void *address, /* 4/16 byte interent address */
9484 S8 *asciiAddr, /* ascii adress representation */
9488 PUBLIC S16 cmInetNtop(type,address, asciiAddr,len)
9489 U8 type; /* ip address type */
9490 Void *address; /* 4/16 byte interent address */
9491 S8 *asciiAddr; /* ascii adress representation */
9499 #if (ERRCLASS & ERRCLS_INT_PAR)
9500 /* error check on parameters */
9501 if (asciiAddr == NULLP || address == NULLP || len == 0 )
9506 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9509 case CM_INET_IPV4ADDR_TYPE :
9512 case CM_INET_IPV6ADDR_TYPE :
9516 if(inet_ntop(domain,address,asciiAddr,len) == NULL)
9525 /* The inet_pton is not supported on all the Solaris Operating system
9526 * versions. This has to be supported on operating systems that support
9527 * IPV6 as per the RFC on the IPV6 socket interface. Hence this function
9528 *is moved under the IPV6_SUPPORTED flag */
9529 #ifdef IPV6_SUPPORTED
9536 * Desc: Converts a IP address string to address.
9538 * Ret: ROK - successful
9548 PUBLIC S16 cmInetPton(
9549 CmInetIpAddr *address, /* 4 byte interent address */
9550 S8 *asciiAddr /* ascii address representation */
9553 PUBLIC S16 cmInetPton(address, asciiAddr)
9554 CmInetIpAddr *address; /* 4 byte interent address */
9555 S8 *asciiAddr; /* ascii address representation */
9562 #if (ERRCLASS & ERRCLS_INT_PAR)
9563 /* error check on parameters */
9564 if ((asciiAddr == NULLP) || (address == NULLP))
9568 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9570 ret = inet_pton(AF_INET, asciiAddr, (void *)address);
9577 } /* end of cmInetPton */
9579 #endif /* IPV6_SUPPORTED */
9581 #ifdef IPV6_SUPPORTED
9587 * Desc: Converts a IP address string to IPV6 address suitable
9588 * to be used in bind.
9590 * Ret: ROK - successful
9599 PUBLIC S16 cmInetPton6(
9600 CmInetIpAddr6 *address6, /* 16 byte interent address */
9601 S8 *asciiAddr /* ascii address representation */
9604 PUBLIC S16 cmInetPton6(address6, asciiAddr)
9605 CmInetIpAddr6 *address6; /* 16 byte interent address */
9606 S8 *asciiAddr; /* ascii address representation */
9612 struct sockaddr_storage ss;
9613 U32 sslen = sizeof(ss);
9617 #if (ERRCLASS & ERRCLS_INT_PAR)
9618 /* error check on parameters */
9619 if ((asciiAddr == NULLP) || (address6 == NULLP))
9623 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9626 ret = inet_pton(AF_INET6, asciiAddr, (void *)address6);
9632 /* cm_inet_c_001.main_44 : In windows inet_pton is not implemented. so we are using the below function
9633 * to convert the ipv6 address string to appropriate form */
9634 WSAStringToAddressA((LPTSTR)asciiAddr, AF_INET6, NULL, (struct sockaddr*)&ss, &sslen);
9635 cmMemcpy((U8*)address6, (U8*)&(((struct sockaddr_in6 *)&ss)->sin6_addr), sizeof(CmInetIpAddr6));
9639 } /* end of cmInetPton6 */
9640 #endif /* IPV6_SUPPORTED */
9646 * Fun: cmInetGetMemSize
9648 * Desc: This function gives the max number of static buffer space that
9649 * the internet library will allocate.
9651 * Ret: ROK - successful
9660 PUBLIC S16 cmInetGetMemSize(
9661 S32 *size /* max used memory size */
9664 PUBLIC S16 cmInetGetMemSize(size)
9665 S32 *size; /* max used memory size */
9669 /* max static memory size depends on max flat buffer size */
9670 *size = CM_INET_MAX_MSG_LEN;
9672 /* max static memory size depends on max flat buffer or iovect size */
9673 *size = CM_INET_MAX_MSG_LEN;
9685 * Desc: This function initializes the socket library.
9687 * Ret: ROK - successful
9689 * Notes: Required only for Winsock and not for 4.3BSD
9696 PUBLIC S16 cmInetInit(
9700 PUBLIC S16 cmInetInit(Void)
9708 version = MAKEWORD(CM_INET_HIGH_VER, CM_INET_LOW_VER);
9709 err = WSAStartup(version, &data);
9724 * Desc: This function de initializes the socket library. The
9725 * WINSOCK implementation de registers the application and
9726 * releases any resources allocated on behalf of the
9729 * Ret: ROK - successful
9731 * Notes: Required only for Winsock and not for 4.3BSD
9738 PUBLIC S16 cmInetDeInit(
9742 PUBLIC S16 cmInetDeInit(Void)
9756 }/* end of cmInetDeInit() */
9761 * Fun: cmInetGetSockName
9763 * Desc: This function is used to retireve the current name
9764 * for the specified socket descriptor. It returns the
9765 * local association(address and port) for the socket.
9767 * Ret: ROK - successful
9770 * Notes: Please note if the socket was bound to CM_INET_INADDR_ANY
9771 * cmInetGetSockName() will not necessarily return the local
9772 * address information unless the socket has been connected.
9779 PUBLIC S16 cmInetGetSockName
9781 CmInetFd *sockFd, /* socket file descriptor */
9785 PUBLIC S16 cmInetGetSockName(sockFd, locAddr)
9786 CmInetFd *sockFd; /* socket file descriptor */
9787 CmInetAddr *locAddr;
9790 struct sockaddr_in *sockAddr;
9791 #ifdef IPV6_SUPPORTED
9792 struct sockaddr_in6 *sockAddr6;
9793 struct sockaddr_in6 lclSockAddr;
9795 CmInetSockAddr lclSockAddr;
9796 #endif /* IPV6_SUPPORTED */
9801 #endif /* SS_LINUX */
9803 /*cm_inet_c_001.main_58 : fix for klockwork issue */
9806 TRC2(cmInetGetSockName);
9808 #if (ERRCLASS & ERRCLS_INT_PAR)
9809 /* error check on parameters */
9810 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
9815 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9817 cmMemset((U8*)&lclSockAddr, 0, sizeof(lclSockAddr));
9818 size = sizeof(lclSockAddr);
9821 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr,
9822 (socklen_t *)&size);
9824 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, (int*)&size);
9825 #endif /* SS_LINUX */
9829 switch(errCode = INET_ERR_CODE)
9832 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9833 #ifdef IPV6_SUPPORTED
9834 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9835 locAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(sockAddr->sin_port);
9837 locAddr->port = CM_INET_NTOH_U16(sockAddr->sin_port);
9838 #endif /* IPV6_SUPPORTED */
9844 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9845 /* cm_inet_c_001.main_62:Warning fix */
9846 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9847 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9848 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9850 /* cm_inet_c_001.main_62:Warning fix */
9851 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9852 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9853 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9854 #endif /* ALIGN_64BIT */
9855 #endif /* CMINETDBG */
9857 }/* end of switch */
9861 /* Fill the returned address in to locAddr */
9862 #ifdef IPV6_SUPPORTED
9863 cmMemset((U8*)locAddr, 0, sizeof(CmInetAddr));
9864 if (size == sizeof(struct sockaddr_in6))
9866 sockAddr6 = (struct sockaddr_in6 *)&lclSockAddr;
9867 locAddr->type = CM_INET_IPV6ADDR_TYPE;
9868 locAddr->u.ipv6Addr.port = CM_INET_NTOH_U16(sockAddr6->sin6_port);
9869 CM_INET_COPY_IPV6ADDR(&locAddr->u.ipv6Addr.ipv6NetAddr,
9870 &sockAddr6->sin6_addr);
9874 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9875 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9876 locAddr->u.ipv4Addr.port = CM_INET_NTOH_U16(sockAddr->sin_port);
9877 locAddr->u.ipv4Addr.address =
9878 CM_INET_NTOH_U32(sockAddr->sin_addr.s_addr);
9881 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9882 locAddr->port = CM_INET_NTOH_U16(sockAddr->sin_port);
9883 locAddr->address = CM_INET_NTOH_U32(sockAddr->sin_addr.s_addr);
9884 #endif /* IPV6_SUPPORTED */
9886 }/* end of cmInetGetSockName() */
9888 /* New functions to peek into the file descriptor
9890 #if (defined(SUNOS) || defined(WIN32) || defined(SS_LINUX) || defined(SS_VW) \
9895 * Fun: cmInetFdSetInfoInit
9897 * Desc: This function is used to initialise operating system specific
9898 * data that will be used to peek into the file descriptor lists
9899 * to get the sockets that are set
9901 * Ret: ROK - successful
9911 PUBLIC S16 cmInetFdSetInfoInit
9913 CmInetFdSetInfo *fdSetInfo
9916 PUBLIC S16 cmInetFdSetInfoInit(fdSetInfo)
9917 CmInetFdSetInfo *fdSetInfo;
9920 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW) || defined(HPOS))
9925 #endif /* SUNOS || SS_LINUX || SS_VW */
9927 #if (ERRCLASS & ERRCLS_INT_PAR)
9928 if (fdSetInfo == NULLP)
9930 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9932 if (fdSetInfo->initDone == TRUE)
9936 fdSetInfo->numFds = 0;
9939 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW)|| defined(HPOS))
9940 /* Check if we are on a big endian machine */
9943 fdSetInfo->bigEndian = FALSE;
9945 fdSetInfo->bigEndian = TRUE;
9947 fdSetInfo->arIdx = 0;
9948 fdSetInfo->ar[0] = 0xff;
9950 /* Initialise the array */
9951 /* The array contains bit positions for the first bit
9952 * for each integer from 1 to 2^8.
9954 for (arIdx = 1; arIdx < 256; arIdx++)
9956 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9957 curByte = (U8)arIdx;
9964 fdSetInfo->ar[arIdx] = bitPos;
9968 curByte = curByte >> 1;
9971 /* Calculate the number of array elements in this fd_set */
9972 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9973 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->__fds_bits[0]);
9975 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->fds_bits[0]);
9976 #endif /* SS_LINUX */
9977 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9979 fdSetInfo->initDone = TRUE;
9981 }/* end of cmInetFdSetInfoInit() */
9988 * Desc: This function is used to get the file descriptor from the
9989 * file descriptor set.
9991 * Ret: ROK - successful
9992 * ROKDNA - socket not found
9994 * RNA - failed, initialisation not done
9996 * Notes: If the application modifies fdSet between calls to this
9997 * function then the results are undefined. This function should
9998 * be called in a loop till either it returns - not ROK, or if
9999 * all sockets in the file descriptor set are processed.
10006 PUBLIC S16 cmInetGetFd
10008 CmInetFdSetInfo *fdSetInfo,
10009 CmInetFdSet *fdSet,
10010 CmInetFdType *sockFd
10013 PUBLIC S16 cmInetGetFd(fdSetInfo, fdSet, sockFd)
10014 CmInetFdSetInfo *fdSetInfo;
10015 CmInetFdSet *fdSet;
10016 CmInetFdType *sockFd;
10019 /*cm_inet_c_001.main_58 : Fix for klockwork issue */
10020 #if (!defined (WIN32))
10021 U32 sizOfFdSetArElem;
10027 #endif /* !defined (WIN32) */
10029 #if (ERRCLASS & ERRCLS_INT_PAR)
10030 if ((fdSetInfo == NULLP) || (fdSet == NULLP) || (sockFd == NULLP))
10033 if (fdSetInfo->initDone != TRUE)
10035 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10038 #if (ERRCLASS & ERRCLS_DEBUG)
10039 if (fdSetInfo->numFds > FD_SETSIZE)
10041 #endif /* ERRCLASS & ERRCLS_DEBUG */
10042 /* cm_inet_c_001.main_32 : Corrected check for number of fd set in
10043 a fdset for WIN32*/
10044 if (fdSetInfo->numFds >= fdSet->fd_count)
10047 *sockFd = fdSet->fd_array[fdSetInfo->numFds];
10048 fdSetInfo->numFds += 1;
10052 /* cm_inet_c_001.main_59: Protected under if not defined WIN32 */
10053 #if (!defined (WIN32))
10054 /* Start with arIdx and continue upto number of array elements. */
10055 curIdx = fdSetInfo->arIdx;
10058 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
10059 sizOfFdSetArElem = sizeof(fdSet->__fds_bits[0]);
10061 sizOfFdSetArElem = sizeof(fdSet->fds_bits[0]);
10062 #endif /* SS_LINUX */
10064 for (curIdx = fdSetInfo->arIdx; curIdx < fdSetInfo->numArElems;
10067 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
10068 if (fdSet->__fds_bits[curIdx])
10070 if (fdSet->fds_bits[curIdx])
10071 #endif /* SS_LINUX */
10073 /* Walk through the bytes in this element */
10074 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
10075 tempByte = (U8 *)&fdSet->__fds_bits[curIdx];
10077 tempByte = (U8 *)&fdSet->fds_bits[curIdx];
10078 #endif /* SS_LINUX */
10080 /* Set the starting byte offset */
10081 if (fdSetInfo->bigEndian)
10082 tempByte += sizOfFdSetArElem - 1;
10084 for (bytesScanned = 0; bytesScanned < sizOfFdSetArElem;
10089 bitPos = fdSetInfo->ar[*tempByte];
10090 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
10091 fdSetInfo->arIdx = (U16)curIdx;
10092 /* Calculate fd depending on where we are */
10093 *sockFd = ((bytesScanned << 3) + bitPos);
10094 *sockFd += (curIdx * (sizOfFdSetArElem << 3));
10095 /* Clear the file descriptor */
10096 *tempByte &= ~(1 << bitPos);
10099 if (fdSetInfo->bigEndian)
10112 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
10113 } /* end of cmInetGetFd */
10115 #endif /* SUNOS || WIN32 || SS_LINUX || SS_VW || HPOS */
10118 /* add cmInetConvertStrToIpAddr and
10119 * cmInetAsciiToIpv4 functions */
10122 * Fun: cmInetConvertStrToIpAddr
10124 * Desc: This function parses the input string for an IPV4/IPV6 address.
10126 * 1) IPV4 in dot number format:
10128 * 2) IPV6, in uncompressed, compressed, and IPV4 embedded format
10129 * 10:20:30:40:502:610:70C:80ad
10131 * 45::AB:34:123.34.5.667
10133 * Ret: ROK - SUCCESS
10134 * RFAILED - FAILURE
10143 PUBLIC S16 cmInetConvertStrToIpAddr
10145 U16 len, /* Length of IP address */
10146 U8 *val, /* Domain Name String */
10147 CmInetNetAddr *address /* IP Address */
10150 PUBLIC S16 cmInetConvertStrToIpAddr(len, val, address)
10151 U16 len; /* Length of IP address */
10152 U8 *val; /* Domain Name String */
10153 CmInetNetAddr *address; /* IP Address */
10156 U8 idx; /* Index for string*/
10157 U8 ipv4[CM_INET_IPV4ADDR_SIZE]; /* IPV4 Address bytes */
10158 #ifdef IPV6_SUPPORTED
10159 U16 *ipv6; /* IPV6 Address bytes */
10160 U16 ipv6Reg[8]; /* regular IPV6 Address bytes */
10161 U16 ipv6Cmp[8]; /* compressed IPV6 Address bytes */
10162 U8 numBlk; /* number of blocks in IPV6 addr */
10163 Bool compressed; /* IPV6 in compressed format */
10164 U8 ipv6Idx; /* counter for IPV6 */
10165 U8 blkBeginIdx; /* IPV6, char index for the
10166 beginning of the block */
10167 U8 i; /* counter for IPV6 */
10168 S16 retVal; /* return value */
10169 Bool embedIPV4 = FALSE; /* IPV4 embedded in IPV6 ? */
10170 #endif /* IPV6_SUPPORTED*/
10172 TRC2(cmInetConvertStrToIpAddr)
10175 #ifdef IPV6_SUPPORTED
10178 compressed = FALSE;
10180 ipv6 = ipv6Reg; /* assign pointer to IPV6 regular, uncompressed */
10181 cmMemset((U8 *)ipv6Reg, 0, CM_INET_IPV6ADDR_SIZE);
10182 cmMemset((U8 *)ipv6Cmp, 0, CM_INET_IPV6ADDR_SIZE);
10183 #endif /* IPV6_SUPPORTED*/
10185 cmMemset((U8 *)ipv4, 0, CM_INET_IPV4ADDR_SIZE);
10187 /* Check for IP Address */
10188 while ((val[idx] != '.') && (val[idx] != ':') &&
10191 #if (ERRCLASS & ERRCLS_DEBUG)
10192 if (((val[idx] < '0') || (val[idx] > '9')) &&
10193 ((val[idx] < 'a') || (val[idx] > 'f')) &&
10194 ((val[idx] < 'A') || (val[idx] > 'F')))
10199 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10201 /* Convert Ascii to integer */
10202 CM_INET_ATOI(ipv4[0], val[idx]);
10204 #ifdef IPV6_SUPPORTED
10205 /* convert Ascii to hex */
10206 CM_INET_ATOH(ipv6[0], val[idx]);
10207 #endif /* IPV6_SUPPORTED */
10209 idx++; /* move to the next character */
10210 } /* while, try to determine IPV4 or IPV6 */
10212 #if (ERRCLASS & ERRCLS_DEBUG)
10213 if ((val[idx] != '.') && (val[idx] != ':'))
10217 } /* if, couldn't determine IPV4 or IPV6 */
10218 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10221 if (val[idx] == '.')
10224 cmInetAsciiToIpv4(3, &(ipv4[1]), (U16)(len - idx), &(val[idx]));
10226 address->type = CM_INET_IPV4ADDR_TYPE;
10227 CM_INET_GET_IPV4_ADDR_FRM_STRING(address->u.ipv4NetAddr, ipv4);
10229 #ifdef IPV6_SUPPORTED
10232 numBlk = 1; /* already converted the 1st block */
10234 while ((val[idx] != '\0') && (idx < len) && (numBlk <= 8))
10236 idx++; /* go to the next char, either a number or the 2nd : */
10237 if (val[idx] == ':')
10239 #if (ERRCLASS & ERRCLS_DEBUG)
10240 if (compressed == TRUE)
10242 /* can't have 2 :: */
10245 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10248 idx++; /* skip the : */
10251 } /* if, IPV6 in compressed format :: */
10255 } /* else, uncompressed, convert next block */
10257 numBlk++; /* increase number of blocks */
10259 /* assign the index the beginning of the block */
10262 while(val[idx] != ':' && val[idx] != '\0' && idx < len)
10264 if (val[idx] == '.')
10266 /* convert number to IPV4 */
10267 ipv6[ipv6Idx] = 0; /* clear out whatever we did */
10268 cmMemset((U8 *)ipv4, 0, CM_INET_IPV4ADDR_SIZE);
10269 retVal = cmInetAsciiToIpv4(4, ipv4, len - blkBeginIdx,
10270 &(val[blkBeginIdx]));
10271 /* stop the loop, embedded IPV4 is the last part of
10279 } /* if, '.' means IPV4 address embedded in IPV6 */
10281 #if (ERRCLASS & ERRCLS_DEBUG)
10282 if (((val[idx] < '0') || (val[idx] > '9')) &&
10283 ((val[idx] < 'a') || (val[idx] > 'f')) &&
10284 ((val[idx] < 'A') || (val[idx] > 'F')))
10289 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10291 /* Convert Ascii to integer */
10292 CM_INET_ATOH(ipv6[ipv6Idx], val[idx]);
10294 /* move to the next index */
10296 } /* while, convert a block of 16 bits Hex number */
10297 if (embedIPV4 == TRUE)
10299 ipv6Idx--; /* deccrease in case of compressed IPV6 */
10300 break; /* stop the while look */
10301 } /* if, IPV4 embedded in IPV6 */
10302 } /* while, IPV6 parsing */
10303 if (compressed == TRUE)
10305 if (embedIPV4 == TRUE)
10307 numBlk = 5; /* the last 2 blocks are IPV4 */
10308 } /* if, IPV4 embedded */
10311 numBlk = 7; /* copy from the last block */
10312 } /* else, no embedded IPV4 */
10314 /* type cast U8 over -1 becasue we want to copy the last block,
10317 for (i = ipv6Idx; i != (U8) (-1); i --)
10319 ipv6Reg[numBlk] = ipv6Cmp[i];
10321 } /* for, copying compress IPV6 to regular IPV6 */
10322 } /* if, compressed format */
10324 if (embedIPV4 == TRUE)
10326 ipv6Reg[6] = PutHiByte(ipv6Reg[6], ipv4[0]);
10327 ipv6Reg[6] = PutLoByte(ipv6Reg[6], ipv4[1]);
10328 ipv6Reg[7] = PutHiByte(ipv6Reg[7], ipv4[2]);
10329 ipv6Reg[7] = PutLoByte(ipv6Reg[7], ipv4[3]);
10330 } /* if, IPV4 embedded */
10332 /* convert IPV6 to cmInetIpv6 */
10333 address->type = CM_INET_IPV6ADDR_TYPE;
10334 cmMemcpy((U8 *)address->u.ipv6NetAddr,
10335 (CONSTANT U8 *) ipv6Reg, CM_INET_IPV6ADDR_SIZE);
10337 #endif /* IPV6_SUPPORTED */
10340 } /* cmInetConvertStrToIpAddr */
10345 * Fun: cmInetAsciiToIpv4
10347 * Desc: This function parses the input string to an IPV4 address.
10348 * The input string can be
10349 * - the whole IPV4 address, '123.43.45.56', or
10350 * - a part of it. '34.56.454'
10351 * numBytes: number of bytes needs to be converted, IPV4 has
10352 * 4 bytes. If we are only converting the end of an
10353 * address, this number needs to be adjusted. For
10354 * example, when converting '34.56.454]', the number
10357 * Ret: ROK - SUCCESS
10358 * RFAILED - FAILURE
10366 PUBLIC S16 cmInetAsciiToIpv4
10368 U8 numBytes, /* number of Byte to convert */
10369 U8 *ipv4Addr, /* IPV4 Address */
10370 U16 len, /* Length of IP address */
10371 U8 *val /* Domain Name String */
10374 PUBLIC S16 cmInetAsciiToIpv4(numBytes, ipv4Addr, len, val)
10375 U8 numBytes; /* number of Byte to convert */
10376 U8 *ipv4Addr; /* IPV4 Address */
10377 U16 len; /* Length of IP address */
10378 U8 *val; /* Domain Name String */
10381 U8 byteCount; /* Byte Count */
10382 U8 idx; /* Index for string*/
10384 TRC2(cmInetAsciiToIpv4)
10387 for (byteCount = 0; byteCount < numBytes; byteCount++)
10389 while((val[idx] != '.') && (idx < len))
10391 #if (ERRCLASS & ERRCLS_DEBUG)
10392 if (val[idx] < '0' || val[idx] > '9')
10397 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
10399 /* Convert Ascii to integer */
10400 CM_INET_ATOI(ipv4Addr[byteCount], val[idx]);
10402 /* move to the next index */
10409 } /* cmInetAsciiToIpv4 */
10411 /* cm_inet_c_001.main_34:Added wrapper function for getaddrinfo and freeaddrinfo */
10412 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
10416 * Fun: cmInetGetAddrInfo
10418 * Desc: a socket file descriptor to a local Internet
10421 * Ret: Value returned by getaddrinfo
10430 PUBLIC S32 cmInetGetAddrInfo
10432 CONSTANT S8 *node, /* Network addr which has to be resolved */
10433 CONSTANT S8 *service, /* Sets the port number in network addr */
10434 CONSTANT CmInetAddrInfo *hints, /* Specifies preferred socket type or protocol */
10435 CmInetAddrInfo **res /* Link list of addrInfo structure */
10438 PUBLIC S32 cmInetGetAddrInfo(node,service,hints,res)
10439 CONSTANT S8 *node; /* Network addr which has to be resolved */
10440 CONSTANT S8 *service; /* Sets the port number in network addr */
10441 CONSTANT CmInetAddrInfo *hints; /* Specifies preferred socket type or protocol */
10442 CmInetAddrInfo **res; /* Link list of addrInfo structure */
10446 TRC2(cmInetGetAddrInfo);
10449 #if (ERRCLASS & ERRCLS_INT_PAR)
10450 /* error check on parameters */
10451 if ((node == NULLP) || (hints == NULLP))
10455 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10457 ret = getaddrinfo(node,service,hints,res);
10461 #ifndef ALIGN_64BIT
10462 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10463 /* cm_inet_c_001.main_62:Warning fix */
10464 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%ld), node(%p),"
10465 " service(%p)\n", ret, node, service);
10466 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET052, 0, prntBuf);
10468 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10469 /* cm_inet_c_001.main_62:Warning fix */
10470 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%d), node(%p),"
10471 " service(%p)\n ", ret, node, service);
10472 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET053, 0, prntBuf);
10473 #endif /* ALIGN_64BIT */
10474 #endif /* CMINETDBG */
10477 } /* end of cmInetGetAddrInfo */
10482 * Fun: cmInetFreeAddrInfo
10484 * Desc: Free the dynamically allocated addrinfo structure
10495 PUBLIC Void cmInetFreeAddrInfo
10497 CmInetAddrInfo *res /* Link list of addrInfo structure */
10500 PUBLIC Void cmInetFreeAddrInfo(res)
10501 CmInetAddrInfo *res; /* Link list of addrInfo structure */
10504 TRC2(cmInetFreeAddrInfo);
10506 #if (ERRCLASS & ERRCLS_INT_PAR)
10507 /* error check on parameters */
10510 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10513 } /* end of cmInetFreeAddrInfo */
10515 #endif /* SS_VW | SS_PS | WIN32*/
10517 /* cm_inet_c_001.main_36 : 1. Added new interface - cmInetFlushRecvBuf()
10518 to flush the data from socket receive buffer. */
10519 #ifdef CM_INET_FLUSH_RECV_BUF
10523 * Fun: cmInetFlushRcvBuf
10525 * Desc: Reads all the data from a socket and throw it!!
10526 * The buffers for the receive buffer for recvfrom() are allocated from the stack.
10528 * Ret: ROK - successful
10529 * ROKDNA - ok, data not available
10530 * RCLOSED - connection closed by peer
10531 * ROUTRES - failed, out of resources
10540 PUBLIC S16 cmInetFlushRecvBuf
10542 CmInetFd *sockFd, /* socket file descriptor */
10543 MsgLen *len, /* number of octects to be flushed */
10544 S32 flags /* additional control flags */
10547 PUBLIC S16 cmInetFlushRecvBuf(sockFd, len, flags)
10548 CmInetFd *sockFd; /* socket file descriptor */
10549 MsgLen *len; /* number of octects to be flushed */
10550 S32 flags; /* additional control flags */
10554 Data recvTempBuf[CM_INET_MAX_BYTES_READ];
10556 #if (defined(WIN32) || defined(CMINETFLATBUF))
10557 S32 ret; /* temporary return value */
10558 U32 pendLen; /* pending data length */
10559 S32 recvLen; /* number of received octets by recvmsg() */
10560 MsgLen curLen; /* current number of octets in buffer */
10561 U32 remAddrLen; /* length of remote address */
10562 struct sockaddr_in *remAddr; /* remote Internet address */
10563 #ifdef IPV6_SUPPORTED
10564 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
10566 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
10567 #endif /* IPV6_SUPPORTED */
10569 S32 ret; /* temporary return value */
10570 MsgLen curLen; /* current number of octets in buffer */
10571 U32 pendLen; /* pending data length */
10572 S32 recvLen; /* number of received octets by recvmsg() */
10573 struct msghdr msg; /* message header */
10574 CmInetIovec rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
10575 U32 remAddrLen; /* length of remote address */
10576 #ifdef IPV6_SUPPORTED
10577 struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
10579 #if (defined(SS_LINUX) || defined(_XPG4_2))
10580 U8 ancillData[CM_INET_IPV6_ANCIL_DATA];
10581 /* from stack for IPv6 ancill data */
10584 CmInetSockAddr remSockAddr; /* to get packet's src IP address */
10585 #if (defined(SS_LINUX) || defined(_XPG4_2))
10586 U8 ancillData[CM_INET_IPV4_ANCIL_DATA];
10587 /* from stack for IPv4 ancill data */
10589 #endif /* IPV6_SUPPORTED */
10590 #endif /* WIN32 | CMINETFLATBUF */
10592 /* used by getsockopt */
10593 U32 errValue; /* error value */
10594 U32 optLen; /* option length */
10596 TRC2(cmInetFlushRcvBuf)
10598 #if (ERRCLASS & ERRCLS_INT_PAR)
10599 /* error check on parameters */
10600 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
10604 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10607 #if (defined(WIN32) || defined(CMINETFLATBUF))
10609 #endif /* (WIN32 | CMINETFLATBUF) */
10611 /* clear the structure */
10612 cmMemset((U8*)&remSockAddr, 0, sizeof(remSockAddr));
10614 /* get number of pending data */
10615 ret = cmInetGetNumRead(sockFd, &pendLen);
10618 /* ret may be RFAILED or ROUTRES */
10622 /* check if connection got closed */
10625 if (sockFd->type == CM_INET_STREAM)
10628 /* cm_inet_c_001.main_50
10629 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
10630 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
10631 * socket that select says is ready to read. This should not be
10632 * considered as connection closed. So return ROKDNA instead of
10638 /* clear error if there is any, because if there is internal error
10639 * here it will cause infinite loop in TUCL */
10642 optLen = sizeof(int);
10644 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10645 (char*)&errValue, (socklen_t *)&optLen);
10647 #if (defined(SS_VW) || defined(SS_PS))
10648 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10649 (char*)&errValue, (int *)&optLen);
10652 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10653 (char*)&errValue, (int *)&optLen);
10654 #endif /* SS_WINCE */
10656 #endif /* SS_LINUX */
10657 if (ret == INET_ERR)
10660 #ifndef ALIGN_64BIT
10661 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10662 /* cm_inet_c_001.main_62:Warning fix */
10663 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10664 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10665 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10667 /* cm_inet_c_001.main_62:Warning fix */
10668 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10669 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10670 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10671 #endif /*ALIGN_64BIT*/
10672 #endif /* CMINETDBG */
10678 /* added separate recvfrom calls different OS */
10679 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10680 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10681 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10683 #if ( defined(SUNOS) || defined(SS_LINUX))
10684 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10685 NULLP, (socklen_t *)&remAddrLen);
10687 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10688 NULLP, (S32 *)&remAddrLen);
10690 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10691 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10696 }/* if (pendLen == 0)*/
10699 if((*len == CM_INET_READ_THROW) || (*len >= CM_INET_MAX_BYTES_READ))
10701 curLen = CM_INET_MAX_BYTES_READ;
10705 curLen = *len; /*set to given number of messasges to be flushed */
10708 if((*len != CM_INET_READ_THROW) && (*len < pendLen))
10713 #if (defined(WIN32) || defined(CMINETFLATBUF))
10717 * maybe needs more than one recvfrom() call to read an entire
10722 cmMemset((U8*)recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10723 /* added separate recvfrom calls different OS */
10725 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10726 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10727 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10729 #if ( defined(SUNOS) || defined(SS_LINUX))
10730 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10731 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
10733 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempbuf, curLen, 0,
10734 &remSockAddr, (S32 *)&remAddrLen);
10736 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10737 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10739 if (recvLen == INET_ERR)
10742 /* added check ERR_WOULDBLOCK */
10743 if ((INET_ERR_CODE == ERR_AGAIN) ||
10744 (INET_ERR_CODE == ERR_WOULDBLOCK))
10751 /* In Windows the recvfrom function fails
10752 * with error code which maps to either WSAECONNABORTED. If
10753 * this happens then cmInetFlushRecvBuf must return RCLOSED */
10754 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
10755 (INET_ERR_CODE == ERR_CONNRESET))
10762 #ifndef ALIGN_64BIT
10763 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10764 /* cm_inet_c_001.main_62:Warning fix */
10765 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10766 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10767 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10769 /* cm_inet_c_001.main_62:Warning fix */
10770 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10771 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10772 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10773 #endif /*ALIGN_64BIT*/
10774 #endif /* CMINETDBG */
10779 if(recvLen < curLen)
10782 pendLen -= recvLen;
10784 if(pendLen < curLen)
10787 } /* while (curLen > 0) */
10789 #else /* end of Win NT/flat buffer specific part */
10792 * maybe needs more than one recvmsg() call to read entire message
10793 * on a stream socket
10797 cmMemset((U8*)recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10798 /* update the message structure */
10800 rxArr[0].iov_base = (Void*)recvTempBuf;
10801 rxArr[0].iov_len = (U32)curLen;
10803 rxArr[0].iov_base = (S8*)recvTempBuf;
10804 rxArr[0].iov_len = curLen;
10805 #endif /* SS_LINUX */
10806 msg.msg_iov = rxArr;
10807 msg.msg_iovlen = 1;
10809 msg.msg_name = NULLP;
10810 msg.msg_namelen = 0;
10812 /* added defined(_XPG4_2). Also changed the
10814 #if (defined(SS_LINUX) || defined(_XPG4_2))
10815 msg.msg_control = ancillData;
10816 msg.msg_controllen = sizeof(ancillData);
10819 msg.msg_accrights = NULLP;
10820 msg.msg_accrightslen = 0;
10821 #endif /* SS_LINUX */
10823 recvLen = recvmsg(sockFd->fd, &msg, flags);
10824 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
10826 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
10827 added check ERR_WOULDBLOCK */
10828 if ((INET_ERR_CODE == ERR_AGAIN) ||
10829 (INET_ERR_CODE == ERR_WOULDBLOCK))
10836 #ifndef ALIGN_64BIT
10837 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
10838 /* cm_inet_c_001.main_62:Warning fix */
10839 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10840 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10841 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10843 /* cm_inet_c_001.main_62:Warning fix */
10844 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10845 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10846 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10847 #endif /*ALIGN_64BIT*/
10848 #endif /* CMINETDBG */
10850 /* If this happens then cmInetFlushRecvBuf must return RCLOSED.
10851 * Needed for getting icmp msgs */
10852 if (INET_ERR_CODE == ERR_CONNABORTED)
10858 }/* if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))*/
10860 if(recvLen < curLen)
10863 pendLen -= recvLen;
10865 if(pendLen < curLen)
10868 } /* while(curLen > 0) */
10870 #endif /* WIN32 | CMINETFLATBUF */
10874 } /* end of cmInetFlushRecvBuf */
10876 #endif /* CM_INET_FLUSH_RECV_BUF*/
10878 /**********************************************************************
10880 **********************************************************************/