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 "common_def.h"
49 #include "cm_inet.h" /* socket library file */
51 /*cm_inet_c_001.main_35 : Updated for C++ compilation */
54 #endif /* __cplusplus */
56 /* environment dependent include files */
68 #if (!defined(SS_VW) && !defined(SS_PS))
75 #include <sys/types.h>
79 #include <sys/socket.h>
80 #include <sys/ioctl.h>
83 #include <sys/times.h>
86 #include <selectLib.h>
89 #if (!defined (SS_PS) && !defined(HPOS))
90 #include <sys/select.h>
95 #include <sys/filio.h>
97 #endif /* SS_PS && HPOS */
103 #include <netinet/in.h>
104 #include <arpa/inet.h>
105 #include <netinet/tcp.h>
106 #ifdef IPV6_SUPPORTED
108 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 adding the new header includes */
109 #if (defined(SS_VW) && defined(SS_VW6_7))
110 #include <ipcom_inet.h>
111 #include <ipcom_sock6.h>
112 #include <netinet/icmp6.h>
114 #include <netinet/icmp6.h>
117 #endif /* IPV6_SUPPORTED */
121 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
123 #include <netinet/sctp.h>
126 /* cm_inet_c_001.main_58: Added new header files to support filteration
127 * of ICMP messages */
129 #ifdef CM_ICMP_FILTER_SUPPORT
130 #include <asm/types.h>
131 #include <linux/icmp.h>
134 /* cm_inet_c_001.main_62:Warning fix */
135 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
140 #endif /* __cplusplus */
141 /* header/extern include files (.x) */
143 #include "cm_inet.x" /* socket library file */
151 /* BSD and Winsock error handling is different */
153 #define INET_ERR SOCKET_ERROR
154 #define INET_ERR_CODE WSAGetLastError()
155 #define ERR_INPROGRESS WSAEINPROGRESS
156 #define ERR_ISCONN WSAEISCONN
157 #define ERR_WOULDBLOCK WSAEWOULDBLOCK
158 #define ERR_INADDRNONE INADDR_NONE
159 #define ERR_NOTCONN WSAENOTCONN
160 #define ERR_ALREADY WSAEALREADY
161 #define ERR_AGAIN WSAEWOULDBLOCK
162 #define ERR_INVAL WSAEINVAL
163 #define ERR_CONNREFUSED WSAECONNREFUSED
164 #define ERR_PIPE WSAENOTCONN
165 /* Changed ERR_TIMEOUT for pSos compilation */
166 #define ERR_TIMEDOUT WSAETIMEDOUT
167 #define ERR_CONNRESET WSAECONNRESET
168 #define ERR_CONNABORTED WSAECONNABORTED
169 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
170 #define ERR_EINTR WSAEINTR
171 /* cm_inet_c_001.main_37 network unreacheble error is added */
172 #define ERR_NETUNREACH WSAENETUNREACH
173 /* cm_inet_c_001.main_61: host unreachable is added */
174 #define ERR_HOSTUNREACH WSAEHOSTUNREACH
177 #define INET_ERR_CODE errno
178 #define ERR_INPROGRESS EINPROGRESS
179 #define ERR_ISCONN EISCONN
180 #define ERR_WOULDBLOCK EWOULDBLOCK
181 #define ERR_INADDRNONE -1
182 #define ERR_NOTCONN ENOTCONN
183 #define ERR_ALREADY EALREADY
184 #define ERR_AGAIN EAGAIN
185 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
186 #define ERR_EINTR EINTR
187 /* EINVAL is not mapped because it is a valid error code here */
189 #define ERR_CONNREFUSED ECONNREFUSED
190 #define ERR_PIPE EPIPE
191 /* Changed ERR_TIMEOUT for pSos compilation */
192 #define ERR_TIMEDOUT ETIMEDOUT
193 #define ERR_CONNRESET ECONNRESET
194 #define ERR_CONNABORTED ECONNABORTED
195 /* cm_inet_c_001.main_37 network unreacheble error is added */
196 #define ERR_NETUNREACH ENETUNREACH
197 /* cm_inet_c_001.main_61: host unreachable is added */
198 #define ERR_HOSTUNREACH EHOSTUNREACH
202 #define MIN_BACK_LOG 0
204 /* added a win2k specific defines in. */
207 #ifndef SIO_UDP_CONNRESET
208 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
211 #define MAX_BACK_LOG 1
213 #define MAX_BACK_LOG 5
216 #ifdef IPV6_OPTS_SUPPORTED
217 #ifndef IPV6_SUPPORTED
218 #error "Enable IPV6_SUPPORTED flag if IPV6_OPTS_SUPPORTED is defined."
220 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
221 #error "Enable _XPG4_2 or SS_LINUX if IPV6_OPTS_SUPPORTED is defined."
222 #endif /* SS_LINUX || _XPG4_2 */
223 #endif /* IPV6_OPTS_SUPPORTED */
226 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
227 #error "Enable _XPG4_2 or SS_LINUX if LOCAL_INTF is defined."
228 #endif /* SS_LINUX || _XPG4_2 */
229 #endif /* LOCAL_INTF */
235 /* forward references */
237 /* added !(defined(CMINETFLATBUF) */
238 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
239 /* Added another function parameter */
240 static S16 buildRecvBuf ARGS((CmInetMemInfo *info, MsgLen len,
241 CmInetIovec rxArr[], Buffer *dBuf[], uint16_t maxSize,
242 struct msghdr *msg, Bool isStrmMsg));
243 static S16 buildRecvMsg ARGS((CmInetMemInfo *info, CmInetIovec rxArr[],
244 S16 numBduf, MsgLen msgLen, Buffer *dBufs[],
246 /* cm_inet_c_001.main_50 - Added parameter to get length of dbufs packed for partial
249 static S16 buildSendIovec ARGS((Buffer *mBuf, MsgLen msgLen,
250 CmInetIovec txArr[], S16 numDBuf,
251 S16 *numIovElems, uint32_t *strtEndDBufNum,
253 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
255 /* prototypes of new functions needed to send and
256 * process after receiving the extension headers through ancillary data */
258 #ifdef IPV6_SUPPORTED
259 #ifdef IPV6_OPTS_SUPPORTED
260 static S16 cmInet6BuildSendHBHOpts ARGS((CmInetIpv6HBHHdrArr *hbhOptsArr,
261 uint8_t *cmsgBuf, uint32_t *curMsgIdx,
263 static S16 cmInet6BuildSendRouteOpts ARGS((CmInetIpv6RtHdr *rtOptsArr,
264 uint8_t *cmsgBuf, uint32_t *curMsgIdx));
266 static S16 cmInet6BuildRecvRtHdr ARGS((uint8_t *cmsgData, uint32_t rtDataLen,
267 CmInetIpv6RtHdr0 *rtHdr0,
268 CmInetIpv6RtHdr *rtOptsArr,
269 CmInetMemInfo *info));
270 static S16 cmInet6BuildRecvHopOptsArr ARGS((uint8_t *cmsgData, uint32_t hbhDataLen,
271 CmInetIpv6HBHHdrArr *hbhOptsArr,
272 uint8_t hdrId, CmInetMemInfo *info));
273 static S16 cmInet6GetHopLimitValue ARGS((uint8_t *cmsgData, uint32_t hopLimitDataLen,
274 CmInetIpv6HdrParm *ipv6HdrParam));
277 static S16 cmInetBuildSendHoplimit ARGS((uint32_t hoplimit, uint8_t *cmsgBuf,
278 uint32_t *curMsgIdx));
279 #endif /* SS_LINUX */
281 static S16 cmInet6BuildSendPktinfo ARGS((CmInetIpAddr6 *srcAddr,
282 uint8_t *cmsgBuf, uint32_t *curMsgIdx,
284 #endif /* LOCAL_INTF */
285 #endif /* IPV6_OPTS_SUPPORTED */
286 #endif /* IPV6_SUPPORTED */
288 /* public variable declarations */
290 /* private variable declarations */
293 /* Global buffer for debug prints */
294 /*cm_inet_c_001.main_62:Warning fix*/
295 Txt prntBuf[CMINET_PRNT_BUF_SIZE];
296 #endif /* CMINETDBG */
298 /* cm_inet_c_001.main_60 POLL Specific Functions defined */
304 * Desc: Poll on pollfdarr
306 * Ret: Number of File Descriptor Selected
316 CmInetPollFd *pollFdArr, /* poll FD Array */
317 uint32_t numFds, /* Number of Fds to be monitored */
318 S16 *numRdyFds, /* number of ready descriptors */
319 uint32_t timeout /* timeout value for Poll */
327 if(numFds > CM_INET_POLL_MAXFDSUPP)
330 /* cm_inet_c_001.main_62:Warning fix */
332 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%lu) invalid \n",numFds);
334 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%u) invalid \n",numFds);
336 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
337 #endif /* CMINETDBG */
341 #if (ERRCLASS & ERRCLS_INT_PAR)
342 /* error check on parameters */
343 if (pollFdArr == NULLP)
346 /* cm_inet_c_001.main_62:Warning fix */
347 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : Invalid Parameter (pollFdArr is NULL)");
348 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
349 #endif /* CMINETDBG */
352 #endif /* ERRCLASS & ERRCLS_INT_PAR */
354 ret = poll(pollFdArr,numFds,timeout);
361 switch(INET_ERR_CODE)
368 /* cm_inet_c_001.main_62:Warning fix */
369 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "File: %s, cmInetPoll() failed on line: %d \n\
370 error(%d)\n", __FILE__, __LINE__, INET_ERR_CODE);
372 #endif /* CMINETDBG */
375 } /* end of switch */
378 *numRdyFds = (S16)ret;
386 * Fun: cmInetPollSetFd
388 * Desc: Set the selected fd in pollFdArr with event eventMask
390 * Ret: RFAILED : if file descriptor is out of range
391 * ROK : if pollFdArr is set.
401 CmInetFd *sockFd, /* socket file descriptor */
402 CmInetPollFd *pollFdArr, /* poll FD Array */
403 S16 idx, /* poll Fd Array Index */
404 uint16_t eventMask /* Event Mask to be set */
409 if ((idx) >= CM_INET_POLL_MAXFDSUPP || (idx) < 0)
412 /* cm_inet_c_001.main_62:Warning fix */
413 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid idx(%d) \n",idx);
414 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
415 #endif /* CMINETDBG */
420 #if (ERRCLASS & ERRCLS_INT_PAR)
421 /* error check on parameters */
422 if (pollFdArr == NULLP)
425 /* cm_inet_c_001.main_62:Warning fix */
426 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid Parameter (pollFdArr is NULL)");
427 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
428 #endif /* CMINETDBG */
431 #endif /* ERRCLASS & ERRCLS_INT_PAR */
435 /* cm_inet_c_001.main_62:Warning fix */
436 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,
437 "cmInetPollSetFd() Before Setting fd : sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set fd(%ld) event(%d) \n",
438 pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
439 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
441 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,
442 "cmInetPollSetFd() Before Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set fd(%d) event(%d) \n",
443 pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
444 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
445 #endif /*ALIGN_64BIT */
446 #endif /* CMINETDBG */
448 /* Setting fd and events with eventMask */
449 pollFdArr[idx].fd = sockFd->fd;
450 pollFdArr[idx].events |= eventMask;
455 /* cm_inet_c_001.main_62:Warning fix */
456 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
457 pollFdArr[idx].fd,idx, pollFdArr[idx].events);
458 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
460 /* cm_inet_c_001.main_62:Warning fix */
461 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
462 pollFdArr[idx].fd,idx, pollFdArr[idx].events);
463 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
464 #endif /*ALIGN_64BIT */
465 #endif /* CMINETDBG */
474 * Fun: cmInetPollFdIsSet
476 * Desc: Checks whether fd is selected
478 * Ret: TRUE : If Fd is Selected
479 * FALSE: If Fd is not Selected
487 S16 cmInetPollFdIsSet
489 CmInetPollFd *pollFdArr, /* poll FD Array */
490 S16 idx, /* poll Fd Array Index */
491 uint16_t eventMask /* Event Mask to be set */
497 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
500 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Index (%d) \n",idx);
501 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
502 #endif /* CMINETDBG */
506 #if (ERRCLASS & ERRCLS_INT_PAR)
507 /* error check on parameters */
508 if (pollFdArr == NULLP)
511 /* cm_inet_c_001.main_62:Warning fix */
512 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Parameter (pollFdArr is NULL)");
513 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
514 #endif /* CMINETDBG */
517 #endif /* ERRCLASS & ERRCLS_INT_PAR */
519 ret = (pollFdArr[idx].revents & eventMask);
526 * Fun: cmInetPollClearFdREvent
528 * Desc: clears the reventMask in revent of the givent FD.
539 S16 cmInetPollClearFdREvent
541 CmInetPollFd *pollFdArr, /* poll FD Array */
542 S16 idx, /* poll Fd Array Index */
543 uint16_t eventMask /* Event Mask to be set */
549 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
552 /* cm_inet_c_001.main_62:Warning fix */
553 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Index (%d) \n",idx);
554 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
555 #endif /* CMINETDBG */
559 #if (ERRCLASS & ERRCLS_INT_PAR)
560 /* error check on parameters */
561 if (pollFdArr == NULLP)
564 /* cm_inet_c_001.main_62:Warning fix */
565 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Parameter (pollFdArr is NULL)");
566 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
567 #endif /* CMINETDBG */
570 #endif /* ERRCLASS & ERRCLS_INT_PAR */
574 /* cm_inet_c_001.main_62:Warning fix */
575 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
576 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
577 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
579 /* cm_inet_c_001.main_62:Warning fix */
580 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
581 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
582 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
583 #endif /*ALIGN_64BIT */
584 #endif /* CMINETDBG */
586 /* Clearing the events with eventMask */
587 pollFdArr[idx].revents = (pollFdArr[idx].revents & (~(eventMask)));
591 /* cm_inet_c_001.main_62:Warning fix */
592 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
593 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
594 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
596 /* cm_inet_c_001.main_62:Warning fix */
597 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
598 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
599 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
600 #endif /*ALIGN_64BIT */
601 #endif /* CMINETDBG */
610 * Fun: cmInetPollClearFdEvent
612 * Desc: clears the eventMask in event of the givent FD.
623 S16 cmInetPollClearFdEvent
625 CmInetPollFd *pollFdArr, /* poll FD Array */
626 S16 idx, /* poll Fd Array Index */
627 uint16_t eventMask /* Event Mask to be set */
633 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
636 /* cm_inet_c_001.main_62:Warning fix */
637 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Index (%d) \n",idx);
638 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
639 #endif /* CMINETDBG */
643 #if (ERRCLASS & ERRCLS_INT_PAR)
644 /* error check on parameters */
645 if (pollFdArr == NULLP)
648 /* cm_inet_c_001.main_62:Warning fix */
649 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Parameter (pollFdArr is NULL)");
650 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
651 #endif /* CMINETDBG */
654 #endif /* ERRCLASS & ERRCLS_INT_PAR */
658 /* cm_inet_c_001.main_62:Warning fix */
659 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask: \n sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
660 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
661 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
663 /* cm_inet_c_001.main_62:Warning fix */
664 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask:\n sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
665 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
666 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
667 #endif /*ALIGN_64BIT */
668 #endif /* CMINETDBG */
670 /* Clearing events with eventMask */
671 pollFdArr[idx].events = (pollFdArr[idx].events & (~(eventMask)));
675 /* cm_inet_c_001.main_62:Warning fix */
676 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
677 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
678 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
680 /* cm_inet_c_001.main_62:Warning fix */
681 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
682 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
683 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
684 #endif /*ALIGN_64BIT */
685 #endif /* CMINETDBG */
694 * Fun: cmInetPollDelFd
696 * Desc: Delete the given FD from the pollFdArray
697 * delIdx : Poll Fd Array Index at which fd has to be deleted.
698 * lastIdx: Last index of poll fd array.
700 * It deletes fd from array by swapping lastIdx pollFd
701 * values to index to be deleted and deinitializes the
707 * Notes: It does not decrement the lastIdx and it has to be
708 * decremented by the caller of this function.
716 CmInetPollFd *pollFdArr, /* poll FD Array */
717 S16 delIdx, /* poll Fd Array Index for which fd has to be deleted*/
718 S16 lastIdx /* Last index of poll Fd Array */
723 if(lastIdx < delIdx || lastIdx < 0 || delIdx < 0)
726 /* cm_inet_c_001.main_62:Warning fix */
727 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Index \n Current Index (%d) Delete Index (%d) \n",lastIdx,delIdx);
728 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
729 #endif /* CMINETDBG */
734 #if (ERRCLASS & ERRCLS_INT_PAR)
735 /* error check on parameters */
736 if (pollFdArr == NULLP)
739 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Parameter (pollFdArr is NULL)");
740 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
741 #endif /* CMINETDBG */
744 #endif /* ERRCLASS & ERRCLS_INT_PAR */
748 /* cm_inet_c_001.main_62:Warning fix */
749 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() Deleting the sockFd->fd(%d) Index(%d) Event(%d) revent(%d) \n",
750 pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
751 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
753 /* cm_inet_c_001.main_62:Warning fix */
754 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
755 pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
756 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
757 #endif /*ALIGN_64BIT */
758 #endif /* CMINETDBG */
760 pollFdArr[delIdx].fd = pollFdArr[lastIdx].fd;
761 pollFdArr[delIdx].events = pollFdArr[lastIdx].events;
762 pollFdArr[delIdx].revents = pollFdArr[lastIdx].revents;
764 pollFdArr[lastIdx].fd = -1;
765 pollFdArr[lastIdx].events = 0;
766 pollFdArr[lastIdx].revents = 0;
774 * Fun: cmInetPollInitFdArr
776 * Desc: Cleans all elements of fd array.
781 * Notes: It does not allocates/deallocates memory for Poll Fd Array.
782 * Caller of function has to allocate/deallocate memory for
789 S16 cmInetPollInitFdArr
791 CmInetPollFd *pollFdArr /* poll FD Array */
796 /* Sets each element of pollFdArr to initial value
801 #if (ERRCLASS & ERRCLS_INT_PAR)
802 /* error check on parameters */
803 if (pollFdArr == NULLP)
806 /* cm_inet_c_001.main_62:Warning fix */
807 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollInitFdArr() : Invalid Parameter (pollFdArr is NULL)");
808 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
809 #endif /* CMINETDBG */
812 #endif /* ERRCLASS & ERRCLS_INT_PAR */
814 for(idx=0; idx < CM_INET_POLL_MAXFDSUPP; idx++)
816 pollFdArr[idx].fd = -1;
817 pollFdArr[idx].events = 0;
818 pollFdArr[idx].revents = 0;
823 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
828 * Desc: Allocates dBufs to receive an entire message.
830 * Ret: ROK - successful
832 * ROUTRES - failed, out of resources
840 static S16 buildRecvBuf
842 CmInetMemInfo *info, /* buffer allocation info */
843 MsgLen len, /* message length */
844 CmInetIovec rxArr[], /* gather array */
845 Buffer *dBuf[], /* allocated dBufs */
846 uint16_t maxSize, /* size of rxArr/dBuf array */
847 struct msghdr *msg, /* message header for recvmsg() */
848 Bool isStrmMsg /* Is a TCP message */
851 S16 ret; /* temporary return value */
852 uint16_t numBuf; /* number of dBufs */
853 uint16_t i; /* dBuf index counter */
854 Data *dPtr; /* data pointer */
855 /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
856 MsgLen bufLen; /* entire receive buffer length, if S16
857 could wrap to negative number */
858 MsgLen dLen; /* buffer length */
863 /* Initialise ret and part of msg here */
866 /* added defined(_XPG4_2) */
867 /* Moved initialisation of msg here. */
869 #if (defined(SS_LINUX) || defined(_XPG4_2))
870 msg->msg_control = NULLP;
871 msg->msg_controllen = 0;
873 msg->msg_accrights = NULLP;
874 msg->msg_accrightslen = 0;
875 #endif /* SS_LINUX */
877 /* Check if maxSize if enough to hold the entire message length before
878 * going into the loop. If the boolean isStrmMsg is TRUE then the recv
879 * buf is built even if the whole message cannot be accomodated. */
881 #ifdef T2K_MEM_LEAK_DBG
882 char * file = __FILE__;
883 uint32_t line = __LINE__;
884 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
886 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
891 /* Get the data part */
892 ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
895 numBuf++; /* because of cleanup */
901 /* The assumption here is that all dBuf's from a given region and
902 * pool have a constance size */
903 if (len > (maxSize * dLen))
906 numBuf++; /* because of cleanup */
912 rxArr[numBuf].iov_base = (Void*)dPtr;
913 rxArr[numBuf].iov_len = (uint32_t)dLen;
915 rxArr[numBuf].iov_base = (S8*)dPtr;
916 rxArr[numBuf].iov_len = dLen;
917 #endif /* SS_LINUX */
922 /* allocate buffer space for entire message length */
925 if (numBuf >= maxSize)
927 /* to big to fit in gather vector array */
931 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
936 ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
939 numBuf++; /* because of cleanup */
943 rxArr[numBuf].iov_base = (Void*)dPtr;
944 rxArr[numBuf].iov_len = (uint32_t)dLen;
946 rxArr[numBuf].iov_base = (S8*)dPtr;
947 rxArr[numBuf].iov_len = dLen;
948 #endif /* SS_LINUX */
953 /* adjust last buffer length */
954 /* check if we broke out because numBuf >= maxSize */
956 rxArr[numBuf - 1].iov_len = dLen;
958 rxArr[numBuf - 1].iov_len = dLen - (bufLen - len);
960 /* setup recvmsg() message header */
961 msg->msg_iov = rxArr;
962 msg->msg_iovlen = numBuf;
968 for (i = 0; i < numBuf; i++)
969 SPutDBuf(info->region, info->pool, dBuf[i]);
974 } /* end of buildRecvBuf */
980 * Desc: Builds a message out of the received dBufs.
982 * Ret: ROK - successful
984 * ROUTRES - failed, out of resources
992 static S16 buildRecvMsg
994 CmInetMemInfo *info, /* buffer allocation info */
995 CmInetIovec rxArr[], /* scatter array */
996 S16 numBuf, /* number of allocated dBufs */
997 MsgLen msgLen, /* message length */
998 Buffer *dBufs[], /* dBufs */
999 Buffer **mPtr /* message built from dBufs */
1002 S16 ret; /* return value */
1003 S16 i; /* dBuf index counter */
1004 MsgLen bufLen; /* length of one particular dBuf */
1005 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
1006 Buffer *mBuf = NULLP; /* allocated message */
1012 ret = SGetMsg(info->region, info->pool, &mBuf);
1018 /* link buffers to message */
1021 /* cm_inet_c_001.main_58: fix for klockwork issue */
1022 bufLen = (MsgLen)rxArr[i].iov_len;
1023 if (msgLen < bufLen)
1027 ret = SUpdMsg(mBuf, dBufs[i], bufLen);
1045 /* cleanup unused buffers */
1048 #ifdef T2K_MEM_LEAK_DBG
1049 char * file = __FILE__;
1050 uint32_t line = __LINE__;
1051 SPutDBuf(info->region, info->pool, dBufs[i]);
1053 SPutDBuf(info->region, info->pool, dBufs[i]);
1059 } /* end of buildRecvMsg */
1065 * Fun: buildSendIovec
1067 * Desc: Builds a io vector to send a message.
1069 * Ret: ROK - successful
1071 * ROUTRES - failed, out of resources
1072 * RNA - failed, not available, indicates that the
1073 * maximum number of dBufs are not sufficient
1074 * to hold the entire message.
1081 static S16 buildSendIovec
1083 Buffer *mBuf, /* Message buffer */
1084 MsgLen msgLen, /* Length of mBuf */
1085 CmInetIovec txArr[], /* transmit scatter vector array */
1086 S16 numDBufs, /* Maximum number of dBufs to use */
1087 S16 *numIovElems, /* Number of iov elements in array */
1088 uint32_t *strtEndDBufNum, /* dBuf number to start and end */
1089 MsgLen *ioLen /* cm_inet_c_001.main_50 - Len of dbuf packed into IO-vector */
1098 uint32_t dBufsToSkip;
1100 /* Initialisations */
1105 /* cm_inet_c_001.main_50 - Intialize the newly added parameter */
1108 /* Set up vector for gathering send */
1109 ret = SInitNxtDBuf(mBuf);
1116 txArr[iovIdx].iov_len = 0;
1118 if ((*strtEndDBufNum != 0))
1120 /* Skip through the required number of dBufs */
1121 dBufsToSkip = *strtEndDBufNum;
1125 ret = SGetNxtDBuf(mBuf, &dBuf);
1134 ret = SGetNxtDBuf(mBuf, &dBuf);
1137 ret = SGetDataTx(dBuf, &dPtr, &dLen);
1144 txArr[iovIdx].iov_base = (S8 *)dPtr;
1145 txArr[iovIdx].iov_len = dLen;
1149 else if (ret == ROKDNA)
1162 if (iovIdx >= numDBufs)
1164 if (allocLen >= msgLen)
1172 (*numIovElems) = iovIdx;
1173 (*strtEndDBufNum) += iovIdx;
1175 /* cm_inet_c_001.main_50 - Assign the value of dbufs packed in IO-vector */
1180 } /* end of buildSendIovec */
1181 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
1188 * Desc: Creates an Internet socket descriptor.
1189 * On default the socket is non-blocking ( can be changed
1190 * with the function cmInetSetOpt()).
1193 * CM_INET_STREAM (TCP)
1194 * CM_INET_DGRAM (UDP)
1196 * Ret: ROK - successful
1205 #ifdef IPV6_SUPPORTED
1208 uint8_t type, /* socket type */
1209 CmInetFd *sockFd, /* socket file descriptor */
1210 uint8_t protocol, /* protocol value */
1211 uint8_t domain /* domain */
1216 uint8_t type, /* socket type */
1217 CmInetFd *sockFd, /* socket file descriptor */
1218 uint8_t protocol /* protocol value */
1220 #endif /* IPV6_SUPPORTED */
1221 #else /* CM_INET2 */
1224 uint8_t type, /* socket type */
1225 CmInetFd *sockFd /* socket file descriptor */
1227 #endif /* CM_INET2 */
1229 S32 ret; /* temporary return value */
1233 #if (defined(WIN32) && defined(WIN2K))
1236 #endif /* WIN2K && WIN32 */
1239 #if (defined(WIN32) && defined(WIN2K))
1241 bNewBehavior = FALSE;
1242 #endif /* WIN32 && WIN2K */
1246 #ifdef IPV6_SUPPORTED
1247 sockFd->fd = socket(domain, type, protocol);
1249 sockFd->fd = socket(AF_INET, type, protocol);
1250 #endif /* IPV6_SUPPORTED */
1251 #else /* CM_INET2 */
1252 sockFd->fd = socket(AF_INET, type, 0);
1253 #endif /* CM_INET2 */
1254 if (CM_INET_INV_SOCK_FD(sockFd))
1258 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1259 /* cm_inet_c_001.main_62:Warning fix */
1260 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%ld)\n",
1261 INET_ERR_CODE, sockFd->fd);
1262 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1264 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%d)\n",
1265 INET_ERR_CODE, sockFd->fd);
1266 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1267 #endif /*ALIGN_64BIT */
1268 #endif /* CMINETDBG */
1269 /* Set sockFd->fd to invalid socket */
1270 sockFd->fd = CM_INET_INV_SOCKFD;
1274 /* set socket type */
1275 sockFd->type = type;
1277 /* set socket protocol type (IPv4/IPv6) */
1278 #ifdef IPV6_SUPPORTED
1279 sockFd->protType = domain;
1280 #endif /* IPV6_SUPPORTED */
1282 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1284 if (protocol != IPPROTO_SCTP)
1287 /* set default options */
1288 optVal = CM_INET_OPT_DISABLE;
1289 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1292 ret = cmInetClose(sockFd);
1297 #ifndef CMINET_BSDCOMPAT
1298 optVal = CM_INET_OPT_ENABLE;
1299 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BSD_COMPAT, (Ptr)&optVal);
1302 ret = cmInetClose(sockFd);
1305 #endif /* CMINET_BSDCOMPAT */
1306 #endif /* SS_LINUX */
1308 #if (defined(WIN32) && defined(WIN2K))
1309 if(type == CM_INET_DGRAM)
1311 ret = WSAIoctl(sockFd->fd, SIO_UDP_CONNRESET, &bNewBehavior,
1312 sizeof(bNewBehavior), NULLP, 0, &bytesReturned,
1318 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1319 /* cm_inet_c_001.main_62:Warning fix */
1320 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%ld)\n",
1321 INET_ERR_CODE, sockFd->fd);
1322 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1324 /* cm_inet_c_001.main_62:Warning fix */
1325 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%d)\n",
1326 INET_ERR_CODE, sockFd->fd);
1327 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1328 #endif /*ALIGN_64BIT*/
1329 #endif /* CMINETDBG */
1330 ret = cmInetClose(sockFd);
1334 #endif /* WIN2K && WIN32 */
1335 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1338 #ifdef CM_LKSCTP_NONBLOCK
1341 /* cm_inet_c_001.main_47:if non-blocking SCTP socket compile time
1342 * * flag is set then even for kernel SCTP make the socket
1345 optVal = CM_INET_OPT_DISABLE;
1346 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1349 ret = cmInetClose(sockFd);
1353 #endif /* CM_LKSCTP_NONBLOCK ends */
1356 } /* end of cmInetSocket */
1363 * Desc: Binds a socket file descriptor to a local Internet
1366 * Ret: ROK - successful
1377 CmInetFd *sockFd, /* socket file descriptor */
1378 CmInetAddr *myAddr /* locale Internet address/port */
1381 S32 ret; /* temporary return value */
1382 struct sockaddr_in srcAddr; /* local Internet address/port */
1383 #ifdef IPV6_SUPPORTED
1384 struct sockaddr_in6 srcAddr6; /* local IPV6 address/port */
1387 #endif /* CMINETDBG */
1388 #endif /* IPV6_SUPPORTED */
1389 uint32_t sizeOfAddr; /* sizeof address passed to the bind call */
1390 CmInetSockAddr *sockAddrPtr;
1393 #if (ERRCLASS & ERRCLS_INT_PAR)
1394 /* error check on parameters */
1395 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1400 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1402 #ifdef IPV6_SUPPORTED
1403 if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1405 memset(&srcAddr6, 0, sizeof(srcAddr6));
1406 srcAddr6.sin6_family = AF_INET6;
1407 srcAddr6.sin6_port = CM_INET_HTON_UINT16(myAddr->u.ipv6Addr.port);
1408 CM_INET_COPY_IPV6ADDR(&srcAddr6.sin6_addr,
1409 &myAddr->u.ipv6Addr.ipv6NetAddr);
1410 sizeOfAddr = sizeof(struct sockaddr_in6);
1411 sockAddrPtr = (CmInetSockAddr *)&srcAddr6;
1415 memset(&srcAddr, 0, sizeof(srcAddr));
1416 srcAddr.sin_family = AF_INET;
1417 srcAddr.sin_port = CM_INET_HTON_UINT16(myAddr->u.ipv4Addr.port);
1418 srcAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(myAddr->u.ipv4Addr.address);
1419 sizeOfAddr = sizeof(struct sockaddr_in);
1420 sockAddrPtr = (CmInetSockAddr *)&srcAddr;
1423 memset(&srcAddr, 0, sizeof(srcAddr));
1424 srcAddr.sin_family = AF_INET;
1425 srcAddr.sin_port = CM_INET_HTON_UINT16(myAddr->port);
1426 srcAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(myAddr->address);
1427 sizeOfAddr = sizeof(struct sockaddr_in);
1428 sockAddrPtr = (CmInetSockAddr *)&srcAddr;
1429 #endif /* IPV6_SUPPORTED */
1431 ret = bind(sockFd->fd, sockAddrPtr, sizeOfAddr);
1432 if (ret == INET_ERR)
1435 #ifdef IPV6_SUPPORTED
1436 if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1437 port = myAddr->u.ipv6Addr.port;
1439 port = myAddr->u.ipv4Addr.port;
1441 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1442 /* cm_inet_c_001.main_62:Warning fix */
1443 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d),"
1444 " port(%d), sockFd->fd(%ld)\n",
1445 INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1446 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1448 /* cm_inet_c_001.main_62:Warning fix */
1449 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d),"
1450 " port(%d), sockFd->fd(%d)\n ",
1451 INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1452 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1453 #endif /*ALIGN_64BIT*/
1456 /* cm_inet_c_001.main_62:Warning fix */
1457 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%lx), port(%d),"
1458 "sockFd->fd(%ld)\n",
1459 INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1460 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1462 /* cm_inet_c_001.main_62:Warning fix */
1463 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%x), port(%d),"
1464 " sockFd->fd(%d)\n",
1465 INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1466 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1467 #endif /*ALIGN_64BIT*/
1468 #endif /* IPV6_SUPPORTED */
1469 #endif /* CMINETDBG */
1474 } /* end of cmInetBind */
1476 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1477 /* cm_inet_c_001.main_51 Added Ipv6 support to KSCtP implementation */
1481 * Fun: cmInetSctpBindx
1483 * Desc: Binds a SCTP socket file descriptor to local Internet
1486 * Ret: ROK - successful
1496 CmInetFd *sockFd, /* socket file descriptor */
1497 CmInetNetAddrLst *addrLst, /* local Internet address list */
1498 uint16_t port /* port number */
1501 S32 ret; /* temporary return value */
1504 uint32_t ipv4_array_size = 0;
1505 struct sockaddr_in addrs[CM_INET_NUM_NET_ADDR];
1506 #ifndef IPV6_SUPPORTED
1507 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1509 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1510 #endif /* IPV6_SUPPORTED */
1513 Data *tempAddrPtr = NULLP;
1515 uint32_t addresses_array_size = 0;
1516 #ifdef IPV6_SUPPORTED
1518 S8 *addrString = NULLP;
1519 uint32_t addrLen = 0;
1520 S8 ipv4Format[23] = "::ffff:";
1521 #endif /* SUN_KSCTP */
1523 uint32_t ipv6_array_size = 0;
1524 struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1525 #endif /* IPV6_SUPPORTED */
1526 struct sockaddr *sockAddrPtr = NULLP;
1527 uint32_t sockAddrLen = 0;
1529 #if (ERRCLASS & ERRCLS_INT_PAR)
1530 /* error check on parameters */
1531 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1537 if(addrLst->count > CM_INET_NUM_NET_ADDR)
1541 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1542 /* cm_inet_c_001.main_62:Warning fix */
1543 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1544 " sockFd->fd(%ld)\n",
1545 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1546 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);
1548 /* cm_inet_c_001.main_62:Warning fix */
1549 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1550 " sockFd->fd(%d)\n",
1551 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1552 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);
1553 #endif /*ALIGN_64BIT*/
1554 #endif /* CMINETDBG */
1557 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1559 memset(&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1560 #ifdef IPV6_SUPPORTED
1561 memset(&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1562 #endif /* IPV6_SUPPORTED */
1564 for (idx = 0; idx < addrLst->count; idx++)
1566 #ifdef IPV6_SUPPORTED
1567 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1569 ipv6_array_size += sizeof(struct sockaddr_in6);
1570 addresses_array_size += sizeof(struct sockaddr_in6);
1571 if (sockFd->protType == AF_INET)
1575 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1576 /* cm_inet_c_001.main_62:Warning fix */
1577 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1578 " sockFd->fd(%ld)\n", sockFd->fd);
1579 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1581 /* cm_inet_c_001.main_62:Warning fix */
1582 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1583 " sockFd->fd(%d)\n", sockFd->fd);
1584 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1585 #endif /*ALIGN_64BIT*/
1586 #endif /* CMINETDBG */
1590 addrs6[idx6].sin6_family = AF_INET6;
1591 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1592 CM_INET_COPY_IPV6ADDR((addrs6[idx6].sin6_addr.s6_addr), &(addrLst->addrs[idx].u.ipv6NetAddr));
1599 ipv6_array_size += sizeof(struct sockaddr_in6);
1600 addresses_array_size += sizeof(struct sockaddr_in6);
1601 if (sockFd->protType == AF_INET)
1605 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1606 /* cm_inet_c_001.main_62:Warning fix */
1607 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1608 " sockFd->fd(%ld)\n", sockFd->fd);
1609 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1611 /* cm_inet_c_001.main_62:Warning fix */
1612 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1613 " sockFd->fd(%d)\n", sockFd->fd);
1614 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1615 #endif /*ALIGN_64BIT*/
1616 #endif /* CMINETDBG */
1620 addrs6[idx6].sin6_family = AF_INET6;
1621 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1622 addrLst->addrs[idx].u.ipv4NetAddr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
1623 cmInetNtoa(addrLst->addrs[idx].u.ipv4NetAddr, &addrString);
1624 addrLen = cmStrlen((uint8_t*)addrString);
1625 memcpy((ipv4Format+7), addrString, addrLen);
1626 ipv4Format[7+addrLen] = '\0';
1627 cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
1630 ipv4_array_size += sizeof(struct sockaddr_in);
1631 addresses_array_size += sizeof(struct sockaddr_in);
1632 addrs[idx4].sin_family = AF_INET;
1633 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1634 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
1636 #endif /* SUN_KSCTP */
1639 ipv4_array_size += sizeof(struct sockaddr_in);
1640 addresses_array_size += sizeof(struct sockaddr_in);
1641 addrs[idx4].sin_family = AF_INET;
1642 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1643 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
1645 #endif /* IPV6_SUPPORTED */
1649 if(ipv4_array_size > 0)
1651 sockAddrPtr = (struct sockaddr*)address_array;
1652 sockAddrLen = sizeof(struct sockaddr_in);
1653 memcpy(address_array, addrs, ipv4_array_size);
1655 #ifdef IPV6_SUPPORTED
1658 sockAddrPtr = (struct sockaddr*)address_array;
1659 sockAddrLen = sizeof(struct sockaddr_in6);
1662 if(ipv6_array_size > 0)
1664 memcpy((address_array + ipv4_array_size), addrs6, ipv6_array_size);
1666 #endif /* IPV6_SUPPORTED */
1670 ret = bind(sockFd->fd, sockAddrPtr, sockAddrLen);
1671 if (ret == INET_ERR)
1676 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1677 /* cm_inet_c_001.main_62:Warning fix */
1678 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1679 " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1680 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1682 /* cm_inet_c_001.main_62:Warning fix */
1683 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1684 " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1685 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1686 #endif /*ALIGN_64BIT*/
1687 #endif /* CMINETDBG */
1691 if (addrLst->count > 1)
1693 if(((struct sockaddr*)address_array)->sa_family == AF_INET)
1695 tempAddrPtr = address_array + (sizeof(struct sockaddr_in));
1697 else if(((struct sockaddr*)address_array)->sa_family == AF_INET6)
1699 tempAddrPtr = address_array + (sizeof(struct sockaddr_in6));
1705 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1706 /* cm_inet_c_001.main_62:Warning fix */
1707 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1708 " sockFd->fd(%ld), error(%d), port(%d)\n ",
1709 INET_ERR_CODE, port, sockFd->fd);
1710 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1712 /* cm_inet_c_001.main_62:Warning fix */
1713 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1714 " sockFd->fd(%d), error(%d), port(%d)\n ",
1715 INET_ERR_CODE, port, sockFd->fd);
1716 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1717 #endif /*ALIGN_64BIT*/
1718 #endif /* CMINETDBG */
1722 ret = sctp_bindx(sockFd->fd, (Void*)tempAddrPtr, addrLst->count - 1, SCTP_BINDX_ADD_ADDR);
1726 ret = sctp_bindx(sockFd->fd, (struct sockaddr*)address_array, addrLst->count, SCTP_BINDX_ADD_ADDR);
1727 UNUSED(sockAddrPtr);
1728 UNUSED(sockAddrLen);
1730 if (ret == INET_ERR)
1734 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1735 /* cm_inet_c_001.main_62:Warning fix */
1736 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1737 " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1738 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1740 /* cm_inet_c_001.main_62:Warning fix */
1741 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1742 " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1743 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1744 #endif /*ALIGN_64BIT*/
1745 #endif /* CMINETDBG */
1754 * Fun: cmInetSctpConnectx
1756 * Desc: Establishes a sctp connection with remote addresses
1758 * Ret: ROK - successful
1766 S16 cmInetSctpConnectx
1768 CmInetFd *sockFd, /* socket file descriptor */
1769 CmInetNetAddr *primAddr, /* primary destination Internet address */
1770 CmInetNetAddrLst *addrLst, /* destination Internet address list */
1771 uint16_t port /* port number */
1776 /* cm_inet_c_001.main_46: Removed SS_LINUX flag */
1779 /* cm_inet_c_001.main_64: New variable used as an argument for sctp_connectx */
1780 #ifdef SCTP_CONNECTX_NEW
1781 uint32_t assocId = 0;
1783 uint32_t addresses_array_size = 0;
1785 struct sockaddr_in addrs[CM_INET_NUM_NET_ADDR];
1786 uint32_t ipv4_array_size = 0;
1788 #ifndef IPV6_SUPPORTED
1789 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1791 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1792 #endif /* IPV6_SUPPORTED */
1794 #ifdef IPV6_SUPPORTED
1796 S8 *addrString = NULLP;
1797 uint32_t addrLen = 0;
1798 S8 ipv4Format[23] = "::ffff:";
1799 CmInetIpAddr ipv4NetAddr;
1800 #endif /* SUN_KSCTP */
1802 struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1803 uint32_t ipv6_array_size = 0;
1804 #endif /* IPV6_SUPPORTED */
1806 uint32_t sockAddrLen = 0;
1807 #endif /* sockAddrLen */
1810 CmInetSockAddr *sockAddrPtr = NULLP;
1811 #endif /* SS_LINUX */
1812 #if (ERRCLASS & ERRCLS_INT_PAR)
1813 /* error check on parameters */
1814 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1815 (primAddr == NULLP))
1819 /* cm_inet_c_001.main_58 : Added check for addrLst to fix klockwork issue */
1820 if (addrLst == NULLP)
1824 /* cm_inet_c_001.main_46: Included check for no of address aginst max */
1825 if( addrLst->count > CM_INET_NUM_NET_ADDR )
1829 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1830 /* cm_inet_c_001.main_62:Warning fix */
1831 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1832 " sockFd->fd(%ld)\n",
1833 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1834 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1836 /* cm_inet_c_001.main_62:Warning fix */
1837 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1838 " sockFd->fd(%d)\n",
1839 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1840 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1841 #endif /*ALIGN_64BIT*/
1842 #endif /* CMINETDBG */
1845 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1848 memset(&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1849 #ifdef IPV6_SUPPORTED
1850 memset(&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1851 #endif /* IPV6_SUPPORTED */
1855 #ifdef IPV6_SUPPORTED
1856 if (primAddr->type == CM_INET_IPV6ADDR_TYPE)
1858 if (sockFd->protType == AF_INET)
1862 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1863 /* cm_inet_c_001.main_62:Warning fix */
1864 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1865 " sockFd->fd(%ld)\n", sockFd->fd);
1866 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
1868 /* cm_inet_c_001.main_62:Warning fix */
1869 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1870 " sockFd->fd(%d)\n", sockFd->fd);
1871 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
1872 #endif /*ALIGN_64BIT*/
1873 #endif /* CMINETDBG */
1877 addrs6[idx6].sin6_family = AF_INET6;
1878 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1879 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr), &(primAddr->u.ipv6NetAddr));
1880 addresses_array_size += sizeof(struct sockaddr_in6);
1881 ipv6_array_size += sizeof(struct sockaddr_in6);
1887 if (sockFd->protType == AF_INET)
1891 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1892 /* cm_inet_c_001.main_62:Warning fix */
1893 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
1894 " sockFd->fd(%ld)\n", sockFd->fd);
1895 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
1897 /* cm_inet_c_001.main_62:Warning fix */
1898 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
1899 " sockFd->fd(%d)\n", sockFd->fd);
1900 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
1901 #endif /*ALIGN_64BIT*/
1902 #endif /* CMINETDBG */
1905 addrs6[idx6].sin6_family = AF_INET6;
1906 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1907 ipv4NetAddr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1908 cmInetNtoa(ipv4NetAddr, &addrString);
1909 addrLen = cmStrlen((uint8_t*)addrString);
1910 memcpy((ipv4Format+7), addrString, addrLen);
1911 ipv4Format[7+addrLen] = '\0';
1912 cmInetPton6((CmInetIpAddr6*)&(addrs6[idx6].sin6_addr), ipv4Format);
1913 addresses_array_size += sizeof(struct sockaddr_in6);
1914 ipv6_array_size += sizeof(struct sockaddr_in6);
1917 addrs[idx4].sin_family = AF_INET;
1918 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1919 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1920 addresses_array_size += sizeof(struct sockaddr_in);
1921 ipv4_array_size += sizeof(struct sockaddr_in);
1926 addrs[idx4].sin_family = AF_INET;
1927 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1928 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1929 addresses_array_size += sizeof(struct sockaddr_in);
1930 ipv4_array_size += sizeof(struct sockaddr_in);
1932 #endif /* IPV6_SUPPORTED */
1936 /* cm_inet_c_001.main_46: Moved the SS_LINUX flag down,
1937 * copy addresses in Solaris also */
1938 if (addrLst != NULLP)
1940 for (idx = 0; idx < addrLst->count; idx++)
1943 /* cm_inet_c_001.main_46: Don't include the primary address
1944 * if its prersent in list */
1945 if ( addrLst->addrs[idx].type == CM_INET_IPV4ADDR_TYPE )
1947 if ( addrLst->addrs[idx].u.ipv4NetAddr == primAddr->u.ipv4NetAddr )
1952 #ifdef IPV6_SUPPORTED
1953 else if ( addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE )
1955 if (( cmMemcmp(addrLst->addrs[idx].u.ipv6NetAddr,
1956 primAddr->u.ipv6NetAddr, sizeof(CmInetIpAddr6) )) == 0 )
1962 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1964 if (sockFd->protType == AF_INET)
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, "Can't connect to IPV6 address through IPV4 socket,"
1971 " sockFd->fd(%ld)\n", sockFd->fd);
1972 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
1974 /* cm_inet_c_001.main_62:Warning fix */
1975 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1976 " sockFd->fd(%d)\n", sockFd->fd);
1977 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
1978 #endif /*ALIGN_64BIT*/
1979 #endif /* CMINETDBG */
1983 addrs6[idx6].sin6_family = AF_INET6;
1984 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1985 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr),
1986 &(addrLst->addrs[idx].u.ipv6NetAddr));
1987 addresses_array_size += sizeof(struct sockaddr_in6);
1988 ipv6_array_size += sizeof(struct sockaddr_in6);
1994 if (sockFd->protType == AF_INET)
1998 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1999 /* cm_inet_c_001.main_62:Warning fix */
2000 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2001 " sockFd->fd(%ld)\n", sockFd->fd);
2002 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2004 /* cm_inet_c_001.main_62:Warning fix */
2005 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2006 " sockFd->fd(%d)\n", sockFd->fd);
2007 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2008 #endif /*ALIGN_64BIT*/
2009 #endif /* CMINETDBG */
2012 addrs6[idx6].sin6_family = AF_INET6;
2013 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
2014 ipv4NetAddr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2015 cmInetNtoa(ipv4NetAddr, &addrString);
2016 addrLen = cmStrlen((uint8_t*)addrString);
2017 memcpy((ipv4Format+7), addrString, addrLen);
2018 ipv4Format[7+addrLen] = '\0';
2019 cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
2020 addresses_array_size += sizeof(struct sockaddr_in6);
2021 ipv6_array_size += sizeof(struct sockaddr_in6);
2024 addrs[idx4].sin_family = AF_INET;
2025 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
2026 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2027 addresses_array_size += sizeof(struct sockaddr_in);
2028 ipv4_array_size += sizeof(struct sockaddr_in);
2030 #endif /* SUN_KSCTP */
2033 addrs[idx4].sin_family = AF_INET;
2034 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
2035 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2036 addresses_array_size += sizeof(struct sockaddr_in);
2037 ipv4_array_size += sizeof(struct sockaddr_in);
2039 #endif /* IPV6_SUPPORTED */
2040 /*cm_inet_c_001.main_39 */
2045 /* cm_inet_c_001.main_46: Moved SS_LINUX flag to here */
2047 /*cm_inet_c_001.main_58 : Added check array_size to fix klockwork issue */
2048 if((ipv4_array_size > 0) && (ipv4_array_size <= (CM_INET_NUM_NET_ADDR * \
2049 sizeof(struct sockaddr_in))))
2051 memcpy(address_array, &addrs[0], ipv4_array_size);
2058 #ifdef IPV6_SUPPORTED
2059 if((ipv6_array_size > 0) && (ipv6_array_size <= (CM_INET_NUM_NET_ADDR * \
2060 sizeof(struct sockaddr_in))))
2062 memcpy((address_array + ipv4_array_size), addrs6, ipv6_array_size);
2068 #endif /* IPV6_SUPPORTED */
2070 /* cm_inet_c_001.main_64: Support for new definition of sctp_connectx */
2071 #ifndef SCTP_CONNECTX_NEW
2072 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt);
2074 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt, (sctp_assoc_t *)&assocId);
2079 /* cm_inet_c_001.main_46: Use next provided address to connect if
2080 * first one fails */
2082 #ifdef CMINET_SUN_CONNECTX
2084 #ifdef IPV6_SUPPORTED
2086 #endif /* IPV6_SUPPORTED */
2087 for (idx = 0; idx < cnt; idx++)
2089 if( addrs[idx4].sin_family == AF_INET)
2091 sockAddrPtr = (CmInetSockAddr *)&addrs[idx4];
2092 sockAddrLen = sizeof(struct sockaddr_in);
2095 #ifdef IPV6_SUPPORTED
2098 sockAddrPtr = (CmInetSockAddr *)&addrs6[idx6];
2099 sockAddrLen = sizeof(struct sockaddr_in6);
2102 #endif/* IPV6_SUPPORTED */
2104 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2106 if ( ret != INET_ERR )
2112 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2113 /* cm_inet_c_001.main_62:Warning fix */
2114 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2115 " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2116 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2118 /* cm_inet_c_001.main_62:Warning fix */
2119 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2120 " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2121 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2122 #endif /*ALIGN_64BIT*/
2123 #endif /* CMINETDBG */
2128 if( addrs[0].sin_family == AF_INET)
2130 sockAddrPtr = (CmInetSockAddr*)&addrs[0];
2131 sockAddrLen = sizeof(struct sockaddr_in);
2134 #ifdef IPV6_SUPPORTED
2137 sockAddrPtr = (CmInetSockAddr*)&addrs6[0];
2138 sockAddrLen = sizeof(struct sockaddr_in6);
2141 #endif/* IPV6_SUPPORTED */
2143 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2145 #endif /* CMINET_SUN_CONNECTX */
2146 #endif /* SS_LINUX */
2148 if (ret == INET_ERR)
2152 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2153 /* cm_inet_c_001.main_62:Warning fix */
2154 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2155 " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2156 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
2158 DU_LOG("\nCmInetSctpConnectx() Failed : error(%d), port(0x%1x),\
2159 sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2160 #endif /*ALIGN_64BIT*/
2161 #endif /* CMINETDBG */
2163 switch (INET_ERR_CODE)
2165 /* non-blocking: connection is in progress */
2166 case ERR_INPROGRESS:
2167 return (RINPROGRESS);
2171 * non-blocking: connection is established
2172 * blocking : connection is already established
2178 /* resource temporarily unavailable */
2179 case ERR_WOULDBLOCK:
2183 /* non-blocking: connection is in progress */
2185 return (RINPROGRESS);
2189 return (RINPROGRESS);
2192 /* Check for connection refused and timeout errors */
2193 case ERR_CONNREFUSED:
2198 /* it is a real error */
2210 * Fun: cmInetSctpPeelOff
2212 * Desc: Branches an existing sctp association off to a seperate socket
2214 * Ret: ROK - successful
2222 S16 cmInetSctpPeelOff
2224 CmInetFd *sockFd, /* socket file descriptor */
2225 uint32_t assocId, /* association id */
2226 CmInetFdType *assocFd /* association fd */
2231 #if (ERRCLASS & ERRCLS_INT_PAR)
2232 /* error check on parameters */
2233 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) || (assocFd == NULLP))
2237 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2240 ret = sctp_peeloff(sockFd->fd, assocId);
2241 if (ret == INET_ERR)
2245 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2246 /* cm_inet_c_001.main_62:Warning fix */
2247 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%ld),"
2248 " sockFd->fd(%ld)\n", INET_ERR_CODE, assocId, sockFd->fd);
2249 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2251 /* cm_inet_c_001.main_55: Fix for compilation warning */
2252 /* cm_inet_c_001.main_62:Warning fix */
2253 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%d),"
2254 " sockFd->fd(%d)\n", INET_ERR_CODE, assocId, sockFd->fd);
2255 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2256 #endif /*ALIGN_64BIT*/
2257 #endif /* CMINETDBG */
2269 * Fun: cmInetSctpSendMsg
2271 * Desc: invokes sctp socket API to send message to the remote addresses
2273 * Ret: ROK - successful
2281 S16 cmInetSctpSendMsg
2283 CmInetFd *sockFd, /* socket file descriptor */
2284 CmInetNetAddr *dstAddr, /* destination Internet address/port */
2285 uint16_t port, /* destination port no. */
2286 CmInetMemInfo *info, /* buffer allocation info */
2287 Buffer *mBuf, /* buffer structure to send */
2288 MsgLen *len, /* number of actually sent octets */
2289 uint16_t strmId, /* sctp stream identifier */
2290 Bool unorderFlg, /* flag to enable the unordered delivery */
2291 uint16_t ttl, /* time to live */
2292 uint32_t ppId, /* opaque value passed along with the message */
2293 uint32_t context /* value to be passed back, if error occurs */
2297 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2298 MsgLen msgLen = 0; /* message length */
2299 MsgLen bufLen = 0; /* send buffer length */
2300 Data *sendBuf = NULLP; /* plain send buffer */
2302 CmInetSockAddr *sockAddrPtr = NULLP;
2303 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2304 MsgLen sockAddrLen = 0;
2305 struct sockaddr_in addr ={0};
2306 #ifdef IPV6_SUPPORTED
2308 S8 *addrString = NULLP;
2309 uint32_t addrLen = 0;
2310 S8 ipv4Format[23] = "::ffff:";
2311 CmInetIpAddr ipv4NetAddr = {0};
2312 #endif /* SUN_KSCTP */
2313 struct sockaddr_in6 addr6 ={0};
2314 #endif /* IPV6_SUPPORTED */
2315 #if (ERRCLASS & ERRCLS_INT_PAR)
2316 /* error check on parameters */
2317 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd)
2318 || (info == NULLP) || (mBuf == NULLP) || (len == NULLP))
2322 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2325 memset(&addr, 0, sizeof(struct sockaddr_in));
2326 #ifdef IPV6_SUPPORTED
2327 memset(&addr6, 0, sizeof(struct sockaddr_in6));
2328 #endif /* IPV6_SUPPORTED */
2330 /* copy message to a flat buffer */
2331 ret = SFndLenMsg(mBuf, &bufLen);
2336 /* max message length is limited to control the memory usage */
2337 /* casting bufLen to avoid warnings */
2338 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
2342 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &sendBuf, bufLen);
2347 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
2348 if ((ret != ROK) || (msgLen != bufLen))
2350 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2354 if ( dstAddr != NULLP)
2356 #ifdef IPV6_SUPPORTED
2357 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
2359 if (sockFd->protType == AF_INET)
2361 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2364 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2365 /* cm_inet_c_001.main_62:Warning fix */
2366 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2367 " IPV4 socket, sockFd->fd(%ld)\n", sockFd->fd);
2368 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2370 /* cm_inet_c_001.main_62:Warning fix */
2371 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2372 " IPV4 socket, sockFd->fd(%d)\n", sockFd->fd);
2373 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2374 #endif /*ALIGN_64BIT*/
2375 #endif /* CMINETDBG */
2379 addr6.sin6_family = AF_INET6;
2380 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2381 CM_INET_COPY_IPV6ADDR(&addr6.sin6_addr.s6_addr, &dstAddr->u.ipv6NetAddr);
2382 sockAddrLen = sizeof(struct sockaddr_in6);
2383 sockAddrPtr = (CmInetSockAddr*)&addr6;
2389 if (sockFd->protType == AF_INET)
2393 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2394 /* cm_inet_c_001.main_62:Warning fix */
2395 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2396 " socket, sockFd->fd(%ld)\n", sockFd->fd);
2397 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2399 /* cm_inet_c_001.main_62:Warning fix */
2400 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2401 " socket, sockFd->fd(%d)\n", sockFd->fd);
2402 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2403 #endif /*ALIGN_64BIT*/
2404 #endif /* CMINETDBG */
2407 addr6.sin6_family = AF_INET6;
2408 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2409 ipv4NetAddr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2410 cmInetNtoa(ipv4NetAddr, &addrString);
2411 addrLen = cmStrlen((uint8_t*)addrString);
2412 memcpy((ipv4Format+7), addrString, addrLen);
2413 ipv4Format[7+addrLen] = '\0';
2414 cmInetPton6((CmInetIpAddr6*)(addr6.sin6_addr.s6_addr), ipv4Format);
2415 sockAddrLen = sizeof(struct sockaddr_in6);
2416 sockAddrPtr = (CmInetSockAddr*)&addr6;
2418 addr.sin_family = AF_INET;
2419 addr.sin_port = CM_INET_HTON_UINT16(port);
2420 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2421 sockAddrLen = sizeof(struct sockaddr_in);
2422 sockAddrPtr = (CmInetSockAddr*)&addr;
2423 #endif /* SUN_KSCTP */
2426 addr.sin_family = AF_INET;
2427 addr.sin_port = CM_INET_HTON_UINT16(port);
2428 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2429 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2430 sockAddrLen = (MsgLen)sizeof(struct sockaddr_in);
2431 sockAddrPtr = (CmInetSockAddr*)&addr;
2432 #endif /* IPV6_SUPPORTED */
2439 sockAddrPtr = (CmInetSockAddr*)&addr;
2441 /* cm_inet_c_001.main_58 : initialized sockAddrLen properly */
2442 #ifdef IPV6_SUPPORTED
2443 sockAddrLen = sizeof(struct sockaddr_in6);
2445 sockAddrLen = sizeof(struct sockaddr_in);
2449 /* Not validating the address, whether addr is a valid address or not */
2454 if (unorderFlg == TRUE)
2457 flags |= MSG_UNORDERED;
2460 flags |= SCTP_UNORDERED;
2463 /*cm_inet_c_001.main_54: converting ppid to network*/
2464 ppId = CM_INET_HTON_UINT32(ppId);
2465 ret = sctp_sendmsg(sockFd->fd, (Void*)sendBuf, bufLen,
2466 (struct sockaddr*)sockAddrPtr, (size_t)sockAddrLen,
2467 ppId, flags, strmId, ttl, context);
2468 if (ret == INET_ERR)
2470 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2473 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2474 /* cm_inet_c_001.main_62:Warning fix */
2475 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%ld),"
2476 " strmId(%u),sockFd->fd(%ld)\n",
2477 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2478 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2480 /* cm_inet_c_001.main_55: Fix for compilation warning */
2481 /* cm_inet_c_001.main_62:Warning fix */
2482 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%d),"
2483 " strmId(%u),sockFd->fd(%d)\n",
2484 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2485 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2486 #endif /*ALIGN_64BIT*/
2487 #endif /* CMINETDBG */
2489 if ((INET_ERR_CODE == ERR_AGAIN) || (INET_ERR_CODE == ERR_WOULDBLOCK))
2490 return (RWOULDBLOCK);
2491 else if (INET_ERR_CODE == ERR_PIPE)
2497 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2501 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2508 * Fun: cmInetSctpRecvMsg
2510 * Desc: invokes sctp API to get the message received at sctp socket
2512 * Ret: ROK - successful
2520 S16 cmInetSctpRecvMsg
2522 CmInetFd *sockFd, /* socket file descriptor */
2523 CmInetNetAddr *srcAddr, /* source Internet address/port */
2524 uint16_t *port, /* source port no. */
2525 CmInetMemInfo *meminfo, /* buffer allocation info */
2526 Buffer **mBuf, /* buffer structure received */
2527 MsgLen *len, /* number of octets received */
2528 CmInetSctpSndRcvInfo *sinfo, /* sctp send-receive info */
2529 uint32_t *flag, /* flags */
2530 CmInetSctpNotification *ntfy /* notification parameters */
2535 struct sctp_sndrcvinfo info;
2536 struct sockaddr_storage addr;
2537 struct sockaddr_in *pAddr = NULLP;
2538 #ifdef IPV6_SUPPORTED
2539 struct sockaddr_in6 *pAddr6 = NULLP;
2542 Data *recvbuf = NULLP;
2544 union sctp_notification *sctpNtfy = NULLP;
2545 /* cm_inet_c_001.main_46: Defined new variable to store length of data */
2548 #endif /* SS_LINUX */
2550 #if (ERRCLASS & ERRCLS_INT_PAR)
2551 /* error check on parameters */
2552 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
2553 (srcAddr == NULLP) || (port == NULLP) || (meminfo == NULLP) ||
2554 (mBuf == NULLP) || (len == NULLP) || (sinfo == NULLP) || (flag == NULLP))
2558 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2563 memset(ntfy, 0, sizeof(CmInetSctpNotification));
2565 buflen = CM_INET_MAX_MSG_LEN;
2567 /* allocate flat receive buffer */
2568 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, &recvbuf, buflen);
2572 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2573 /* cm_inet_c_001.main_62:Warning fix */
2574 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failed to allocate memory\n");
2575 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET065, 0, prntBuf);
2576 #endif /* CMINETDBG */
2580 addrlen = sizeof(struct sockaddr_storage);
2582 memset(&addr, 0, sizeof(struct sockaddr_storage));
2583 memset(&info, 0, sizeof(struct sctp_sndrcvinfo));
2585 ret = sctp_recvmsg(sockFd->fd, (Void *)recvbuf, (size_t)buflen,
2586 (struct sockaddr*)&addr, &addrlen, &info,
2588 if (ret == INET_ERR)
2591 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2594 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2595 /* cm_inet_c_001.main_62:Warning fix */
2596 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2597 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
2598 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2600 DU_LOG("\ncmInetSctpRecvMsg() Failed : error(%d), sockFd->fd(%d)", \
2601 INET_ERR_CODE, sockFd->fd);
2602 #endif /*ALIGN_64BIT*/
2603 #endif /* CMINETDBG */
2608 /* save the length of the received message */
2609 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2612 #ifdef IPV6_SUPPORTED
2613 if (addr.ss_family == AF_INET6)
2615 uint8_t ipv4Format[12] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff};
2616 pAddr6 = (struct sockaddr_in6*)&addr;
2617 *port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
2619 if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
2621 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2622 memcpy(&srcAddr->u.ipv4NetAddr, ((pAddr6->sin6_addr.s6_addr) + 12), sizeof(uint32_t));
2623 srcAddr->u.ipv4NetAddr = CM_INET_HTON_uint32_t(srcAddr->u.ipv4NetAddr);
2628 srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2629 CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr);
2634 pAddr = (struct sockaddr_in*)&addr;
2635 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2636 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2637 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2640 pAddr = (struct sockaddr_in*)&addr;
2641 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2642 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2643 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2644 #endif /* IPV6_SUPPORTED */
2646 /* fill sndrcv info */
2647 sinfo->stream = info.sinfo_stream;
2648 sinfo->ssn = info.sinfo_ssn;
2649 sinfo->flags = info.sinfo_flags;
2650 /*cm_inet_c_001.main_54: converting ppid to host*/
2651 sinfo->ppid = CM_INET_NTOH_UINT32(info.sinfo_ppid);
2652 sinfo->context = info.sinfo_context;
2653 sinfo->timetolive = info.sinfo_timetolive;
2654 sinfo->tsn = info.sinfo_tsn;
2655 sinfo->cumtsn = info.sinfo_cumtsn;
2656 sinfo->assocId = info.sinfo_assoc_id;
2658 /* fill message flags */
2660 if ((msgFlags & MSG_EOR) != 0)
2661 *flag |= CM_INET_SCTP_MSG_EOR;
2663 if ((msgFlags & MSG_NOTIFICATION) != 0)
2665 *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2668 sctpNtfy = (union sctp_notification*)recvbuf;
2670 ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2671 ntfy->header.nLen = sctpNtfy->sn_header.sn_length;
2673 switch(sctpNtfy->sn_header.sn_type)
2675 case SCTP_ASSOC_CHANGE:
2676 ntfy->header.nType = CM_INET_SCTP_ASSOC_CHANGE;
2677 switch(sctpNtfy->sn_assoc_change.sac_state)
2680 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2682 case SCTP_COMM_LOST:
2683 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2686 ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2688 case SCTP_SHUTDOWN_COMP:
2689 ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2691 case SCTP_CANT_STR_ASSOC:
2692 ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
2697 ntfy->u.assocChange.error = sctpNtfy->sn_assoc_change.sac_error;
2698 ntfy->u.assocChange.outStreams = sctpNtfy->sn_assoc_change.sac_outbound_streams;
2699 ntfy->u.assocChange.inStreams = sctpNtfy->sn_assoc_change.sac_inbound_streams;
2700 ntfy->u.assocChange.assocId = sctpNtfy->sn_assoc_change.sac_assoc_id;
2702 ntfy->u.assocChange.info = sctpNtfy->sn_assoc_change.sac_info;
2705 case SCTP_PEER_ADDR_CHANGE:
2706 ntfy->header.nType = CM_INET_SCTP_PEER_ADDR_CHANGE;
2707 switch(sctpNtfy->sn_paddr_change.spc_state)
2709 case SCTP_ADDR_AVAILABLE:
2710 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2712 case SCTP_ADDR_UNREACHABLE:
2713 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2715 case SCTP_ADDR_REMOVED:
2716 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2718 case SCTP_ADDR_ADDED:
2719 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2721 case SCTP_ADDR_MADE_PRIM:
2722 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2725 case SCTP_ADDR_CONFIRMED:
2726 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2733 #ifdef IPV6_SUPPORTED
2734 if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
2736 pAddr6 = (struct sockaddr_in6*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2737 ntfy->u.paddrChange.addr.type = CM_INET_IPV6ADDR_TYPE;
2738 CM_INET_COPY_IPV6ADDR(&ntfy->u.paddrChange.addr.u.ipv6NetAddr,
2739 &pAddr6->sin6_addr.s6_addr);
2743 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2744 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2745 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2748 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2749 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2750 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2751 #endif /* IPV6_SUPPORTED */
2753 ntfy->u.paddrChange.error = sctpNtfy->sn_paddr_change.spc_error;
2754 ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2756 case SCTP_REMOTE_ERROR:
2757 ntfy->header.nType = CM_INET_SCTP_REMOTE_ERROR;
2759 ntfy->u.remoteErr.error = sctpNtfy->sn_remote_error.sre_error;
2760 ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2762 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2763 datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2765 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__, meminfo->region, meminfo->pool, \
2766 &ntfy->u.remoteErr.data, datlen );
2769 ntfy->u.remoteErr.data = NULLP;
2772 memcpy(ntfy->u.remoteErr.data,\
2773 sctpNtfy->sn_remote_error.sre_data, datlen);
2776 case SCTP_SEND_FAILED:
2777 ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2779 ntfy->u.sndFailed.error = sctpNtfy->sn_send_failed.ssf_error;
2780 ntfy->u.sndFailed.assocId = sctpNtfy->sn_send_failed.ssf_assoc_id;
2782 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2783 datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2785 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__, meminfo->region, meminfo->pool, \
2786 &ntfy->u.sndFailed.data, datlen );
2789 ntfy->u.sndFailed.data = NULLP;
2792 memcpy(ntfy->u.sndFailed.data,\
2793 sctpNtfy->sn_send_failed.ssf_data, datlen );
2795 ntfy->u.sndFailed.info.stream = sctpNtfy->sn_send_failed.ssf_info.sinfo_stream;
2796 ntfy->u.sndFailed.info.ssn = sctpNtfy->sn_send_failed.ssf_info.sinfo_ssn;
2797 ntfy->u.sndFailed.info.flags = sctpNtfy->sn_send_failed.ssf_info.sinfo_flags;
2798 ntfy->u.sndFailed.info.ppid = sctpNtfy->sn_send_failed.ssf_info.sinfo_ppid;
2799 ntfy->u.sndFailed.info.context = sctpNtfy->sn_send_failed.ssf_info.sinfo_context;
2800 ntfy->u.sndFailed.info.timetolive = sctpNtfy->sn_send_failed.ssf_info.sinfo_timetolive;
2801 ntfy->u.sndFailed.info.tsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_tsn;
2802 ntfy->u.sndFailed.info.cumtsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_cumtsn;
2803 ntfy->u.sndFailed.info.assocId = sctpNtfy->sn_send_failed.ssf_info.sinfo_assoc_id;
2805 case SCTP_SHUTDOWN_EVENT:
2806 ntfy->header.nType = CM_INET_SCTP_SHUTDOWN_EVENT;
2808 ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2811 case SCTP_ADAPTION_INDICATION :
2814 case SCTP_ADAPTATION_INDICATION :
2816 ntfy->header.nType = CM_INET_SCTP_ADAPTATION_INDICATION;
2819 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
2820 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaption_event.sai_assoc_id;
2823 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
2824 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaptation_event.sai_assoc_id;
2827 case SCTP_PARTIAL_DELIVERY_EVENT:
2828 ntfy->header.nType = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
2830 ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
2831 ntfy->u.pdapiEvt.assocId = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
2839 /* get a message buffer */
2840 ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
2843 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2847 ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
2851 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2857 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2864 * Fun: cmInetSctpGetPAddrs
2866 * Desc: returns the list of peer addresses
2868 * Ret: ROK - successful
2876 S16 cmInetSctpGetPAddrs
2878 CmInetFd *sockFd, /* socket file descriptor */
2879 uint32_t assocId, /* association id */
2880 CmInetNetAddrLst *addrlst /* peer address list */
2883 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2886 uint8_t *byteAddress;
2887 struct sockaddr *peerAddrList;
2888 struct sockaddr_in *pAddr;
2889 #ifdef IPV6_SUPPORTED
2890 struct sockaddr_in6 *pAddr6;
2891 #endif /* IPV6_SUPPORTED */
2894 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
2896 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
2901 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2902 /* cm_inet_c_001.main_62:Warning fix */
2903 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2904 " sockFd->fd(%ld), assocId(%ld)\n",
2905 INET_ERR_CODE, sockFd->fd, assocId);
2906 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2908 /* cm_inet_c_001.main_55: Fix for compilation warning */
2909 /* cm_inet_c_001.main_62:Warning fix */
2910 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2911 " sockFd->fd(%d),assocId(%d)\n",
2912 INET_ERR_CODE, sockFd->fd, assocId);
2913 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2914 #endif /*ALIGN_64BIT*/
2915 #endif /* CMINETDBG */
2920 byteAddress = (uint8_t*)peerAddrList;
2921 for (idx = 0; idx < cnt; idx++)
2923 #ifdef IPV6_SUPPORTED
2925 if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
2927 if (sockFd->protType == AF_INET)
2931 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2932 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2933 " sockFd->fd(%ld)", sockFd->fd);
2934 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2936 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2937 " sockFd->fd(%d)", sockFd->fd);
2938 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2939 #endif /*ALIGN_64BIT*/
2940 #endif /* CMINETDBG */
2942 sctp_freepaddrs(peerAddrList);
2946 pAddr6 = (struct sockaddr_in6*)byteAddress;
2948 addrlst->addrs[idx].type = CM_INET_IPV6ADDR_TYPE;
2949 CM_INET_COPY_IPV6ADDR(&(addrlst->addrs[idx].u.ipv6NetAddr), &(pAddr6->sin6_addr.s6_addr));
2950 byteAddress += sizeof(struct sockaddr_in6);
2954 pAddr = (struct sockaddr_in*)byteAddress;
2955 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2956 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2957 byteAddress += sizeof(struct sockaddr_in);
2960 pAddr = (struct sockaddr_in*)byteAddress;
2961 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2962 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2963 byteAddress += sizeof(struct sockaddr_in);
2964 #endif /* IPV6_SUPPORTED */
2967 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2968 addrlst->count = (uint8_t)cnt;
2970 sctp_freepaddrs(peerAddrList);
2979 * Desc: invokes socket API to retrive specified socket options
2981 * Ret: ROK - successful
2991 CmInetFd *sockFd, /* socket file descriptor */
2992 uint32_t level, /* option level */
2993 uint32_t type, /* option type */
2994 Ptr value /* option value */
2998 struct sctp_status status;
2999 struct sctp_paddrinfo addrInfo;
3000 struct sockaddr_in *pAddr;
3001 #ifdef IPV6_SUPPORTED
3002 struct sockaddr_in6 *pAddr6;
3003 #endif /* IPV6_SUPPORTED */
3004 struct sctp_assocparams assocParams;
3005 /*cm_inet_c_001.main_40 Updated for the support of configurable RTO parameters,
3006 HBeat value Max retransmissions (Init, Path, Association)*/
3007 struct sctp_initmsg initMsg;
3008 struct sctp_rtoinfo rtoInfo;
3009 struct sctp_paddrparams addrParams;
3010 CmInetSctpStatus *pSctpStatus;
3011 CmInetSctpPeerAddrInfo *pPeerAddrInfo;
3012 CmInetSctpInitMsg *pInitMsg;
3013 CmInetSctpAssocParams *pAssocParams;
3014 CmInetSctpRtoInfo *pRtoInfo;
3015 CmInetSctpPeerAddrParams *pPeerAddrParams;
3016 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3020 #if (ERRCLASS & ERRCLS_INT_PAR)
3021 /* error check on parameters */
3022 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3026 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3030 case CM_INET_OPT_SCTP_GET_ASSOC_STA:
3031 pSctpStatus = (CmInetSctpStatus*)value;
3032 memset(&status, 0, sizeof(struct sctp_status));
3033 len = sizeof(status);
3034 status.sstat_assoc_id = pSctpStatus->assocId;
3036 ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
3038 pSctpStatus->rwnd = status.sstat_rwnd;
3039 pSctpStatus->unackdata = status.sstat_unackdata;
3040 pSctpStatus->penddata = status.sstat_penddata;
3041 pSctpStatus->instrms = status.sstat_instrms;
3042 pSctpStatus->outstrms = status.sstat_outstrms;
3043 pSctpStatus->fragPoint = status.sstat_fragmentation_point;
3045 switch (status.sstat_state)
3055 pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3062 pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3068 case SCTPS_COOKIE_WAIT:
3070 case SCTP_COOKIE_WAIT:
3073 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3078 case SCTPS_COOKIE_ECHOED:
3080 case SCTP_COOKIE_ECHOED:
3083 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3088 case SCTPS_ESTABLISHED:
3090 case SCTP_ESTABLISHED:
3093 pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3098 case SCTPS_SHUTDOWN_PENDING:
3100 case SCTP_SHUTDOWN_PENDING:
3103 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3108 case SCTPS_SHUTDOWN_SENT:
3110 case SCTP_SHUTDOWN_SENT:
3113 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3118 case SCTPS_SHUTDOWN_RECEIVED:
3120 case SCTP_SHUTDOWN_RECEIVED:
3123 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3128 case SCTPS_SHUTDOWN_ACK_SENT:
3130 case SCTP_SHUTDOWN_ACK_SENT:
3133 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3144 #ifdef IPV6_SUPPORTED
3145 if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3147 pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3148 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
3150 pSctpStatus->primary.addr.type = CM_INET_IPV6ADDR_TYPE;
3151 CM_INET_COPY_IPV6ADDR(&pSctpStatus->primary.addr.u.ipv6NetAddr,
3152 &pAddr6->sin6_addr.s6_addr);
3156 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3157 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3158 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3159 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3162 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3163 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3164 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3165 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3166 #endif /* IPV6_SUPPORTED */
3168 pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3169 if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3170 pSctpStatus->primary.isActive = TRUE;
3173 pSctpStatus->primary.isActive = FALSE;
3174 pSctpStatus->primary.cwnd = status.sstat_primary.spinfo_cwnd;
3175 pSctpStatus->primary.srtt = status.sstat_primary.spinfo_srtt;
3176 pSctpStatus->primary.rto = status.sstat_primary.spinfo_rto;
3177 pSctpStatus->primary.mtu = status.sstat_primary.spinfo_mtu;
3181 case CM_INET_OPT_SCTP_GET_PADDR_INFO:
3182 pPeerAddrInfo = (CmInetSctpPeerAddrInfo*)value;
3183 memset(&addrInfo, 0, sizeof(struct sctp_paddrinfo));
3184 len = sizeof(addrInfo);
3185 addrInfo.spinfo_assoc_id = pPeerAddrInfo->assocId;
3187 #ifdef IPV6_SUPPORTED
3188 if (pPeerAddrInfo->addr.type == CM_INET_IPV6ADDR_TYPE)
3190 if (sockFd->protType == AF_INET)
3194 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3195 /* cm_inet_c_001.main_62:Warning fix */
3196 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3197 " sockFd->fd(%ld)\n", sockFd->fd);
3198 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3200 /* cm_inet_c_001.main_62:Warning fix */
3201 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3202 " sockFd->fd(%d)\n", sockFd->fd);
3203 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3204 #endif /*ALIGN_64BIT*/
3205 #endif /* CMINETDBG */
3209 pAddr6 = (struct sockaddr_in6*)&(addrInfo.spinfo_address);
3210 pAddr6->sin6_family = AF_INET6;
3211 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3212 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrInfo->addr.u.ipv6NetAddr);
3216 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3217 pAddr->sin_family = AF_INET;
3218 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3219 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3222 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3223 pAddr->sin_family = AF_INET;
3224 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3225 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3226 #endif /* IPV6_SUPPORTED */
3228 /* Not validating the address, whether Addr is a valid address or not */
3230 ret = getsockopt(sockFd->fd, level, SCTP_GET_PEER_ADDR_INFO, &addrInfo, &len);
3232 if (addrInfo.spinfo_state == SCTP_ACTIVE)
3233 pPeerAddrInfo->isActive = TRUE;
3235 pPeerAddrInfo->isActive = FALSE;
3236 pPeerAddrInfo->cwnd = addrInfo.spinfo_cwnd;
3237 pPeerAddrInfo->srtt = addrInfo.spinfo_srtt;
3238 pPeerAddrInfo->rto = addrInfo.spinfo_rto;
3239 pPeerAddrInfo->mtu = addrInfo.spinfo_mtu;
3242 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
3244 pPeerAddrParams = (CmInetSctpPeerAddrParams *)value;
3246 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
3248 addrParams.spp_assoc_id = pPeerAddrParams->assocId;
3250 if (pPeerAddrParams->s.addrPres == TRUE)
3252 #ifdef IPV6_SUPPORTED
3253 if (pPeerAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
3255 if (sockFd->protType == AF_INET)
3259 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3260 /* cm_inet_c_001.main_62:Warning fix */
3261 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%ld)\n",
3263 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3265 /* cm_inet_c_001.main_62:Warning fix */
3266 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%d)\n",
3268 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3269 #endif /*ALIGN_64BIT*/
3270 #endif /* CMINETDBG */
3274 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
3275 pAddr6->sin6_family = AF_INET6;
3276 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3277 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrParams->s.addr.u.ipv6NetAddr);
3281 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3282 pAddr->sin_family = AF_INET;
3283 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3284 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3287 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3288 pAddr->sin_family = AF_INET;
3289 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3290 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3291 #endif /* IPV6_SUPPORTED */
3295 #ifdef IPV6_SUPPORTED
3296 if (sockFd->protType == AF_INET6)
3297 addrParams.spp_address.ss_family = AF_INET6;
3299 addrParams.spp_address.ss_family = AF_INET;
3301 addrParams.spp_address.ss_family = AF_INET;
3305 len = sizeof(addrParams);
3307 ret = getsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, &len);
3308 /* cm_inet_c_001.main_41 : Fixed the Solaris compilation problem */
3311 pPeerAddrParams->hbInterval = addrParams.spp_hbinterval;
3312 pPeerAddrParams->pathMaxRxt = addrParams.spp_pathmaxrxt;
3313 pPeerAddrParams->assocId = addrParams.spp_assoc_id;
3314 pPeerAddrParams->pathMtu = addrParams.spp_pathmtu;
3315 pPeerAddrParams->sackDelay = addrParams.spp_sackdelay;
3317 if (addrParams.spp_flags & SPP_HB_ENABLE)
3318 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_ENABLE;
3320 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_DISABLE;
3322 if (addrParams.spp_flags & SPP_PMTUD_ENABLE)
3323 pPeerAddrParams->pmtudFlag = CM_INET_OPT_ENABLE;
3325 pPeerAddrParams->pmtudFlag = CM_INET_OPT_DISABLE;
3327 if (addrParams.spp_flags & SPP_SACKDELAY_ENABLE)
3328 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_ENABLE;
3330 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_DISABLE;
3335 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
3337 pAssocParams = (CmInetSctpAssocParams *)value;
3339 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
3341 assocParams.sasoc_assoc_id = pAssocParams->assocId;
3343 len = sizeof(assocParams);
3345 ret = getsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, &len);
3347 pAssocParams->assocMaxReTx = assocParams.sasoc_asocmaxrxt;
3348 pAssocParams->cookieLife = assocParams.sasoc_cookie_life;
3349 pAssocParams->assocId = assocParams.sasoc_assoc_id;
3350 pAssocParams->numberOfPeerDest = assocParams.sasoc_number_peer_destinations;
3351 pAssocParams->peerRwnd = assocParams.sasoc_peer_rwnd;
3352 pAssocParams->localRwnd = assocParams.sasoc_local_rwnd;
3356 case CM_INET_OPT_SCTP_RTO_INFO:
3358 pRtoInfo = (CmInetSctpRtoInfo *)value;
3360 memset(&rtoInfo, 0, sizeof(struct sctp_rtoinfo));
3362 len = sizeof(rtoInfo);
3364 ret = getsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoInfo, &len);
3366 pRtoInfo->assocId = rtoInfo.srto_assoc_id;
3367 pRtoInfo->rtoInitial = rtoInfo.srto_initial;
3368 pRtoInfo->rtoMax = rtoInfo.srto_max;
3369 pRtoInfo->rtoMin = rtoInfo.srto_min;
3373 case CM_INET_OPT_SCTP_INIT_MSG:
3375 pInitMsg = (CmInetSctpInitMsg *)value;
3377 memset(&initMsg, 0, sizeof(struct sctp_initmsg));
3379 len = sizeof(initMsg);
3381 ret = getsockopt(sockFd->fd, level, SCTP_INITMSG, &initMsg, &len);
3383 pInitMsg->maxInitReTx = initMsg.sinit_max_attempts;
3384 pInitMsg->maxInitTimeout = initMsg.sinit_max_init_timeo;
3385 pInitMsg->numOstreams = initMsg.sinit_num_ostreams;
3386 pInitMsg->maxInstreams = initMsg.sinit_max_instreams;
3394 if (ret == INET_ERR)
3398 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3399 /* cm_inet_c_001.main_62:Warning fix */
3400 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3401 " error(%d), sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3402 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3404 /* cm_inet_c_001.main_62:Warning fix */
3405 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3406 " error(%d), sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3407 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3408 #endif /*ALIGN_64BIT*/
3409 #endif /* CMINETDBG */
3416 /* cm_inet_c_001.main_54: Added new function cmInetShutDownSctp()*/
3419 * Fun: cmInetShutDownSctp
3421 * Desc: Shutdown the SCTP association gracefully.
3423 * Ret: ROK - successful
3431 S16 cmInetShutDownSctp
3433 CmInetFd *sockFd /* socket file descriptor */
3436 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3438 struct sctp_sndrcvinfo sndRcvInfo;
3441 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3444 sndRcvInfo.sinfo_flags = MSG_EOF;
3446 sndRcvInfo.sinfo_flags = SCTP_EOF;
3449 /* Call the sctp_send with flag set to termiante the association */
3451 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3457 /* cm_inet_c_001.main_62:Warning fix */
3458 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%ld)\n",
3459 INET_ERR_CODE, sockFd->fd);
3460 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3462 /* cm_inet_c_001.main_62:Warning fix */
3463 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%d)\n",
3464 INET_ERR_CODE, sockFd->fd);
3465 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3466 #endif /*ALIGN_64BIT*/
3467 #endif /* CMINETDBG */
3475 /* cm_inet_c_001.main_61: Added new function cmInetAbortSctpAssoc()*/
3478 * Fun: cmInetAbortSctpAssoc
3480 * Desc: ABORT the association.
3482 * Ret: ROK - successful
3490 S16 cmInetAbortSctpAssoc
3492 CmInetFd *sockFd, /* socket file descriptor */
3493 UConnId assocId /* Association ID */
3497 struct sctp_sndrcvinfo sndRcvInfo;
3500 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3503 sndRcvInfo.sinfo_flags = MSG_ABORT;
3505 sndRcvInfo.sinfo_flags = SCTP_ABORT;
3508 sndRcvInfo.sinfo_assoc_id = assocId;
3510 /* Call the sctp_send with flag set to termiante the association */
3512 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3518 /* cm_inet_c_001.main_62:Warning fix */
3519 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%ld)\n",
3520 INET_ERR_CODE, sockFd->fd);
3521 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3523 /* cm_inet_c_001.main_62:Warning fix */
3524 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%d)\n",
3525 INET_ERR_CODE, sockFd->fd);
3526 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3527 #endif /*ALIGN_64BIT*/
3528 #endif /* CMINETDBG */
3541 * Fun: cmInetConnect
3543 * Desc: Establishs a connection to a foreign address (TCP) or associates
3544 * a UDP socket to a foreign address.
3546 * Ret: ROK - successful
3547 * ROKDNA - resource temporarily unavaiable
3548 * RINPROGRESS - connection is in progress (only non-blocking)
3549 * RISCONN - connection is established (only non-blocking)
3560 CmInetFd *sockFd, /* socket file descriptor */
3561 CmInetAddr *servAddr /* foreign Internet address/port */
3564 S32 ret; /* temporary return value */
3565 struct sockaddr_in dstAddr; /* foreign Internet address/port */
3566 #ifdef IPV6_SUPPORTED
3567 struct sockaddr_in6 dstAddr6; /* foreign Internet IPV6 address/port */
3570 #endif /* CMINETDBG */
3571 #endif /* IPV6_SUPPORTED */
3573 CmInetSockAddr *sockAddrPtr;
3576 #if (ERRCLASS & ERRCLS_INT_PAR)
3577 /* error check on parameters */
3578 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3579 (servAddr == NULLP))
3583 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3585 #ifdef IPV6_SUPPORTED
3586 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3588 memset(&dstAddr6, 0, sizeof(dstAddr6));
3589 dstAddr6.sin6_family = AF_INET6;
3590 dstAddr6.sin6_port = CM_INET_HTON_UINT16(servAddr->u.ipv6Addr.port);
3591 CM_INET_COPY_IPV6ADDR(&dstAddr6.sin6_addr,
3592 &servAddr->u.ipv6Addr.ipv6NetAddr);
3593 sizeOfAddr = sizeof(struct sockaddr_in6);
3594 sockAddrPtr = (CmInetSockAddr *)&dstAddr6;
3598 memset(&dstAddr, 0, sizeof(dstAddr));
3599 dstAddr.sin_family = AF_INET;
3600 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->u.ipv4Addr.port);
3601 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->u.ipv4Addr.address);
3602 sizeOfAddr = sizeof(struct sockaddr_in);
3603 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3606 memset(&dstAddr, 0, sizeof(dstAddr));
3607 dstAddr.sin_family = AF_INET;
3608 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->port);
3609 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->address);
3610 sizeOfAddr = sizeof(struct sockaddr_in);
3611 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3612 #endif /* IPV6_SUPPORTED */
3614 ret = connect(sockFd->fd, sockAddrPtr, sizeOfAddr);
3615 if (ret == INET_ERR)
3617 switch (INET_ERR_CODE)
3619 /* non-blocking: connection is in progress */
3620 case ERR_INPROGRESS:
3621 return (RINPROGRESS);
3625 * non-blocking: connection is established
3626 * blocking : connection is already established
3632 /* resource temporarily unavailable */
3633 case ERR_WOULDBLOCK:
3637 /* non-blocking: connection is in progress */
3639 return (RINPROGRESS);
3643 return (RINPROGRESS);
3646 /* Check for connection refused and timeout errors */
3647 case ERR_CONNREFUSED:
3652 /* it is a real error */
3655 #ifdef IPV6_SUPPORTED
3656 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3657 port = servAddr->u.ipv6Addr.port;
3659 port = servAddr->u.ipv4Addr.port;
3661 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3663 /* cm_inet_c_001.main_62:Warning fix */
3664 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3665 " addrtype(0x%x), port(0x%1x), sockFd->fd(%ld)\n",
3666 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3667 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3669 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3670 " addrtype(0x%x), port(0x%1x), sockFd->fd(%d)\n",
3671 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3672 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3673 #endif /*ALIGN_64BIT*/
3676 /* cm_inet_c_001.main_62:Warning fix */
3677 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%lx),"
3678 "port(0x%1x), sockFd->fd(%ld)\n", INET_ERR_CODE ,
3679 servAddr->address, servAddr->port, sockFd->fd);
3680 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3682 /* cm_inet_c_001.main_62:Warning fix */
3683 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%x),"
3684 "port(0x%x), sockFd->fd(%d)\n", INET_ERR_CODE ,
3685 servAddr->address, servAddr->port, sockFd->fd);
3686 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3687 #endif /*ALIGN_64BIT*/
3688 #endif /* IPV6_SUPPORTED */
3689 #endif /* CMINETDBG */
3696 } /* end of cmInetConnect */
3703 * Desc: Indicates the willingness of a socket to listen for incomming
3704 * connection requests.
3706 * Ret: ROK - successful
3709 * Notes: The backLog value has to be within 0..5
3717 CmInetFd *sockFd, /* socket file descriptor */
3718 S16 backLog /* max. number of outstandig connections 0..5 */
3721 S32 ret; /* temporary return value */
3724 #if (ERRCLASS & ERRCLS_INT_PAR)
3725 /* error check on parameters */
3726 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3727 (backLog < MIN_BACK_LOG) || (backLog > MAX_BACK_LOG))
3731 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3733 ret = listen(sockFd->fd, backLog);
3734 if (ret == INET_ERR)
3738 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3739 /* cm_inet_c_001.main_62:Warning fix */
3740 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3741 " sockFd->fd(%ld)\n", INET_ERR_CODE, backLog, sockFd->fd);
3742 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3744 /* cm_inet_c_001.main_62:Warning fix */
3745 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3746 " sockFd->fd(%d)\n", INET_ERR_CODE, backLog, sockFd->fd);
3747 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3748 #endif /*ALIGN_64BIT*/
3749 #endif /* CMINETDBG */
3754 } /* end of cmInetListen */
3761 * Desc: Accepts an incoming connection.
3762 * On default the new socket is non-blocking. The options can be
3763 * changed with the function cmInetSetOpt().
3765 * Ret: ROK - successful
3766 * ROKDNA - there is no connection present to accept (only
3778 CmInetFd *sockFd, /* socket file descriptor */
3779 CmInetAddr *fromAddr, /* calling Internet address/port */
3780 CmInetFd *newSockFd /* socket file descriptor for new connection*/
3783 S32 ret; /* temporary return value */
3784 S32 addrLen; /* address structure length */
3785 struct sockaddr_in *peerAddr; /* calling Internet address/port */
3786 #ifdef IPV6_SUPPORTED
3787 struct sockaddr_in6 *peerAddr6; /* calling Internet address/port */
3788 struct sockaddr_in6 sockAddr;
3790 CmInetSockAddr sockAddr;
3791 #endif /* IPV6_SUPPORTED */
3797 #if (ERRCLASS & ERRCLS_INT_PAR)
3798 /* error check on parameters */
3799 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3803 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3805 /* change CmInetSockAddr to sockAddr */
3806 addrLen = sizeof(sockAddr);
3809 #if ( defined(SUNOS) || defined(SS_LINUX))
3810 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3811 (socklen_t *)&addrLen);
3813 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3815 #endif /* SUNOS || SS_LINUX */
3817 /* cm_inet_c_001.main_58: Moved setting of protType below */
3819 if (CM_INET_INV_SOCK_FD(newSockFd))
3821 if (INET_ERR_CODE == ERR_WOULDBLOCK)
3823 /* no connection present to accept */
3830 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3831 /* cm_inet_c_001.main_62:Warning fix */
3832 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3833 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3834 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3836 /* cm_inet_c_001.main_62:Warning fix */
3837 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3838 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3839 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3840 #endif /*ALIGN_64BIT*/
3841 #endif /* CMINETDBG */
3847 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
3848 /* added for IPv6/IPv4 socket distinguishing */
3849 #ifdef IPV6_SUPPORTED
3850 if (addrLen == sizeof(struct sockaddr_in))
3851 newSockFd->protType = AF_INET;
3852 else if(addrLen == sizeof(struct sockaddr_in6))
3853 newSockFd->protType = AF_INET6;
3858 /* cm_inet_c_001.main_62:Warning fix */
3859 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%ld)\n", sockFd->fd);
3860 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3862 /* cm_inet_c_001.main_62:Warning fix */
3863 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%d)\n", sockFd->fd);
3864 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3865 #endif /*ALIGN_64BIT*/
3866 #endif /* CMINETDBG */
3869 #endif /* IPV6_SUPPORTED */
3871 /* set the new socket file descriptor type */
3872 newSockFd->type = CM_INET_STREAM;
3874 /* set default options for new socket file descriptor */
3875 optVal = CM_INET_OPT_DISABLE;
3876 ret = cmInetSetOpt(newSockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, &optVal);
3879 ret = cmInetClose(newSockFd);
3883 #ifdef IPV6_SUPPORTED
3884 memset(fromAddr, 0, sizeof(fromAddr));
3885 if (addrLen == sizeof(struct sockaddr_in))
3887 peerAddr = (struct sockaddr_in *)&sockAddr;
3888 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
3889 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3890 fromAddr->u.ipv4Addr.address =
3891 CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3893 else if (addrLen == sizeof(struct sockaddr_in6))
3895 peerAddr6 = (struct sockaddr_in6 *)&sockAddr;
3896 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
3897 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(peerAddr6->sin6_port);
3898 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
3899 &peerAddr6->sin6_addr);
3902 peerAddr = (struct sockaddr_in *)&sockAddr;
3903 fromAddr->port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3904 fromAddr->address = CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3905 #endif /* IPV6_SUPPORTED */
3907 } /* end of cmInetAccept */
3912 * Fun: cmInet4FillTos
3914 * Desc: This function inserts tos (into ancillary data) which
3915 * will be used to fill tos value in ip header in outgoing IP packet
3916 * when sending that packet using sendmsg()function.
3926 static S16 cmInet4FillTos
3928 uint8_t tos, /* tos value to be filled in ipheader */
3929 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
3930 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
3933 struct cmsghdr *tempHdr;
3940 /* cmsghdr struc will appear before data in the ancillary data object.
3941 * So put cmsghdr struc in flat buffer first. */
3943 /* cmsghdr struc points to flat buffer's starting address */
3944 tempHdr = (struct cmsghdr *)cmsgBuf;
3946 /* fill up level & type of cmsghdr structure */
3947 tempHdr->cmsg_level = IPPROTO_IPV6;
3948 tempHdr->cmsg_type = IP_TOS;
3949 (*(uint8_t*)CMSG_DATA(tempHdr)) = tos;
3950 len = CMSG_SPACE(sizeof tos);
3953 /* fill up the length of cmsghdr structure */
3954 tempHdr->cmsg_len = len;
3959 }/* end of cmInet4FillTos */
3962 * Fun: cmInetSendDscpMsg
3964 * Desc: Sends the message data hold by mBuf.
3965 * The len paramter gives the actual written octets. If the socket
3966 * is non-blocking this value can be differ from the mBuf length
3967 * because there was not enough transmit buffer space available. If
3968 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
3970 * Values for flag parameter:
3972 * CM_INET_NO_FLAG - no additional control flag
3974 * Ret: ROK - successful
3975 * RWOULDBLOCK - no or not entire mBuf sent because would block
3976 * ROUTRES - failed, out of resources
3977 * RCLOSED - connection was closed by the peer
3980 * Notes: The successful completion of a send call does not indicate that
3981 * the data has been successfully delivered!
3983 * This function does not free any sent buffers.
3990 S16 cmInetSendDscpMsg
3992 CmInetFd *sockFd, /* socket file descriptor */
3993 CmInetAddr *dstAddr, /* destination Internet address/port */
3994 CmInetMemInfo *info, /* buffer allocation info */
3995 Buffer *mBuf, /* buffer structure to send */
3996 MsgLen *len, /* number of actually sent octets */
3997 /* added for IPv6 ext hdr */
3998 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
3999 S16 flags /* additional control flags, unused */
4002 #if (defined(WIN32) || defined(CMINETFLATBUF))
4003 S32 ret =0; /* temporary return value */
4004 MsgLen msgLen =0; /* message length */
4005 MsgLen bufLen =0; /* send buffer length */
4006 Data *sendBuf =0; /* plain send buffer */
4008 S32 ret =0; /* temporary return value */
4009 S32 retVal =0; /* temporary return value */
4010 S16 i =0; /* loop index */
4011 CmInetIovec txArr[CM_INET_MAX_DBUF] = {{0}}; /* scatter vector */
4012 S16 numDBufs =0; /* number of dBufs in message */
4013 struct msghdr msg ={0}; /* sendmsg() message header */
4014 MsgLen msgLen =0; /* message length */
4015 uint32_t strtEndDBufNum =0; /* starting/ending DBuf number */
4016 MsgLen unSentLen =0; /* sent len */
4017 #ifdef IPV6_SUPPORTED
4018 uint32_t curMsgIdx =0; /* indx in cmsgData where to write an ext hdr */
4019 /* added for IPv6 ext hdr */
4020 #if (defined(SS_LINUX) || defined(_XPG4_2))
4021 /* alloc from stack for IPv6 ancill data */
4022 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA]= {0};
4023 #endif /* SS_LINUX || _XPG4_2 */
4025 uint32_t curMsgIdx =0; /* indx in cmsgData where to write an ext hdr */
4026 #if (defined(SS_LINUX) || defined(_XPG4_2))
4027 /* alloc from stack for IPv4 ancill data */
4028 uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA]={0};
4029 #endif /* SS_LINUX || _XPG4_2 */
4030 #endif /* IPV6_SUPPORTED */
4031 #endif /* WIN32 | CMINETFLATBUF */
4033 struct sockaddr_in remAddr ={0}; /* remote Internet address */
4034 #ifdef IPV6_SUPPORTED
4035 struct sockaddr_in6 remAddr6 = {0}; /* remote Internet address */
4036 #endif /* IPV8_SUPPORTED */
4037 CmInetSockAddr *sockAddrPtr = NULLP;
4038 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4039 uint32_t sizeOfAddr =0;
4041 /* cm_inet_c_001.main_50 - Added for partial send handling */
4042 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4043 #if (!defined(WIN32))
4050 #if (ERRCLASS & ERRCLS_INT_PAR)
4051 /* error check on parameters */
4052 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4053 (info == NULLP) || (len == NULLP))
4057 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4059 /* added for IPv6 ext hdr */
4060 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4061 #if (defined(SS_LINUX) || defined(_XPG4_2))
4062 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4063 #endif /* SS_LINUX || _XPG4_2 */
4065 #endif /* WIN32 | CMINETFLATBUF */
4067 msgLen = 0; /* need by CC to pass without warning */
4068 sockAddrPtr = NULLP;
4071 /* setup remote address */
4072 if (dstAddr != NULLP)
4074 #ifdef IPV6_SUPPORTED
4075 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4077 memset(&remAddr6, 0, sizeof(remAddr6));
4078 remAddr6.sin6_family = AF_INET6;
4079 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4080 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4081 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4082 sizeOfAddr = sizeof(remAddr6);
4083 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4087 memset(&remAddr, 0, sizeof(remAddr));
4088 remAddr.sin_family = AF_INET;
4089 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4090 remAddr.sin_addr.s_addr =
4091 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4092 sizeOfAddr = sizeof(remAddr);
4093 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4096 /* memset(&remAddr, 0, sizeof(remAddr)); */
4097 remAddr.sin_family = AF_INET;
4098 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4099 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4100 sizeOfAddr = sizeof(remAddr);
4101 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4102 #endif /* IPV6_SUPPORTED */
4105 #if (defined(WIN32) || defined(CMINETFLATBUF))
4106 /* copy message to a flat buffer */
4107 ret = SFndLenMsg(mBuf, &bufLen);
4112 /* max message length is limited to control the memory usage */
4113 /* casting bufLen to avoid warnings */
4114 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4118 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &sendBuf, bufLen);
4123 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4124 if ((ret != ROK) || (msgLen != bufLen))
4127 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4131 if (dstAddr == NULLP)
4133 /* VxWorks sendto has some problem
4134 * with connected UDP socket, use send */
4136 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4139 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4140 #endif /* end of SS_VW */
4143 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4145 #if (defined(SS_VW) && defined(SS_VW6_7))
4146 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4148 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4151 #endif /* end of SS_VW6_7 and SS_VW */
4153 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4154 sockAddrPtr, sizeOfAddr);
4157 if (ret == INET_ERR)
4160 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4162 if(INET_ERR_CODE == ERR_AGAIN)
4165 return (RWOULDBLOCK);
4168 /* Check for ERR_WOULDBLOCK */
4169 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4172 return (RWOULDBLOCK);
4177 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4178 /* cm_inet_c_001.main_62:Warning fix */
4179 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4180 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4181 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4183 /* cm_inet_c_001.main_62:Warning fix */
4184 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4185 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4186 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4187 #endif /*ALIGN_64BIT*/
4188 #endif /* CMINETDBG */
4190 /* cm_inet_c_001.main_37 network unreacheble error is added */
4191 /* check if network is reacheble*/
4192 if ((INET_ERR_CODE == ERR_NETUNREACH))
4194 return (RNETFAILED);
4198 /* Check if connection was closed */
4199 if ((INET_ERR_CODE == ERR_PIPE) ||
4200 (INET_ERR_CODE == ERR_CONNABORTED) ||
4201 (INET_ERR_CODE == ERR_CONNRESET))
4212 /* check if entire message could be sent */
4217 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4218 return (RWOULDBLOCK);
4222 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4224 #else /* end of Win NT/flat buffer specific part */
4225 ret = SFndLenMsg(mBuf, &msgLen);
4232 /* memset(&msg, 0, sizeof(msg)); */
4235 if (dstAddr != NULLP)
4238 msg.msg_name = (Void*)sockAddrPtr;
4241 msg.msg_name = (char *)sockAddrPtr;
4243 msg.msg_name = (caddr_t)sockAddrPtr;
4245 #endif /* SS_LINUX */
4246 msg.msg_namelen = sizeOfAddr;
4250 msg.msg_name = NULLP;
4251 msg.msg_namelen = 0;
4253 /* added defined(_XPG4_2) */
4254 #if (defined(SS_LINUX) || defined(_XPG4_2))
4255 msg.msg_control = NULLP;
4256 msg.msg_controllen = 0;
4258 msg.msg_accrights = 0;
4259 msg.msg_accrightslen = NULLP;
4260 #endif /* SS_LINUX */
4262 /* allocate scatter vector */
4263 numDBufs = CM_INET_MAX_DBUF;
4269 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV4ADDR_TYPE))
4270 if((ipHdrParams->u.hdrParmIpv4.tos.pres == TRUE)&& \
4271 (ipHdrParams->u.hdrParmIpv4.tos.val != 0))
4273 cmInet4FillTos(ipHdrParams->u.hdrParmIpv4.tos.val,
4274 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4275 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4276 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4278 /* if the sender wants to send Ipv6 exten. headers */
4279 #ifdef IPV6_OPTS_SUPPORTED
4280 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4283 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4285 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4286 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4288 #endif /* SS_LINUX */
4291 /* have to decide how to get the src addr to add in in6_pktinfo */
4292 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4294 cmInet6BuildSendPktinfo(
4295 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4296 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4299 #endif /* LOCAL_INTF */
4301 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4302 * cmsgData one by one. */
4304 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4305 /* build HBH ext header in cmsgData starting at indx 0 */
4306 cmInet6BuildSendHBHOpts(
4307 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4308 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4310 /* now copy the elements from the Destination Option array one by
4311 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4312 * which is the end of HBH hdr. */
4313 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4314 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4315 cmInet6BuildSendDestOpts(
4316 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4317 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4319 /* copy Route header to to the Flat Buffer cmsgData */
4320 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4321 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4322 cmInet6BuildSendRouteOpts(
4323 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4324 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4326 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4327 * will be the curMsgIdx */
4328 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4329 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4332 #endif /* IPV6_OPTS_SUPPORTED */
4334 /* Loop till all the data is sent or till the sendmsg call cannot send
4338 /* build the send vector */
4339 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4340 total length of the packed dbufs */
4341 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4342 &strtEndDBufNum, &ioLen);
4347 /* Incase of UDP/RAW messages call SCompressMsg. */
4348 if (sockFd->type != CM_INET_STREAM)
4350 /* Compress the message into a single dBuf */
4351 ret = SCompressMsg(mBuf);
4356 /* Rebuild the send vector */
4357 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4358 total length of the packed dbuf */
4359 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4360 &strtEndDBufNum, &ioLen);
4370 msg.msg_iov = txArr;
4377 if ( sockFd->fd >= 0xD001)
4378 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4380 ret = sendmsg(sockFd->fd, &msg, 0);
4383 ret = sendmsg(sockFd->fd, &msg, 0);
4385 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4386 if (ret == INET_ERR)
4388 if((INET_ERR_CODE == ERR_AGAIN) ||
4389 (INET_ERR_CODE == ERR_WOULDBLOCK))
4391 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4392 message was sent earlier */
4393 return (RWOULDBLOCK);
4397 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4398 /* cm_inet_c_001.main_62:Warning fix */
4399 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4400 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4401 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4403 /* cm_inet_c_001.main_62:Warning fix */
4404 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4405 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4406 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4407 #endif /*ALIGN_64BIT*/
4408 #endif /* CMINETDBG */
4410 /* cm_inet_c_001.main_37 network unreacheble error is added */
4411 /* check if network is reacheble or not */
4412 if ((INET_ERR_CODE == ERR_NETUNREACH))
4414 return (RNETFAILED);
4417 /* Check if connection was closed by the peer */
4418 if ((INET_ERR_CODE == ERR_PIPE) ||
4419 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4420 (INET_ERR_CODE == ERR_CONNABORTED))
4428 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4431 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4432 * to be sent, then return WOULDBLOCK
4435 return (RWOULDBLOCK);
4439 } while (*len < msgLen);
4440 #endif /* WIN32 | CMINETFLATBUF */
4444 } /* end of cmInetSendDscpMsg */
4448 * Fun: cmInetSendMsg
4450 * Desc: Sends the message data hold by mBuf.
4451 * The len paramter gives the actual written octets. If the socket
4452 * is non-blocking this value can be differ from the mBuf length
4453 * because there was not enough transmit buffer space available. If
4454 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4456 * Values for flag parameter:
4458 * CM_INET_NO_FLAG - no additional control flag
4460 * Ret: ROK - successful
4461 * RWOULDBLOCK - no or not entire mBuf sent because would block
4462 * ROUTRES - failed, out of resources
4463 * RCLOSED - connection was closed by the peer
4466 * Notes: The successful completion of a send call does not indicate that
4467 * the data has been successfully delivered!
4469 * This function does not free any sent buffers.
4478 CmInetFd *sockFd, /* socket file descriptor */
4479 CmInetAddr *dstAddr, /* destination Internet address/port */
4480 CmInetMemInfo *info, /* buffer allocation info */
4481 Buffer *mBuf, /* buffer structure to send */
4482 MsgLen *len, /* number of actually sent octets */
4483 /* added for IPv6 ext hdr */
4484 #ifdef IPV6_OPTS_SUPPORTED
4485 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4486 #endif /* IPV6_OPTS_SUPPORTED */
4487 S16 flags /* additional control flags, unused */
4490 #if (defined(WIN32) || defined(CMINETFLATBUF))
4491 S32 ret; /* temporary return value */
4492 MsgLen msgLen; /* message length */
4493 MsgLen bufLen; /* send buffer length */
4494 Data *sendBuf; /* plain send buffer */
4496 S32 ret; /* temporary return value */
4497 S32 retVal; /* temporary return value */
4498 S16 i; /* loop index */
4499 CmInetIovec txArr[CM_INET_MAX_DBUF] ={{0}}; /* scatter vector */
4500 S16 numDBufs; /* number of dBufs in message */
4501 struct msghdr msg; /* sendmsg() message header */
4502 MsgLen msgLen; /* message length */
4503 uint32_t strtEndDBufNum; /* starting/ending DBuf number */
4504 MsgLen unSentLen; /* sent len */
4505 #ifdef IPV6_SUPPORTED
4506 /* added for IPv6 ext hdr */
4507 #ifdef IPV6_OPTS_SUPPORTED
4508 uint32_t curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4509 #if (defined(SS_LINUX) || defined(_XPG4_2))
4510 /* alloc from stack for IPv6 ancill data */
4511 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA];
4512 #endif /* SS_LINUX || _XPG4_2 */
4513 #endif /* IPV6_OPTS_SUPPORTED */
4515 #if (defined(SS_LINUX) || defined(_XPG4_2))
4516 /* alloc from stack for IPv4 ancill data */
4517 /* uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA];*/
4518 #endif /* SS_LINUX || _XPG4_2 */
4519 #endif /* IPV6_SUPPORTED */
4520 #endif /* WIN32 | CMINETFLATBUF */
4522 struct sockaddr_in remAddr; /* remote Internet address */
4523 #ifdef IPV6_SUPPORTED
4524 struct sockaddr_in6 remAddr6; /* remote Internet address */
4525 #endif /* IPV8_SUPPORTED */
4526 CmInetSockAddr *sockAddrPtr;
4527 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4528 uint32_t sizeOfAddr;
4530 /* cm_inet_c_001.main_50 - Added for partial send handling */
4531 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4532 #if (!defined(WIN32))
4539 #if (ERRCLASS & ERRCLS_INT_PAR)
4540 /* error check on parameters */
4541 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4542 (info == NULLP) || (len == NULLP))
4546 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4548 /* added for IPv6 ext hdr */
4549 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4550 #if (defined(SS_LINUX) || defined(_XPG4_2))
4551 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4552 #endif /* SS_LINUX || _XPG4_2 */
4553 #ifdef IPV6_OPTS_SUPPORTED
4555 #endif /* IPV6_SUPPORTED */
4556 #endif /* WIN32 | CMINETFLATBUF */
4558 msgLen = 0; /* need by CC to pass without warning */
4559 sockAddrPtr = NULLP;
4562 /* setup remote address */
4563 if (dstAddr != NULLP)
4565 #ifdef IPV6_SUPPORTED
4566 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4568 memset(&remAddr6, 0, sizeof(remAddr6));
4569 remAddr6.sin6_family = AF_INET6;
4570 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4571 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4572 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4573 sizeOfAddr = sizeof(remAddr6);
4574 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4578 memset(&remAddr, 0, sizeof(remAddr));
4579 remAddr.sin_family = AF_INET;
4580 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4581 remAddr.sin_addr.s_addr =
4582 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4583 sizeOfAddr = sizeof(remAddr);
4584 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4587 /* memset(&remAddr, 0, sizeof(remAddr)); */
4588 remAddr.sin_family = AF_INET;
4589 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4590 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4591 sizeOfAddr = sizeof(remAddr);
4592 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4593 #endif /* IPV6_SUPPORTED */
4596 #if (defined(WIN32) || defined(CMINETFLATBUF))
4597 /* copy message to a flat buffer */
4598 ret = SFndLenMsg(mBuf, &bufLen);
4603 /* max message length is limited to control the memory usage */
4604 /* casting bufLen to avoid warnings */
4605 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4609 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &sendBuf, bufLen);
4614 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4615 if ((ret != ROK) || (msgLen != bufLen))
4618 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4622 if (dstAddr == NULLP)
4624 /* VxWorks sendto has some problem
4625 * with connected UDP socket, use send */
4627 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4630 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4631 #endif /* end of SS_VW */
4634 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4636 #if (defined(SS_VW) && defined(SS_VW6_7))
4637 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4639 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4642 #endif /* end of SS_VW6_7 and SS_VW */
4644 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4645 sockAddrPtr, sizeOfAddr);
4648 if (ret == INET_ERR)
4651 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4653 if(INET_ERR_CODE == ERR_AGAIN)
4656 return (RWOULDBLOCK);
4659 /* Check for ERR_WOULDBLOCK */
4660 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4663 return (RWOULDBLOCK);
4668 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4669 /* cm_inet_c_001.main_62:Warning fix */
4670 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4671 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4672 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4674 /* cm_inet_c_001.main_62:Warning fix */
4675 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4676 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4677 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4678 #endif /*ALIGN_64BIT*/
4679 #endif /* CMINETDBG */
4681 /* cm_inet_c_001.main_37 network unreacheble error is added */
4682 /* check if network is reacheble*/
4683 if ((INET_ERR_CODE == ERR_NETUNREACH))
4685 return (RNETFAILED);
4689 /* Check if connection was closed */
4690 if ((INET_ERR_CODE == ERR_PIPE) ||
4691 (INET_ERR_CODE == ERR_CONNABORTED) ||
4692 (INET_ERR_CODE == ERR_CONNRESET))
4703 /* check if entire message could be sent */
4708 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4709 return (RWOULDBLOCK);
4713 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4715 #else /* end of Win NT/flat buffer specific part */
4716 ret = SFndLenMsg(mBuf, &msgLen);
4723 /* memset(&msg, 0, sizeof(msg)); */
4726 if (dstAddr != NULLP)
4729 msg.msg_name = (Void*)sockAddrPtr;
4732 msg.msg_name = (char *)sockAddrPtr;
4734 msg.msg_name = (caddr_t)sockAddrPtr;
4736 #endif /* SS_LINUX */
4737 msg.msg_namelen = sizeOfAddr;
4741 msg.msg_name = NULLP;
4742 msg.msg_namelen = 0;
4744 /* added defined(_XPG4_2) */
4745 #if (defined(SS_LINUX) || defined(_XPG4_2))
4746 msg.msg_control = NULLP;
4747 msg.msg_controllen = 0;
4749 msg.msg_accrights = 0;
4750 msg.msg_accrightslen = NULLP;
4751 #endif /* SS_LINUX */
4753 /* allocate scatter vector */
4754 numDBufs = CM_INET_MAX_DBUF;
4761 /* if the sender wants to send Ipv6 exten. headers */
4762 #ifdef IPV6_OPTS_SUPPORTED
4763 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4766 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4768 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4769 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4771 #endif /* SS_LINUX */
4774 /* have to decide how to get the src addr to add in in6_pktinfo */
4775 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4777 cmInet6BuildSendPktinfo(
4778 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4779 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4782 #endif /* LOCAL_INTF */
4784 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4785 * cmsgData one by one. */
4787 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4788 /* build HBH ext header in cmsgData starting at indx 0 */
4789 cmInet6BuildSendHBHOpts(
4790 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4791 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4793 /* now copy the elements from the Destination Option array one by
4794 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4795 * which is the end of HBH hdr. */
4796 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4797 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4798 cmInet6BuildSendDestOpts(
4799 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4800 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4802 /* copy Route header to to the Flat Buffer cmsgData */
4803 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4804 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4805 cmInet6BuildSendRouteOpts(
4806 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4807 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4809 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4810 * will be the curMsgIdx */
4811 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4812 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4815 #endif /* IPV6_OPTS_SUPPORTED */
4817 /* Loop till all the data is sent or till the sendmsg call cannot send
4821 /* build the send vector */
4822 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4823 total length of the packed dbufs */
4824 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4825 &strtEndDBufNum, &ioLen);
4830 /* Incase of UDP/RAW messages call SCompressMsg. */
4831 if (sockFd->type != CM_INET_STREAM)
4833 /* Compress the message into a single dBuf */
4834 ret = SCompressMsg(mBuf);
4839 /* Rebuild the send vector */
4840 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4841 total length of the packed dbuf */
4842 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4843 &strtEndDBufNum, &ioLen);
4853 msg.msg_iov = txArr;
4860 if ( sockFd->fd >= 0xD001)
4861 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4863 ret = sendmsg(sockFd->fd, &msg, 0);
4866 ret = sendmsg(sockFd->fd, &msg, 0);
4868 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4869 if (ret == INET_ERR)
4871 if((INET_ERR_CODE == ERR_AGAIN) ||
4872 (INET_ERR_CODE == ERR_WOULDBLOCK))
4874 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4875 message was sent earlier */
4876 return (RWOULDBLOCK);
4880 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4881 /* cm_inet_c_001.main_62:Warning fix */
4882 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4883 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4884 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4886 /* cm_inet_c_001.main_62:Warning fix */
4887 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4888 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4889 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4890 #endif /*ALIGN_64BIT*/
4891 #endif /* CMINETDBG */
4893 /* cm_inet_c_001.main_37 network unreacheble error is added */
4894 /* check if network is reacheble or not */
4895 if ((INET_ERR_CODE == ERR_NETUNREACH))
4897 return (RNETFAILED);
4900 /* Check if connection was closed by the peer */
4901 if ((INET_ERR_CODE == ERR_PIPE) ||
4902 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4903 (INET_ERR_CODE == ERR_CONNABORTED))
4911 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4914 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4915 * to be sent, then return WOULDBLOCK
4918 return (RWOULDBLOCK);
4922 } while (*len < msgLen);
4923 #endif /* WIN32 | CMINETFLATBUF */
4927 } /* end of cmInetSendMsg */
4930 /* added new functions for IPv6 extension headers */
4931 #ifdef IPV6_OPTS_SUPPORTED
4935 * Fun: cmInet6BuildSendPktinfo
4937 * Desc: This function inserts src address (into ancillary data) which
4938 * will be used as the src addr in outgoing IP packet when sending
4939 * that packet using sendmsg()function.
4949 static S16 cmInet6BuildSendPktinfo
4951 CmInetIpAddr6 *srcAddr, /* src ip addr to set on outgoing packet */
4952 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
4953 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4954 uint8_t protType /* whether IPv4/IPv6 socket */
4957 struct cmsghdr *tempHdr;
4958 struct in6_pktinfo *ipv6Pktinfo;
4959 struct in6_addr lpBkAddr;
4965 lpBkAddr = in6addr_loopback;
4967 /* cmsghdr struc will appear before data in the ancillary data object.
4968 * So put cmsghdr struc in flat buffer first. */
4970 /* cmsghdr struc points to flat buffer's starting address */
4971 tempHdr = (struct cmsghdr *)cmsgBuf;
4973 /* fill up level & type of cmsghdr structure */
4974 if (protType == AF_INET6)
4976 tempHdr->cmsg_level = IPPROTO_IPV6;
4977 tempHdr->cmsg_type = IPV6_PKTINFO;
4980 else if(protType == AF_INET)
4982 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4983 /* cm_inet_c_001.main_62:Warning fix */
4984 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
4985 "protType(%d)\n", protType);
4986 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET025, 0, prntBuf);
4990 /* skip length of cmsghdr structure - 12 bytes */
4991 len += sizeof(struct cmsghdr);
4993 if(protType == AF_INET6)
4994 ipv6Pktinfo = (struct in6_pktinfo *)(cmsgBuf + len);
4998 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4999 /* cm_inet_c_001.main_62:Warning fix */
5000 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5001 "protType(%d)\n", protType);
5002 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET026, 0, prntBuf);
5006 /* insert the hoplimit. This will override the kernel's
5007 * default hoplimit value */
5008 if(protType == AF_INET6)
5010 /* store ipv6 src addr */
5011 memcpy(&(ipv6Pktinfo->ipi6_addr), srcAddr, 16);
5014 /* store interface index */
5015 /* 0 is invalid intf indx it tells kernel to chose any intf it likes to
5016 * send this pkt. if we use nozero intf indx then kernel will send this
5017 * pkt only through that intf */
5018 ipv6Pktinfo->ipi6_ifindex = 0;
5022 else if(protType == AF_INET)
5024 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5025 /* cm_inet_c_001.main_62:Warning fix */
5026 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5027 "protType(%d)\n", protType);
5028 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET027, 0, prntBuf);
5032 /* fill up the length of cmsghdr structure */
5033 tempHdr->cmsg_len = len;
5038 }/* end of cmInet6BuildSendPktinfo */
5039 #endif /* LOCAL_INTF */
5045 * Fun: cmInetBuildSendHoplimit
5047 * Desc: This function inserts hoplimit value to be sent out by ancillary
5048 * data by calling sendmsg()function.
5058 static S16 cmInetBuildSendHoplimit
5060 uint32_t hoplimit, /* the hoplimit value to be set on outgoing packet */
5061 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5062 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5065 struct cmsghdr *tempHdr;
5071 /* cmsghdr struc will appear before data in the ancillary data object.
5072 * So put cmsghdr struc in flat buffer first. */
5074 /* cmsghdr struc points to flat buffer's starting address */
5075 tempHdr = (struct cmsghdr *)cmsgBuf;
5077 /* fill up level & type of cmsghdr structure */
5078 tempHdr->cmsg_level = IPPROTO_IPV6;
5079 tempHdr->cmsg_type = IPV6_HOPLIMIT;
5081 /* skip cmsghdr struc (length of cmsghdr structure) */
5082 len += sizeof(struct cmsghdr);
5084 /* insert the hoplimit. This will override the kernel's
5085 * default hoplimit value */
5086 *(cmsgBuf + len) = hoplimit;
5087 len += sizeof(hoplimit);
5089 /* fill up the length of cmsghdr structure */
5090 tempHdr->cmsg_len = len;
5094 } /* end of cmInetBuildSendHoplimit */
5095 #endif /* SS_LINUX */
5100 * Fun: cmInet6BuildSendHBHOpts
5102 * Desc: This function builds the HopByHop option which will be put
5103 * in the data portion of the ancillary data object. To build
5104 * the HopByHop option this function takes an array of
5105 * individual HopByHop option and fill them in a flat buffer.
5106 * cmsghdr struc always appear before HopBYHop Options, Dest
5107 * Options and Route header option.
5109 * The address of the flat Buffer *cmsgBuf is passed to this
5110 * function from cmInetSendMsg. This buffer will have all extension
5111 * headers. This buffer is passed as ancillary data by sendmsg()
5115 * Notes: This function will also be used for Destination options
5121 static S16 cmInet6BuildSendHBHOpts
5123 CmInetIpv6HBHHdrArr *hbhOptsArr,/* IPv6 extensions headers HBH/Dest opts */
5124 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5125 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5126 uint8_t hdrId /* 0: HBH hdr, 1:Dest Hdr */
5129 struct cmsghdr *tempHdr;
5137 /* cmsghdr struc will appear before data in the ancillary data object.
5138 * So put cmsghdr struc in flat buffer first. */
5140 /* cmsghdr struc points to flat buffer's starting address */
5141 tempHdr = (struct cmsghdr *)cmsgBuf;
5143 /* fill up level & type of cmsghdr structure */
5146 tempHdr->cmsg_level = IPPROTO_IPV6;
5147 tempHdr->cmsg_type = IPV6_HOPOPTS;
5149 else if (hdrId == 1)
5151 tempHdr->cmsg_level = IPPROTO_IPV6;
5152 tempHdr->cmsg_type = IPV6_DSTOPTS;
5155 /* skip cmsghdr struc (length of cmsghdr structure) */
5156 len += (sizeof(tempHdr->cmsg_level) + sizeof(tempHdr->cmsg_len) +
5157 sizeof(tempHdr->cmsg_type));
5159 /* Next Hdr: will be fill up accordingly by Kernel */
5160 *(cmsgBuf + len) = 0x00;
5163 /* Header Ext Length: will be fill up by us. In units of 8-byte excluding
5164 * first 8 bytes starting from Next Header field. */
5165 *(cmsgBuf + len) = 0x00;
5168 /* fillup all HBH/dest options' TLV. Here, we assume that all the HBH/dest
5169 * options are packed inside 1 HBH option header. */
5170 for (optsIdx = 0; optsIdx < hbhOptsArr->numHBHOpts;
5173 /* Copy the TLV into cmsgBuf data portion */
5174 /* copy type field of every HBH/dest option */
5175 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].type;
5176 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].type);
5178 /* copy length field of every HBH/dest option */
5179 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].length;
5180 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].length);
5182 /* copy all value bytes of current HBH/dest option to the flat buffer */
5183 memcpy((cmsgBuf + len),
5184 (hbhOptsArr->hbhOpts[optsIdx].value),
5185 hbhOptsArr->hbhOpts[optsIdx].length);
5186 len += hbhOptsArr->hbhOpts[optsIdx].length;
5189 /* cuMsgIdx will have the total length of HBH options array */
5190 /* add this length to the length of cmsgHdr struc */
5192 /* Padding: Different header has different padding requirement(xn+y). For
5193 * HBH Router Alert we need 2 bytes of padding. As this same function is
5194 * used for Destination option also and there is no option for it is yet
5195 * proposed, we are passing padN options - 6 bytes to make the Dest Option
5196 * hdr a multiple of 8 bytes. */
5198 /* HBH: padN of 2 bytes needed for Router Alert */
5199 /* This logic is present currently to support router alert which is the
5200 * only supported HBH option today. For other, generic method needed */
5203 *(cmsgBuf + len) = 0x01;
5205 *(cmsgBuf + len) = 0x00;
5209 /* fill up the length of cmsghdr structure */
5210 tempHdr->cmsg_len = len;
5214 } /* end of cmInet6BuildSendHBHOpts */
5219 * Fun: cmInet6BuildSendRouteOpts
5221 * Desc: This function transfers bytes from the Route hdr array to the
5222 * flat buffer. First the top cmsghdr structure will be filled in
5223 * the flat buffer, then route hdr type 0 will be added after
5224 * cmsghdr struc in the flat buffer. Then all IPV6 addresses will
5235 static S16 cmInet6BuildSendRouteOpts
5237 CmInetIpv6RtHdr *rtOptsArr, /* IPv6 destination options array */
5238 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5239 uint32_t *curMsgIdx /* idx in cmsgBuf where to start building RT hdr */
5242 struct cmsghdr *tempHdr;
5243 CmInetIpv6RtHdr0 *tempRtHdr;
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 */
5255 tempHdr = (struct cmsghdr *)(cmsgBuf);
5257 tempHdr->cmsg_level = IPPROTO_IPV6;
5258 tempHdr->cmsg_type = IPV6_RTHDR;
5260 /* skip cmsghdr structure */
5261 len += sizeof(struct cmsghdr);
5263 /* we know the total size of Route hdr if we know the num of ipv6 addrs */
5264 tempHdr->cmsg_len = len + sizeof(CmInetIpv6RtHdr0)
5265 + rtOptsArr->numAddrs * sizeof(CmInetIpAddr6);
5267 /* attach route hdr type 0 after cmsghdr structure */
5268 tempRtHdr = (CmInetIpv6RtHdr0 *)(cmsgBuf + len);
5270 /* fill up fields of route hdr type 0 */
5272 /* will be filled up by Kernel */
5273 tempRtHdr->ip6r0_nextHdr = 0x00;
5275 tempRtHdr->ip6r0_hdrExtLen = (2 * rtOptsArr->numAddrs);
5277 /* only type supported today */
5278 tempRtHdr->ip6r0_type = 0x00;
5280 tempRtHdr->ip6r0_segLeft = rtOptsArr->numAddrs;
5282 /* Note: rfc 2292(1998) mentions 1 reserve byte & 3 strict/loose bytes
5283 * restricting total 23 ipv6 addresses can be added to the route header.
5284 * But rfc 2292(2002) mentions all 4 bytes are reserved which allows
5285 * as many ipv6 addresses as wishes to be added to the route header */
5287 tempRtHdr->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5289 /* move pointer in the flat buffer to the end of this structure */
5290 len += sizeof(CmInetIpv6RtHdr0);
5292 /* fill up all IPV6 addresses from rtOptsArr in the flat buffer */
5293 for (addrIdx = 0; addrIdx < rtOptsArr->numAddrs; addrIdx++)
5295 memcpy((cmsgBuf + len),
5296 (rtOptsArr->ipv6Addrs[addrIdx]), 16);
5302 } /* end of cmInet6BuildSendRouteOpts */
5307 * Fun: cmInet6BuildRecvHopOptsArr
5309 * Desc: This function fills up the HopByHop Array of ipHdrParam from
5310 * the ancillary data received through recvmsg() call. The memory
5311 * to hold the extension headers is allocated here. All received
5312 * ext hdr info will be passed to upper user as ipHdrParam.
5314 * Ret: ROK - successful
5323 static S16 cmInet6BuildRecvHopOptsArr
5325 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5326 uint32_t hbhDataLen, /* byte len of cmsghdr + hbh ancil data */
5327 CmInetIpv6HBHHdrArr *hbhOptsArr, /* IPv6 extensions headers */
5328 uint8_t hdrId, /* 0: HBH, 1: DEST */
5329 CmInetMemInfo *info /* Memory information */
5332 uint32_t curDataIdx; /* to keep track where we are in the hbh Data */
5333 uint8_t optsIdx; /* how many hbh opts present in data */
5334 uint8_t numOpts; /* number of hbh opts present in data */
5340 /* get length of actual hbh ancillary data */
5341 hbhDataLen -= sizeof(struct cmsghdr);
5347 /* skip Next Hdr byte & Hdr Ext Length byte */
5350 /* First find out how many hop-by-hop headers we need to allocate */
5353 /* break when all HBH data is copied to hbhOptsArr */
5354 if (curDataIdx >= hbhDataLen)
5360 tempType = *(uint8_t *)(cmsgData + curDataIdx);
5363 /* take care of pad1 option */
5366 /* not considering the pad1 as valid option */
5372 tempLen = *(uint8_t *)(cmsgData + curDataIdx);
5374 /* 1 is to skip length. tempLen to skip the value field */
5375 curDataIdx += (1 + tempLen);
5377 /* considering the padN as valid option for Dest Opt Hdr!!! As this is
5378 * the "only" valid option today. Ignore for HBH hdr */
5384 /* allocate mem needed to hold all HBH/Dest options */
5385 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5386 (Data **)&hbhOptsArr->hbhOpts,
5387 (Size)((sizeof(CmInetIpv6HBHHdr)) * numOpts));
5391 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5392 /* cm_inet_c_001.main_62:Warning fix */
5393 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvHopOptsArr\n");
5394 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET028, 0, prntBuf);
5395 #endif /* CMINETDBG */
5402 /* skip Next Hdr byte & Hdr Ext Length byte */
5405 hbhOptsArr->numHBHOpts = numOpts;
5407 /* fill up HBH/dest opt array from recvd ancillary data */
5410 /* break when all HBH data is copied to hbhOptsArr */
5411 if (curDataIdx >= hbhDataLen)
5414 /* only copy Router Alert HBH option part which has type 5. Otherwise,
5415 * skip it when it is a PAD1, PADN or Jumbogram option for HBH. But
5416 * consider padN as valid option for dest opt hdr. */
5418 /* get the type of current HBH/dest option */
5419 tempType = *(cmsgData + curDataIdx);
5422 /* ignore PAD1 for both HBH/dest by skipping to next option */
5426 /* calculate how much to skip for padN in case of HBH */
5431 /* get the length field of padN option */
5432 tempLen = *(cmsgData + curDataIdx);
5435 /* move pointer forward to skip value field */
5436 curDataIdx += tempLen;
5440 hbhOptsArr->hbhOpts[optsIdx].type = tempType;
5442 /* copy the length */
5443 hbhOptsArr->hbhOpts[optsIdx].length = *(cmsgData + curDataIdx);
5446 /* take care of PADN = 2 when value field empty. We also don't need
5447 * to allocate memory for empty value field */
5448 if (hbhOptsArr->hbhOpts[optsIdx].length == 0)
5449 hbhOptsArr->hbhOpts[optsIdx].value = NULLP;
5452 /* take care of all other options having valid value field
5453 * such as Router Alert, PADN >= 3 bytes and Jumbo */
5454 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5455 (Data **)&hbhOptsArr->hbhOpts[optsIdx].value,
5456 (Size)hbhOptsArr->hbhOpts[optsIdx].length);
5460 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5461 /* cm_inet_c_001.main_62:Warning fix */
5462 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 2 cmInet6BuildRecvHopOptsArr\n");
5463 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET029, 0, prntBuf);
5464 #endif /* CMINETDBG */
5465 /* now go inside every separate HBH option and free the memory
5466 * allocated for its value field */
5467 for (; optsIdx > 0; optsIdx --)
5469 if (hbhOptsArr->hbhOpts[optsIdx - 1].value != NULLP)
5472 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5473 /* cm_inet_c_001.main_62:Warning fix */
5474 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 1 in BuildRecvHopOptsArr\n");
5475 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET030, 0, prntBuf);
5476 #endif /* CMINETDBG */
5477 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5478 (Data *)hbhOptsArr->hbhOpts[optsIdx - 1].value,
5479 (Size)hbhOptsArr->hbhOpts[optsIdx - 1].length);
5482 /* clean up all CmInetIpv6HBHHdr structures allocated for all
5483 * arrived HBH options OR numOpts CmInetIpv6HBHHdr structures
5484 * allocated after counting numOpts */
5486 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5487 /* cm_inet_c_001.main_62:Warning fix */
5488 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 2 in BuildRecvHopOptsArr\n");
5489 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET031, 0, prntBuf);
5490 #endif /* CMINETDBG */
5491 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5492 (Data *)hbhOptsArr->hbhOpts, numOpts * sizeof(CmInetIpv6HBHHdr));
5493 hbhOptsArr->numHBHOpts = 0;
5494 hbhOptsArr->hbhOpts = NULLP;
5497 /* copy the value bytes */
5498 memcpy(hbhOptsArr->hbhOpts[optsIdx].value,
5499 (cmsgData + curDataIdx),
5500 hbhOptsArr->hbhOpts[optsIdx].length);
5501 curDataIdx += hbhOptsArr->hbhOpts[optsIdx].length;
5504 /* get next option */
5508 } /* end of cmInet6BuildRecvHopOptsArr() */
5513 * Fun: cmInet6BuildRecvRtHdr
5515 * Desc: This function fills up the Route Header in the cmInetIpv6HdrParm
5516 * from the recvd ancillary data from recvmsg system call.
5518 * Ret: ROK - successful
5527 static S16 cmInet6BuildRecvRtHdr
5529 uint8_t *cmsgData, /* flat buffer where to build Route hdr */
5530 uint32_t rtDataLen, /* byte len of cmsghdr struc+rtHdr ancil data */
5531 CmInetIpv6RtHdr0 *rtHdr0, /* rtHeader0 struct that precedes IPV6 addrss */
5532 CmInetIpv6RtHdr *rtOptsArr,/* IPv6 extensions headers */
5533 CmInetMemInfo *info /* Memory information */
5536 uint32_t curDataIdx; /* to keep track where we are in hbh Data */
5537 uint8_t i; /* loop counter */
5538 S16 ret; /* temporary return value */
5541 /* byte len of actual rtHdr ancil data */
5542 rtDataLen -= sizeof(struct cmsghdr);
5544 /* start from beginning */
5547 /* copy next header byte */
5548 rtHdr0->ip6r0_nextHdr = *(cmsgData + curDataIdx);
5551 /* copy header extension length byte */
5552 rtHdr0->ip6r0_hdrExtLen = *(cmsgData + curDataIdx);
5555 /* copy type byte (always 0) */
5556 rtHdr0->ip6r0_type = 0x00;
5559 /* copy segment left byte */
5560 rtHdr0->ip6r0_segLeft = *(cmsgData + curDataIdx);
5563 /* copy 1 reserve byte + 3 strict/loose bytes */
5564 memcpy((&rtOptsArr->slMap),
5565 (cmsgData + curDataIdx), 4);
5568 /* also save reserv byte + 3 sl bytes to rtHdro struc */
5569 rtHdr0->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5571 /* subtract 8 bytes for Next Hdr, Hdr Ext Len, .... + SL bit map */
5572 rtOptsArr->numAddrs = (rtDataLen - 8)/16;
5574 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5575 (Data **)&rtOptsArr->ipv6Addrs,
5576 (Size)rtOptsArr->numAddrs * 16);
5580 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5581 /* cm_inet_c_001.main_62:Warning fix */
5582 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvRtHdr\n");
5583 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET032, 0, prntBuf);
5584 #endif /* CMINETDBG */
5588 /* copy all the ipv6 addresses */
5589 for(i=0; i < rtOptsArr->numAddrs; i++)
5591 memcpy((rtOptsArr->ipv6Addrs[i]),
5592 (cmsgData + curDataIdx), 16);
5597 } /* end of cmInet6BuildRecvRtHdr() */
5602 * Fun: cmInet6GetHopLimitValue
5604 * Desc: This function extracts the hop limit value(ttl) of from the
5605 * ancillary data received through recvmsg() call. Then this
5606 * hoplimit value will be passed to upper user as ipHdrParam.
5608 * Ret: ROK - successful
5616 static S16 cmInet6GetHopLimitValue
5618 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5619 uint32_t hopLimitDataLen, /* byte len of cmsghdr + hbh ancil data */
5620 CmInetIpv6HdrParm *ipv6HdrParam /* ipv6 header parameters */
5623 uint16_t curDataIdx; /* to keep track where we are in the ancillary Data */
5624 uint32_t *hopLimitValue; /* ttl/hoplimit value */
5626 hopLimitValue = NULL;
5629 /* get length of actual hbh ancillary data */
5630 hopLimitDataLen -= sizeof(struct cmsghdr);
5632 /* go to the first byte of hop limit which present after cmsghdr struc */
5633 curDataIdx += sizeof(struct cmsghdr);
5635 /* mark that hoplimit(ttl) is present */
5636 ipv6HdrParam->ttl.pres = TRUE;
5638 /* the first byte will be the HopLimit value */
5639 hopLimitValue = (uint32_t *)(cmsgData);
5640 ipv6HdrParam->ttl.val = (uint8_t)(*hopLimitValue);
5644 #endif /* IPV6_OPTS_SUPPORTED */
5649 * Fun: cmInetRecvMsg
5651 * Desc: Reads data from a socket into a message.
5652 * The buffers for the message are allocated within the
5653 * cmInetRead() function from the pool and region Id set in the
5655 * If the number of octets given by the paramter len is not
5656 * available the function immediately returns with RKDNA.
5657 * If the len parameter is set to CM_INET_READ_ANY, the currently
5658 * available data is read.
5659 * Values for flag parameter:
5661 * CM_INET_NO_FLAG - no additional control flag
5662 * CM_INET_MSG_PEEK - do not destroy data on receive buffer
5664 * Ret: ROK - successful
5665 * ROKDNA - ok, data not available
5666 * RCLOSED - connection closed by peer
5667 * ROUTRES - failed, out of resources
5677 CmInetFd *sockFd, /* socket file descriptor */
5678 CmInetAddr *fromAddr, /* sender Internet address/port */
5679 CmInetMemInfo *info, /* buffer allocation info */
5680 Buffer **mPtr, /* received buffer structure */
5681 MsgLen *len, /* number of octets to read */
5682 /* added for IPv6 */
5683 #ifdef IPV6_OPTS_SUPPORTED
5684 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
5685 #endif /* IPV6_OPTS_SUPPORTED */
5687 CmInetLocalInf *localIf, /* local interface on which pkt was recvd */
5688 #endif /* LOCAL_INTF */
5689 S32 flags /* additional control flags */
5692 #if (defined(WIN32) || defined(CMINETFLATBUF))
5693 S32 ret = 0; /* temporary return value */
5694 uint32_t pendLen =0; /* pending data length */
5695 S32 recvLen =0; /* number of received octets by recvmsg() */
5696 MsgLen bufLen =0; /* entire number of received octets */
5697 MsgLen curLen =0; /* current number of octets in buffer */
5698 Data *recvBuf =NULLP; /* receive buffer */
5699 Data *bufPtr =NULLP; /* current buffer position */
5700 Buffer *mBuf = NULLP; /* received message */
5701 uint32_t remAddrLen =0; /* length of remote address */
5702 struct sockaddr_in *remAddr = {0}; /* remote Internet address */
5703 #ifdef IPV6_SUPPORTED
5704 struct sockaddr_in6 *remAddr6 = {0}; /* remote Internet address */
5705 struct sockaddr_in6 remSockAddr ={0}; /* to get packet's source IP address */
5707 CmInetSockAddr remSockAddr ={0}; /* to get packet's source IP address */
5708 #endif /* IPV6_SUPPORTED */
5710 S32 ret =0; /* temporary return value */
5711 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
5712 uint16_t i =0; /* index */
5713 uint32_t pendLen =0; /* pending data length */
5714 S32 numBuf =0; /* number of allocated dBufs */
5715 S32 recvLen =0; /* number of received octets by recvmsg() */
5716 MsgLen bufLen =0; /* entire number of received octets */
5717 struct msghdr msg = {0}; /* message header */
5718 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5719 Buffer *tempMsg = NULLP; /* temporary message */
5720 CmInetIovec rxArr[CM_INET_MAX_DBUF]= {{0}}; /* dynamic gather array */
5721 Buffer **dBufs = NULLP; /* dynamic array with allocated dBufs */
5722 S16 numDBufs =0; /* number of allocated dBufs */
5724 /* cm_inet_c_001.main_55: As remAddrLen is only being used when
5725 * WIN32 or CMINETFLATBUF is defined, then Removed variable
5727 struct sockaddr_in *remAddr = {0}; /* remote Internet address */
5728 #ifdef IPV6_SUPPORTED
5729 struct sockaddr_in6 *remAddr6 ={0}; /* remote Internet address */
5730 struct sockaddr_in6 remSockAddr ={0};/* to get packet's source IP address */
5731 /* added for IPv6 ext headers support */
5732 #ifdef IPV6_OPTS_SUPPORTED
5733 CmInetIpv6RtHdr0 rtHdr0 ={0}; /* type 0 route header */
5734 #endif /* IPV6_OPTS_SUPPORTED */
5737 struct in6_pktinfo *pkt6Info = {0}; /* IPv6 IP_PKTINFO */
5738 #endif /* LOCAL_INTF */
5740 #if (defined(SS_LINUX) || defined(_XPG4_2))
5741 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
5742 /* from stack for IPv6 ancill data */
5745 CmInetSockAddr remSockAddr ={0}; /* to get packet's src IP address */
5746 #if (defined(SS_LINUX) || defined(_XPG4_2))
5747 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
5748 /* from stack for IPv4 ancill data */
5750 #endif /* IPV6_SUPPORTED */
5751 /* added new definitions */
5752 Bool allocFlatBuf; /* allocate a flat buffer */
5753 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5754 Data *recvBuf = NULLP; /* receive buffer */
5757 struct in_pktinfo *pkt4Info; /* IPv4 IP_PKTINFO */
5759 #endif /* SS_LINUX */
5760 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
5761 struct cmsghdr *cmsgptr;/* pointer to struct cmsghdr */
5763 #endif /* WIN32 | CMINETFLATBUF */
5764 /* used by getsockopt */
5766 /* cm_inet_c_001.main_55:Removed unused variables errValue and optLen */
5769 #if (ERRCLASS & ERRCLS_INT_PAR)
5770 /* error check on parameters */
5771 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
5772 (info == NULLP) || (mPtr == NULLP) || (len == NULLP))
5776 #endif /* ERRCLASS & ERRCLS_INT_PAR */
5780 /*cm_inet_c_001.main_48 variables declaration */
5781 #if !((defined(WIN32) || defined(CMINETFLATBUF)))
5786 #if (defined(WIN32) || defined(CMINETFLATBUF))
5788 #ifdef IPV6_SUPPORTED
5790 #endif /* IPV6_SUPPORTED */
5792 #ifdef IPV6_SUPPORTED
5795 #endif /* IPV6_SUPPORTED */
5797 #if (defined(SS_LINUX) || defined(_XPG4_2))
5798 memset(ancillData, 0, sizeof(ancillData));
5799 #endif /* SS_LINUX || _XPG4_2 */
5801 #endif /* (WIN32 | CMINETFLATBUF) */
5803 /* clear the structure */
5804 memset(&remSockAddr, 0, sizeof(remSockAddr));
5806 /* get number of pending data */
5807 /* removed 3rd arg memInfo. MemInfo is no longer
5808 needed as we call ioctl for all sockets */
5810 /* cm_inet_c_001.main_48 : call ioctl only for STREAM
5811 * sockets now. For Non-Stream sockets(Raw & UDP), fix
5812 * pending length to CM_INET_MAX_UDPRAW_MSGSIZE
5814 if(sockFd->type == CM_INET_STREAM)
5816 ret = cmInetGetNumRead(sockFd, &pendLen);
5819 /* ret may be RFAILED or ROUTRES */
5825 /* cm_inet_c_001.main_48 : pendLen is set 1 greater
5826 * than the #defined value. If recvFrom/recvMsg
5827 * returns the len == pendLen, we would drop the
5828 * message as the msg len is larger than the largest
5829 * msg we are willing to accept.
5831 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE+1;
5835 /* check if connection got closed */
5838 if (sockFd->type == CM_INET_STREAM)
5840 /* cm_inet_c_001.main_50:
5841 * cm_inet_c_001.main_56: Removed comment for cm_inet_c_001.main_50 as
5842 * the current patch changes its functionality */
5843 uint8_t readBuf[1]; /* declaration of variable for Peek */
5846 * cm_inet_c_001.main_56:
5847 * We are peeking the socket buffer again with peek as on some machines
5848 * like solaris, there is a latency observed in ioctl. In such cases,
5849 * ioctl may return 0, even though there are bytes available to read.
5850 * We reconfirm through peek whether 0 means EOF or its ioctl latency
5853 ret = cmInetPeekNew(sockFd, NULLP, info, 0, 1, readBuf);
5858 /* cm_inet_c_001.main_56:
5859 * Returning ROKDNA even cmInetPeekNew returns ROK. Because currently
5860 * we are not sure about pending length. Anyway socket FD already set,
5861 * we do another iteration to get exact pendLen value. We cannot call
5862 * cmInetGetNumRead at this point because of latency between the ioctl
5863 * call and recvfrom call issues on some machines ioctl call may
5864 * return ZERO even their a data to read. */
5868 /* cm_inet_c_001.main_52: Support for partial reception */
5869 /* cm_inet_c_001.main_59: Fix for compilation warning */
5870 if ((sockFd->type == CM_INET_STREAM) && (*len > (MsgLen)pendLen))
5872 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5873 *len = (MsgLen)pendLen;
5876 /* check if there are enough pending data to read */
5877 if ((*len == CM_INET_READ_ANY) || ((uint32_t)*len <= pendLen))
5879 if (*len == CM_INET_READ_ANY)
5881 /* added check for TCP socket. Pending data length in
5882 the socket recv buffer is determined by ioctl call in
5884 For TCP it can't be > CM_INET_MAX_MSG_LEN. */
5885 if (sockFd->type == CM_INET_STREAM)
5887 /* max message length is limited to control the memory usage */
5888 if (pendLen > CM_INET_MAX_MSG_LEN)
5889 pendLen = CM_INET_MAX_MSG_LEN;
5891 /* cm_inet_c_001.main_48 : removed the check for
5892 * Non Stream sockets (pendLen < MAX_UDPRAW_MSGSIZE)
5893 * as we are hardcoding pendLen for Non-Stream sockets.
5896 /* read all pending data */
5897 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5898 bufLen = (MsgLen)pendLen;
5899 *len = (MsgLen)pendLen;
5903 /* cm_inet_c_001.main_45- Returning CM_INET_MAX_MSG_LEN when input is larger than
5906 /* max message length is limited to control the memory usage */
5907 if ((*len) > CM_INET_MAX_MSG_LEN)
5909 (*len) = CM_INET_MAX_MSG_LEN;
5912 /* read data length given by user */
5916 #if (defined(WIN32) || defined(CMINETFLATBUF))
5918 /* set destination Internet address structure */
5919 if (fromAddr != NULLP)
5921 remAddrLen = sizeof(remSockAddr);
5928 /* allocate flat receive buffer */
5929 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &recvBuf, bufLen);
5938 * maybe needs more than one recvfrom() call to read an entire
5939 * message from a stream socket (TCP)
5943 /* added separate recvfrom calls different OS */
5945 /*cm_inet_c_001.main_42 1. In Vx-Works the 5th and 6th parameter of recvfrom
5946 system call are either NULL or should be valid pointer.*/
5947 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
5949 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5950 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
5952 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5953 NULLP, (int *)&remAddrLen);
5955 #if ( defined(SUNOS) || defined(SS_LINUX))
5957 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5958 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
5960 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5961 NULLP, (socklen_t *)&remAddrLen);
5964 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5965 &remSockAddr, (S32 *)&remAddrLen);
5967 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5968 NULLP, (S32 *)&remAddrLen);
5970 #endif /* defined(SUNOS) || defined(SS_LINUX) */
5971 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
5973 if (recvLen == INET_ERR)
5976 /* moved cleanup here */
5977 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
5979 /* added check ERR_WOULDBLOCK */
5980 if ((INET_ERR_CODE == ERR_AGAIN) ||
5981 (INET_ERR_CODE == ERR_WOULDBLOCK))
5988 /* In Windows the recvfrom function fails
5989 * with error code which maps to either WSAECONNABORTED. If
5990 * this happens then cmInetRecvMsg must return RCLOSED */
5991 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
5992 (INET_ERR_CODE == ERR_CONNRESET))
6000 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6001 /* cm_inet_c_001.main_62:Warning fix */
6002 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6003 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6004 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6006 /* cm_inet_c_001.main_62:Warning fix */
6007 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6008 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6009 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6010 #endif /*ALIGN_64BIT*/
6011 #endif /* CMINETDBG */
6019 * a message is always read atomically on a datagram socket,
6020 * therefore it's ok to read less than pending data!
6023 if ((sockFd->type == CM_INET_RAW) ||
6024 (sockFd->type == CM_INET_DGRAM))
6029 #else /* CM_INET2 */
6030 if (sockFd->type == CM_INET_DGRAM)
6035 #endif /* CM_INET2 */
6036 } /* while (curLen > 0) (only for stream sockets) */
6038 /* For UDP, it is possible to receive
6039 * a 0 byte datagram, in this case just return ROKDNA.
6042 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6045 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6048 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6052 /* cm_inet_c_001.main_48 : If Received
6053 * len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6057 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6058 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6060 if ((sockFd->type == CM_INET_DGRAM)
6061 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6066 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6067 /* cm_inet_c_001.main_62:Warning fix */
6068 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6069 " > than allowed(%lu), sockFd->fd(%ld) \n",
6070 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6071 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6073 /* cm_inet_c_001.main_62:Warning fix */
6074 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6075 " > than allowed(%lu), sockFd->fd(%d) \n",
6076 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6077 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6078 #endif /*ALIGN_64BIT*/
6080 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6084 /* cm_inet_c_001.main_48 : copy data to a message structure */
6085 ret = SGetMsg(info->region, info->pool, &mBuf);
6089 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6094 if ((sockFd->type == CM_INET_DGRAM) ||
6095 (sockFd->type == CM_INET_RAW))
6097 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6101 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6104 #else /* CM_INET2 */
6105 if (sockFd->type == CM_INET_DGRAM)
6107 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6111 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6113 #endif /* CM_INET2 */
6117 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6123 /* setup return destination Internet address */
6124 /* added the check of (remAddrLen > 0) */
6125 if ((fromAddr != NULLP) && (remAddrLen > 0))
6127 #ifdef IPV6_SUPPORTED
6128 if (remAddrLen == sizeof(struct sockaddr_in6))
6130 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6131 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6132 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6133 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6134 &remAddr6->sin6_addr);
6138 remAddr = (struct sockaddr_in *)&remSockAddr;
6139 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6140 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6141 fromAddr->u.ipv4Addr.address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6144 remAddr = (struct sockaddr_in *)&remSockAddr;
6145 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6146 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6147 #endif /* IPV6_SUPPORTED */
6151 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6153 #else /* end of Win NT/flat buffer specific part */
6155 /* Initialise variable */
6156 allocFlatBuf = FALSE;
6159 * maybe needs more than one recvmsg() call to read entire message
6160 * on a stream socket
6164 /* allocate gather vector, it's a dynamic array */
6165 numDBufs = CM_INET_MAX_DBUF;
6167 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data**)&dBufs,
6168 numDBufs*sizeof(Buffer*));
6174 /* Allocate dBufs for gather read */
6175 /* allocate dBufs for gathering read */
6176 if (sockFd->type == CM_INET_STREAM)
6177 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6180 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6184 /* check if the function returned RNA */
6187 /* Incase of UDP/RAW messages allocate a flat buffer. Incase
6188 * of TCP ignore this error condition. The user will call
6189 * cmInetRecvMsg again */
6190 /* cm_inet_c_001.main_62:Warning fix */
6191 if (sockFd->type != (uint8_t)CM_INET_STREAM)/* G++ */
6194 #ifdef T2K_MEM_LEAK_DBG
6195 char * file = __FILE__;
6196 uint32_t line = __LINE__;
6199 /* cleanup the dBuf array */
6200 for (i = 0; i < msg.msg_iovlen; i++)
6201 SPutDBuf(info->region, info->pool, dBufs[i]);
6203 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6204 numDBufs * sizeof(Buffer*));
6206 /* allocate flat receive buffer */
6207 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &recvBuf, bufLen);
6211 allocFlatBuf = TRUE;
6213 /* update the message structure */
6215 rxArr[0].iov_base = (Void*)recvBuf;
6216 rxArr[0].iov_len = (uint32_t)bufLen;
6218 rxArr[0].iov_base = (S8*)recvBuf;
6219 rxArr[0].iov_len = bufLen;
6220 #endif /* SS_LINUX */
6221 msg.msg_iov = rxArr;
6227 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6228 numDBufs*sizeof(Buffer*));
6233 numBuf = msg.msg_iovlen;
6235 /* setup destination Internet address structure */
6236 if (fromAddr != NULLP)
6239 msg.msg_name = (Void*)&remSockAddr;
6242 msg.msg_name = (char *)&remSockAddr;
6244 msg.msg_name = (caddr_t)&remSockAddr;
6246 #endif /* SS_LINUX */
6247 msg.msg_namelen = sizeof(remSockAddr);
6251 msg.msg_name = NULLP;
6252 msg.msg_namelen = 0;
6255 /* added defined(_XPG4_2). Also changed the
6257 #if (defined(SS_LINUX) || defined(_XPG4_2))
6258 msg.msg_control = ancillData;
6259 msg.msg_controllen = sizeof(ancillData);
6261 msg.msg_accrights = NULLP;
6262 msg.msg_accrightslen = 0;
6263 #endif /* SS_LINUX */
6265 recvLen = recvmsg(sockFd->fd, &msg, flags);
6266 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
6268 /* Moved up the cleanup precedures here before returning */
6269 /* Cleanup flat buffer if allocated */
6271 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6275 for (i = 0; i < numBuf; i++)
6277 #ifdef T2K_MEM_LEAK_DBG
6278 char * file = __FILE__;
6279 uint32_t line = __LINE__;
6282 SPutDBuf(info->region, info->pool, dBufs[i]);
6284 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6285 numDBufs*sizeof(Buffer*));
6288 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6289 * it has partially received data
6291 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
6292 added check ERR_WOULDBLOCK */
6293 if ((INET_ERR_CODE == ERR_AGAIN) ||
6294 (INET_ERR_CODE == ERR_WOULDBLOCK))
6296 /* cm_inet_c_001.main_50 : If message is read partially then just return
6297 * OK without freeing the mPtr. This will gaurd us
6298 * against unexpected WOULDBLOCKS observed in solaris
6306 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6307 * it has partially received data
6315 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6316 /* cm_inet_c_001.main_62:Warning fix */
6317 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6318 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6319 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6321 /* cm_inet_c_001.main_62:Warning fix */
6322 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6323 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6324 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6325 #endif /*ALIGN_64BIT*/
6326 #endif /* CMINETDBG */
6328 /* If this happens then cmInetRecvMsg must return RCLOSED.
6329 * Needed for getting icmp msgs */
6330 if (INET_ERR_CODE == ERR_CONNABORTED)
6340 /* added for IPv6 extn headers */
6341 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6343 /* check if ancillary data has been received.
6344 * Return the allocated memory when no ancillary data received */
6345 #if (defined(SS_LINUX) || defined(_XPG4_2))
6346 if (msg.msg_controllen)
6348 cmsgptr = CMSG_FIRSTHDR(&msg);
6354 #endif /* SS_LINUX || _XPG4_2 */
6356 if (cmsgptr != NULLP)
6358 #ifdef IPV6_OPTS_SUPPORTED
6359 if(ipHdrParams != NULLP)
6361 ipHdrParams->u.ipv6HdrParm.ttl.pres = FALSE;
6362 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt = FALSE;
6363 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt = FALSE;
6364 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt = FALSE;
6366 /* get all ancillary data objects recvd one by one */
6367 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6368 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6370 if (cmsgptr->cmsg_level == IPPROTO_IPV6)
6372 /* Initialise ipHdrParams properly */
6373 ipHdrParams->type = CM_INET_IPV6ADDR_TYPE;
6375 if (cmsgptr->cmsg_type == IPV6_HOPOPTS)
6377 /* build up HBH opt array from recvd ancillary data */
6378 ret = cmInet6BuildRecvHopOptsArr(
6379 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6380 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
6384 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt =
6388 else if(cmsgptr->cmsg_type == IPV6_DSTOPTS)
6390 else if ((cmsgptr->cmsg_type == IPV6_DSTOPTS) ||
6391 (cmsgptr->cmsg_type == IPV6_RTHDRDSTOPTS))
6392 #endif /* SS_LINUX */
6394 /* build up Dest opt array from recvd ancillary data */
6395 ret = cmInet6BuildRecvDstOptsArr(
6396 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6397 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr,
6401 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt =
6404 else if (cmsgptr->cmsg_type == IPV6_RTHDR)
6406 /* build up Route Hdr from recvd ancillary data */
6407 ret = cmInet6BuildRecvRtHdr(
6408 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, &rtHdr0,
6409 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
6413 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt =
6416 else if(cmsgptr->cmsg_type == IPV6_HOPLIMIT)
6418 /* get the received hoplimit */
6419 ret = cmInet6GetHopLimitValue((uint8_t *)CMSG_DATA(cmsgptr),
6420 cmsgptr->cmsg_len, &ipHdrParams->u.ipv6HdrParm);
6427 #endif /* IPV6_OPTS_SUPPORTED */
6429 #ifdef IPV6_SUPPORTED
6431 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6432 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6434 if(cmsgptr->cmsg_type == IPV6_PKTINFO)
6436 pkt6Info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
6437 localIf->intfPrsnt = TRUE;
6438 localIf->localIf = pkt6Info->ipi6_ifindex;
6439 localIf->localIfAddr.type = CM_INET_IPV6ADDR_TYPE;
6440 memcpy(&localIf->localIfAddr.u.ipv6NetAddr,
6441 &pkt6Info->ipi6_addr, 16);
6444 #endif /* LOCAL_INTF */
6447 #if (defined(SS_LINUX) && defined(LOCAL_INTF))
6448 #ifdef IPV6_SUPPORTED
6449 if(sockFd->protType == AF_INET)
6452 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
6453 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6455 if (cmsgptr->cmsg_level == IPPROTO_IP &&
6456 cmsgptr->cmsg_type == IP_PKTINFO)
6458 pkt4Info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
6459 localIf->intfPrsnt = TRUE;
6460 localIf->localIf = pkt4Info->ipi_ifindex;
6461 localIf->localIfAddr.type = CM_INET_IPV4ADDR_TYPE;
6462 localIf->localIfAddr.u.ipv4NetAddr =
6463 ntohl(*(int *)&pkt4Info->ipi_addr);
6466 #ifdef IPV6_SUPPORTED
6469 #endif /* SS_LINUX */
6471 #endif /* IPV6_OPTS_SUPPORTED || LOCAL_INTF */
6473 /* setup return destination Internet address */
6474 if (fromAddr != NULLP)
6476 #ifdef IPV6_SUPPORTED
6477 if (msg.msg_namelen == sizeof(struct sockaddr_in6))
6479 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6480 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6481 fromAddr->u.ipv6Addr.port =
6482 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6483 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6484 &remAddr6->sin6_addr);
6488 remAddr = (struct sockaddr_in *)&remSockAddr;
6489 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6490 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6491 fromAddr->u.ipv4Addr.address =
6492 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6495 remAddr = (struct sockaddr_in *)&remSockAddr;
6496 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6497 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6498 #endif /* IPV6_SUPPORTED */
6501 /* Incase a flat buffer was allocated get
6502 * a message to pass up */
6508 ret = SGetMsg(info->region, info->pool, &tempMsg);
6512 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6516 /* cm_inet_c_001.main_48 : A 0 len UDP packet could be received */
6519 ret = SAddPstMsgMult(recvBuf, recvLen, tempMsg);
6522 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6530 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6531 /* cm_inet_c_001.main_48 :flat buffers are allocated
6532 * for non -TCP sockets. On these sockets we can receive
6533 * only one message at a time
6535 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6536 *len = (MsgLen)recvLen;
6541 /* build message out of dBufs */
6542 ret = buildRecvMsg(info, rxArr, numBuf, recvLen, dBufs, &tempMsg);
6545 /* Deallocate previously allocated
6549 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6550 numDBufs*sizeof(Buffer*));
6557 /* it's first recvmsg() call */
6562 /* concatenate messages */
6563 ret = SCatMsg(*mPtr, tempMsg, M1M2);
6569 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6570 numDBufs*sizeof(Buffer*));
6576 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6577 numDBufs*sizeof(Buffer*));
6580 * a message is always read atomically on a datagram socket,
6581 * therefore it's ok to read less than pending data!
6584 if ((sockFd->type == CM_INET_DGRAM) ||
6585 (sockFd->type == CM_INET_RAW))
6587 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6588 *len = (MsgLen)recvLen;
6591 #else /* CM_INET2 */
6592 if (sockFd->type == CM_INET_DGRAM)
6594 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6595 *len = (MsgLen)recvLen;
6598 #endif /* CM_INET2 */
6599 } /* while(bufLen > 0) (only for stream sockets) */
6601 /* cm_inet_c_001.main_48 : For UDP, it is possible to receive
6602 * a 0 byte datagram, in this case just return ROKDNA
6606 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6609 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6621 /* Received len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6626 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6627 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6629 if ((sockFd->type == CM_INET_DGRAM)
6630 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6641 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6642 /* cm_inet_c_001.main_62:Warning fix */
6643 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6644 " allowed(%d),sockFd->fd(%ld)\n",
6645 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6646 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6648 /* cm_inet_c_001.main_62:Warning fix */
6649 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6650 " allowed(%d),sockFd->fd(%d)\n",
6651 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6652 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6659 #endif /* WIN32 | CMINETFLATBUF */
6663 /* not enough data pending yet */
6668 } /* end of cmInetRecvMsg */
6671 /* cm_inet_c_001.main_56: Added new function cmInetPeekNew() */
6675 * Fun: cmInetPeekNew
6677 * Desc: Reads some data from the socket without destroying the socket
6679 * The data is specified by the byte positon (first byte is at
6680 * position 0) and the length.
6682 * Ret: ROK - successful
6683 * ROKDNA - ok, data not available
6684 * RCLOSED - connection closed by peer
6687 * Notes: Following are the differences from the cmInetPeek to cmInetPeekNew.
6688 * This primitive does not call the select function as this is already
6689 * taken care by the called primitive. This primitive will not use any
6690 * ioctl calls, because on some machines due to latency in ioctl call
6691 * length may return as ZERO, even there is some data to be read from
6692 * the socket and this primitive only peek buffer using recvfrom.
6694 * Caller of this function need to allocate the sufficient memory to hold
6695 * the data peeked from the socket i.e. dataPos + dataLen. Socket data
6696 * will be copied in the "data" starting from dataPos offset.
6698 * For example, caller passed the following values to this function.
6699 * dataPos = 2 and dataLen = 10,then size of data buffer received should
6700 * be minimum of (dataPos + dataLen)12 bytes and socket data will be
6701 * copied in the data buffer from offset 2 (dataPos) onwards.
6709 CmInetFd *sockFd, /* socket file descriptor */
6710 CmInetAddr *fromAddr, /* sender Internet address/port */
6711 CmInetMemInfo *info, /* buffer allocation info */
6712 MsgLen dataPos, /* position of data */
6713 MsgLen dataLen, /* length of read data */
6714 Data *data /* read data */
6717 /* cm_inet_c_001.main_57 - Fix for validation and compilation warning */
6718 S32 recvLen; /* number of received octets */
6719 S32 remAddrLen; /* length of remote address length */
6720 struct sockaddr_in *remAddr; /* remote Internet address */
6721 #ifdef IPV6_SUPPORTED
6722 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6723 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6725 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6726 #endif /* IPV6_SUPPORTED */
6729 #if (ERRCLASS & ERRCLS_INT_PAR)
6730 /* error check on parameters */
6731 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6732 (info == NULLP) || (data == NULLP) ||
6733 (dataPos < 0) || (dataLen < 0))
6737 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6739 /* check if fromAddr is present or not */
6740 if (fromAddr != NULLP)
6742 remAddrLen = sizeof(remSockAddr);
6749 /* added different recvfrom calls with different 6th arg for
6750 * different OS If remAddrLen is 0, pass NULLP */
6751 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
6753 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6754 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
6756 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6757 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
6759 #if ( defined(SUNOS) || defined(SS_LINUX))
6761 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6762 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
6763 (socklen_t *)&remAddrLen);
6765 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6766 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
6769 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6770 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
6772 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6773 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
6774 #endif /* defined(SUNOS) || defined(SS_LINUX) */
6775 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
6777 /* removed the check of returned remAddrLen */
6778 if (recvLen == INET_ERR)
6780 /* added check ERR_WOULDBLOCK */
6781 if ((INET_ERR_CODE == ERR_AGAIN) ||
6782 (INET_ERR_CODE == ERR_WOULDBLOCK))
6787 /* cm_inet_c_001.main_61: added host unreachable check */
6788 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
6789 (INET_ERR_CODE == ERR_CONNRESET) ||
6790 (INET_ERR_CODE == ERR_HOSTUNREACH) ||
6791 (INET_ERR_CODE == ERR_CONNREFUSED))
6798 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6799 /* cm_inet_c_001.main_62:Warning fix */
6800 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%ld)\n",
6801 INET_ERR_CODE, sockFd->fd);
6802 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6804 /* cm_inet_c_001.main_62:Warning fix */
6805 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%d)\n",
6806 INET_ERR_CODE, sockFd->fd);
6807 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6809 #endif /* CMINETDBG */
6813 else if (recvLen == 0)
6818 /* cm_inet_c_001.main_57 - Fix for validation */
6819 if (recvLen < (S32)dataLen) /* maybe happen */
6824 /* setup return destination Internet address */
6825 /* added the check of (remAddLen > 0) */
6826 if ((fromAddr != NULLP) && (remAddrLen > 0))
6828 #ifdef IPV6_SUPPORTED
6829 memset(fromAddr, 0, sizeof(fromAddr));
6830 if (remAddrLen == sizeof(struct sockaddr_in6))
6832 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6833 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6834 fromAddr->u.ipv6Addr.port =
6835 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6836 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6837 &remAddr6->sin6_addr);
6841 remAddr = (struct sockaddr_in *)&remSockAddr;
6842 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6843 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6844 fromAddr->u.ipv4Addr.address =
6845 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6848 remAddr = (struct sockaddr_in *)&remSockAddr;
6849 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6850 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6851 #endif /* IPV6_SUPPORTED */
6855 } /* end of cmInetPeeknew */
6862 * Desc: Reads some data from the socket without destroying the socket
6864 * The data is specified by the byte positon (first byte is at
6865 * position 0) and the length.
6867 * Ret: ROK - successful
6868 * ROKDNA - ok, data not available
6869 * RCLOSED - connection closed by peer
6880 CmInetFd *sockFd, /* socket file descriptor */
6881 CmInetAddr *fromAddr, /* sender Internet address/port */
6882 CmInetMemInfo *info, /* buffer allocation info */
6883 MsgLen dataPos, /* position of data */
6884 MsgLen dataLen, /* length of read data */
6885 Data *data /* read data */
6888 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6889 Data *recvBuf = NULLP; /* plain receive buffer */
6890 /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
6891 MsgLen bufLen; /* buffer length */
6892 MsgLen i; /* index */
6893 MsgLen j; /* index */
6894 S32 ret; /* temporary return value */
6895 uint32_t timeout; /* timeout for cmInetSelect() */
6896 uint32_t *timeoutPtr; /* pointer to timeout */
6897 S16 numFdS; /* number of ready descriptors */
6898 /* cm_inet_c_001.main_45 - fixing the UMR issue in 64bit linux */
6899 uint32_t pendLen = 0; /* pending data length */
6900 S32 recvLen; /* number of received octets */
6901 S32 remAddrLen; /* length of remote address length */
6902 CmInetFdSet readFdS; /* socket file descriptor set */
6903 struct sockaddr_in *remAddr; /* remote Internet address */
6904 #ifdef IPV6_SUPPORTED
6905 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6906 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6908 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6909 #endif /* IPV6_SUPPORTED */
6912 #if (ERRCLASS & ERRCLS_INT_PAR)
6913 /* error check on parameters */
6914 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6915 (info == NULLP) || (data == NULLP) ||
6916 (dataPos < 0) || (dataLen < 0))
6920 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6922 /* check if there are some datas */
6923 if (sockFd->blocking)
6930 /* poll (non-blocking) */
6932 timeoutPtr = &timeout;
6934 CM_INET_FD_ZERO(&readFdS);
6935 CM_INET_FD_SET(sockFd, &readFdS);
6937 ret = cmInetSelect(&readFdS, NULLP, timeoutPtr, &numFdS);
6938 if (CM_INET_FD_ISSET(sockFd, &readFdS))
6940 /* get number of pending data */
6941 /* removed 3rd arg memInfo. MemInfo is no longer needed as we
6942 call ioctl for all sockets */
6943 ret = cmInetGetNumRead(sockFd, &pendLen);
6946 /* cm_inet_c_001.main_50
6947 * Return RCLOSED if cmInetGetNumRead returns RCLOSED. For other
6948 * errors just return RFAILED.
6956 /* check if connection got closed */
6960 /* cm_inet_c_001.main_50
6961 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
6962 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
6963 * socket that select says is ready to read. This should not be
6964 * considered as connection closed. So return ROKDNA instead of
6965 * RCLOSED even for TCP sockets
6969 /* added check for TCP/UDP socket. Pending data len in the socket
6970 recv buffer is determined by ioctl call in cmInetGetNumRead.
6971 For TCP it can't be > CM_INET_MAX_MSG_LEN.
6972 For UDP it can't be > CM_INET_MAX_UDPRAW_MSGSIZE. */
6973 if (sockFd->type == CM_INET_STREAM)
6975 /* max message length is limited to control the memory usage */
6976 if (pendLen > CM_INET_MAX_MSG_LEN)
6977 pendLen = CM_INET_MAX_MSG_LEN;
6978 /* In STREAM remote address is not required */
6983 if (pendLen > CM_INET_MAX_UDPRAW_MSGSIZE)
6984 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE;
6986 remAddrLen = sizeof(CmInetSockAddr);
6989 /* check if there are enough pending data to read */
6990 bufLen = dataPos + dataLen;
6992 /* check if fromAddr is present or not */
6993 if (fromAddr != NULLP)
6995 remAddrLen = sizeof(remSockAddr);
7002 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
7003 if ((MsgLen)pendLen >= bufLen)
7005 /* allocate receive buffer (flat structure) */
7006 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &recvBuf, bufLen);
7012 /* added different recvfrom calls with
7013 * different 6th arg for different OS */
7015 /* If remAddrLen is 0, pass NULLP */
7016 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7018 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7019 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7021 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7022 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7024 #if ( defined(SUNOS) || defined(SS_LINUX))
7026 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7027 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7028 (socklen_t *)&remAddrLen);
7030 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7031 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7034 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7035 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7037 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7038 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7039 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7040 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7042 /* removed the check of returned remAddrLen */
7043 if (recvLen == INET_ERR)
7046 /* moved cleanup here */
7047 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
7049 /* added check ERR_WOULDBLOCK */
7050 if ((INET_ERR_CODE == ERR_AGAIN) ||
7051 (INET_ERR_CODE == ERR_WOULDBLOCK))
7057 /* moved up the cleanup */
7061 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7062 /* cm_inet_c_001.main_62:Warning fix */
7063 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%ld)\n",
7064 INET_ERR_CODE, sockFd->fd);
7065 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7067 /* cm_inet_c_001.main_62:Warning fix */
7068 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%d)\n",
7069 INET_ERR_CODE, sockFd->fd);
7070 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7072 #endif /* CMINETDBG */
7074 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7075 (INET_ERR_CODE == ERR_CONNRESET))
7083 if (recvLen < (S32)bufLen) /* maybe happen */
7086 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
7091 for (j = 0, i = dataPos; i < bufLen; j++, i++)
7092 data[j] = recvBuf[i];
7094 /* setup return destination Internet address */
7095 /* added the check of (remAddLen > 0) */
7096 if ((fromAddr != NULLP) && (remAddrLen > 0))
7098 #ifdef IPV6_SUPPORTED
7099 memset(fromAddr, 0, sizeof(fromAddr));
7100 if (remAddrLen == sizeof(struct sockaddr_in6))
7102 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7103 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7104 fromAddr->u.ipv6Addr.port =
7105 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
7106 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
7107 &remAddr6->sin6_addr);
7111 remAddr = (struct sockaddr_in *)&remSockAddr;
7112 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7113 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7114 fromAddr->u.ipv4Addr.address =
7115 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7118 remAddr = (struct sockaddr_in *)&remSockAddr;
7119 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7120 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7121 #endif /* IPV6_SUPPORTED */
7125 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
7129 /* not enough data pending yet */
7135 /* no data pending */
7140 } /* end of cmInetPeek */
7147 * Desc: Close a socket gracefully.
7149 * Ret: ROK - successful
7160 CmInetFd *sockFd /* socket file descriptor */
7163 S32 ret; /* temporary return value */
7166 #if (ERRCLASS & ERRCLS_INT_PAR)
7167 /* error check on parameters */
7168 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7172 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7175 ret = closesocket(sockFd->fd);
7177 ret = close(sockFd->fd);
7179 if (ret == INET_ERR)
7183 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7184 /* cm_inet_c_001.main_62:Warning fix */
7185 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%ld)\n",
7186 INET_ERR_CODE, sockFd->fd);
7187 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7189 /* cm_inet_c_001.main_62:Warning fix */
7190 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%d)\n",
7191 INET_ERR_CODE, sockFd->fd);
7192 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7193 #endif /*ALIGN_64BIT*/
7194 #endif /* CMINETDBG */
7199 } /* end of cmInetClose */
7204 * Fun: cmInetShutdown
7206 * Desc: Close an Internet connection with more control over the data of
7207 * the full-duplex connection.
7208 * Values for the howTo parameter:
7210 * CM_INET_SHTDWN_RECV - discard data in receive buffer
7211 * CM_INET_SHTDWN_SEND - discard data in transmit buffer
7212 * CM_INET_SHTDWN_BOTH - discard data in receive and transmit buffer
7214 * Ret: ROK - successful
7217 * Notes: This function does not free the socket descriptor but only closes the
7218 * connection (cmInetClose() has to be called afterwards).
7219 * No error is returned if the socket is not connected while calling
7228 CmInetFd *sockFd, /* socket file descriptor */
7229 S32 howTo /* operation flag */
7232 S32 ret; /* temporary return value */
7235 #if (ERRCLASS & ERRCLS_INT_PAR)
7236 /* error check on parameters */
7237 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7241 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7243 ret = shutdown(sockFd->fd, howTo);
7244 if (ret == INET_ERR)
7246 if (INET_ERR_CODE == ERR_NOTCONN)
7248 /* socket is not connected */
7256 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7257 /* cm_inet_c_001.main_62:Warning fix */
7258 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7259 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
7260 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7262 /* cm_inet_c_001.main_62:Warning fix */
7263 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7264 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
7265 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7266 #endif /*ALIGN_64BIT*/
7267 #endif /* CMINETDBG */
7273 } /* end of cmInetShutdown */
7280 * Desc: Allows multiplex i/o requests among multiple sockets.
7281 * If the parameter mSecTimeout points to a value of zero the
7282 * call immediatley returns (poll), if it is a null pointer, the
7283 * timeout is set to infinit.
7284 * numFdS returns the number of ready file descriptors contained
7285 * in the file descriptor sets
7287 * Ret: ROK - successful
7288 * RTIMEOUT - timout expired
7299 CmInetFdSet *readFdS, /* read socket descriptor file set */
7300 CmInetFdSet *writeFdS, /* write socket descriptor file set */
7301 uint32_t *mSecTimeout, /* timeout in msecs */
7302 S16 *numFdS /* number of ready descriptors */
7305 S32 ret; /* temporary return value */
7306 struct timeval timeout; /* timeout structure */
7307 struct timeval *timeoutPtr;
7310 #if (ERRCLASS & ERRCLS_INT_PAR)
7311 /* error check on parameters */
7312 if (numFdS == NULLP)
7316 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7320 if (mSecTimeout != NULLP)
7322 timeout.tv_sec = *mSecTimeout / 1000;
7323 timeout.tv_usec = (*mSecTimeout % 1000) * 1000;
7324 timeoutPtr = &timeout;
7328 /* infinite timeout */
7334 timeout.tv_usec = 1;
7337 /* cm_inet_c_001.main_53 - Removed do-while loop */
7338 ret = select(FD_SETSIZE, readFdS, writeFdS, (fd_set*)0, timeoutPtr);
7340 /* cm_inet_c_001.main_53 - Return ROKDNA in case select was interrupted */
7341 if ((ret == INET_ERR) && (INET_ERR_CODE == ERR_EINTR))
7346 /* timeout occured */
7352 if (ret == INET_ERR)
7354 /* asa: Added a check for ERR_INVAL to return ROK
7355 * readFdS and writeFdS may be passed as NULL to
7356 * cmInetSelect() call
7358 switch(errCode = INET_ERR_CODE)
7365 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7366 /* cm_inet_c_001.main_62:Warning fix */
7367 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSelect() Failed : error(%d)\n",
7369 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET039, 0, prntBuf);
7370 #endif /* CMINETDBG */
7373 } /* end of switch */
7376 /* return number of ready file descriptors */
7377 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7381 } /* end of cmInetSelect */
7388 * Desc: Sets a socket option.
7389 * The function supports following options:
7391 * CM_INET_OPT_BLOCK:
7392 * value: CM_INET_OPT_DISABLE non-blocking
7393 * value: CM_INET_OPT_ENABLE blocking
7395 * CM_INET_OPT_REUSEADDR:
7396 * value: CM_INET_OPT_ENABLE reuse address
7398 * CM_INET_OPT_BROADCAST:
7399 * value: CM_INET_OPT_DISABLE
7400 * value: CM_INET_OPT_ENABLE
7402 * CM_INET_OPT_KEEPALIVE:
7403 * value: CM_INET_OPT_DISABLE
7404 * value: CM_INET_OPT_ENABLE
7406 * CM_INET_OPT_RX_BUF_SIZE:
7407 * value: receive buffer size in bytes
7409 * CM_INET_OPT_TX_BUF_SIZE:
7410 * value: transmitter buffer size in bytes
7412 * CM_INET_OPT_ADD_MCAST_MBR:
7413 * value: address of CmInetMCastInf structure
7415 * CM_INET_OPT_DRP_MCAST_MBR:
7416 * value: address of CmInetMCastInf structure
7418 * CM_INET_OPT_TCP_NODELAY:
7419 * value: CM_INET_OPT_DISABLE
7420 * value: CM_INET_OPT_ENABLE
7422 * CM_INET_OPT_BSD_COMPAT: For Linux only
7423 * value: CM_INET_OPT_ENABLE
7424 * value: CM_INET_OPT_DISABLE
7426 * CM_INET_OPT_HDR_INCLD:
7427 * value: CM_INET_ENABLE
7428 * value: CM_INET_DISABLE
7430 * CM_INET_OPT_DONT_FRAGMENT:
7431 * value: CM_INET_OPT_ENABLE
7432 * value: CM_INET_DISABLE
7435 * value: Type of Service.
7438 * value: Time To Live.
7440 * CM_INET_OPT_IP_OPTIONS:
7441 * value: IPv4 header option value
7444 * CM_INET_OPT_IP_ROUTER_ALERT:
7445 * value: CM_INET_OPT_DISABLE
7446 * value: CM_INET_OPT_ENABLE
7448 * CM_INET_OPT_IPV4_PKTINFO
7449 * value: CM_INET_OPT_ENABLE
7450 * value: CM_INET_OPT_DISABLE
7452 * CM_INET_OPT_MCAST_LOOP:
7453 * value: CM_INET_OPT_DISABLE
7454 * value: CM_INET_OPT_ENABLE
7456 * CM_INET_OPT_MCAST_IF:
7457 * value: Address of interface.
7459 * CM_INET_OPT_MCAST_TTL:
7460 * value: TTL of the outgoing multicast packet.
7462 * The next options are defined only if IPV6 is
7465 * CM_INET_OPT_ADD_MCAST6_MBR:
7466 * value: address of CmInetMCastInf6 structure
7468 * CM_INET_OPT_DRP_MCAST6_MBR:
7469 * value: address of CmInetMCastInf6 structure
7471 * CM_INET_OPT_MCAST6_LOOP:
7472 * value: CM_INET_OPT_DISABLE
7473 * value: CM_INET_OPT_ENABLE
7475 * CM_INET_OPT_MCAST6_IF:
7476 * value: Interface index
7478 * CM_INET_OPT_MCAST6_HOPS:
7479 * value: multicast hop limit
7481 * CM_INET_OPT_RECVIPV6_HOPLIM:
7482 * value: CM_INET_OPT_ENABLE hop limit will be returned
7484 * value: CM_INET_OPT_DISABLE hop limit wont be returned
7487 * CM_INET_OPT_RECVIPV6_HBHOPTS:
7488 * value: CM_INET_OPT_ENABLE HBH Options will be returned
7490 * value: CM_INET_OPT_DISABLE HBH Options wont be returned
7493 * CM_INET_OPT_RECVIPV6_DSTOPTS:
7494 * value: CM_INET_OPT_ENABLE Dest Options will be returned
7496 * value: CM_INET_OPT_DISABLE Dest Options wont be returned
7499 * CM_INET_OPT_RECVIPV6_RTHDR:
7500 * value: CM_INET_OPT_ENABLE Route Hdr Opt will be turned
7502 * value: CM_INET_OPT_DISABLE Route Hdr Opt will be turned
7503 * OFF on the socket.
7505 * CM_INET_OPT_IP_ROUTER_ALERT6
7506 * value: CM_INET_OPT_ENABLE
7507 * value: CM_INET_OPT_DISABLE
7509 * CM_INET_OPT_IPV6_PKTINFO
7510 * value: CM_INET_OPT_ENABLE Enable sending and receiving
7512 * value: CM_INET_OPT_DISABLE Disable sending and receiving
7515 * CM_INET_OPT_LINGER
7516 * value: address of CmInetSockLinger structure
7518 * CM_INET_OPT_SCTP_EVENTS
7519 * value: address of CmInetSctpSockEvent structure
7521 * CM_INET_OPT_SCTP_PRIM_ADDR
7522 * value: address of CmInetSctpPrimAddr structure
7524 * CM_INET_OPT_SCTP_PEERADDR_PARAMS
7525 * value: address of CmInetSctpPeerAddrParams structure
7528 * Ret: ROK - successful
7530 * RNA - failed, option not available
7531 * (Only when CM_INET2 is defined)
7533 * Notes: The send and receive buffer size may be system
7534 * specific. The cmInetSetOpt() call may return
7535 * successfuly although not the entire buffer size
7543 CmInetFd *sockFd, /* socket file descriptor */
7544 uint32_t level, /* option level */
7545 uint32_t type, /* option type */
7546 Ptr value /* option value */
7549 S32 ret = ROK; /* temporary return value */
7550 uint32_t disable = 0; /* disable option */
7551 uint32_t enable = 1; /* enable option */
7553 /* added for IPv4 options */
7554 #ifdef IPV4_OPTS_SUPPORTED
7555 #if((!defined (SS_VW)) && (!defined(SS_LINUX)))
7556 TknStr64 *tempTknStr64; /* points TknStr64 structure */
7557 /* which has value for IPv4 hdr options.*/
7558 #endif /* SS_VW && SS_LINUX */
7562 #endif /* IPV4_OPTS_SUPPORTED */
7564 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST)\
7566 uint8_t lpEnable = 1; /* multicast loop enable */
7567 uint8_t lpDisable = 0; /* multicast loop disable */
7568 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7571 BOOL boolEnable = TRUE; /* enable option */
7572 BOOL boolDisable = FALSE; /* disable option */
7575 #if (defined(SUNOS) || defined(WIN32) || defined(SS_PS) || \
7576 defined(SS_VW_MCAST) || defined(HPOS))
7577 struct ip_mreq stMreq;
7578 CmInetMCastInf *mCast;
7579 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7581 #ifdef IPV6_SUPPORTED
7582 uint32_t loopEna = 1; /* IPv6 multicast loop enable */
7583 uint32_t loopDis = 0; /* IPv6 multicast loop disable */
7584 struct ipv6_mreq *stMreq6Ptr;
7585 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
7586 this flag is gaurded under ICMPV6_FILTER_SUPPORTED. so if user want this
7587 support he has to enable the above flag.*/
7588 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
7589 * to support filteration of ICMP messages */
7590 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
7591 struct icmp6_filter *icmp6Filter;
7592 #endif /* ICMPV6_FILTER_SUPPORTED */
7593 #endif /* IPV6_SUPPORTED */
7595 /* cm_inet_c_001.main_58 : Added new local variables to support filteration
7596 * of ICMP messages */
7598 #ifdef CM_ICMP_FILTER_SUPPORT
7599 struct icmp_filter icmpFilter;
7603 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
7606 struct sctp_event_subscribe event;
7607 struct sctp_paddrparams addrParams;
7608 struct sctp_setprim setPrim;
7609 struct sockaddr_in *pAddr;
7610 struct sctp_assocparams assocParams;
7611 struct sctp_initmsg initmsg;
7612 struct sctp_rtoinfo rtoinfo;
7613 #ifdef IPV6_SUPPORTED
7614 struct sockaddr_in6 *pAddr6;
7615 #endif /* IPV6_SUPPORTED */
7617 CmInetSockLinger *pSockLinger;
7618 CmInetSctpSockEvent *pSctpEvent;
7619 CmInetSctpPrimAddr *pSctpPrimAddr;
7620 CmInetSctpPeerAddrParams *pSctpPAddrParams;
7621 CmInetSctpRtoInfo *pSctpRtoInfo;
7622 CmInetSctpInitMsg *pSctpInitMsg;
7623 CmInetSctpAssocParams *pSctpAssocParams;
7629 /* cm_inet_c_001.main_58 : Added NULL check for value field */
7635 #if (ERRCLASS & ERRCLS_INT_PAR)
7636 /* error check on parameters */
7637 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7641 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7645 case CM_INET_OPT_BLOCK:
7646 optVal = (uint32_t*)value;
7649 case CM_INET_OPT_ENABLE:
7652 /* cm_inet_c_001.main_59: Fix for compilation warning */
7653 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&disable);
7656 ret = ioctl(sockFd->fd, FIONBIO, (char*)&disable);
7659 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&disable);
7661 ret = ioctl(sockFd->fd, (S32)FIONBIO, &disable);
7666 sockFd->blocking = 1;
7669 case CM_INET_OPT_DISABLE:
7671 /* cm_inet_c_001.main_59: Fix for compilation warning */
7672 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&enable);
7675 ret = ioctl(sockFd->fd, FIONBIO, (char*)&enable);
7678 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&enable);
7680 ret = ioctl(sockFd->fd, (S32)FIONBIO, &enable);
7684 sockFd->blocking = 0;
7694 case CM_INET_OPT_REUSEADDR:
7695 optVal = (uint32_t*)value;
7696 if (*optVal == CM_INET_OPT_ENABLE)
7699 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7700 (char*)&boolEnable, sizeof(boolEnable));
7702 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7703 (char*)&enable, sizeof(enable));
7705 setsockopt(sockFd->fd, level, SO_REUSEPORT,
7706 (char*)&enable, sizeof(enable));
7710 else if (*optVal == CM_INET_OPT_DISABLE)
7713 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7714 (char*)&boolDisable, sizeof(boolDisable));
7716 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7717 (char*)&disable, sizeof(disable));
7719 ret = setsockopt(sockFd->fd, level, SO_REUSEPORT,
7720 (char*)&disable, sizeof(disable));
7726 case CM_INET_OPT_BROADCAST:
7727 optVal = (uint32_t*)value;
7728 if (*optVal == CM_INET_OPT_ENABLE)
7731 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7732 (char*)&boolEnable, sizeof(boolEnable));
7734 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7735 (char*)&enable, sizeof(enable));
7738 else if (*optVal == CM_INET_OPT_DISABLE)
7741 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7742 (char*)&boolDisable, sizeof(boolDisable));
7744 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7745 (char*)&disable, sizeof(disable));
7750 case CM_INET_OPT_KEEPALIVE:
7751 optVal = (uint32_t*)value;
7752 if (*optVal == CM_INET_OPT_ENABLE)
7755 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7756 (char*)&boolEnable, sizeof(boolEnable));
7758 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7759 (char*)&enable, sizeof(enable));
7762 else if (*optVal == CM_INET_OPT_DISABLE)
7765 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7766 (char*)&boolDisable, sizeof(boolDisable));
7768 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7769 (char*)&disable, sizeof(disable));
7774 case CM_INET_OPT_RX_BUF_SIZE:
7775 optVal = (uint32_t*)value;
7776 ret = setsockopt(sockFd->fd, level, SO_RCVBUF,
7777 (char*)optVal, sizeof(*optVal));
7780 case CM_INET_OPT_TX_BUF_SIZE:
7781 optVal = (uint32_t*)value;
7782 ret = setsockopt(sockFd->fd, level, SO_SNDBUF,
7783 (char*)optVal, sizeof(*optVal));
7786 case CM_INET_OPT_TCP_NODELAY:
7787 optVal = (uint32_t*)value;
7788 if (*optVal == CM_INET_OPT_ENABLE)
7792 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7793 (char*)&boolEnable, sizeof(boolEnable));
7794 #endif /* SS_WINCE */
7796 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7797 (char*)&enable, sizeof(enable));
7800 else if (*optVal == CM_INET_OPT_DISABLE)
7804 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7805 (char*)&boolDisable, sizeof(boolDisable));
7806 #endif /* SS_WINCE */
7808 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7809 (char*)&disable, sizeof(disable));
7814 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || \
7815 defined(SS_VW_MCAST) || defined(HPOS))
7817 case CM_INET_OPT_ADD_MCAST_MBR:
7818 mCast = (CmInetMCastInf*)value;
7820 /* Copy the addresses to stMreq structure */
7822 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7824 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7826 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7828 ret = setsockopt(sockFd->fd, level, IP_ADD_MEMBERSHIP,
7829 (char*)&stMreq, sizeof(stMreq));
7832 case CM_INET_OPT_DRP_MCAST_MBR:
7833 mCast = (CmInetMCastInf*)value;
7835 /* Copy the addresses to stMreq structure */
7837 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7839 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7841 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7843 ret = setsockopt(sockFd->fd, level, IP_DROP_MEMBERSHIP,
7844 (char*)&stMreq, sizeof(stMreq));
7847 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7850 /* cm_inet_c_001.main_37 - Enable CMINET_BSDCOMPAT flag if system doesnt
7851 support CM_INET_OPT_BSD_COMPAT */
7852 #ifndef CMINET_BSDCOMPAT
7853 case CM_INET_OPT_BSD_COMPAT:
7854 optVal = (uint32_t*)value;
7855 if (*optVal == CM_INET_OPT_ENABLE)
7857 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7858 &enable, sizeof(enable));
7860 else if (*optVal == CM_INET_OPT_DISABLE)
7862 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7863 &disable, sizeof(disable));
7866 #endif /* CMINET_BSDCOMPAT */
7867 #endif /* SS_LINUX */
7870 /* Added for support of Raw socket modify according to the
7871 * option available on different platform */
7872 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW) \
7874 case CM_INET_OPT_HDR_INCLD:
7875 optVal = (uint32_t*)value;
7876 if (*optVal == CM_INET_OPT_ENABLE)
7881 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7882 (char*)&enable, sizeof(enable));
7885 else if (*optVal == CM_INET_OPT_DISABLE)
7890 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7891 (char*)&disable, sizeof(disable));
7896 /* added new options */
7897 #ifdef IPV4_OPTS_SUPPORTED
7899 /* Linux: set Router Alert socket option to Intercept RAW RSVP
7900 packets at the Intermediate node(Router) with Router Alert SET.
7901 This socket option is MUST be set (when this server is opened)
7902 if the RSVP server wants to intercept raw RSVP packets. */
7903 case CM_INET_OPT_IP_ROUTER_ALERT:
7904 optVal = (uint32_t*)value;
7905 if (*optVal == CM_INET_OPT_ENABLE)
7907 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7908 (char*)&enable, sizeof(enable));
7912 else if (*optVal == CM_INET_OPT_DISABLE)
7914 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7915 (char*)&disable, sizeof(disable));
7920 #endif /* SS_LINUX */
7922 /* set Router Alert socket option */
7923 case CM_INET_OPT_IP_OPTIONS:
7924 #if (defined (SS_VW) || defined(SS_LINUX))
7927 tempTknStr64=(TknStr64 *)value;
7928 if (tempTknStr64->pres == TRUE)
7930 if (tempTknStr64->len == 0)
7932 /* disable the IP_OPTIONS for Router Alert. */
7934 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7935 (const char *)&disableOpt, sizeof(int));
7937 ret = setsockopt(sockFd->fd, level, IP_OPTIONS, NULL, 0);
7941 /* enable the IP_OPTIONS for Router Alert */
7942 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7943 (char *)tempTknStr64->val, tempTknStr64->len);
7946 return RFAILED; /* Trying to set IPv4 Hdr option
7947 * without giving option values*/
7948 #endif /* SS_VW || SS_LINUX */
7950 #endif /* IPV4_OPTS_SUPPORTED */
7952 /* added new options */
7953 #if (defined(SS_LINUX) && (!defined(SS_VW) && !defined(WIN32)))
7955 case CM_INET_OPT_IPV4_PKTINFO:
7956 optVal = (uint32_t*)value;
7957 if (*optVal == CM_INET_OPT_ENABLE)
7959 /* set IP_PKTINFO option when IP_ROUTER_ALERT is set in linux */
7960 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7961 (char*)&enable, sizeof(enable));
7966 else if (*optVal == CM_INET_OPT_DISABLE)
7968 /* disable IP_PKTINFO when IP_ROUTER_ALERT is set in linux */
7969 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7970 (char*)&disable, sizeof(disable));
7976 #endif /* LOCAL_INTF */
7977 #endif /* SS_LINUX */
7979 #endif /* SUNOS || WIN32 || SS_PS || SS_VW || HPOS */
7981 case CM_INET_OPT_DONTFRAGMENT:
7982 optVal = (uint32_t*)value;
7983 if (*optVal == CM_INET_OPT_ENABLE)
7986 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
7987 (char*)&boolEnable, sizeof(boolEnable));
7990 else if (*optVal == CM_INET_OPT_DISABLE)
7993 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
7994 (char*)&boolDisable, sizeof(boolDisable));
7999 /* also add these 2 options for VxWorks */
8000 #if (defined(SUNOS)|| defined(WIN32) || defined(HPOS) || defined(SS_VW))
8001 case CM_INET_OPT_TOS:
8002 optVal = (uint32_t*)value;
8003 ret = setsockopt(sockFd->fd, level, IP_TOS,
8004 (char*)optVal, sizeof(*optVal));
8007 case CM_INET_OPT_TTL:
8008 optVal = (uint32_t*)value;
8009 ret = setsockopt(sockFd->fd, level, IP_TTL,
8010 (char*)optVal, sizeof(*optVal));
8012 #endif /* SUNOS || WIN32 || HPOS || SS_VW */
8013 #endif /* CM_INET2 */
8015 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST) \
8017 case CM_INET_OPT_MCAST_LOOP:
8018 optVal = (uint32_t*)value;
8019 if (*optVal == CM_INET_OPT_ENABLE)
8022 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8023 (char *)&lpEnable, sizeof(lpEnable));
8025 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8026 (const char *)&lpEnable, sizeof(lpEnable));
8032 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8033 (char *)&lpDisable, sizeof(lpDisable));
8035 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8036 (const char *)&lpDisable, sizeof(lpDisable));
8041 case CM_INET_OPT_MCAST_IF:
8042 optVal = (uint32_t*)value;
8043 *optVal = CM_INET_HTON_UINT32((uint32_t)*optVal);
8044 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_IF,
8045 (char *)optVal, sizeof(struct in_addr));
8048 case CM_INET_OPT_MCAST_TTL:
8049 optVal = (uint32_t*)value;
8050 /* remove const in setsockopt for VW */
8052 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8053 (char *)optVal, sizeof(uint8_t));
8055 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8056 (const char *)optVal, sizeof(uint8_t));
8059 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8061 #ifdef IPV6_SUPPORTED
8062 case CM_INET_OPT_IPV6_TTL:
8063 optVal = (uint32_t*)value;
8064 ret = setsockopt(sockFd->fd, level, IPV6_UNICAST_HOPS,
8065 (char*)optVal, sizeof(*optVal));
8068 case CM_INET_OPT_ADD_MCAST6_MBR:
8069 stMreq6Ptr = (struct ipv6_mreq *)value;
8070 ret = setsockopt(sockFd->fd, level, IPV6_JOIN_GROUP,
8071 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8074 case CM_INET_OPT_DRP_MCAST6_MBR:
8075 stMreq6Ptr = (struct ipv6_mreq *)value;
8076 ret = setsockopt(sockFd->fd, level, IPV6_LEAVE_GROUP,
8077 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8080 case CM_INET_OPT_MCAST6_LOOP:
8081 optVal = (uint32_t*)value;
8082 if (*optVal == CM_INET_OPT_ENABLE)
8084 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8085 &loopEna, sizeof(loopEna));
8089 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8090 &loopDis, sizeof(loopDis));
8094 case CM_INET_OPT_MCAST6_IF:
8095 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_IF,
8096 (uint32_t *)value, sizeof(uint32_t));
8099 case CM_INET_OPT_MCAST6_HOPS:
8100 optVal = (uint32_t*)value;
8101 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_HOPS,
8102 (char *)optVal, sizeof(uint32_t));
8105 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
8106 this flag is gaurded under ICMPV6_SUPPORTED. so if user want this
8107 support he has to enable the above flag.*/
8108 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8109 * to support filteration of ICMP messages */
8110 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8111 case CM_INET_OPT_ICMP6_FILTER:
8112 icmp6Filter = (struct icmp6_filter *)value;
8113 ret = setsockopt(sockFd->fd, level, ICMP6_FILTER,
8114 (char *)icmp6Filter, sizeof(struct icmp6_filter));
8116 #endif /* ICMPV6_FILTER_SUPPORTED */
8118 /* added new options */
8119 #ifdef IPV6_OPTS_SUPPORTED
8120 case CM_INET_OPT_RECVIPV6_HOPLIM:
8121 optVal = (uint32_t*)value;
8123 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8124 (char *)optVal, sizeof(uint32_t));
8126 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8127 (char *)optVal, sizeof(uint32_t));
8128 /* enable the reception of IPv6 HopLimit value as ancillary data */
8129 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPLIMIT,
8130 (char*)&enable, sizeof(enable));
8131 #endif /* SS_LINUX */
8135 case CM_INET_OPT_RECVIPV6_HBHOPTS:
8136 optVal = (uint32_t*)value;
8138 ret = setsockopt(sockFd->fd, level, IPV6_HOPOPTS,
8139 (char *)optVal, sizeof(uint32_t));
8141 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPOPTS,
8142 (char *)optVal, sizeof(uint32_t));
8143 #endif /* SS_LINUX */
8146 case CM_INET_OPT_RECVIPV6_DSTOPTS:
8147 optVal = (uint32_t*)value;
8149 ret = setsockopt(sockFd->fd, level, IPV6_DSTOPTS,
8150 (char *)optVal, sizeof(uint32_t));
8152 ret = setsockopt(sockFd->fd, level, IPV6_RECVDSTOPTS,
8153 (char *)optVal, sizeof(uint32_t));
8154 #endif /* SS_LINUX */
8157 case CM_INET_OPT_RECVIPV6_RTHDR:
8158 optVal = (uint32_t*)value;
8160 ret = setsockopt(sockFd->fd, level, IPV6_RTHDR,
8161 (char *)optVal, sizeof(uint32_t));
8163 ret = setsockopt(sockFd->fd, level, IPV6_RECVRTHDR,
8164 (char *)optVal, sizeof(uint32_t));
8165 #endif /* SS_LINUX */
8168 /* works ONLY for IPPROTO_RAW type socket. so if it this socket
8169 * option is tried to set for IPPROTO_RSVP, then it is supposed
8170 * to fail with EINVAL according to net/ipv6/ipv6_sockglue.c
8172 * if HI_SRVC_RAW_RAW is not used during ServOpenReq as the server
8173 * type, then it will fail here due to above reason */
8175 case CM_INET_OPT_IP_ROUTER_ALERT6:
8176 optVal = (uint32_t*)value;
8177 if(*optVal == CM_INET_OPT_ENABLE)
8178 ret = setsockopt(sockFd->fd, IPPROTO_IPV6, IPV6_ROUTER_ALERT,
8179 (char *)&enable, sizeof(enable));
8181 ret = setsockopt(sockFd->fd, level, IPV6_ROUTER_ALERT,
8182 (char *)&disable, sizeof(disable));
8185 #endif /* SS_LINUX */
8186 #endif /* IPV6_OPTS_SUPPORTED */
8189 case CM_INET_OPT_IPV6_PKTINFO:
8190 optVal = (uint32_t*)value;
8192 ret = setsockopt(sockFd->fd, level, IPV6_PKTINFO,
8193 (char *)optVal, sizeof(uint32_t));
8195 ret = setsockopt(sockFd->fd, level, IPV6_RECVPKTINFO,
8196 (char *)&enable, sizeof(enable));
8197 #endif /* SS_LINUX */
8199 #endif /* LOCAL_INTF */
8201 #endif /* IPV6_SUPPORTED */
8203 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8205 case CM_INET_OPT_LINGER:
8206 pSockLinger = (CmInetSockLinger *)value;
8208 memset(&lngr, 0, sizeof(struct linger));
8210 if (pSockLinger->enable == TRUE)
8215 lngr.l_linger = pSockLinger->lingerTime;
8216 ret = setsockopt(sockFd->fd, level, SO_LINGER, &lngr, sizeof(lngr));
8219 case CM_INET_OPT_SCTP_EVENTS:
8220 pSctpEvent = (CmInetSctpSockEvent *)value;
8222 memset(&event, 0, sizeof(struct sctp_event_subscribe));
8224 if (pSctpEvent->dataIoEvent == TRUE)
8225 event.sctp_data_io_event = 1;
8227 if (pSctpEvent->associationEvent == TRUE)
8228 event.sctp_association_event = 1;
8230 if (pSctpEvent->addressEvent == TRUE)
8231 event.sctp_address_event = 1;
8233 if (pSctpEvent->sendFailureEvent == TRUE)
8234 event.sctp_send_failure_event = 1;
8236 if (pSctpEvent->peerErrorEvent == TRUE)
8237 event.sctp_peer_error_event = 1;
8239 if (pSctpEvent->shutdownEvent == TRUE)
8240 event.sctp_shutdown_event = 1;
8242 if (pSctpEvent->partialDeliveryEvent == TRUE)
8243 event.sctp_partial_delivery_event = 1;
8245 if (pSctpEvent->adaptationLayerEvent == TRUE)
8247 event.sctp_adaption_layer_event = 1;
8249 event.sctp_adaptation_layer_event = 1;
8252 ret = setsockopt(sockFd->fd, level, SCTP_EVENTS, &event, sizeof(event));
8255 case CM_INET_OPT_SCTP_PRIM_ADDR:
8256 pSctpPrimAddr = (CmInetSctpPrimAddr *)value;
8258 memset(&setPrim, 0, sizeof(struct sctp_setprim));
8260 #ifdef IPV6_SUPPORTED
8261 if (pSctpPrimAddr->addr.type == CM_INET_IPV6ADDR_TYPE)
8263 if (sockFd->protType == AF_INET)
8267 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8268 /* cm_inet_c_001.main_62:Warning fix */
8269 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8270 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8271 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8273 /* cm_inet_c_001.main_62:Warning fix */
8274 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8275 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8276 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8277 #endif /*ALIGN_64BIT*/
8278 #endif /* CMINETDBG */
8282 pAddr6 = (struct sockaddr_in6*)&(setPrim.ssp_addr);
8283 pAddr6->sin6_family = AF_INET6;
8284 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8285 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPrimAddr->addr.u.ipv6NetAddr);
8289 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8290 pAddr->sin_family = AF_INET;
8291 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8292 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8295 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8296 pAddr->sin_family = AF_INET;
8297 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8298 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8299 #endif /* IPV6_SUPPORTED */
8301 setPrim.ssp_assoc_id = pSctpPrimAddr->assocId;
8303 ret = setsockopt(sockFd->fd, level, SCTP_PRIMARY_ADDR, &setPrim, sizeof(setPrim));
8306 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
8307 pSctpPAddrParams = (CmInetSctpPeerAddrParams *)value;
8309 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
8312 if (pSctpPAddrParams->s.addrPres == TRUE)
8314 #ifdef IPV6_SUPPORTED
8315 if (pSctpPAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
8317 if (sockFd->protType == AF_INET)
8321 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8322 /* cm_inet_c_001.main_62:Warning fix */
8323 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8324 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8325 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8327 /* cm_inet_c_001.main_62:Warning fix */
8328 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8329 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8330 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8331 #endif /*ALIGN_64BIT*/
8332 #endif /* CMINETDBG */
8337 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
8338 pAddr6->sin6_family = AF_INET6;
8339 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8340 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPAddrParams->s.addr.u.ipv6NetAddr);
8344 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8345 pAddr->sin_family = AF_INET;
8346 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8347 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8350 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8351 pAddr->sin_family = AF_INET;
8352 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8353 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8354 #endif /* IPV6_SUPPORTED */
8358 #ifdef IPV6_SUPPORTED
8359 if (sockFd->protType == AF_INET6)
8360 addrParams.spp_address.ss_family = AF_INET6;
8362 addrParams.spp_address.ss_family = AF_INET;
8364 addrParams.spp_address.ss_family = AF_INET;
8368 /* Not validating the address, whether addr is a valid address or not */
8370 addrParams.spp_assoc_id = pSctpPAddrParams->assocId;
8371 /*cm_inet_c_001.main_58 : fix for klockwork issue */
8372 addrParams.spp_pathmaxrxt = (uint16_t)pSctpPAddrParams->pathMaxRxt;
8374 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8375 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8377 addrParams.spp_hbinterval = 0;
8380 addrParams.spp_flags = 0;
8382 if (pSctpPAddrParams->pmtudFlag == CM_INET_OPT_ENABLE)
8384 addrParams.spp_flags |= SPP_PMTUD_ENABLE;
8385 addrParams.spp_pathmtu = pSctpPAddrParams->pathMtu;
8387 else if(pSctpPAddrParams->pmtudFlag == CM_INET_OPT_DISABLE)
8388 addrParams.spp_flags |= SPP_PMTUD_DISABLE;
8390 if (pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_ENABLE)
8392 addrParams.spp_flags |= SPP_SACKDELAY_ENABLE;
8393 addrParams.spp_sackdelay = pSctpPAddrParams->sackDelay;
8395 else if(pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_DISABLE)
8396 addrParams.spp_flags |= SPP_SACKDELAY_DISABLE;
8398 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8400 addrParams.spp_flags |= SPP_HB_ENABLE;
8401 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8403 else if(pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_DISABLE)
8404 addrParams.spp_flags |= SPP_HB_DISABLE;
8406 ret = setsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, sizeof(addrParams));
8409 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
8410 pSctpAssocParams = (CmInetSctpAssocParams *)value;
8412 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
8414 assocParams.sasoc_cookie_life = pSctpAssocParams->cookieLife;
8415 assocParams.sasoc_asocmaxrxt = pSctpAssocParams->assocMaxReTx;
8416 assocParams.sasoc_assoc_id = pSctpAssocParams->assocId;
8417 assocParams.sasoc_number_peer_destinations = pSctpAssocParams->numberOfPeerDest;
8418 assocParams.sasoc_peer_rwnd = pSctpAssocParams->peerRwnd;
8419 assocParams.sasoc_local_rwnd = pSctpAssocParams->localRwnd;
8421 ret = setsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams));
8424 case CM_INET_OPT_SCTP_RTO_INFO:
8425 pSctpRtoInfo = (CmInetSctpRtoInfo *)value;
8427 memset(&rtoinfo, 0, sizeof(struct sctp_rtoinfo));
8429 rtoinfo.srto_assoc_id = pSctpRtoInfo->assocId;
8430 rtoinfo.srto_initial = pSctpRtoInfo->rtoInitial;
8431 rtoinfo.srto_max = pSctpRtoInfo->rtoMax;
8432 rtoinfo.srto_min = pSctpRtoInfo->rtoMin;
8434 ret = setsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
8437 case CM_INET_OPT_SCTP_INIT_MSG:
8438 pSctpInitMsg = (CmInetSctpInitMsg *)value;
8440 memset(&initmsg, 0, sizeof(struct sctp_initmsg));
8442 initmsg.sinit_max_attempts = pSctpInitMsg->maxInitReTx;
8443 initmsg.sinit_max_init_timeo = pSctpInitMsg->maxInitTimeout;
8444 initmsg.sinit_num_ostreams = pSctpInitMsg->numOstreams;
8445 initmsg.sinit_max_instreams = pSctpInitMsg->maxInstreams;
8447 ret = setsockopt(sockFd->fd, level, SCTP_INITMSG, &initmsg, sizeof(initmsg));
8450 #endif /*CM_LKSCTP*/
8452 /* cm_inet_c_001.main_58 : Added to support filteration of ICMP
8453 * messages and protected under CM_ICMP_FILTER_SUPPORT flag. Its a
8454 * partial implementaion for icmp filter done for TUCL */
8456 #ifdef CM_ICMP_FILTER_SUPPORT
8457 case CM_INET_OPT_ICMP_FILTER:
8458 optVal = (uint32_t*)value;
8459 ret = setsockopt(sockFd->fd, level, ICMP_FILTER,
8460 optVal, sizeof(icmpFilter));
8466 /* wrong socket option type */
8471 if (ret == INET_ERR)
8475 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8476 /* cm_inet_c_001.main_62:Warning fix */
8477 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%ld)\n",
8478 INET_ERR_CODE, sockFd->fd);
8479 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8481 /* cm_inet_c_001.main_62:Warning fix */
8482 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%d)\n",
8483 INET_ERR_CODE, sockFd->fd);
8484 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8485 #endif /*ALIGN_64BIT*/
8486 #endif /* CMINETDBG */
8490 } /* end of cmInetSetOpt */
8496 * Fun: cmInetGetNumRead
8498 * Desc: Gives the number of pending octets in the socket receive buffer.
8500 * Ret: ROK - successful
8509 S16 cmInetGetNumRead
8511 CmInetFd *sockFd, /* socket file descriptor */
8512 uint32_t *dataLen /* number of pending octets */
8513 /* removed 3rd argument memInfo */
8516 S32 ret; /* temporary return value */
8518 /* removed local variables added for recvfrom call */
8521 #if (ERRCLASS & ERRCLS_INT_PAR)
8522 /* error check on parameters */
8523 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
8530 /* use ioctl call for all types of socket to get length of
8531 pending data in the socket recv buffer */
8533 /* cm_inet_c_001.main_59: Fix for compilation warning */
8534 ret = ioctlsocket(sockFd->fd, FIONREAD, (uint32_t *)dataLen);
8537 ret = ioctl(sockFd->fd, FIOREAD, (char*)dataLen);
8540 ret = ioctl(sockFd->fd, FIONREAD, (S32)dataLen);
8542 ret = ioctl(sockFd->fd, FIONREAD, dataLen);
8547 /* For UDP socket assign the length of pending data in the
8548 socket recv buffer to largest datagram size.
8549 Removed recvfrom call & necessary processing for it. */
8551 if (ret == INET_ERR)
8553 /* removed error check CONABORTED added for recvfrom call.
8554 Also return value changed from RCLOSED to ROK */
8555 /* Check for reset connection */
8556 /* cm_inet_c_001.main_45: Close the TCP connection only when err is one of these*/
8557 if ((INET_ERR_CODE == ERR_CONNREFUSED) ||
8558 (INET_ERR_CODE == ERR_CONNABORTED) ||
8559 (INET_ERR_CODE == ERR_TIMEDOUT))
8563 /* cm_inet_c_001.main_50
8564 * Return RCLOSED instead of ROK to initiate connection closure.
8565 * ROK will be returned only if the ioctl call above returns ROK.
8566 * The routines calling this function have been modified to not
8567 * return RCLOSED when this function returns ROK with pending data
8568 * length value of 0. This modification is needed because:
8569 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
8570 * returns successfully with pend length as 0 on a TCP socket that
8571 * select says is ready to read. This should not be considered as
8572 * connection closed.
8577 /* removed error check ERR_WOULDBLOCK */
8578 /* cm_inet_c_001.main_45: Dont close the connection in case of ERR_CONNRESET */
8579 if ((INET_ERR_CODE == ERR_AGAIN) ||
8580 (INET_ERR_CODE == ERR_CONNRESET))
8587 /* cm_inet_c_001.main_45: Change 2048 to CM_INET_MAX_UDPRAW_MSGSIZE */
8588 *dataLen = CM_INET_MAX_UDPRAW_MSGSIZE;
8590 #endif /* SS_LINUX */
8592 /* removed error debug printing added for recvfrom call. */
8596 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8597 /* cm_inet_c_001.main_62:Warning fix */
8598 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8599 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
8600 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8602 /* cm_inet_c_001.main_62:Warning fix */
8603 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8604 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
8605 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8606 #endif /*ALIGN_64BIT*/
8607 #endif /* CMINETDBG */
8612 } /* end of cmInetGetNumRead */
8618 * Fun: cmInetGetHostByName
8620 * Desc: Resolves a host name into the appropriate 4 byte Internet
8623 * Ret: ROK - successful
8632 S16 cmInetGetHostByName
8634 S8 *hostName, /* host name */
8635 CmInetIpAddrTbl *addrTbl /* Address Table of IPV4 Addresses */
8639 uint8_t numAddrs; /* Number of Addresses */
8642 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8643 struct hostent *hostid; /* pointer to host information */
8646 struct hostent hostid; /* host information */
8647 S8 infoBuf[CM_INET_MAX_INFO]; /* info buffer */
8648 S32 err; /* error code */
8650 #endif /* WIN32 || SS_LINUX || HPOS */
8653 #if (ERRCLASS & ERRCLS_INT_PAR)
8654 /* error check on parameters */
8655 if ((hostName == NULLP) || (addrTbl == NULLP))
8659 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8668 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8669 hostid = gethostbyname(hostName);
8673 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8674 /* cm_inet_c_001.main_62:Warning fix */
8675 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8676 " hostName(%p)\n", INET_ERR_CODE, hostName);
8677 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET044, 0, prntBuf);
8678 #endif /* CMINETDBG */
8681 if (hostid->h_addrtype != AF_INET)
8684 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8685 /* cm_inet_c_001.main_62:Warning fix */
8686 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetHostByName() Failed : error(%d),"
8687 " hostName(%p), hostid->h_addrtype(%d)\n",
8688 INET_ERR_CODE, hostName, hostid->h_addrtype);
8689 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET045, 0, prntBuf);
8690 #endif /* CMINETDBG */
8695 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8696 (hostid->h_addr_list[numAddrs] != NULLP))
8698 addrTbl->netAddr[addrTbl->count++] =
8699 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8709 vwIpAddr = hostGetByName(hostName);
8710 if (vwIpAddr == INET_ERR)
8713 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8714 /* cm_inet_c_001.main_62:Warning fix */
8715 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8716 " hostName(%p)\n", INET_ERR_CODE, hostName);
8717 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET046, 0, prntBuf);
8718 #endif /* CMINETDBG */
8721 CM_COPY_VWIPADDR(vwIpAddr, &(addrTbl->netAddr[addrTbl->count]));
8726 err = 0; /* err is not reset by gethostnyname_r()! */
8728 gethostbyname_r(hostName, &hostid, infoBuf, CM_INET_MAX_INFO, (int*)&err);
8729 if ((hostid.h_addrtype != AF_INET) || (err < 0))
8732 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8733 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d), hostName(%p),"
8734 " hostid.h_addrtype(%d)\n",
8735 INET_ERR_CODE, hostName, hostid.h_addrtype);
8736 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET047, 0, prntBuf);
8737 #endif /* CMINETDBG */
8742 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8743 (hostid.h_addr_list[numAddrs] != NULLP))
8745 addrTbl->netAddr[addrTbl->count++] =
8746 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid.h_addr_list[numAddrs]));
8752 #endif /* WIN32 || SS_LINUX || HPOS */
8756 } /* end of cmInetGetHostByName */
8759 /* The getipnodebyname is not supported on all the Solaris Operating system
8760 * versions. This has to be supported on operating systems that support IPV6
8761 * as per the RFC on the IPV6 socket interface. Hence this function is moved
8762 * under the IPV6_SUPPORTED flag */
8764 /* This function now can be called for both IPv4 and IPv6. However, we will
8765 * call cmInetGetHostByName inside for IPv4. Move all flag dependencies
8766 * inside this function. */
8769 * Fun: cmInetGetIpNodeByName
8771 * Desc: Resolves a host name into the appropriate 4 byte Internet
8772 * address or into the appropriate 16 byte IPV6 address.
8773 * This function is expected to be thread safe and should be used
8774 * instead of the cmInetGetHostByName function.
8776 * Ret: ROK - successful
8784 S16 cmInetGetIpNodeByName
8786 S8 *hostName, /* host name */
8787 CmInetIpAddrArr *addrArr /* Array of addressed filled in */
8790 /* for return value from cmInetGetHostByName */
8791 #ifndef IPV6_SUPPORTED
8796 uint8_t numAddrs=0; /* Number of addresses */
8797 int err=0; /* error code */
8798 struct hostent *hostid; /* host information */
8799 #endif /* SS_LINUX */
8801 #endif /* IPV6_SUPPORTED */
8805 #if (ERRCLASS & ERRCLS_INT_PAR)
8806 /* error check on parameters */
8807 if ((hostName == NULLP) || (addrArr == NULLP))
8811 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8813 #ifdef IPV6_SUPPORTED
8817 #ifdef IPV6_SUPPORTED
8818 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8819 hostid = getipnodebyname(hostName, AF_INET6, 0, &err);
8821 #endif /* IPV6_SUPPORTED */
8822 hostid = getipnodebyname(hostName, AF_INET, 0, &err);
8826 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8827 /* cm_inet_c_001.main_62:Warning fix */
8828 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetIpNodeByName() Failed : error(%d),"
8829 " hostName(%p), addrArr->type(%d)n",
8830 err, hostName, addrArr->type);
8831 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET048, 0, prntBuf);
8832 #endif /* CMINETDBG */
8836 #ifdef IPV6_SUPPORTED
8837 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8839 if (hostid->h_addrtype == AF_INET6)
8841 while ((numAddrs < CM_INET_IPV6_NUM_ADDR) &&
8842 (hostid->h_addr_list[numAddrs] != NULLP))
8844 /* Use the cminet fill macro here */
8845 CM_INET_COPY_IPV6ADDR(&addrArr->u.ipv6AddrArr.netAddr[numAddrs],
8846 hostid->h_addr_list[numAddrs]);
8847 addrArr->u.ipv6AddrArr.count++;
8854 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8855 /* cm_inet_c_001.main_62:Warning fix */
8856 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8857 " hostName(%p), addrArr->type(%d),hostid->h_addrtype(%d) \n",
8858 err, hostName, addrArr->type, hostid->h_addrtype);
8859 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET049, 0, prntBuf);
8860 #endif /* CMINETDBG */
8865 #endif /* IPV6_SUPPORTED */
8867 if (hostid->h_addrtype == AF_INET)
8869 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8870 (hostid->h_addr_list[numAddrs] != NULLP))
8872 addrArr->u.ipv4AddrArr.count ++;
8873 addrArr->u.ipv4AddrArr.netAddr[numAddrs] =
8874 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8881 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8882 /* cm_inet_c_001.main_62:Warning fix */
8883 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8884 " hostName(%p), hostid->h_addrtype(%d), addrArr->type(%d)\n",
8885 err, hostName, hostid->h_addrtype, addrArr->type);
8886 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET050, 0, prntBuf);
8887 #endif /* CMINETDBG */
8891 #endif /* SS_LINUX */
8896 ret = cmInetGetHostByName(hostName, &addrArr->u.ipv4AddrArr);
8898 #endif /* IPV6_SUPPORTED */
8900 } /* end of cmInetGetIpNodeByName */
8907 * Desc: Converts an ASCII string containig an internet address
8908 * ("xxx.xxx.xxx.xxx") into a CmInetIpAddr (uint32_t) format.
8909 * This function is a wrapper for the inet_addr() call.
8911 * Ret: ROK - successful
8921 S8 *asciiAddr, /* ascii address representation */
8922 CmInetIpAddr *address /* 4 byte interent address */
8926 #if (ERRCLASS & ERRCLS_INT_PAR)
8927 /* error check on parameters */
8928 if (asciiAddr == NULLP)
8932 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8934 *address = inet_addr(asciiAddr);
8935 if (*address == (uint32_t)ERR_INADDRNONE)
8937 /* asciiAddr does not contain a valid internet address */
8949 * Desc: Converts an CmInetIPAddr based IP address into a string
8950 * of the format "xxx.xxx.xxx.xxx".
8951 * This function is a wrapper for the inet_ntoa() call.
8953 * Ret: ROK - successful
8956 * Notes: This function delivers a pointer to a static buffer
8957 * within the system. Therefore the string has to be copied
8958 * by the caller before another call is made!
8965 CmInetIpAddr address, /* 4 byte interent address */
8966 S8 **asciiAddr /* ascii address representation */
8969 struct in_addr inetAddr; /* internet address structure */
8972 #if (ERRCLASS & ERRCLS_INT_PAR)
8973 /* error check on parameters */
8974 if (asciiAddr == NULLP)
8978 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8980 inetAddr.s_addr = address;
8982 *asciiAddr = inet_ntoa(inetAddr);
8983 if (*asciiAddr == NULL)
8994 * Desc: Converts an network address into a string.
8995 * This function is a wrapper for the inet_ntop() call.
8997 * Ret: ROK - successful
9000 * Notes: This function copies the resulting string to the buffer pointed to
9001 * by asciiaddr,which must be a non NULL pointer.The caller specifies
9002 * the number of bytes available in this buffer in the argument len.
9009 uint8_t type, /* ip address type */
9010 Void *address, /* 4/16 byte interent address */
9011 S8 *asciiAddr, /* ascii adress representation */
9018 #if (ERRCLASS & ERRCLS_INT_PAR)
9019 /* error check on parameters */
9020 if (asciiAddr == NULLP || address == NULLP || len == 0 )
9025 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9028 case CM_INET_IPV4ADDR_TYPE :
9031 case CM_INET_IPV6ADDR_TYPE :
9035 if(inet_ntop(domain,address,asciiAddr,len) == NULL)
9044 /* The inet_pton is not supported on all the Solaris Operating system
9045 * versions. This has to be supported on operating systems that support
9046 * IPV6 as per the RFC on the IPV6 socket interface. Hence this function
9047 *is moved under the IPV6_SUPPORTED flag */
9048 #ifdef IPV6_SUPPORTED
9055 * Desc: Converts a IP address string to address.
9057 * Ret: ROK - successful
9067 CmInetIpAddr *address, /* 4 byte interent address */
9068 S8 *asciiAddr /* ascii address representation */
9074 #if (ERRCLASS & ERRCLS_INT_PAR)
9075 /* error check on parameters */
9076 if ((asciiAddr == NULLP) || (address == NULLP))
9080 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9082 ret = inet_pton(AF_INET, asciiAddr, (void *)address);
9089 } /* end of cmInetPton */
9091 #endif /* IPV6_SUPPORTED */
9093 #ifdef IPV6_SUPPORTED
9099 * Desc: Converts a IP address string to IPV6 address suitable
9100 * to be used in bind.
9102 * Ret: ROK - successful
9111 CmInetIpAddr6 *address6, /* 16 byte interent address */
9112 S8 *asciiAddr /* ascii address representation */
9118 struct sockaddr_storage ss;
9119 uint32_t sslen = sizeof(ss);
9122 #if (ERRCLASS & ERRCLS_INT_PAR)
9123 /* error check on parameters */
9124 if ((asciiAddr == NULLP) || (address6 == NULLP))
9128 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9131 ret = inet_pton(AF_INET6, asciiAddr, (void *)address6);
9137 /* cm_inet_c_001.main_44 : In windows inet_pton is not implemented. so we are using the below function
9138 * to convert the ipv6 address string to appropriate form */
9139 WSAStringToAddressA((LPTSTR)asciiAddr, AF_INET6, NULL, (struct sockaddr*)&ss, &sslen);
9140 memcpy(address6, &(((struct sockaddr_in6 *)&ss)->sin6_addr), sizeof(CmInetIpAddr6));
9144 } /* end of cmInetPton6 */
9145 #endif /* IPV6_SUPPORTED */
9151 * Fun: cmInetGetMemSize
9153 * Desc: This function gives the max number of static buffer space that
9154 * the internet library will allocate.
9156 * Ret: ROK - successful
9164 S16 cmInetGetMemSize(
9165 S32 *size /* max used memory size */
9169 /* max static memory size depends on max flat buffer size */
9170 *size = CM_INET_MAX_MSG_LEN;
9172 /* max static memory size depends on max flat buffer or iovect size */
9173 *size = CM_INET_MAX_MSG_LEN;
9185 * Desc: This function initializes the socket library.
9187 * Ret: ROK - successful
9189 * Notes: Required only for Winsock and not for 4.3BSD
9195 S16 cmInetInit(Void)
9202 version = MAKEWORD(CM_INET_HIGH_VER, CM_INET_LOW_VER);
9203 err = WSAStartup(version, &data);
9218 * Desc: This function de initializes the socket library. The
9219 * WINSOCK implementation de registers the application and
9220 * releases any resources allocated on behalf of the
9223 * Ret: ROK - successful
9225 * Notes: Required only for Winsock and not for 4.3BSD
9231 S16 cmInetDeInit(Void)
9244 }/* end of cmInetDeInit() */
9249 * Fun: cmInetGetSockName
9251 * Desc: This function is used to retireve the current name
9252 * for the specified socket descriptor. It returns the
9253 * local association(address and port) for the socket.
9255 * Ret: ROK - successful
9258 * Notes: Please note if the socket was bound to CM_INET_INADDR_ANY
9259 * cmInetGetSockName() will not necessarily return the local
9260 * address information unless the socket has been connected.
9266 S16 cmInetGetSockName
9268 CmInetFd *sockFd, /* socket file descriptor */
9272 struct sockaddr_in *sockAddr;
9273 #ifdef IPV6_SUPPORTED
9274 struct sockaddr_in6 *sockAddr6;
9275 struct sockaddr_in6 lclSockAddr;
9277 CmInetSockAddr lclSockAddr;
9278 #endif /* IPV6_SUPPORTED */
9283 #endif /* SS_LINUX */
9285 /*cm_inet_c_001.main_58 : fix for klockwork issue */
9289 #if (ERRCLASS & ERRCLS_INT_PAR)
9290 /* error check on parameters */
9291 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
9296 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9298 memset(&lclSockAddr, 0, sizeof(lclSockAddr));
9299 size = sizeof(lclSockAddr);
9302 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr,
9303 (socklen_t *)&size);
9305 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, (int*)&size);
9306 #endif /* SS_LINUX */
9310 switch(errCode = INET_ERR_CODE)
9313 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9314 #ifdef IPV6_SUPPORTED
9315 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9316 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9318 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9319 #endif /* IPV6_SUPPORTED */
9325 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9326 /* cm_inet_c_001.main_62:Warning fix */
9327 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9328 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9329 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9331 /* cm_inet_c_001.main_62:Warning fix */
9332 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9333 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9334 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9335 #endif /* ALIGN_64BIT */
9336 #endif /* CMINETDBG */
9338 }/* end of switch */
9342 /* Fill the returned address in to locAddr */
9343 #ifdef IPV6_SUPPORTED
9344 memset(locAddr, 0, sizeof(CmInetAddr));
9345 if (size == sizeof(struct sockaddr_in6))
9347 sockAddr6 = (struct sockaddr_in6 *)&lclSockAddr;
9348 locAddr->type = CM_INET_IPV6ADDR_TYPE;
9349 locAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(sockAddr6->sin6_port);
9350 CM_INET_COPY_IPV6ADDR(&locAddr->u.ipv6Addr.ipv6NetAddr,
9351 &sockAddr6->sin6_addr);
9355 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9356 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9357 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9358 locAddr->u.ipv4Addr.address =
9359 CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9362 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9363 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9364 locAddr->address = CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9365 #endif /* IPV6_SUPPORTED */
9367 }/* end of cmInetGetSockName() */
9369 /* New functions to peek into the file descriptor
9371 #if (defined(SUNOS) || defined(WIN32) || defined(SS_LINUX) || defined(SS_VW) \
9376 * Fun: cmInetFdSetInfoInit
9378 * Desc: This function is used to initialise operating system specific
9379 * data that will be used to peek into the file descriptor lists
9380 * to get the sockets that are set
9382 * Ret: ROK - successful
9391 S16 cmInetFdSetInfoInit
9393 CmInetFdSetInfo *fdSetInfo
9396 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW) || defined(HPOS))
9401 #endif /* SUNOS || SS_LINUX || SS_VW */
9403 #if (ERRCLASS & ERRCLS_INT_PAR)
9404 if (fdSetInfo == NULLP)
9406 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9408 if (fdSetInfo->initDone == TRUE)
9412 fdSetInfo->numFds = 0;
9415 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW)|| defined(HPOS))
9416 /* Check if we are on a big endian machine */
9418 if (*(uint8_t *)&arIdx)
9419 fdSetInfo->bigEndian = FALSE;
9421 fdSetInfo->bigEndian = TRUE;
9423 fdSetInfo->arIdx = 0;
9424 fdSetInfo->ar[0] = 0xff;
9426 /* Initialise the array */
9427 /* The array contains bit positions for the first bit
9428 * for each integer from 1 to 2^8.
9430 for (arIdx = 1; arIdx < 256; arIdx++)
9432 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9433 curByte = (uint8_t)arIdx;
9440 fdSetInfo->ar[arIdx] = bitPos;
9444 curByte = curByte >> 1;
9447 /* Calculate the number of array elements in this fd_set */
9448 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9449 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->__fds_bits[0]);
9451 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->fds_bits[0]);
9452 #endif /* SS_LINUX */
9453 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9455 fdSetInfo->initDone = TRUE;
9457 }/* end of cmInetFdSetInfoInit() */
9464 * Desc: This function is used to get the file descriptor from the
9465 * file descriptor set.
9467 * Ret: ROK - successful
9468 * ROKDNA - socket not found
9470 * RNA - failed, initialisation not done
9472 * Notes: If the application modifies fdSet between calls to this
9473 * function then the results are undefined. This function should
9474 * be called in a loop till either it returns - not ROK, or if
9475 * all sockets in the file descriptor set are processed.
9483 CmInetFdSetInfo *fdSetInfo,
9485 CmInetFdType *sockFd
9488 /*cm_inet_c_001.main_58 : Fix for klockwork issue */
9489 #if (!defined (WIN32))
9490 uint32_t sizOfFdSetArElem;
9491 uint8_t bytesScanned;
9496 #endif /* !defined (WIN32) */
9498 #if (ERRCLASS & ERRCLS_INT_PAR)
9499 if ((fdSetInfo == NULLP) || (fdSet == NULLP) || (sockFd == NULLP))
9502 if (fdSetInfo->initDone != TRUE)
9504 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9507 #if (ERRCLASS & ERRCLS_DEBUG)
9508 if (fdSetInfo->numFds > FD_SETSIZE)
9510 #endif /* ERRCLASS & ERRCLS_DEBUG */
9511 /* cm_inet_c_001.main_32 : Corrected check for number of fd set in
9513 if (fdSetInfo->numFds >= fdSet->fd_count)
9516 *sockFd = fdSet->fd_array[fdSetInfo->numFds];
9517 fdSetInfo->numFds += 1;
9521 /* cm_inet_c_001.main_59: Protected under if not defined WIN32 */
9522 #if (!defined (WIN32))
9523 /* Start with arIdx and continue upto number of array elements. */
9524 curIdx = fdSetInfo->arIdx;
9527 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9528 sizOfFdSetArElem = sizeof(fdSet->__fds_bits[0]);
9530 sizOfFdSetArElem = sizeof(fdSet->fds_bits[0]);
9531 #endif /* SS_LINUX */
9533 for (curIdx = fdSetInfo->arIdx; curIdx < fdSetInfo->numArElems;
9536 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9537 if (fdSet->__fds_bits[curIdx])
9539 if (fdSet->fds_bits[curIdx])
9540 #endif /* SS_LINUX */
9542 /* Walk through the bytes in this element */
9543 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9544 tempByte = (uint8_t *)&fdSet->__fds_bits[curIdx];
9546 tempByte = (uint8_t *)&fdSet->fds_bits[curIdx];
9547 #endif /* SS_LINUX */
9549 /* Set the starting byte offset */
9550 if (fdSetInfo->bigEndian)
9551 tempByte += sizOfFdSetArElem - 1;
9553 for (bytesScanned = 0; bytesScanned < sizOfFdSetArElem;
9558 bitPos = fdSetInfo->ar[*tempByte];
9559 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9560 fdSetInfo->arIdx = (uint16_t)curIdx;
9561 /* Calculate fd depending on where we are */
9562 *sockFd = ((bytesScanned << 3) + bitPos);
9563 *sockFd += (curIdx * (sizOfFdSetArElem << 3));
9564 /* Clear the file descriptor */
9565 *tempByte &= ~(1 << bitPos);
9568 if (fdSetInfo->bigEndian)
9581 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9582 } /* end of cmInetGetFd */
9584 #endif /* SUNOS || WIN32 || SS_LINUX || SS_VW || HPOS */
9587 /* add cmInetConvertStrToIpAddr and
9588 * cmInetAsciiToIpv4 functions */
9591 * Fun: cmInetConvertStrToIpAddr
9593 * Desc: This function parses the input string for an IPV4/IPV6 address.
9595 * 1) IPV4 in dot number format:
9597 * 2) IPV6, in uncompressed, compressed, and IPV4 embedded format
9598 * 10:20:30:40:502:610:70C:80ad
9600 * 45::AB:34:123.34.5.667
9602 * Ret: ROK - SUCCESS
9611 S16 cmInetConvertStrToIpAddr
9613 uint16_t len, /* Length of IP address */
9614 uint8_t *val, /* Domain Name String */
9615 CmInetNetAddr *address /* IP Address */
9618 uint8_t idx; /* Index for string*/
9619 uint8_t ipv4[CM_INET_IPV4ADDR_SIZE]; /* IPV4 Address bytes */
9620 #ifdef IPV6_SUPPORTED
9621 uint16_t *ipv6; /* IPV6 Address bytes */
9622 uint16_t ipv6Reg[8]; /* regular IPV6 Address bytes */
9623 uint16_t ipv6Cmp[8]; /* compressed IPV6 Address bytes */
9624 uint8_t numBlk; /* number of blocks in IPV6 addr */
9625 Bool compressed; /* IPV6 in compressed format */
9626 uint8_t ipv6Idx; /* counter for IPV6 */
9627 uint8_t blkBeginIdx; /* IPV6, char index for the
9628 beginning of the block */
9629 uint8_t i; /* counter for IPV6 */
9630 S16 retVal; /* return value */
9631 Bool embedIPV4 = FALSE; /* IPV4 embedded in IPV6 ? */
9632 #endif /* IPV6_SUPPORTED*/
9636 #ifdef IPV6_SUPPORTED
9641 ipv6 = ipv6Reg; /* assign pointer to IPV6 regular, uncompressed */
9642 memset(ipv6Reg, 0, CM_INET_IPV6ADDR_SIZE);
9643 memset(ipv6Cmp, 0, CM_INET_IPV6ADDR_SIZE);
9644 #endif /* IPV6_SUPPORTED*/
9646 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9648 /* Check for IP Address */
9649 while ((val[idx] != '.') && (val[idx] != ':') &&
9652 #if (ERRCLASS & ERRCLS_DEBUG)
9653 if (((val[idx] < '0') || (val[idx] > '9')) &&
9654 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9655 ((val[idx] < 'A') || (val[idx] > 'F')))
9660 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9662 /* Convert Ascii to integer */
9663 CM_INET_ATOI(ipv4[0], val[idx]);
9665 #ifdef IPV6_SUPPORTED
9666 /* convert Ascii to hex */
9667 CM_INET_ATOH(ipv6[0], val[idx]);
9668 #endif /* IPV6_SUPPORTED */
9670 idx++; /* move to the next character */
9671 } /* while, try to determine IPV4 or IPV6 */
9673 #if (ERRCLASS & ERRCLS_DEBUG)
9674 if ((val[idx] != '.') && (val[idx] != ':'))
9678 } /* if, couldn't determine IPV4 or IPV6 */
9679 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9682 if (val[idx] == '.')
9685 cmInetAsciiToIpv4(3, &(ipv4[1]), (uint16_t)(len - idx), &(val[idx]));
9687 address->type = CM_INET_IPV4ADDR_TYPE;
9688 CM_INET_GET_IPV4_ADDR_FRM_STRING(address->u.ipv4NetAddr, ipv4);
9690 #ifdef IPV6_SUPPORTED
9693 numBlk = 1; /* already converted the 1st block */
9695 while ((val[idx] != '\0') && (idx < len) && (numBlk <= 8))
9697 idx++; /* go to the next char, either a number or the 2nd : */
9698 if (val[idx] == ':')
9700 #if (ERRCLASS & ERRCLS_DEBUG)
9701 if (compressed == TRUE)
9703 /* can't have 2 :: */
9706 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9709 idx++; /* skip the : */
9712 } /* if, IPV6 in compressed format :: */
9716 } /* else, uncompressed, convert next block */
9718 numBlk++; /* increase number of blocks */
9720 /* assign the index the beginning of the block */
9723 while(val[idx] != ':' && val[idx] != '\0' && idx < len)
9725 if (val[idx] == '.')
9727 /* convert number to IPV4 */
9728 ipv6[ipv6Idx] = 0; /* clear out whatever we did */
9729 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9730 retVal = cmInetAsciiToIpv4(4, ipv4, len - blkBeginIdx,
9731 &(val[blkBeginIdx]));
9732 /* stop the loop, embedded IPV4 is the last part of
9740 } /* if, '.' means IPV4 address embedded in IPV6 */
9742 #if (ERRCLASS & ERRCLS_DEBUG)
9743 if (((val[idx] < '0') || (val[idx] > '9')) &&
9744 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9745 ((val[idx] < 'A') || (val[idx] > 'F')))
9750 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9752 /* Convert Ascii to integer */
9753 CM_INET_ATOH(ipv6[ipv6Idx], val[idx]);
9755 /* move to the next index */
9757 } /* while, convert a block of 16 bits Hex number */
9758 if (embedIPV4 == TRUE)
9760 ipv6Idx--; /* deccrease in case of compressed IPV6 */
9761 break; /* stop the while look */
9762 } /* if, IPV4 embedded in IPV6 */
9763 } /* while, IPV6 parsing */
9764 if (compressed == TRUE)
9766 if (embedIPV4 == TRUE)
9768 numBlk = 5; /* the last 2 blocks are IPV4 */
9769 } /* if, IPV4 embedded */
9772 numBlk = 7; /* copy from the last block */
9773 } /* else, no embedded IPV4 */
9775 /* type cast uint8_t over -1 becasue we want to copy the last block,
9778 for (i = ipv6Idx; i != (uint8_t) (-1); i --)
9780 ipv6Reg[numBlk] = ipv6Cmp[i];
9782 } /* for, copying compress IPV6 to regular IPV6 */
9783 } /* if, compressed format */
9785 if (embedIPV4 == TRUE)
9787 ipv6Reg[6] = PutHiByte(ipv6Reg[6], ipv4[0]);
9788 ipv6Reg[6] = PutLoByte(ipv6Reg[6], ipv4[1]);
9789 ipv6Reg[7] = PutHiByte(ipv6Reg[7], ipv4[2]);
9790 ipv6Reg[7] = PutLoByte(ipv6Reg[7], ipv4[3]);
9791 } /* if, IPV4 embedded */
9793 /* convert IPV6 to cmInetIpv6 */
9794 address->type = CM_INET_IPV6ADDR_TYPE;
9795 memcpy(address->u.ipv6NetAddr,
9796 ipv6Reg, CM_INET_IPV6ADDR_SIZE);
9798 #endif /* IPV6_SUPPORTED */
9801 } /* cmInetConvertStrToIpAddr */
9806 * Fun: cmInetAsciiToIpv4
9808 * Desc: This function parses the input string to an IPV4 address.
9809 * The input string can be
9810 * - the whole IPV4 address, '123.43.45.56', or
9811 * - a part of it. '34.56.454'
9812 * numBytes: number of bytes needs to be converted, IPV4 has
9813 * 4 bytes. If we are only converting the end of an
9814 * address, this number needs to be adjusted. For
9815 * example, when converting '34.56.454]', the number
9818 * Ret: ROK - SUCCESS
9826 S16 cmInetAsciiToIpv4
9828 uint8_t numBytes, /* number of Byte to convert */
9829 uint8_t *ipv4Addr, /* IPV4 Address */
9830 uint16_t len, /* Length of IP address */
9831 uint8_t *val /* Domain Name String */
9834 uint8_t byteCount; /* Byte Count */
9835 uint8_t idx; /* Index for string*/
9839 for (byteCount = 0; byteCount < numBytes; byteCount++)
9841 while((val[idx] != '.') && (idx < len))
9843 #if (ERRCLASS & ERRCLS_DEBUG)
9844 if (val[idx] < '0' || val[idx] > '9')
9849 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9851 /* Convert Ascii to integer */
9852 CM_INET_ATOI(ipv4Addr[byteCount], val[idx]);
9854 /* move to the next index */
9861 } /* cmInetAsciiToIpv4 */
9863 /* cm_inet_c_001.main_34:Added wrapper function for getaddrinfo and freeaddrinfo */
9864 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
9868 * Fun: cmInetGetAddrInfo
9870 * Desc: a socket file descriptor to a local Internet
9873 * Ret: Value returned by getaddrinfo
9881 S32 cmInetGetAddrInfo
9883 const S8 *node, /* Network addr which has to be resolved */
9884 const S8 *service, /* Sets the port number in network addr */
9885 const CmInetAddrInfo *hints, /* Specifies preferred socket type or protocol */
9886 CmInetAddrInfo **res /* Link list of addrInfo structure */
9892 #if (ERRCLASS & ERRCLS_INT_PAR)
9893 /* error check on parameters */
9894 if ((node == NULLP) || (hints == NULLP))
9898 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9900 ret = getaddrinfo(node,service,hints,res);
9905 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9906 /* cm_inet_c_001.main_62:Warning fix */
9907 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%ld), node(%p),"
9908 " service(%p)\n", ret, node, service);
9909 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET052, 0, prntBuf);
9911 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9912 /* cm_inet_c_001.main_62:Warning fix */
9913 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%d), node(%p),"
9914 " service(%p)\n ", ret, node, service);
9915 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET053, 0, prntBuf);
9916 #endif /* ALIGN_64BIT */
9917 #endif /* CMINETDBG */
9920 } /* end of cmInetGetAddrInfo */
9925 * Fun: cmInetFreeAddrInfo
9927 * Desc: Free the dynamically allocated addrinfo structure
9937 Void cmInetFreeAddrInfo
9939 CmInetAddrInfo *res /* Link list of addrInfo structure */
9943 #if (ERRCLASS & ERRCLS_INT_PAR)
9944 /* error check on parameters */
9947 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9950 } /* end of cmInetFreeAddrInfo */
9952 #endif /* SS_VW | SS_PS | WIN32*/
9954 /* cm_inet_c_001.main_36 : 1. Added new interface - cmInetFlushRecvBuf()
9955 to flush the data from socket receive buffer. */
9956 #ifdef CM_INET_FLUSH_RECV_BUF
9960 * Fun: cmInetFlushRcvBuf
9962 * Desc: Reads all the data from a socket and throw it!!
9963 * The buffers for the receive buffer for recvfrom() are allocated from the stack.
9965 * Ret: ROK - successful
9966 * ROKDNA - ok, data not available
9967 * RCLOSED - connection closed by peer
9968 * ROUTRES - failed, out of resources
9976 S16 cmInetFlushRecvBuf
9978 CmInetFd *sockFd, /* socket file descriptor */
9979 MsgLen *len, /* number of octects to be flushed */
9980 S32 flags /* additional control flags */
9984 Data recvTempBuf[CM_INET_MAX_BYTES_READ];
9986 #if (defined(WIN32) || defined(CMINETFLATBUF))
9987 S32 ret; /* temporary return value */
9988 uint32_t pendLen; /* pending data length */
9989 S32 recvLen; /* number of received octets by recvmsg() */
9990 MsgLen curLen; /* current number of octets in buffer */
9991 uint32_t remAddrLen; /* length of remote address */
9992 struct sockaddr_in *remAddr; /* remote Internet address */
9993 #ifdef IPV6_SUPPORTED
9994 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
9996 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
9997 #endif /* IPV6_SUPPORTED */
9999 S32 ret; /* temporary return value */
10000 MsgLen curLen; /* current number of octets in buffer */
10001 uint32_t pendLen; /* pending data length */
10002 S32 recvLen; /* number of received octets by recvmsg() */
10003 struct msghdr msg; /* message header */
10004 CmInetIovec rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
10005 uint32_t remAddrLen; /* length of remote address */
10006 #ifdef IPV6_SUPPORTED
10007 struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
10009 #if (defined(SS_LINUX) || defined(_XPG4_2))
10010 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
10011 /* from stack for IPv6 ancill data */
10014 CmInetSockAddr remSockAddr; /* to get packet's src IP address */
10015 #if (defined(SS_LINUX) || defined(_XPG4_2))
10016 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
10017 /* from stack for IPv4 ancill data */
10019 #endif /* IPV6_SUPPORTED */
10020 #endif /* WIN32 | CMINETFLATBUF */
10022 /* used by getsockopt */
10023 uint32_t errValue; /* error value */
10024 uint32_t optLen; /* option length */
10027 #if (ERRCLASS & ERRCLS_INT_PAR)
10028 /* error check on parameters */
10029 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
10033 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10036 #if (defined(WIN32) || defined(CMINETFLATBUF))
10038 #endif /* (WIN32 | CMINETFLATBUF) */
10040 /* clear the structure */
10041 memset(&remSockAddr, 0, sizeof(remSockAddr));
10043 /* get number of pending data */
10044 ret = cmInetGetNumRead(sockFd, &pendLen);
10047 /* ret may be RFAILED or ROUTRES */
10051 /* check if connection got closed */
10054 if (sockFd->type == CM_INET_STREAM)
10057 /* cm_inet_c_001.main_50
10058 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
10059 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
10060 * socket that select says is ready to read. This should not be
10061 * considered as connection closed. So return ROKDNA instead of
10067 /* clear error if there is any, because if there is internal error
10068 * here it will cause infinite loop in TUCL */
10071 optLen = sizeof(int);
10073 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10074 (char*)&errValue, (socklen_t *)&optLen);
10076 #if (defined(SS_VW) || defined(SS_PS))
10077 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10078 (char*)&errValue, (int *)&optLen);
10081 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10082 (char*)&errValue, (int *)&optLen);
10083 #endif /* SS_WINCE */
10085 #endif /* SS_LINUX */
10086 if (ret == INET_ERR)
10089 #ifndef ALIGN_64BIT
10090 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10091 /* cm_inet_c_001.main_62:Warning fix */
10092 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10093 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10094 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10096 /* cm_inet_c_001.main_62:Warning fix */
10097 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10098 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10099 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10100 #endif /*ALIGN_64BIT*/
10101 #endif /* CMINETDBG */
10107 /* added separate recvfrom calls different OS */
10108 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10109 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10110 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10112 #if ( defined(SUNOS) || defined(SS_LINUX))
10113 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10114 NULLP, (socklen_t *)&remAddrLen);
10116 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10117 NULLP, (S32 *)&remAddrLen);
10119 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10120 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10125 }/* if (pendLen == 0)*/
10128 if((*len == CM_INET_READ_THROW) || (*len >= CM_INET_MAX_BYTES_READ))
10130 curLen = CM_INET_MAX_BYTES_READ;
10134 curLen = *len; /*set to given number of messasges to be flushed */
10137 if((*len != CM_INET_READ_THROW) && (*len < pendLen))
10142 #if (defined(WIN32) || defined(CMINETFLATBUF))
10146 * maybe needs more than one recvfrom() call to read an entire
10151 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10152 /* added separate recvfrom calls different OS */
10154 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10155 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10156 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10158 #if ( defined(SUNOS) || defined(SS_LINUX))
10159 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10160 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
10162 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempbuf, curLen, 0,
10163 &remSockAddr, (S32 *)&remAddrLen);
10165 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10166 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10168 if (recvLen == INET_ERR)
10171 /* added check ERR_WOULDBLOCK */
10172 if ((INET_ERR_CODE == ERR_AGAIN) ||
10173 (INET_ERR_CODE == ERR_WOULDBLOCK))
10180 /* In Windows the recvfrom function fails
10181 * with error code which maps to either WSAECONNABORTED. If
10182 * this happens then cmInetFlushRecvBuf must return RCLOSED */
10183 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
10184 (INET_ERR_CODE == ERR_CONNRESET))
10191 #ifndef ALIGN_64BIT
10192 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10193 /* cm_inet_c_001.main_62:Warning fix */
10194 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10195 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10196 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10198 /* cm_inet_c_001.main_62:Warning fix */
10199 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10200 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10201 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10202 #endif /*ALIGN_64BIT*/
10203 #endif /* CMINETDBG */
10208 if(recvLen < curLen)
10211 pendLen -= recvLen;
10213 if(pendLen < curLen)
10216 } /* while (curLen > 0) */
10218 #else /* end of Win NT/flat buffer specific part */
10221 * maybe needs more than one recvmsg() call to read entire message
10222 * on a stream socket
10226 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10227 /* update the message structure */
10229 rxArr[0].iov_base = (Void*)recvTempBuf;
10230 rxArr[0].iov_len = (uint32_t)curLen;
10232 rxArr[0].iov_base = (S8*)recvTempBuf;
10233 rxArr[0].iov_len = curLen;
10234 #endif /* SS_LINUX */
10235 msg.msg_iov = rxArr;
10236 msg.msg_iovlen = 1;
10238 msg.msg_name = NULLP;
10239 msg.msg_namelen = 0;
10241 /* added defined(_XPG4_2). Also changed the
10243 #if (defined(SS_LINUX) || defined(_XPG4_2))
10244 msg.msg_control = ancillData;
10245 msg.msg_controllen = sizeof(ancillData);
10248 msg.msg_accrights = NULLP;
10249 msg.msg_accrightslen = 0;
10250 #endif /* SS_LINUX */
10252 recvLen = recvmsg(sockFd->fd, &msg, flags);
10253 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
10255 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
10256 added check ERR_WOULDBLOCK */
10257 if ((INET_ERR_CODE == ERR_AGAIN) ||
10258 (INET_ERR_CODE == ERR_WOULDBLOCK))
10265 #ifndef ALIGN_64BIT
10266 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
10267 /* cm_inet_c_001.main_62:Warning fix */
10268 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10269 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10270 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10272 /* cm_inet_c_001.main_62:Warning fix */
10273 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10274 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10275 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10276 #endif /*ALIGN_64BIT*/
10277 #endif /* CMINETDBG */
10279 /* If this happens then cmInetFlushRecvBuf must return RCLOSED.
10280 * Needed for getting icmp msgs */
10281 if (INET_ERR_CODE == ERR_CONNABORTED)
10287 }/* if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))*/
10289 if(recvLen < curLen)
10292 pendLen -= recvLen;
10294 if(pendLen < curLen)
10297 } /* while(curLen > 0) */
10299 #endif /* WIN32 | CMINETFLATBUF */
10303 } /* end of cmInetFlushRecvBuf */
10305 #endif /* CM_INET_FLUSH_RECV_BUF*/
10307 /**********************************************************************
10309 **********************************************************************/