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 */
1774 int32_t tempErrorNo=0;
1777 /* cm_inet_c_001.main_46: Removed SS_LINUX flag */
1780 /* cm_inet_c_001.main_64: New variable used as an argument for sctp_connectx */
1781 #ifdef SCTP_CONNECTX_NEW
1782 uint32_t assocId = 0;
1784 uint32_t addresses_array_size = 0;
1786 struct sockaddr_in addrs[CM_INET_NUM_NET_ADDR];
1787 uint32_t ipv4_array_size = 0;
1789 #ifndef IPV6_SUPPORTED
1790 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1792 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1793 #endif /* IPV6_SUPPORTED */
1795 #ifdef IPV6_SUPPORTED
1797 S8 *addrString = NULLP;
1798 uint32_t addrLen = 0;
1799 S8 ipv4Format[23] = "::ffff:";
1800 CmInetIpAddr ipv4NetAddr;
1801 #endif /* SUN_KSCTP */
1803 struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1804 uint32_t ipv6_array_size = 0;
1805 #endif /* IPV6_SUPPORTED */
1807 uint32_t sockAddrLen = 0;
1808 #endif /* sockAddrLen */
1811 CmInetSockAddr *sockAddrPtr = NULLP;
1812 #endif /* SS_LINUX */
1813 #if (ERRCLASS & ERRCLS_INT_PAR)
1814 /* error check on parameters */
1815 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1816 (primAddr == NULLP))
1820 /* cm_inet_c_001.main_58 : Added check for addrLst to fix klockwork issue */
1821 if (addrLst == NULLP)
1825 /* cm_inet_c_001.main_46: Included check for no of address aginst max */
1826 if( addrLst->count > CM_INET_NUM_NET_ADDR )
1830 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1831 /* cm_inet_c_001.main_62:Warning fix */
1832 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1833 " sockFd->fd(%ld)\n",
1834 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1835 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1837 /* cm_inet_c_001.main_62:Warning fix */
1838 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1839 " sockFd->fd(%d)\n",
1840 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1841 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1842 #endif /*ALIGN_64BIT*/
1843 #endif /* CMINETDBG */
1846 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1849 memset(&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1850 #ifdef IPV6_SUPPORTED
1851 memset(&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1852 #endif /* IPV6_SUPPORTED */
1856 #ifdef IPV6_SUPPORTED
1857 if (primAddr->type == CM_INET_IPV6ADDR_TYPE)
1859 if (sockFd->protType == AF_INET)
1863 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1864 /* cm_inet_c_001.main_62:Warning fix */
1865 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1866 " sockFd->fd(%ld)\n", sockFd->fd);
1867 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
1869 /* cm_inet_c_001.main_62:Warning fix */
1870 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1871 " sockFd->fd(%d)\n", sockFd->fd);
1872 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
1873 #endif /*ALIGN_64BIT*/
1874 #endif /* CMINETDBG */
1878 addrs6[idx6].sin6_family = AF_INET6;
1879 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1880 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr), &(primAddr->u.ipv6NetAddr));
1881 addresses_array_size += sizeof(struct sockaddr_in6);
1882 ipv6_array_size += sizeof(struct sockaddr_in6);
1888 if (sockFd->protType == AF_INET)
1892 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1893 /* cm_inet_c_001.main_62:Warning fix */
1894 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
1895 " sockFd->fd(%ld)\n", sockFd->fd);
1896 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
1898 /* cm_inet_c_001.main_62:Warning fix */
1899 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
1900 " sockFd->fd(%d)\n", sockFd->fd);
1901 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
1902 #endif /*ALIGN_64BIT*/
1903 #endif /* CMINETDBG */
1906 addrs6[idx6].sin6_family = AF_INET6;
1907 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1908 ipv4NetAddr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1909 cmInetNtoa(ipv4NetAddr, &addrString);
1910 addrLen = cmStrlen((uint8_t*)addrString);
1911 memcpy((ipv4Format+7), addrString, addrLen);
1912 ipv4Format[7+addrLen] = '\0';
1913 cmInetPton6((CmInetIpAddr6*)&(addrs6[idx6].sin6_addr), ipv4Format);
1914 addresses_array_size += sizeof(struct sockaddr_in6);
1915 ipv6_array_size += sizeof(struct sockaddr_in6);
1918 addrs[idx4].sin_family = AF_INET;
1919 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1920 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1921 addresses_array_size += sizeof(struct sockaddr_in);
1922 ipv4_array_size += sizeof(struct sockaddr_in);
1927 addrs[idx4].sin_family = AF_INET;
1928 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1929 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1930 addresses_array_size += sizeof(struct sockaddr_in);
1931 ipv4_array_size += sizeof(struct sockaddr_in);
1933 #endif /* IPV6_SUPPORTED */
1937 /* cm_inet_c_001.main_46: Moved the SS_LINUX flag down,
1938 * copy addresses in Solaris also */
1939 if (addrLst != NULLP)
1941 for (idx = 0; idx < addrLst->count; idx++)
1944 /* cm_inet_c_001.main_46: Don't include the primary address
1945 * if its prersent in list */
1946 if ( addrLst->addrs[idx].type == CM_INET_IPV4ADDR_TYPE )
1948 if ( addrLst->addrs[idx].u.ipv4NetAddr == primAddr->u.ipv4NetAddr )
1953 #ifdef IPV6_SUPPORTED
1954 else if ( addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE )
1956 if (( cmMemcmp(addrLst->addrs[idx].u.ipv6NetAddr,
1957 primAddr->u.ipv6NetAddr, sizeof(CmInetIpAddr6) )) == 0 )
1963 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1965 if (sockFd->protType == AF_INET)
1969 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1970 /* cm_inet_c_001.main_62:Warning fix */
1971 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1972 " sockFd->fd(%ld)\n", sockFd->fd);
1973 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
1975 /* cm_inet_c_001.main_62:Warning fix */
1976 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1977 " sockFd->fd(%d)\n", sockFd->fd);
1978 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
1979 #endif /*ALIGN_64BIT*/
1980 #endif /* CMINETDBG */
1984 addrs6[idx6].sin6_family = AF_INET6;
1985 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1986 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr),
1987 &(addrLst->addrs[idx].u.ipv6NetAddr));
1988 addresses_array_size += sizeof(struct sockaddr_in6);
1989 ipv6_array_size += sizeof(struct sockaddr_in6);
1995 if (sockFd->protType == AF_INET)
1999 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2000 /* cm_inet_c_001.main_62:Warning fix */
2001 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2002 " sockFd->fd(%ld)\n", sockFd->fd);
2003 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2005 /* cm_inet_c_001.main_62:Warning fix */
2006 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2007 " sockFd->fd(%d)\n", sockFd->fd);
2008 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2009 #endif /*ALIGN_64BIT*/
2010 #endif /* CMINETDBG */
2013 addrs6[idx6].sin6_family = AF_INET6;
2014 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
2015 ipv4NetAddr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2016 cmInetNtoa(ipv4NetAddr, &addrString);
2017 addrLen = cmStrlen((uint8_t*)addrString);
2018 memcpy((ipv4Format+7), addrString, addrLen);
2019 ipv4Format[7+addrLen] = '\0';
2020 cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
2021 addresses_array_size += sizeof(struct sockaddr_in6);
2022 ipv6_array_size += sizeof(struct sockaddr_in6);
2025 addrs[idx4].sin_family = AF_INET;
2026 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
2027 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2028 addresses_array_size += sizeof(struct sockaddr_in);
2029 ipv4_array_size += sizeof(struct sockaddr_in);
2031 #endif /* SUN_KSCTP */
2034 addrs[idx4].sin_family = AF_INET;
2035 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
2036 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2037 addresses_array_size += sizeof(struct sockaddr_in);
2038 ipv4_array_size += sizeof(struct sockaddr_in);
2040 #endif /* IPV6_SUPPORTED */
2041 /*cm_inet_c_001.main_39 */
2046 /* cm_inet_c_001.main_46: Moved SS_LINUX flag to here */
2048 /*cm_inet_c_001.main_58 : Added check array_size to fix klockwork issue */
2049 if((ipv4_array_size > 0) && (ipv4_array_size <= (CM_INET_NUM_NET_ADDR * \
2050 sizeof(struct sockaddr_in))))
2052 memcpy(address_array, &addrs[0], ipv4_array_size);
2059 #ifdef IPV6_SUPPORTED
2060 if((ipv6_array_size > 0) && (ipv6_array_size <= (CM_INET_NUM_NET_ADDR * \
2061 sizeof(struct sockaddr_in))))
2063 memcpy((address_array + ipv4_array_size), addrs6, ipv6_array_size);
2069 #endif /* IPV6_SUPPORTED */
2071 /* cm_inet_c_001.main_64: Support for new definition of sctp_connectx */
2072 #ifndef SCTP_CONNECTX_NEW
2073 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt);
2075 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt, (sctp_assoc_t *)&assocId);
2080 /* cm_inet_c_001.main_46: Use next provided address to connect if
2081 * first one fails */
2083 #ifdef CMINET_SUN_CONNECTX
2085 #ifdef IPV6_SUPPORTED
2087 #endif /* IPV6_SUPPORTED */
2088 for (idx = 0; idx < cnt; idx++)
2090 if( addrs[idx4].sin_family == AF_INET)
2092 sockAddrPtr = (CmInetSockAddr *)&addrs[idx4];
2093 sockAddrLen = sizeof(struct sockaddr_in);
2096 #ifdef IPV6_SUPPORTED
2099 sockAddrPtr = (CmInetSockAddr *)&addrs6[idx6];
2100 sockAddrLen = sizeof(struct sockaddr_in6);
2103 #endif/* IPV6_SUPPORTED */
2105 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2107 if ( ret != INET_ERR )
2113 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2114 /* cm_inet_c_001.main_62:Warning fix */
2115 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2116 " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2117 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2119 /* cm_inet_c_001.main_62:Warning fix */
2120 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2121 " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2122 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2123 #endif /*ALIGN_64BIT*/
2124 #endif /* CMINETDBG */
2129 if( addrs[0].sin_family == AF_INET)
2131 sockAddrPtr = (CmInetSockAddr*)&addrs[0];
2132 sockAddrLen = sizeof(struct sockaddr_in);
2135 #ifdef IPV6_SUPPORTED
2138 sockAddrPtr = (CmInetSockAddr*)&addrs6[0];
2139 sockAddrLen = sizeof(struct sockaddr_in6);
2142 #endif/* IPV6_SUPPORTED */
2144 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2146 #endif /* CMINET_SUN_CONNECTX */
2147 #endif /* SS_LINUX */
2148 tempErrorNo = INET_ERR_CODE;
2149 if (ret == INET_ERR)
2153 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2154 /* cm_inet_c_001.main_62:Warning fix */
2155 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2156 " sockFd->fd(%ld)\n", tempErrorNo, port, sockFd->fd);
2157 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
2159 DU_LOG("\nCmInetSctpConnectx() Failed : error(%d), port(0x%1x),\
2160 sockFd->fd(%d)\n", tempErrorNo, port, sockFd->fd);
2161 #endif /*ALIGN_64BIT*/
2162 #endif /* CMINETDBG */
2164 switch (tempErrorNo)
2166 /* non-blocking: connection is in progress */
2167 case ERR_INPROGRESS:
2168 return (RINPROGRESS);
2172 * non-blocking: connection is established
2173 * blocking : connection is already established
2179 /* resource temporarily unavailable */
2180 case ERR_WOULDBLOCK:
2184 /* non-blocking: connection is in progress */
2186 return (RINPROGRESS);
2190 return (RINPROGRESS);
2193 /* Check for connection refused and timeout errors */
2194 case ERR_CONNREFUSED:
2199 /* it is a real error */
2211 * Fun: cmInetSctpPeelOff
2213 * Desc: Branches an existing sctp association off to a seperate socket
2215 * Ret: ROK - successful
2223 S16 cmInetSctpPeelOff
2225 CmInetFd *sockFd, /* socket file descriptor */
2226 uint32_t assocId, /* association id */
2227 CmInetFdType *assocFd /* association fd */
2232 #if (ERRCLASS & ERRCLS_INT_PAR)
2233 /* error check on parameters */
2234 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) || (assocFd == NULLP))
2238 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2241 ret = sctp_peeloff(sockFd->fd, assocId);
2242 if (ret == INET_ERR)
2246 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2247 /* cm_inet_c_001.main_62:Warning fix */
2248 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%ld),"
2249 " sockFd->fd(%ld)\n", INET_ERR_CODE, assocId, sockFd->fd);
2250 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2252 /* cm_inet_c_001.main_55: Fix for compilation warning */
2253 /* cm_inet_c_001.main_62:Warning fix */
2254 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%d),"
2255 " sockFd->fd(%d)\n", INET_ERR_CODE, assocId, sockFd->fd);
2256 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2257 #endif /*ALIGN_64BIT*/
2258 #endif /* CMINETDBG */
2270 * Fun: cmInetSctpSendMsg
2272 * Desc: invokes sctp socket API to send message to the remote addresses
2274 * Ret: ROK - successful
2282 S16 cmInetSctpSendMsg
2284 CmInetFd *sockFd, /* socket file descriptor */
2285 CmInetNetAddr *dstAddr, /* destination Internet address/port */
2286 uint16_t port, /* destination port no. */
2287 CmInetMemInfo *info, /* buffer allocation info */
2288 Buffer *mBuf, /* buffer structure to send */
2289 MsgLen *len, /* number of actually sent octets */
2290 uint16_t strmId, /* sctp stream identifier */
2291 Bool unorderFlg, /* flag to enable the unordered delivery */
2292 uint16_t ttl, /* time to live */
2293 uint32_t ppId, /* opaque value passed along with the message */
2294 uint32_t context /* value to be passed back, if error occurs */
2298 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2299 MsgLen msgLen = 0; /* message length */
2300 MsgLen bufLen = 0; /* send buffer length */
2301 Data *sendBuf = NULLP; /* plain send buffer */
2303 CmInetSockAddr *sockAddrPtr = NULLP;
2304 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2305 MsgLen sockAddrLen = 0;
2306 struct sockaddr_in addr ={0};
2307 #ifdef IPV6_SUPPORTED
2309 S8 *addrString = NULLP;
2310 uint32_t addrLen = 0;
2311 S8 ipv4Format[23] = "::ffff:";
2312 CmInetIpAddr ipv4NetAddr = {0};
2313 #endif /* SUN_KSCTP */
2314 struct sockaddr_in6 addr6 ={0};
2315 #endif /* IPV6_SUPPORTED */
2316 #if (ERRCLASS & ERRCLS_INT_PAR)
2317 /* error check on parameters */
2318 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd)
2319 || (info == NULLP) || (mBuf == NULLP) || (len == NULLP))
2323 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2326 memset(&addr, 0, sizeof(struct sockaddr_in));
2327 #ifdef IPV6_SUPPORTED
2328 memset(&addr6, 0, sizeof(struct sockaddr_in6));
2329 #endif /* IPV6_SUPPORTED */
2331 /* copy message to a flat buffer */
2332 ret = SFndLenMsg(mBuf, &bufLen);
2337 /* max message length is limited to control the memory usage */
2338 /* casting bufLen to avoid warnings */
2339 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
2343 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &sendBuf, bufLen);
2348 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
2349 if ((ret != ROK) || (msgLen != bufLen))
2351 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2355 if ( dstAddr != NULLP)
2357 #ifdef IPV6_SUPPORTED
2358 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
2360 if (sockFd->protType == AF_INET)
2362 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2365 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2366 /* cm_inet_c_001.main_62:Warning fix */
2367 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2368 " IPV4 socket, sockFd->fd(%ld)\n", sockFd->fd);
2369 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2371 /* cm_inet_c_001.main_62:Warning fix */
2372 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2373 " IPV4 socket, sockFd->fd(%d)\n", sockFd->fd);
2374 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2375 #endif /*ALIGN_64BIT*/
2376 #endif /* CMINETDBG */
2380 addr6.sin6_family = AF_INET6;
2381 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2382 CM_INET_COPY_IPV6ADDR(&addr6.sin6_addr.s6_addr, &dstAddr->u.ipv6NetAddr);
2383 sockAddrLen = sizeof(struct sockaddr_in6);
2384 sockAddrPtr = (CmInetSockAddr*)&addr6;
2390 if (sockFd->protType == AF_INET)
2394 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2395 /* cm_inet_c_001.main_62:Warning fix */
2396 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2397 " socket, sockFd->fd(%ld)\n", sockFd->fd);
2398 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2400 /* cm_inet_c_001.main_62:Warning fix */
2401 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2402 " socket, sockFd->fd(%d)\n", sockFd->fd);
2403 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2404 #endif /*ALIGN_64BIT*/
2405 #endif /* CMINETDBG */
2408 addr6.sin6_family = AF_INET6;
2409 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2410 ipv4NetAddr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2411 cmInetNtoa(ipv4NetAddr, &addrString);
2412 addrLen = cmStrlen((uint8_t*)addrString);
2413 memcpy((ipv4Format+7), addrString, addrLen);
2414 ipv4Format[7+addrLen] = '\0';
2415 cmInetPton6((CmInetIpAddr6*)(addr6.sin6_addr.s6_addr), ipv4Format);
2416 sockAddrLen = sizeof(struct sockaddr_in6);
2417 sockAddrPtr = (CmInetSockAddr*)&addr6;
2419 addr.sin_family = AF_INET;
2420 addr.sin_port = CM_INET_HTON_UINT16(port);
2421 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2422 sockAddrLen = sizeof(struct sockaddr_in);
2423 sockAddrPtr = (CmInetSockAddr*)&addr;
2424 #endif /* SUN_KSCTP */
2427 addr.sin_family = AF_INET;
2428 addr.sin_port = CM_INET_HTON_UINT16(port);
2429 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2430 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2431 sockAddrLen = (MsgLen)sizeof(struct sockaddr_in);
2432 sockAddrPtr = (CmInetSockAddr*)&addr;
2433 #endif /* IPV6_SUPPORTED */
2440 sockAddrPtr = (CmInetSockAddr*)&addr;
2442 /* cm_inet_c_001.main_58 : initialized sockAddrLen properly */
2443 #ifdef IPV6_SUPPORTED
2444 sockAddrLen = sizeof(struct sockaddr_in6);
2446 sockAddrLen = sizeof(struct sockaddr_in);
2450 /* Not validating the address, whether addr is a valid address or not */
2455 if (unorderFlg == TRUE)
2458 flags |= MSG_UNORDERED;
2461 flags |= SCTP_UNORDERED;
2464 /*cm_inet_c_001.main_54: converting ppid to network*/
2465 ppId = CM_INET_HTON_UINT32(ppId);
2466 ret = sctp_sendmsg(sockFd->fd, (Void*)sendBuf, bufLen,
2467 (struct sockaddr*)sockAddrPtr, (size_t)sockAddrLen,
2468 ppId, flags, strmId, ttl, context);
2469 if (ret == INET_ERR)
2471 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2474 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2475 /* cm_inet_c_001.main_62:Warning fix */
2476 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%ld),"
2477 " strmId(%u),sockFd->fd(%ld)\n",
2478 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2479 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2481 /* cm_inet_c_001.main_55: Fix for compilation warning */
2482 /* cm_inet_c_001.main_62:Warning fix */
2483 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%d),"
2484 " strmId(%u),sockFd->fd(%d)\n",
2485 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2486 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2487 #endif /*ALIGN_64BIT*/
2488 #endif /* CMINETDBG */
2490 if ((INET_ERR_CODE == ERR_AGAIN) || (INET_ERR_CODE == ERR_WOULDBLOCK))
2491 return (RWOULDBLOCK);
2492 else if (INET_ERR_CODE == ERR_PIPE)
2498 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2502 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
2509 * Fun: cmInetSctpRecvMsg
2511 * Desc: invokes sctp API to get the message received at sctp socket
2513 * Ret: ROK - successful
2521 S16 cmInetSctpRecvMsg
2523 CmInetFd *sockFd, /* socket file descriptor */
2524 CmInetNetAddr *srcAddr, /* source Internet address/port */
2525 uint16_t *port, /* source port no. */
2526 CmInetMemInfo *meminfo, /* buffer allocation info */
2527 Buffer **mBuf, /* buffer structure received */
2528 MsgLen *len, /* number of octets received */
2529 CmInetSctpSndRcvInfo *sinfo, /* sctp send-receive info */
2530 uint32_t *flag, /* flags */
2531 CmInetSctpNotification *ntfy /* notification parameters */
2536 struct sctp_sndrcvinfo info;
2537 struct sockaddr_storage addr;
2538 struct sockaddr_in *pAddr = NULLP;
2539 #ifdef IPV6_SUPPORTED
2540 struct sockaddr_in6 *pAddr6 = NULLP;
2543 Data *recvbuf = NULLP;
2545 union sctp_notification *sctpNtfy = NULLP;
2546 /* cm_inet_c_001.main_46: Defined new variable to store length of data */
2549 #endif /* SS_LINUX */
2551 #if (ERRCLASS & ERRCLS_INT_PAR)
2552 /* error check on parameters */
2553 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
2554 (srcAddr == NULLP) || (port == NULLP) || (meminfo == NULLP) ||
2555 (mBuf == NULLP) || (len == NULLP) || (sinfo == NULLP) || (flag == NULLP))
2559 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2564 memset(ntfy, 0, sizeof(CmInetSctpNotification));
2566 buflen = CM_INET_MAX_MSG_LEN;
2568 /* allocate flat receive buffer */
2569 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, &recvbuf, buflen);
2573 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2574 /* cm_inet_c_001.main_62:Warning fix */
2575 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failed to allocate memory\n");
2576 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET065, 0, prntBuf);
2577 #endif /* CMINETDBG */
2581 addrlen = sizeof(struct sockaddr_storage);
2583 memset(&addr, 0, sizeof(struct sockaddr_storage));
2584 memset(&info, 0, sizeof(struct sctp_sndrcvinfo));
2586 ret = sctp_recvmsg(sockFd->fd, (Void *)recvbuf, (size_t)buflen,
2587 (struct sockaddr*)&addr, &addrlen, &info,
2589 if (ret == INET_ERR)
2592 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2595 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2596 /* cm_inet_c_001.main_62:Warning fix */
2597 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2598 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
2599 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2601 DU_LOG("\ncmInetSctpRecvMsg() Failed : error(%d), sockFd->fd(%d)", \
2602 INET_ERR_CODE, sockFd->fd);
2603 #endif /*ALIGN_64BIT*/
2604 #endif /* CMINETDBG */
2609 /* save the length of the received message */
2610 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2613 #ifdef IPV6_SUPPORTED
2614 if (addr.ss_family == AF_INET6)
2616 uint8_t ipv4Format[12] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff};
2617 pAddr6 = (struct sockaddr_in6*)&addr;
2618 *port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
2620 if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
2622 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2623 memcpy(&srcAddr->u.ipv4NetAddr, ((pAddr6->sin6_addr.s6_addr) + 12), sizeof(uint32_t));
2624 srcAddr->u.ipv4NetAddr = CM_INET_HTON_uint32_t(srcAddr->u.ipv4NetAddr);
2629 srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2630 CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr);
2635 pAddr = (struct sockaddr_in*)&addr;
2636 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2637 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2638 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2641 pAddr = (struct sockaddr_in*)&addr;
2642 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2643 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2644 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2645 #endif /* IPV6_SUPPORTED */
2647 /* fill sndrcv info */
2648 sinfo->stream = info.sinfo_stream;
2649 sinfo->ssn = info.sinfo_ssn;
2650 sinfo->flags = info.sinfo_flags;
2651 /*cm_inet_c_001.main_54: converting ppid to host*/
2652 sinfo->ppid = CM_INET_NTOH_UINT32(info.sinfo_ppid);
2653 sinfo->context = info.sinfo_context;
2654 sinfo->timetolive = info.sinfo_timetolive;
2655 sinfo->tsn = info.sinfo_tsn;
2656 sinfo->cumtsn = info.sinfo_cumtsn;
2657 sinfo->assocId = info.sinfo_assoc_id;
2659 /* fill message flags */
2661 if ((msgFlags & MSG_EOR) != 0)
2662 *flag |= CM_INET_SCTP_MSG_EOR;
2664 if ((msgFlags & MSG_NOTIFICATION) != 0)
2666 *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2669 sctpNtfy = (union sctp_notification*)recvbuf;
2671 ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2672 ntfy->header.nLen = sctpNtfy->sn_header.sn_length;
2674 switch(sctpNtfy->sn_header.sn_type)
2676 case SCTP_ASSOC_CHANGE:
2677 ntfy->header.nType = CM_INET_SCTP_ASSOC_CHANGE;
2678 switch(sctpNtfy->sn_assoc_change.sac_state)
2681 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2683 case SCTP_COMM_LOST:
2684 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2687 ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2689 case SCTP_SHUTDOWN_COMP:
2690 ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2692 case SCTP_CANT_STR_ASSOC:
2693 ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
2698 ntfy->u.assocChange.error = sctpNtfy->sn_assoc_change.sac_error;
2699 ntfy->u.assocChange.outStreams = sctpNtfy->sn_assoc_change.sac_outbound_streams;
2700 ntfy->u.assocChange.inStreams = sctpNtfy->sn_assoc_change.sac_inbound_streams;
2701 ntfy->u.assocChange.assocId = sctpNtfy->sn_assoc_change.sac_assoc_id;
2703 ntfy->u.assocChange.info = sctpNtfy->sn_assoc_change.sac_info;
2706 case SCTP_PEER_ADDR_CHANGE:
2707 ntfy->header.nType = CM_INET_SCTP_PEER_ADDR_CHANGE;
2708 switch(sctpNtfy->sn_paddr_change.spc_state)
2710 case SCTP_ADDR_AVAILABLE:
2711 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2713 case SCTP_ADDR_UNREACHABLE:
2714 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2716 case SCTP_ADDR_REMOVED:
2717 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2719 case SCTP_ADDR_ADDED:
2720 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2722 case SCTP_ADDR_MADE_PRIM:
2723 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2726 case SCTP_ADDR_CONFIRMED:
2727 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2734 #ifdef IPV6_SUPPORTED
2735 if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
2737 pAddr6 = (struct sockaddr_in6*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2738 ntfy->u.paddrChange.addr.type = CM_INET_IPV6ADDR_TYPE;
2739 CM_INET_COPY_IPV6ADDR(&ntfy->u.paddrChange.addr.u.ipv6NetAddr,
2740 &pAddr6->sin6_addr.s6_addr);
2744 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2745 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2746 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2749 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2750 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2751 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2752 #endif /* IPV6_SUPPORTED */
2754 ntfy->u.paddrChange.error = sctpNtfy->sn_paddr_change.spc_error;
2755 ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2757 case SCTP_REMOTE_ERROR:
2758 ntfy->header.nType = CM_INET_SCTP_REMOTE_ERROR;
2760 ntfy->u.remoteErr.error = sctpNtfy->sn_remote_error.sre_error;
2761 ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2763 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2764 datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2766 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__, meminfo->region, meminfo->pool, \
2767 &ntfy->u.remoteErr.data, datlen );
2770 ntfy->u.remoteErr.data = NULLP;
2773 memcpy(ntfy->u.remoteErr.data,\
2774 sctpNtfy->sn_remote_error.sre_data, datlen);
2777 case SCTP_SEND_FAILED:
2778 ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2780 ntfy->u.sndFailed.error = sctpNtfy->sn_send_failed.ssf_error;
2781 ntfy->u.sndFailed.assocId = sctpNtfy->sn_send_failed.ssf_assoc_id;
2783 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2784 datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2786 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__, meminfo->region, meminfo->pool, \
2787 &ntfy->u.sndFailed.data, datlen );
2790 ntfy->u.sndFailed.data = NULLP;
2793 memcpy(ntfy->u.sndFailed.data,\
2794 sctpNtfy->sn_send_failed.ssf_data, datlen );
2796 ntfy->u.sndFailed.info.stream = sctpNtfy->sn_send_failed.ssf_info.sinfo_stream;
2797 ntfy->u.sndFailed.info.ssn = sctpNtfy->sn_send_failed.ssf_info.sinfo_ssn;
2798 ntfy->u.sndFailed.info.flags = sctpNtfy->sn_send_failed.ssf_info.sinfo_flags;
2799 ntfy->u.sndFailed.info.ppid = sctpNtfy->sn_send_failed.ssf_info.sinfo_ppid;
2800 ntfy->u.sndFailed.info.context = sctpNtfy->sn_send_failed.ssf_info.sinfo_context;
2801 ntfy->u.sndFailed.info.timetolive = sctpNtfy->sn_send_failed.ssf_info.sinfo_timetolive;
2802 ntfy->u.sndFailed.info.tsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_tsn;
2803 ntfy->u.sndFailed.info.cumtsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_cumtsn;
2804 ntfy->u.sndFailed.info.assocId = sctpNtfy->sn_send_failed.ssf_info.sinfo_assoc_id;
2806 case SCTP_SHUTDOWN_EVENT:
2807 ntfy->header.nType = CM_INET_SCTP_SHUTDOWN_EVENT;
2809 ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2812 case SCTP_ADAPTION_INDICATION :
2815 case SCTP_ADAPTATION_INDICATION :
2817 ntfy->header.nType = CM_INET_SCTP_ADAPTATION_INDICATION;
2820 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
2821 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaption_event.sai_assoc_id;
2824 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
2825 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaptation_event.sai_assoc_id;
2828 case SCTP_PARTIAL_DELIVERY_EVENT:
2829 ntfy->header.nType = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
2831 ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
2832 ntfy->u.pdapiEvt.assocId = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
2840 /* get a message buffer */
2841 ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
2844 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2848 ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
2852 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2858 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,meminfo->region, meminfo->pool, recvbuf, buflen);
2865 * Fun: cmInetSctpGetPAddrs
2867 * Desc: returns the list of peer addresses
2869 * Ret: ROK - successful
2877 S16 cmInetSctpGetPAddrs
2879 CmInetFd *sockFd, /* socket file descriptor */
2880 uint32_t assocId, /* association id */
2881 CmInetNetAddrLst *addrlst /* peer address list */
2884 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2887 uint8_t *byteAddress;
2888 struct sockaddr *peerAddrList;
2889 struct sockaddr_in *pAddr;
2890 #ifdef IPV6_SUPPORTED
2891 struct sockaddr_in6 *pAddr6;
2892 #endif /* IPV6_SUPPORTED */
2895 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
2897 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
2902 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2903 /* cm_inet_c_001.main_62:Warning fix */
2904 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2905 " sockFd->fd(%ld), assocId(%ld)\n",
2906 INET_ERR_CODE, sockFd->fd, assocId);
2907 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2909 /* cm_inet_c_001.main_55: Fix for compilation warning */
2910 /* cm_inet_c_001.main_62:Warning fix */
2911 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2912 " sockFd->fd(%d),assocId(%d)\n",
2913 INET_ERR_CODE, sockFd->fd, assocId);
2914 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2915 #endif /*ALIGN_64BIT*/
2916 #endif /* CMINETDBG */
2921 byteAddress = (uint8_t*)peerAddrList;
2922 for (idx = 0; idx < cnt; idx++)
2924 #ifdef IPV6_SUPPORTED
2926 if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
2928 if (sockFd->protType == AF_INET)
2932 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2933 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2934 " sockFd->fd(%ld)", sockFd->fd);
2935 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2937 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2938 " sockFd->fd(%d)", sockFd->fd);
2939 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2940 #endif /*ALIGN_64BIT*/
2941 #endif /* CMINETDBG */
2943 sctp_freepaddrs(peerAddrList);
2947 pAddr6 = (struct sockaddr_in6*)byteAddress;
2949 addrlst->addrs[idx].type = CM_INET_IPV6ADDR_TYPE;
2950 CM_INET_COPY_IPV6ADDR(&(addrlst->addrs[idx].u.ipv6NetAddr), &(pAddr6->sin6_addr.s6_addr));
2951 byteAddress += sizeof(struct sockaddr_in6);
2955 pAddr = (struct sockaddr_in*)byteAddress;
2956 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2957 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2958 byteAddress += sizeof(struct sockaddr_in);
2961 pAddr = (struct sockaddr_in*)byteAddress;
2962 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2963 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2964 byteAddress += sizeof(struct sockaddr_in);
2965 #endif /* IPV6_SUPPORTED */
2968 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2969 addrlst->count = (uint8_t)cnt;
2971 sctp_freepaddrs(peerAddrList);
2980 * Desc: invokes socket API to retrive specified socket options
2982 * Ret: ROK - successful
2992 CmInetFd *sockFd, /* socket file descriptor */
2993 uint32_t level, /* option level */
2994 uint32_t type, /* option type */
2995 Ptr value /* option value */
2999 struct sctp_status status;
3000 struct sctp_paddrinfo addrInfo;
3001 struct sockaddr_in *pAddr;
3002 #ifdef IPV6_SUPPORTED
3003 struct sockaddr_in6 *pAddr6;
3004 #endif /* IPV6_SUPPORTED */
3005 struct sctp_assocparams assocParams;
3006 /*cm_inet_c_001.main_40 Updated for the support of configurable RTO parameters,
3007 HBeat value Max retransmissions (Init, Path, Association)*/
3008 struct sctp_initmsg initMsg;
3009 struct sctp_rtoinfo rtoInfo;
3010 struct sctp_paddrparams addrParams;
3011 CmInetSctpStatus *pSctpStatus;
3012 CmInetSctpPeerAddrInfo *pPeerAddrInfo;
3013 CmInetSctpInitMsg *pInitMsg;
3014 CmInetSctpAssocParams *pAssocParams;
3015 CmInetSctpRtoInfo *pRtoInfo;
3016 CmInetSctpPeerAddrParams *pPeerAddrParams;
3017 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3021 #if (ERRCLASS & ERRCLS_INT_PAR)
3022 /* error check on parameters */
3023 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3027 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3031 case CM_INET_OPT_SCTP_GET_ASSOC_STA:
3032 pSctpStatus = (CmInetSctpStatus*)value;
3033 memset(&status, 0, sizeof(struct sctp_status));
3034 len = sizeof(status);
3035 status.sstat_assoc_id = pSctpStatus->assocId;
3037 ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
3039 pSctpStatus->rwnd = status.sstat_rwnd;
3040 pSctpStatus->unackdata = status.sstat_unackdata;
3041 pSctpStatus->penddata = status.sstat_penddata;
3042 pSctpStatus->instrms = status.sstat_instrms;
3043 pSctpStatus->outstrms = status.sstat_outstrms;
3044 pSctpStatus->fragPoint = status.sstat_fragmentation_point;
3046 switch (status.sstat_state)
3056 pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3063 pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3069 case SCTPS_COOKIE_WAIT:
3071 case SCTP_COOKIE_WAIT:
3074 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3079 case SCTPS_COOKIE_ECHOED:
3081 case SCTP_COOKIE_ECHOED:
3084 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3089 case SCTPS_ESTABLISHED:
3091 case SCTP_ESTABLISHED:
3094 pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3099 case SCTPS_SHUTDOWN_PENDING:
3101 case SCTP_SHUTDOWN_PENDING:
3104 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3109 case SCTPS_SHUTDOWN_SENT:
3111 case SCTP_SHUTDOWN_SENT:
3114 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3119 case SCTPS_SHUTDOWN_RECEIVED:
3121 case SCTP_SHUTDOWN_RECEIVED:
3124 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3129 case SCTPS_SHUTDOWN_ACK_SENT:
3131 case SCTP_SHUTDOWN_ACK_SENT:
3134 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3145 #ifdef IPV6_SUPPORTED
3146 if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3148 pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3149 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
3151 pSctpStatus->primary.addr.type = CM_INET_IPV6ADDR_TYPE;
3152 CM_INET_COPY_IPV6ADDR(&pSctpStatus->primary.addr.u.ipv6NetAddr,
3153 &pAddr6->sin6_addr.s6_addr);
3157 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3158 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3159 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3160 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3163 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3164 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3165 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3166 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3167 #endif /* IPV6_SUPPORTED */
3169 pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3170 if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3171 pSctpStatus->primary.isActive = TRUE;
3174 pSctpStatus->primary.isActive = FALSE;
3175 pSctpStatus->primary.cwnd = status.sstat_primary.spinfo_cwnd;
3176 pSctpStatus->primary.srtt = status.sstat_primary.spinfo_srtt;
3177 pSctpStatus->primary.rto = status.sstat_primary.spinfo_rto;
3178 pSctpStatus->primary.mtu = status.sstat_primary.spinfo_mtu;
3182 case CM_INET_OPT_SCTP_GET_PADDR_INFO:
3183 pPeerAddrInfo = (CmInetSctpPeerAddrInfo*)value;
3184 memset(&addrInfo, 0, sizeof(struct sctp_paddrinfo));
3185 len = sizeof(addrInfo);
3186 addrInfo.spinfo_assoc_id = pPeerAddrInfo->assocId;
3188 #ifdef IPV6_SUPPORTED
3189 if (pPeerAddrInfo->addr.type == CM_INET_IPV6ADDR_TYPE)
3191 if (sockFd->protType == AF_INET)
3195 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3196 /* cm_inet_c_001.main_62:Warning fix */
3197 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3198 " sockFd->fd(%ld)\n", sockFd->fd);
3199 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3201 /* cm_inet_c_001.main_62:Warning fix */
3202 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3203 " sockFd->fd(%d)\n", sockFd->fd);
3204 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3205 #endif /*ALIGN_64BIT*/
3206 #endif /* CMINETDBG */
3210 pAddr6 = (struct sockaddr_in6*)&(addrInfo.spinfo_address);
3211 pAddr6->sin6_family = AF_INET6;
3212 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3213 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrInfo->addr.u.ipv6NetAddr);
3217 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3218 pAddr->sin_family = AF_INET;
3219 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3220 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3223 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3224 pAddr->sin_family = AF_INET;
3225 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3226 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3227 #endif /* IPV6_SUPPORTED */
3229 /* Not validating the address, whether Addr is a valid address or not */
3231 ret = getsockopt(sockFd->fd, level, SCTP_GET_PEER_ADDR_INFO, &addrInfo, &len);
3233 if (addrInfo.spinfo_state == SCTP_ACTIVE)
3234 pPeerAddrInfo->isActive = TRUE;
3236 pPeerAddrInfo->isActive = FALSE;
3237 pPeerAddrInfo->cwnd = addrInfo.spinfo_cwnd;
3238 pPeerAddrInfo->srtt = addrInfo.spinfo_srtt;
3239 pPeerAddrInfo->rto = addrInfo.spinfo_rto;
3240 pPeerAddrInfo->mtu = addrInfo.spinfo_mtu;
3243 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
3245 pPeerAddrParams = (CmInetSctpPeerAddrParams *)value;
3247 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
3249 addrParams.spp_assoc_id = pPeerAddrParams->assocId;
3251 if (pPeerAddrParams->s.addrPres == TRUE)
3253 #ifdef IPV6_SUPPORTED
3254 if (pPeerAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
3256 if (sockFd->protType == AF_INET)
3260 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3261 /* cm_inet_c_001.main_62:Warning fix */
3262 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%ld)\n",
3264 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3266 /* cm_inet_c_001.main_62:Warning fix */
3267 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%d)\n",
3269 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3270 #endif /*ALIGN_64BIT*/
3271 #endif /* CMINETDBG */
3275 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
3276 pAddr6->sin6_family = AF_INET6;
3277 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3278 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrParams->s.addr.u.ipv6NetAddr);
3282 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3283 pAddr->sin_family = AF_INET;
3284 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3285 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3288 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3289 pAddr->sin_family = AF_INET;
3290 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3291 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3292 #endif /* IPV6_SUPPORTED */
3296 #ifdef IPV6_SUPPORTED
3297 if (sockFd->protType == AF_INET6)
3298 addrParams.spp_address.ss_family = AF_INET6;
3300 addrParams.spp_address.ss_family = AF_INET;
3302 addrParams.spp_address.ss_family = AF_INET;
3306 len = sizeof(addrParams);
3308 ret = getsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, &len);
3309 /* cm_inet_c_001.main_41 : Fixed the Solaris compilation problem */
3312 pPeerAddrParams->hbInterval = addrParams.spp_hbinterval;
3313 pPeerAddrParams->pathMaxRxt = addrParams.spp_pathmaxrxt;
3314 pPeerAddrParams->assocId = addrParams.spp_assoc_id;
3315 pPeerAddrParams->pathMtu = addrParams.spp_pathmtu;
3316 pPeerAddrParams->sackDelay = addrParams.spp_sackdelay;
3318 if (addrParams.spp_flags & SPP_HB_ENABLE)
3319 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_ENABLE;
3321 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_DISABLE;
3323 if (addrParams.spp_flags & SPP_PMTUD_ENABLE)
3324 pPeerAddrParams->pmtudFlag = CM_INET_OPT_ENABLE;
3326 pPeerAddrParams->pmtudFlag = CM_INET_OPT_DISABLE;
3328 if (addrParams.spp_flags & SPP_SACKDELAY_ENABLE)
3329 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_ENABLE;
3331 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_DISABLE;
3336 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
3338 pAssocParams = (CmInetSctpAssocParams *)value;
3340 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
3342 assocParams.sasoc_assoc_id = pAssocParams->assocId;
3344 len = sizeof(assocParams);
3346 ret = getsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, &len);
3348 pAssocParams->assocMaxReTx = assocParams.sasoc_asocmaxrxt;
3349 pAssocParams->cookieLife = assocParams.sasoc_cookie_life;
3350 pAssocParams->assocId = assocParams.sasoc_assoc_id;
3351 pAssocParams->numberOfPeerDest = assocParams.sasoc_number_peer_destinations;
3352 pAssocParams->peerRwnd = assocParams.sasoc_peer_rwnd;
3353 pAssocParams->localRwnd = assocParams.sasoc_local_rwnd;
3357 case CM_INET_OPT_SCTP_RTO_INFO:
3359 pRtoInfo = (CmInetSctpRtoInfo *)value;
3361 memset(&rtoInfo, 0, sizeof(struct sctp_rtoinfo));
3363 len = sizeof(rtoInfo);
3365 ret = getsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoInfo, &len);
3367 pRtoInfo->assocId = rtoInfo.srto_assoc_id;
3368 pRtoInfo->rtoInitial = rtoInfo.srto_initial;
3369 pRtoInfo->rtoMax = rtoInfo.srto_max;
3370 pRtoInfo->rtoMin = rtoInfo.srto_min;
3374 case CM_INET_OPT_SCTP_INIT_MSG:
3376 pInitMsg = (CmInetSctpInitMsg *)value;
3378 memset(&initMsg, 0, sizeof(struct sctp_initmsg));
3380 len = sizeof(initMsg);
3382 ret = getsockopt(sockFd->fd, level, SCTP_INITMSG, &initMsg, &len);
3384 pInitMsg->maxInitReTx = initMsg.sinit_max_attempts;
3385 pInitMsg->maxInitTimeout = initMsg.sinit_max_init_timeo;
3386 pInitMsg->numOstreams = initMsg.sinit_num_ostreams;
3387 pInitMsg->maxInstreams = initMsg.sinit_max_instreams;
3395 if (ret == INET_ERR)
3399 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3400 /* cm_inet_c_001.main_62:Warning fix */
3401 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3402 " error(%d), sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3403 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3405 /* cm_inet_c_001.main_62:Warning fix */
3406 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3407 " error(%d), sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3408 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3409 #endif /*ALIGN_64BIT*/
3410 #endif /* CMINETDBG */
3417 /* cm_inet_c_001.main_54: Added new function cmInetShutDownSctp()*/
3420 * Fun: cmInetShutDownSctp
3422 * Desc: Shutdown the SCTP association gracefully.
3424 * Ret: ROK - successful
3432 S16 cmInetShutDownSctp
3434 CmInetFd *sockFd /* socket file descriptor */
3437 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3439 struct sctp_sndrcvinfo sndRcvInfo;
3442 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3445 sndRcvInfo.sinfo_flags = MSG_EOF;
3447 sndRcvInfo.sinfo_flags = SCTP_EOF;
3450 /* Call the sctp_send with flag set to termiante the association */
3452 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3458 /* cm_inet_c_001.main_62:Warning fix */
3459 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%ld)\n",
3460 INET_ERR_CODE, sockFd->fd);
3461 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3463 /* cm_inet_c_001.main_62:Warning fix */
3464 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%d)\n",
3465 INET_ERR_CODE, sockFd->fd);
3466 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3467 #endif /*ALIGN_64BIT*/
3468 #endif /* CMINETDBG */
3476 /* cm_inet_c_001.main_61: Added new function cmInetAbortSctpAssoc()*/
3479 * Fun: cmInetAbortSctpAssoc
3481 * Desc: ABORT the association.
3483 * Ret: ROK - successful
3491 S16 cmInetAbortSctpAssoc
3493 CmInetFd *sockFd, /* socket file descriptor */
3494 UConnId assocId /* Association ID */
3498 struct sctp_sndrcvinfo sndRcvInfo;
3501 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3504 sndRcvInfo.sinfo_flags = MSG_ABORT;
3506 sndRcvInfo.sinfo_flags = SCTP_ABORT;
3509 sndRcvInfo.sinfo_assoc_id = assocId;
3511 /* Call the sctp_send with flag set to termiante the association */
3513 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3519 /* cm_inet_c_001.main_62:Warning fix */
3520 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%ld)\n",
3521 INET_ERR_CODE, sockFd->fd);
3522 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3524 /* cm_inet_c_001.main_62:Warning fix */
3525 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%d)\n",
3526 INET_ERR_CODE, sockFd->fd);
3527 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3528 #endif /*ALIGN_64BIT*/
3529 #endif /* CMINETDBG */
3542 * Fun: cmInetConnect
3544 * Desc: Establishs a connection to a foreign address (TCP) or associates
3545 * a UDP socket to a foreign address.
3547 * Ret: ROK - successful
3548 * ROKDNA - resource temporarily unavaiable
3549 * RINPROGRESS - connection is in progress (only non-blocking)
3550 * RISCONN - connection is established (only non-blocking)
3561 CmInetFd *sockFd, /* socket file descriptor */
3562 CmInetAddr *servAddr /* foreign Internet address/port */
3565 S32 ret; /* temporary return value */
3566 struct sockaddr_in dstAddr; /* foreign Internet address/port */
3567 #ifdef IPV6_SUPPORTED
3568 struct sockaddr_in6 dstAddr6; /* foreign Internet IPV6 address/port */
3571 #endif /* CMINETDBG */
3572 #endif /* IPV6_SUPPORTED */
3574 CmInetSockAddr *sockAddrPtr;
3577 #if (ERRCLASS & ERRCLS_INT_PAR)
3578 /* error check on parameters */
3579 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3580 (servAddr == NULLP))
3584 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3586 #ifdef IPV6_SUPPORTED
3587 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3589 memset(&dstAddr6, 0, sizeof(dstAddr6));
3590 dstAddr6.sin6_family = AF_INET6;
3591 dstAddr6.sin6_port = CM_INET_HTON_UINT16(servAddr->u.ipv6Addr.port);
3592 CM_INET_COPY_IPV6ADDR(&dstAddr6.sin6_addr,
3593 &servAddr->u.ipv6Addr.ipv6NetAddr);
3594 sizeOfAddr = sizeof(struct sockaddr_in6);
3595 sockAddrPtr = (CmInetSockAddr *)&dstAddr6;
3599 memset(&dstAddr, 0, sizeof(dstAddr));
3600 dstAddr.sin_family = AF_INET;
3601 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->u.ipv4Addr.port);
3602 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->u.ipv4Addr.address);
3603 sizeOfAddr = sizeof(struct sockaddr_in);
3604 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3607 memset(&dstAddr, 0, sizeof(dstAddr));
3608 dstAddr.sin_family = AF_INET;
3609 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->port);
3610 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->address);
3611 sizeOfAddr = sizeof(struct sockaddr_in);
3612 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3613 #endif /* IPV6_SUPPORTED */
3615 ret = connect(sockFd->fd, sockAddrPtr, sizeOfAddr);
3616 if (ret == INET_ERR)
3618 switch (INET_ERR_CODE)
3620 /* non-blocking: connection is in progress */
3621 case ERR_INPROGRESS:
3622 return (RINPROGRESS);
3626 * non-blocking: connection is established
3627 * blocking : connection is already established
3633 /* resource temporarily unavailable */
3634 case ERR_WOULDBLOCK:
3638 /* non-blocking: connection is in progress */
3640 return (RINPROGRESS);
3644 return (RINPROGRESS);
3647 /* Check for connection refused and timeout errors */
3648 case ERR_CONNREFUSED:
3653 /* it is a real error */
3656 #ifdef IPV6_SUPPORTED
3657 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3658 port = servAddr->u.ipv6Addr.port;
3660 port = servAddr->u.ipv4Addr.port;
3662 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3664 /* cm_inet_c_001.main_62:Warning fix */
3665 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3666 " addrtype(0x%x), port(0x%1x), sockFd->fd(%ld)\n",
3667 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3668 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3670 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3671 " addrtype(0x%x), port(0x%1x), sockFd->fd(%d)\n",
3672 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3673 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3674 #endif /*ALIGN_64BIT*/
3677 /* cm_inet_c_001.main_62:Warning fix */
3678 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%lx),"
3679 "port(0x%1x), sockFd->fd(%ld)\n", INET_ERR_CODE ,
3680 servAddr->address, servAddr->port, sockFd->fd);
3681 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3683 /* cm_inet_c_001.main_62:Warning fix */
3684 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%x),"
3685 "port(0x%x), sockFd->fd(%d)\n", INET_ERR_CODE ,
3686 servAddr->address, servAddr->port, sockFd->fd);
3687 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3688 #endif /*ALIGN_64BIT*/
3689 #endif /* IPV6_SUPPORTED */
3690 #endif /* CMINETDBG */
3697 } /* end of cmInetConnect */
3704 * Desc: Indicates the willingness of a socket to listen for incomming
3705 * connection requests.
3707 * Ret: ROK - successful
3710 * Notes: The backLog value has to be within 0..5
3718 CmInetFd *sockFd, /* socket file descriptor */
3719 S16 backLog /* max. number of outstandig connections 0..5 */
3722 S32 ret; /* temporary return value */
3725 #if (ERRCLASS & ERRCLS_INT_PAR)
3726 /* error check on parameters */
3727 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3728 (backLog < MIN_BACK_LOG) || (backLog > MAX_BACK_LOG))
3732 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3734 ret = listen(sockFd->fd, backLog);
3735 if (ret == INET_ERR)
3739 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3740 /* cm_inet_c_001.main_62:Warning fix */
3741 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3742 " sockFd->fd(%ld)\n", INET_ERR_CODE, backLog, sockFd->fd);
3743 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3745 /* cm_inet_c_001.main_62:Warning fix */
3746 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3747 " sockFd->fd(%d)\n", INET_ERR_CODE, backLog, sockFd->fd);
3748 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3749 #endif /*ALIGN_64BIT*/
3750 #endif /* CMINETDBG */
3755 } /* end of cmInetListen */
3762 * Desc: Accepts an incoming connection.
3763 * On default the new socket is non-blocking. The options can be
3764 * changed with the function cmInetSetOpt().
3766 * Ret: ROK - successful
3767 * ROKDNA - there is no connection present to accept (only
3779 CmInetFd *sockFd, /* socket file descriptor */
3780 CmInetAddr *fromAddr, /* calling Internet address/port */
3781 CmInetFd *newSockFd /* socket file descriptor for new connection*/
3784 S32 ret; /* temporary return value */
3785 S32 addrLen; /* address structure length */
3786 struct sockaddr_in *peerAddr; /* calling Internet address/port */
3787 #ifdef IPV6_SUPPORTED
3788 struct sockaddr_in6 *peerAddr6; /* calling Internet address/port */
3789 struct sockaddr_in6 sockAddr;
3791 CmInetSockAddr sockAddr;
3792 #endif /* IPV6_SUPPORTED */
3798 #if (ERRCLASS & ERRCLS_INT_PAR)
3799 /* error check on parameters */
3800 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3804 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3806 /* change CmInetSockAddr to sockAddr */
3807 addrLen = sizeof(sockAddr);
3810 #if ( defined(SUNOS) || defined(SS_LINUX))
3811 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3812 (socklen_t *)&addrLen);
3814 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3816 #endif /* SUNOS || SS_LINUX */
3818 /* cm_inet_c_001.main_58: Moved setting of protType below */
3820 if (CM_INET_INV_SOCK_FD(newSockFd))
3822 if (INET_ERR_CODE == ERR_WOULDBLOCK)
3824 /* no connection present to accept */
3831 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3832 /* cm_inet_c_001.main_62:Warning fix */
3833 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3834 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3835 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3837 /* cm_inet_c_001.main_62:Warning fix */
3838 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3839 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3840 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3841 #endif /*ALIGN_64BIT*/
3842 #endif /* CMINETDBG */
3848 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
3849 /* added for IPv6/IPv4 socket distinguishing */
3850 #ifdef IPV6_SUPPORTED
3851 if (addrLen == sizeof(struct sockaddr_in))
3852 newSockFd->protType = AF_INET;
3853 else if(addrLen == sizeof(struct sockaddr_in6))
3854 newSockFd->protType = AF_INET6;
3859 /* cm_inet_c_001.main_62:Warning fix */
3860 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%ld)\n", sockFd->fd);
3861 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3863 /* cm_inet_c_001.main_62:Warning fix */
3864 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%d)\n", sockFd->fd);
3865 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3866 #endif /*ALIGN_64BIT*/
3867 #endif /* CMINETDBG */
3870 #endif /* IPV6_SUPPORTED */
3872 /* set the new socket file descriptor type */
3873 newSockFd->type = CM_INET_STREAM;
3875 /* set default options for new socket file descriptor */
3876 optVal = CM_INET_OPT_DISABLE;
3877 ret = cmInetSetOpt(newSockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, &optVal);
3880 ret = cmInetClose(newSockFd);
3884 #ifdef IPV6_SUPPORTED
3885 memset(fromAddr, 0, sizeof(fromAddr));
3886 if (addrLen == sizeof(struct sockaddr_in))
3888 peerAddr = (struct sockaddr_in *)&sockAddr;
3889 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
3890 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3891 fromAddr->u.ipv4Addr.address =
3892 CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3894 else if (addrLen == sizeof(struct sockaddr_in6))
3896 peerAddr6 = (struct sockaddr_in6 *)&sockAddr;
3897 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
3898 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(peerAddr6->sin6_port);
3899 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
3900 &peerAddr6->sin6_addr);
3903 peerAddr = (struct sockaddr_in *)&sockAddr;
3904 fromAddr->port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3905 fromAddr->address = CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3906 #endif /* IPV6_SUPPORTED */
3908 } /* end of cmInetAccept */
3913 * Fun: cmInet4FillTos
3915 * Desc: This function inserts tos (into ancillary data) which
3916 * will be used to fill tos value in ip header in outgoing IP packet
3917 * when sending that packet using sendmsg()function.
3927 static S16 cmInet4FillTos
3929 uint8_t tos, /* tos value to be filled in ipheader */
3930 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
3931 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
3934 struct cmsghdr *tempHdr;
3941 /* cmsghdr struc will appear before data in the ancillary data object.
3942 * So put cmsghdr struc in flat buffer first. */
3944 /* cmsghdr struc points to flat buffer's starting address */
3945 tempHdr = (struct cmsghdr *)cmsgBuf;
3947 /* fill up level & type of cmsghdr structure */
3948 tempHdr->cmsg_level = IPPROTO_IPV6;
3949 tempHdr->cmsg_type = IP_TOS;
3950 (*(uint8_t*)CMSG_DATA(tempHdr)) = tos;
3951 len = CMSG_SPACE(sizeof tos);
3954 /* fill up the length of cmsghdr structure */
3955 tempHdr->cmsg_len = len;
3960 }/* end of cmInet4FillTos */
3963 * Fun: cmInetSendDscpMsg
3965 * Desc: Sends the message data hold by mBuf.
3966 * The len paramter gives the actual written octets. If the socket
3967 * is non-blocking this value can be differ from the mBuf length
3968 * because there was not enough transmit buffer space available. If
3969 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
3971 * Values for flag parameter:
3973 * CM_INET_NO_FLAG - no additional control flag
3975 * Ret: ROK - successful
3976 * RWOULDBLOCK - no or not entire mBuf sent because would block
3977 * ROUTRES - failed, out of resources
3978 * RCLOSED - connection was closed by the peer
3981 * Notes: The successful completion of a send call does not indicate that
3982 * the data has been successfully delivered!
3984 * This function does not free any sent buffers.
3991 S16 cmInetSendDscpMsg
3993 CmInetFd *sockFd, /* socket file descriptor */
3994 CmInetAddr *dstAddr, /* destination Internet address/port */
3995 CmInetMemInfo *info, /* buffer allocation info */
3996 Buffer *mBuf, /* buffer structure to send */
3997 MsgLen *len, /* number of actually sent octets */
3998 /* added for IPv6 ext hdr */
3999 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4000 S16 flags /* additional control flags, unused */
4003 #if (defined(WIN32) || defined(CMINETFLATBUF))
4004 S32 ret =0; /* temporary return value */
4005 MsgLen msgLen =0; /* message length */
4006 MsgLen bufLen =0; /* send buffer length */
4007 Data *sendBuf =0; /* plain send buffer */
4009 S32 ret =0; /* temporary return value */
4010 S32 retVal =0; /* temporary return value */
4011 S16 i =0; /* loop index */
4012 CmInetIovec txArr[CM_INET_MAX_DBUF] = {{0}}; /* scatter vector */
4013 S16 numDBufs =0; /* number of dBufs in message */
4014 struct msghdr msg ={0}; /* sendmsg() message header */
4015 MsgLen msgLen =0; /* message length */
4016 uint32_t strtEndDBufNum =0; /* starting/ending DBuf number */
4017 MsgLen unSentLen =0; /* sent len */
4018 #ifdef IPV6_SUPPORTED
4019 uint32_t curMsgIdx =0; /* indx in cmsgData where to write an ext hdr */
4020 /* added for IPv6 ext hdr */
4021 #if (defined(SS_LINUX) || defined(_XPG4_2))
4022 /* alloc from stack for IPv6 ancill data */
4023 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA]= {0};
4024 #endif /* SS_LINUX || _XPG4_2 */
4026 uint32_t curMsgIdx =0; /* indx in cmsgData where to write an ext hdr */
4027 #if (defined(SS_LINUX) || defined(_XPG4_2))
4028 /* alloc from stack for IPv4 ancill data */
4029 uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA]={0};
4030 #endif /* SS_LINUX || _XPG4_2 */
4031 #endif /* IPV6_SUPPORTED */
4032 #endif /* WIN32 | CMINETFLATBUF */
4034 struct sockaddr_in remAddr ={0}; /* remote Internet address */
4035 #ifdef IPV6_SUPPORTED
4036 struct sockaddr_in6 remAddr6 = {0}; /* remote Internet address */
4037 #endif /* IPV8_SUPPORTED */
4038 CmInetSockAddr *sockAddrPtr = NULLP;
4039 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4040 uint32_t sizeOfAddr =0;
4042 /* cm_inet_c_001.main_50 - Added for partial send handling */
4043 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4044 #if (!defined(WIN32))
4051 #if (ERRCLASS & ERRCLS_INT_PAR)
4052 /* error check on parameters */
4053 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4054 (info == NULLP) || (len == NULLP))
4058 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4060 /* added for IPv6 ext hdr */
4061 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4062 #if (defined(SS_LINUX) || defined(_XPG4_2))
4063 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4064 #endif /* SS_LINUX || _XPG4_2 */
4066 #endif /* WIN32 | CMINETFLATBUF */
4068 msgLen = 0; /* need by CC to pass without warning */
4069 sockAddrPtr = NULLP;
4072 /* setup remote address */
4073 if (dstAddr != NULLP)
4075 #ifdef IPV6_SUPPORTED
4076 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4078 memset(&remAddr6, 0, sizeof(remAddr6));
4079 remAddr6.sin6_family = AF_INET6;
4080 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4081 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4082 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4083 sizeOfAddr = sizeof(remAddr6);
4084 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4088 memset(&remAddr, 0, sizeof(remAddr));
4089 remAddr.sin_family = AF_INET;
4090 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4091 remAddr.sin_addr.s_addr =
4092 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4093 sizeOfAddr = sizeof(remAddr);
4094 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4097 /* memset(&remAddr, 0, sizeof(remAddr)); */
4098 remAddr.sin_family = AF_INET;
4099 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4100 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4101 sizeOfAddr = sizeof(remAddr);
4102 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4103 #endif /* IPV6_SUPPORTED */
4106 #if (defined(WIN32) || defined(CMINETFLATBUF))
4107 /* copy message to a flat buffer */
4108 ret = SFndLenMsg(mBuf, &bufLen);
4113 /* max message length is limited to control the memory usage */
4114 /* casting bufLen to avoid warnings */
4115 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4119 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &sendBuf, bufLen);
4124 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4125 if ((ret != ROK) || (msgLen != bufLen))
4128 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4132 if (dstAddr == NULLP)
4134 /* VxWorks sendto has some problem
4135 * with connected UDP socket, use send */
4137 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4140 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4141 #endif /* end of SS_VW */
4144 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4146 #if (defined(SS_VW) && defined(SS_VW6_7))
4147 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4149 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4152 #endif /* end of SS_VW6_7 and SS_VW */
4154 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4155 sockAddrPtr, sizeOfAddr);
4158 if (ret == INET_ERR)
4161 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4163 if(INET_ERR_CODE == ERR_AGAIN)
4166 return (RWOULDBLOCK);
4169 /* Check for ERR_WOULDBLOCK */
4170 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4173 return (RWOULDBLOCK);
4178 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4179 /* cm_inet_c_001.main_62:Warning fix */
4180 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4181 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4182 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4184 /* cm_inet_c_001.main_62:Warning fix */
4185 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4186 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4187 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4188 #endif /*ALIGN_64BIT*/
4189 #endif /* CMINETDBG */
4191 /* cm_inet_c_001.main_37 network unreacheble error is added */
4192 /* check if network is reacheble*/
4193 if ((INET_ERR_CODE == ERR_NETUNREACH))
4195 return (RNETFAILED);
4199 /* Check if connection was closed */
4200 if ((INET_ERR_CODE == ERR_PIPE) ||
4201 (INET_ERR_CODE == ERR_CONNABORTED) ||
4202 (INET_ERR_CODE == ERR_CONNRESET))
4213 /* check if entire message could be sent */
4218 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4219 return (RWOULDBLOCK);
4223 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4225 #else /* end of Win NT/flat buffer specific part */
4226 ret = SFndLenMsg(mBuf, &msgLen);
4233 /* memset(&msg, 0, sizeof(msg)); */
4236 if (dstAddr != NULLP)
4239 msg.msg_name = (Void*)sockAddrPtr;
4242 msg.msg_name = (char *)sockAddrPtr;
4244 msg.msg_name = (caddr_t)sockAddrPtr;
4246 #endif /* SS_LINUX */
4247 msg.msg_namelen = sizeOfAddr;
4251 msg.msg_name = NULLP;
4252 msg.msg_namelen = 0;
4254 /* added defined(_XPG4_2) */
4255 #if (defined(SS_LINUX) || defined(_XPG4_2))
4256 msg.msg_control = NULLP;
4257 msg.msg_controllen = 0;
4259 msg.msg_accrights = 0;
4260 msg.msg_accrightslen = NULLP;
4261 #endif /* SS_LINUX */
4263 /* allocate scatter vector */
4264 numDBufs = CM_INET_MAX_DBUF;
4270 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV4ADDR_TYPE))
4271 if((ipHdrParams->u.hdrParmIpv4.tos.pres == TRUE)&& \
4272 (ipHdrParams->u.hdrParmIpv4.tos.val != 0))
4274 cmInet4FillTos(ipHdrParams->u.hdrParmIpv4.tos.val,
4275 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4276 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4277 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4279 /* if the sender wants to send Ipv6 exten. headers */
4280 #ifdef IPV6_OPTS_SUPPORTED
4281 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4284 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4286 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4287 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4289 #endif /* SS_LINUX */
4292 /* have to decide how to get the src addr to add in in6_pktinfo */
4293 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4295 cmInet6BuildSendPktinfo(
4296 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4297 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4300 #endif /* LOCAL_INTF */
4302 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4303 * cmsgData one by one. */
4305 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4306 /* build HBH ext header in cmsgData starting at indx 0 */
4307 cmInet6BuildSendHBHOpts(
4308 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4309 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4311 /* now copy the elements from the Destination Option array one by
4312 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4313 * which is the end of HBH hdr. */
4314 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4315 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4316 cmInet6BuildSendDestOpts(
4317 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4318 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4320 /* copy Route header to to the Flat Buffer cmsgData */
4321 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4322 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4323 cmInet6BuildSendRouteOpts(
4324 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4325 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4327 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4328 * will be the curMsgIdx */
4329 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4330 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4333 #endif /* IPV6_OPTS_SUPPORTED */
4335 /* Loop till all the data is sent or till the sendmsg call cannot send
4339 /* build the send vector */
4340 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4341 total length of the packed dbufs */
4342 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4343 &strtEndDBufNum, &ioLen);
4348 /* Incase of UDP/RAW messages call SCompressMsg. */
4349 if (sockFd->type != CM_INET_STREAM)
4351 /* Compress the message into a single dBuf */
4352 ret = SCompressMsg(mBuf);
4357 /* Rebuild the send vector */
4358 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4359 total length of the packed dbuf */
4360 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4361 &strtEndDBufNum, &ioLen);
4371 msg.msg_iov = txArr;
4378 if ( sockFd->fd >= 0xD001)
4379 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4381 ret = sendmsg(sockFd->fd, &msg, 0);
4384 ret = sendmsg(sockFd->fd, &msg, 0);
4386 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4387 if (ret == INET_ERR)
4389 if((INET_ERR_CODE == ERR_AGAIN) ||
4390 (INET_ERR_CODE == ERR_WOULDBLOCK))
4392 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4393 message was sent earlier */
4394 return (RWOULDBLOCK);
4398 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4399 /* cm_inet_c_001.main_62:Warning fix */
4400 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4401 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4402 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4404 /* cm_inet_c_001.main_62:Warning fix */
4405 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4406 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4407 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4408 #endif /*ALIGN_64BIT*/
4409 #endif /* CMINETDBG */
4411 /* cm_inet_c_001.main_37 network unreacheble error is added */
4412 /* check if network is reacheble or not */
4413 if ((INET_ERR_CODE == ERR_NETUNREACH))
4415 return (RNETFAILED);
4418 /* Check if connection was closed by the peer */
4419 if ((INET_ERR_CODE == ERR_PIPE) ||
4420 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4421 (INET_ERR_CODE == ERR_CONNABORTED))
4429 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4432 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4433 * to be sent, then return WOULDBLOCK
4436 return (RWOULDBLOCK);
4440 } while (*len < msgLen);
4441 #endif /* WIN32 | CMINETFLATBUF */
4445 } /* end of cmInetSendDscpMsg */
4449 * Fun: cmInetSendMsg
4451 * Desc: Sends the message data hold by mBuf.
4452 * The len paramter gives the actual written octets. If the socket
4453 * is non-blocking this value can be differ from the mBuf length
4454 * because there was not enough transmit buffer space available. If
4455 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4457 * Values for flag parameter:
4459 * CM_INET_NO_FLAG - no additional control flag
4461 * Ret: ROK - successful
4462 * RWOULDBLOCK - no or not entire mBuf sent because would block
4463 * ROUTRES - failed, out of resources
4464 * RCLOSED - connection was closed by the peer
4467 * Notes: The successful completion of a send call does not indicate that
4468 * the data has been successfully delivered!
4470 * This function does not free any sent buffers.
4479 CmInetFd *sockFd, /* socket file descriptor */
4480 CmInetAddr *dstAddr, /* destination Internet address/port */
4481 CmInetMemInfo *info, /* buffer allocation info */
4482 Buffer *mBuf, /* buffer structure to send */
4483 MsgLen *len, /* number of actually sent octets */
4484 /* added for IPv6 ext hdr */
4485 #ifdef IPV6_OPTS_SUPPORTED
4486 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4487 #endif /* IPV6_OPTS_SUPPORTED */
4488 S16 flags /* additional control flags, unused */
4491 #if (defined(WIN32) || defined(CMINETFLATBUF))
4492 S32 ret; /* temporary return value */
4493 MsgLen msgLen; /* message length */
4494 MsgLen bufLen; /* send buffer length */
4495 Data *sendBuf; /* plain send buffer */
4497 S32 ret; /* temporary return value */
4498 S32 retVal; /* temporary return value */
4499 S16 i; /* loop index */
4500 CmInetIovec txArr[CM_INET_MAX_DBUF] ={{0}}; /* scatter vector */
4501 S16 numDBufs; /* number of dBufs in message */
4502 struct msghdr msg; /* sendmsg() message header */
4503 MsgLen msgLen; /* message length */
4504 uint32_t strtEndDBufNum; /* starting/ending DBuf number */
4505 MsgLen unSentLen; /* sent len */
4506 #ifdef IPV6_SUPPORTED
4507 /* added for IPv6 ext hdr */
4508 #ifdef IPV6_OPTS_SUPPORTED
4509 uint32_t curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4510 #if (defined(SS_LINUX) || defined(_XPG4_2))
4511 /* alloc from stack for IPv6 ancill data */
4512 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA];
4513 #endif /* SS_LINUX || _XPG4_2 */
4514 #endif /* IPV6_OPTS_SUPPORTED */
4516 #if (defined(SS_LINUX) || defined(_XPG4_2))
4517 /* alloc from stack for IPv4 ancill data */
4518 /* uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA];*/
4519 #endif /* SS_LINUX || _XPG4_2 */
4520 #endif /* IPV6_SUPPORTED */
4521 #endif /* WIN32 | CMINETFLATBUF */
4523 struct sockaddr_in remAddr; /* remote Internet address */
4524 #ifdef IPV6_SUPPORTED
4525 struct sockaddr_in6 remAddr6; /* remote Internet address */
4526 #endif /* IPV8_SUPPORTED */
4527 CmInetSockAddr *sockAddrPtr;
4528 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4529 uint32_t sizeOfAddr;
4531 /* cm_inet_c_001.main_50 - Added for partial send handling */
4532 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4533 #if (!defined(WIN32))
4540 #if (ERRCLASS & ERRCLS_INT_PAR)
4541 /* error check on parameters */
4542 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4543 (info == NULLP) || (len == NULLP))
4547 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4549 /* added for IPv6 ext hdr */
4550 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4551 #if (defined(SS_LINUX) || defined(_XPG4_2))
4552 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4553 #endif /* SS_LINUX || _XPG4_2 */
4554 #ifdef IPV6_OPTS_SUPPORTED
4556 #endif /* IPV6_SUPPORTED */
4557 #endif /* WIN32 | CMINETFLATBUF */
4559 msgLen = 0; /* need by CC to pass without warning */
4560 sockAddrPtr = NULLP;
4563 /* setup remote address */
4564 if (dstAddr != NULLP)
4566 #ifdef IPV6_SUPPORTED
4567 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4569 memset(&remAddr6, 0, sizeof(remAddr6));
4570 remAddr6.sin6_family = AF_INET6;
4571 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4572 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4573 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4574 sizeOfAddr = sizeof(remAddr6);
4575 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4579 memset(&remAddr, 0, sizeof(remAddr));
4580 remAddr.sin_family = AF_INET;
4581 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4582 remAddr.sin_addr.s_addr =
4583 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4584 sizeOfAddr = sizeof(remAddr);
4585 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4588 /* memset(&remAddr, 0, sizeof(remAddr)); */
4589 remAddr.sin_family = AF_INET;
4590 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4591 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4592 sizeOfAddr = sizeof(remAddr);
4593 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4594 #endif /* IPV6_SUPPORTED */
4597 #if (defined(WIN32) || defined(CMINETFLATBUF))
4598 /* copy message to a flat buffer */
4599 ret = SFndLenMsg(mBuf, &bufLen);
4604 /* max message length is limited to control the memory usage */
4605 /* casting bufLen to avoid warnings */
4606 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4610 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &sendBuf, bufLen);
4615 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4616 if ((ret != ROK) || (msgLen != bufLen))
4619 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4623 if (dstAddr == NULLP)
4625 /* VxWorks sendto has some problem
4626 * with connected UDP socket, use send */
4628 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4631 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4632 #endif /* end of SS_VW */
4635 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4637 #if (defined(SS_VW) && defined(SS_VW6_7))
4638 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4640 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4643 #endif /* end of SS_VW6_7 and SS_VW */
4645 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4646 sockAddrPtr, sizeOfAddr);
4649 if (ret == INET_ERR)
4652 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4654 if(INET_ERR_CODE == ERR_AGAIN)
4657 return (RWOULDBLOCK);
4660 /* Check for ERR_WOULDBLOCK */
4661 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4664 return (RWOULDBLOCK);
4669 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4670 /* cm_inet_c_001.main_62:Warning fix */
4671 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4672 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4673 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4675 /* cm_inet_c_001.main_62:Warning fix */
4676 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4677 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4678 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4679 #endif /*ALIGN_64BIT*/
4680 #endif /* CMINETDBG */
4682 /* cm_inet_c_001.main_37 network unreacheble error is added */
4683 /* check if network is reacheble*/
4684 if ((INET_ERR_CODE == ERR_NETUNREACH))
4686 return (RNETFAILED);
4690 /* Check if connection was closed */
4691 if ((INET_ERR_CODE == ERR_PIPE) ||
4692 (INET_ERR_CODE == ERR_CONNABORTED) ||
4693 (INET_ERR_CODE == ERR_CONNRESET))
4704 /* check if entire message could be sent */
4709 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4710 return (RWOULDBLOCK);
4714 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, sendBuf, bufLen);
4716 #else /* end of Win NT/flat buffer specific part */
4717 ret = SFndLenMsg(mBuf, &msgLen);
4724 /* memset(&msg, 0, sizeof(msg)); */
4727 if (dstAddr != NULLP)
4730 msg.msg_name = (Void*)sockAddrPtr;
4733 msg.msg_name = (char *)sockAddrPtr;
4735 msg.msg_name = (caddr_t)sockAddrPtr;
4737 #endif /* SS_LINUX */
4738 msg.msg_namelen = sizeOfAddr;
4742 msg.msg_name = NULLP;
4743 msg.msg_namelen = 0;
4745 /* added defined(_XPG4_2) */
4746 #if (defined(SS_LINUX) || defined(_XPG4_2))
4747 msg.msg_control = NULLP;
4748 msg.msg_controllen = 0;
4750 msg.msg_accrights = 0;
4751 msg.msg_accrightslen = NULLP;
4752 #endif /* SS_LINUX */
4754 /* allocate scatter vector */
4755 numDBufs = CM_INET_MAX_DBUF;
4762 /* if the sender wants to send Ipv6 exten. headers */
4763 #ifdef IPV6_OPTS_SUPPORTED
4764 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4767 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4769 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4770 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4772 #endif /* SS_LINUX */
4775 /* have to decide how to get the src addr to add in in6_pktinfo */
4776 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4778 cmInet6BuildSendPktinfo(
4779 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4780 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4783 #endif /* LOCAL_INTF */
4785 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4786 * cmsgData one by one. */
4788 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4789 /* build HBH ext header in cmsgData starting at indx 0 */
4790 cmInet6BuildSendHBHOpts(
4791 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4792 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4794 /* now copy the elements from the Destination Option array one by
4795 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4796 * which is the end of HBH hdr. */
4797 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4798 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4799 cmInet6BuildSendDestOpts(
4800 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4801 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4803 /* copy Route header to to the Flat Buffer cmsgData */
4804 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4805 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4806 cmInet6BuildSendRouteOpts(
4807 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4808 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4810 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4811 * will be the curMsgIdx */
4812 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4813 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4816 #endif /* IPV6_OPTS_SUPPORTED */
4818 /* Loop till all the data is sent or till the sendmsg call cannot send
4822 /* build the send vector */
4823 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4824 total length of the packed dbufs */
4825 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4826 &strtEndDBufNum, &ioLen);
4831 /* Incase of UDP/RAW messages call SCompressMsg. */
4832 if (sockFd->type != CM_INET_STREAM)
4834 /* Compress the message into a single dBuf */
4835 ret = SCompressMsg(mBuf);
4840 /* Rebuild the send vector */
4841 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4842 total length of the packed dbuf */
4843 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4844 &strtEndDBufNum, &ioLen);
4854 msg.msg_iov = txArr;
4861 if ( sockFd->fd >= 0xD001)
4862 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4864 ret = sendmsg(sockFd->fd, &msg, 0);
4867 ret = sendmsg(sockFd->fd, &msg, 0);
4869 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4870 if (ret == INET_ERR)
4872 if((INET_ERR_CODE == ERR_AGAIN) ||
4873 (INET_ERR_CODE == ERR_WOULDBLOCK))
4875 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4876 message was sent earlier */
4877 return (RWOULDBLOCK);
4881 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4882 /* cm_inet_c_001.main_62:Warning fix */
4883 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4884 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4885 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4887 /* cm_inet_c_001.main_62:Warning fix */
4888 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4889 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4890 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4891 #endif /*ALIGN_64BIT*/
4892 #endif /* CMINETDBG */
4894 /* cm_inet_c_001.main_37 network unreacheble error is added */
4895 /* check if network is reacheble or not */
4896 if ((INET_ERR_CODE == ERR_NETUNREACH))
4898 return (RNETFAILED);
4901 /* Check if connection was closed by the peer */
4902 if ((INET_ERR_CODE == ERR_PIPE) ||
4903 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4904 (INET_ERR_CODE == ERR_CONNABORTED))
4912 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4915 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4916 * to be sent, then return WOULDBLOCK
4919 return (RWOULDBLOCK);
4923 } while (*len < msgLen);
4924 #endif /* WIN32 | CMINETFLATBUF */
4928 } /* end of cmInetSendMsg */
4931 /* added new functions for IPv6 extension headers */
4932 #ifdef IPV6_OPTS_SUPPORTED
4936 * Fun: cmInet6BuildSendPktinfo
4938 * Desc: This function inserts src address (into ancillary data) which
4939 * will be used as the src addr in outgoing IP packet when sending
4940 * that packet using sendmsg()function.
4950 static S16 cmInet6BuildSendPktinfo
4952 CmInetIpAddr6 *srcAddr, /* src ip addr to set on outgoing packet */
4953 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
4954 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4955 uint8_t protType /* whether IPv4/IPv6 socket */
4958 struct cmsghdr *tempHdr;
4959 struct in6_pktinfo *ipv6Pktinfo;
4960 struct in6_addr lpBkAddr;
4966 lpBkAddr = in6addr_loopback;
4968 /* cmsghdr struc will appear before data in the ancillary data object.
4969 * So put cmsghdr struc in flat buffer first. */
4971 /* cmsghdr struc points to flat buffer's starting address */
4972 tempHdr = (struct cmsghdr *)cmsgBuf;
4974 /* fill up level & type of cmsghdr structure */
4975 if (protType == AF_INET6)
4977 tempHdr->cmsg_level = IPPROTO_IPV6;
4978 tempHdr->cmsg_type = IPV6_PKTINFO;
4981 else if(protType == AF_INET)
4983 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4984 /* cm_inet_c_001.main_62:Warning fix */
4985 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
4986 "protType(%d)\n", protType);
4987 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET025, 0, prntBuf);
4991 /* skip length of cmsghdr structure - 12 bytes */
4992 len += sizeof(struct cmsghdr);
4994 if(protType == AF_INET6)
4995 ipv6Pktinfo = (struct in6_pktinfo *)(cmsgBuf + len);
4999 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5000 /* cm_inet_c_001.main_62:Warning fix */
5001 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5002 "protType(%d)\n", protType);
5003 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET026, 0, prntBuf);
5007 /* insert the hoplimit. This will override the kernel's
5008 * default hoplimit value */
5009 if(protType == AF_INET6)
5011 /* store ipv6 src addr */
5012 memcpy(&(ipv6Pktinfo->ipi6_addr), srcAddr, 16);
5015 /* store interface index */
5016 /* 0 is invalid intf indx it tells kernel to chose any intf it likes to
5017 * send this pkt. if we use nozero intf indx then kernel will send this
5018 * pkt only through that intf */
5019 ipv6Pktinfo->ipi6_ifindex = 0;
5023 else if(protType == AF_INET)
5025 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5026 /* cm_inet_c_001.main_62:Warning fix */
5027 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5028 "protType(%d)\n", protType);
5029 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET027, 0, prntBuf);
5033 /* fill up the length of cmsghdr structure */
5034 tempHdr->cmsg_len = len;
5039 }/* end of cmInet6BuildSendPktinfo */
5040 #endif /* LOCAL_INTF */
5046 * Fun: cmInetBuildSendHoplimit
5048 * Desc: This function inserts hoplimit value to be sent out by ancillary
5049 * data by calling sendmsg()function.
5059 static S16 cmInetBuildSendHoplimit
5061 uint32_t hoplimit, /* the hoplimit value to be set on outgoing packet */
5062 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5063 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5066 struct cmsghdr *tempHdr;
5072 /* cmsghdr struc will appear before data in the ancillary data object.
5073 * So put cmsghdr struc in flat buffer first. */
5075 /* cmsghdr struc points to flat buffer's starting address */
5076 tempHdr = (struct cmsghdr *)cmsgBuf;
5078 /* fill up level & type of cmsghdr structure */
5079 tempHdr->cmsg_level = IPPROTO_IPV6;
5080 tempHdr->cmsg_type = IPV6_HOPLIMIT;
5082 /* skip cmsghdr struc (length of cmsghdr structure) */
5083 len += sizeof(struct cmsghdr);
5085 /* insert the hoplimit. This will override the kernel's
5086 * default hoplimit value */
5087 *(cmsgBuf + len) = hoplimit;
5088 len += sizeof(hoplimit);
5090 /* fill up the length of cmsghdr structure */
5091 tempHdr->cmsg_len = len;
5095 } /* end of cmInetBuildSendHoplimit */
5096 #endif /* SS_LINUX */
5101 * Fun: cmInet6BuildSendHBHOpts
5103 * Desc: This function builds the HopByHop option which will be put
5104 * in the data portion of the ancillary data object. To build
5105 * the HopByHop option this function takes an array of
5106 * individual HopByHop option and fill them in a flat buffer.
5107 * cmsghdr struc always appear before HopBYHop Options, Dest
5108 * Options and Route header option.
5110 * The address of the flat Buffer *cmsgBuf is passed to this
5111 * function from cmInetSendMsg. This buffer will have all extension
5112 * headers. This buffer is passed as ancillary data by sendmsg()
5116 * Notes: This function will also be used for Destination options
5122 static S16 cmInet6BuildSendHBHOpts
5124 CmInetIpv6HBHHdrArr *hbhOptsArr,/* IPv6 extensions headers HBH/Dest opts */
5125 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5126 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5127 uint8_t hdrId /* 0: HBH hdr, 1:Dest Hdr */
5130 struct cmsghdr *tempHdr;
5138 /* cmsghdr struc will appear before data in the ancillary data object.
5139 * So put cmsghdr struc in flat buffer first. */
5141 /* cmsghdr struc points to flat buffer's starting address */
5142 tempHdr = (struct cmsghdr *)cmsgBuf;
5144 /* fill up level & type of cmsghdr structure */
5147 tempHdr->cmsg_level = IPPROTO_IPV6;
5148 tempHdr->cmsg_type = IPV6_HOPOPTS;
5150 else if (hdrId == 1)
5152 tempHdr->cmsg_level = IPPROTO_IPV6;
5153 tempHdr->cmsg_type = IPV6_DSTOPTS;
5156 /* skip cmsghdr struc (length of cmsghdr structure) */
5157 len += (sizeof(tempHdr->cmsg_level) + sizeof(tempHdr->cmsg_len) +
5158 sizeof(tempHdr->cmsg_type));
5160 /* Next Hdr: will be fill up accordingly by Kernel */
5161 *(cmsgBuf + len) = 0x00;
5164 /* Header Ext Length: will be fill up by us. In units of 8-byte excluding
5165 * first 8 bytes starting from Next Header field. */
5166 *(cmsgBuf + len) = 0x00;
5169 /* fillup all HBH/dest options' TLV. Here, we assume that all the HBH/dest
5170 * options are packed inside 1 HBH option header. */
5171 for (optsIdx = 0; optsIdx < hbhOptsArr->numHBHOpts;
5174 /* Copy the TLV into cmsgBuf data portion */
5175 /* copy type field of every HBH/dest option */
5176 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].type;
5177 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].type);
5179 /* copy length field of every HBH/dest option */
5180 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].length;
5181 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].length);
5183 /* copy all value bytes of current HBH/dest option to the flat buffer */
5184 memcpy((cmsgBuf + len),
5185 (hbhOptsArr->hbhOpts[optsIdx].value),
5186 hbhOptsArr->hbhOpts[optsIdx].length);
5187 len += hbhOptsArr->hbhOpts[optsIdx].length;
5190 /* cuMsgIdx will have the total length of HBH options array */
5191 /* add this length to the length of cmsgHdr struc */
5193 /* Padding: Different header has different padding requirement(xn+y). For
5194 * HBH Router Alert we need 2 bytes of padding. As this same function is
5195 * used for Destination option also and there is no option for it is yet
5196 * proposed, we are passing padN options - 6 bytes to make the Dest Option
5197 * hdr a multiple of 8 bytes. */
5199 /* HBH: padN of 2 bytes needed for Router Alert */
5200 /* This logic is present currently to support router alert which is the
5201 * only supported HBH option today. For other, generic method needed */
5204 *(cmsgBuf + len) = 0x01;
5206 *(cmsgBuf + len) = 0x00;
5210 /* fill up the length of cmsghdr structure */
5211 tempHdr->cmsg_len = len;
5215 } /* end of cmInet6BuildSendHBHOpts */
5220 * Fun: cmInet6BuildSendRouteOpts
5222 * Desc: This function transfers bytes from the Route hdr array to the
5223 * flat buffer. First the top cmsghdr structure will be filled in
5224 * the flat buffer, then route hdr type 0 will be added after
5225 * cmsghdr struc in the flat buffer. Then all IPV6 addresses will
5236 static S16 cmInet6BuildSendRouteOpts
5238 CmInetIpv6RtHdr *rtOptsArr, /* IPv6 destination options array */
5239 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5240 uint32_t *curMsgIdx /* idx in cmsgBuf where to start building RT hdr */
5243 struct cmsghdr *tempHdr;
5244 CmInetIpv6RtHdr0 *tempRtHdr;
5252 /* cmsghdr struc will appear before data in the ancillary data object.
5253 * So put cmsghdr struc in flat buffer first */
5255 /* cmsghdr struc points to flat buffer */
5256 tempHdr = (struct cmsghdr *)(cmsgBuf);
5258 tempHdr->cmsg_level = IPPROTO_IPV6;
5259 tempHdr->cmsg_type = IPV6_RTHDR;
5261 /* skip cmsghdr structure */
5262 len += sizeof(struct cmsghdr);
5264 /* we know the total size of Route hdr if we know the num of ipv6 addrs */
5265 tempHdr->cmsg_len = len + sizeof(CmInetIpv6RtHdr0)
5266 + rtOptsArr->numAddrs * sizeof(CmInetIpAddr6);
5268 /* attach route hdr type 0 after cmsghdr structure */
5269 tempRtHdr = (CmInetIpv6RtHdr0 *)(cmsgBuf + len);
5271 /* fill up fields of route hdr type 0 */
5273 /* will be filled up by Kernel */
5274 tempRtHdr->ip6r0_nextHdr = 0x00;
5276 tempRtHdr->ip6r0_hdrExtLen = (2 * rtOptsArr->numAddrs);
5278 /* only type supported today */
5279 tempRtHdr->ip6r0_type = 0x00;
5281 tempRtHdr->ip6r0_segLeft = rtOptsArr->numAddrs;
5283 /* Note: rfc 2292(1998) mentions 1 reserve byte & 3 strict/loose bytes
5284 * restricting total 23 ipv6 addresses can be added to the route header.
5285 * But rfc 2292(2002) mentions all 4 bytes are reserved which allows
5286 * as many ipv6 addresses as wishes to be added to the route header */
5288 tempRtHdr->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5290 /* move pointer in the flat buffer to the end of this structure */
5291 len += sizeof(CmInetIpv6RtHdr0);
5293 /* fill up all IPV6 addresses from rtOptsArr in the flat buffer */
5294 for (addrIdx = 0; addrIdx < rtOptsArr->numAddrs; addrIdx++)
5296 memcpy((cmsgBuf + len),
5297 (rtOptsArr->ipv6Addrs[addrIdx]), 16);
5303 } /* end of cmInet6BuildSendRouteOpts */
5308 * Fun: cmInet6BuildRecvHopOptsArr
5310 * Desc: This function fills up the HopByHop Array of ipHdrParam from
5311 * the ancillary data received through recvmsg() call. The memory
5312 * to hold the extension headers is allocated here. All received
5313 * ext hdr info will be passed to upper user as ipHdrParam.
5315 * Ret: ROK - successful
5324 static S16 cmInet6BuildRecvHopOptsArr
5326 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5327 uint32_t hbhDataLen, /* byte len of cmsghdr + hbh ancil data */
5328 CmInetIpv6HBHHdrArr *hbhOptsArr, /* IPv6 extensions headers */
5329 uint8_t hdrId, /* 0: HBH, 1: DEST */
5330 CmInetMemInfo *info /* Memory information */
5333 uint32_t curDataIdx; /* to keep track where we are in the hbh Data */
5334 uint8_t optsIdx; /* how many hbh opts present in data */
5335 uint8_t numOpts; /* number of hbh opts present in data */
5341 /* get length of actual hbh ancillary data */
5342 hbhDataLen -= sizeof(struct cmsghdr);
5348 /* skip Next Hdr byte & Hdr Ext Length byte */
5351 /* First find out how many hop-by-hop headers we need to allocate */
5354 /* break when all HBH data is copied to hbhOptsArr */
5355 if (curDataIdx >= hbhDataLen)
5361 tempType = *(uint8_t *)(cmsgData + curDataIdx);
5364 /* take care of pad1 option */
5367 /* not considering the pad1 as valid option */
5373 tempLen = *(uint8_t *)(cmsgData + curDataIdx);
5375 /* 1 is to skip length. tempLen to skip the value field */
5376 curDataIdx += (1 + tempLen);
5378 /* considering the padN as valid option for Dest Opt Hdr!!! As this is
5379 * the "only" valid option today. Ignore for HBH hdr */
5385 /* allocate mem needed to hold all HBH/Dest options */
5386 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5387 (Data **)&hbhOptsArr->hbhOpts,
5388 (Size)((sizeof(CmInetIpv6HBHHdr)) * numOpts));
5392 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5393 /* cm_inet_c_001.main_62:Warning fix */
5394 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvHopOptsArr\n");
5395 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET028, 0, prntBuf);
5396 #endif /* CMINETDBG */
5403 /* skip Next Hdr byte & Hdr Ext Length byte */
5406 hbhOptsArr->numHBHOpts = numOpts;
5408 /* fill up HBH/dest opt array from recvd ancillary data */
5411 /* break when all HBH data is copied to hbhOptsArr */
5412 if (curDataIdx >= hbhDataLen)
5415 /* only copy Router Alert HBH option part which has type 5. Otherwise,
5416 * skip it when it is a PAD1, PADN or Jumbogram option for HBH. But
5417 * consider padN as valid option for dest opt hdr. */
5419 /* get the type of current HBH/dest option */
5420 tempType = *(cmsgData + curDataIdx);
5423 /* ignore PAD1 for both HBH/dest by skipping to next option */
5427 /* calculate how much to skip for padN in case of HBH */
5432 /* get the length field of padN option */
5433 tempLen = *(cmsgData + curDataIdx);
5436 /* move pointer forward to skip value field */
5437 curDataIdx += tempLen;
5441 hbhOptsArr->hbhOpts[optsIdx].type = tempType;
5443 /* copy the length */
5444 hbhOptsArr->hbhOpts[optsIdx].length = *(cmsgData + curDataIdx);
5447 /* take care of PADN = 2 when value field empty. We also don't need
5448 * to allocate memory for empty value field */
5449 if (hbhOptsArr->hbhOpts[optsIdx].length == 0)
5450 hbhOptsArr->hbhOpts[optsIdx].value = NULLP;
5453 /* take care of all other options having valid value field
5454 * such as Router Alert, PADN >= 3 bytes and Jumbo */
5455 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5456 (Data **)&hbhOptsArr->hbhOpts[optsIdx].value,
5457 (Size)hbhOptsArr->hbhOpts[optsIdx].length);
5461 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5462 /* cm_inet_c_001.main_62:Warning fix */
5463 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 2 cmInet6BuildRecvHopOptsArr\n");
5464 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET029, 0, prntBuf);
5465 #endif /* CMINETDBG */
5466 /* now go inside every separate HBH option and free the memory
5467 * allocated for its value field */
5468 for (; optsIdx > 0; optsIdx --)
5470 if (hbhOptsArr->hbhOpts[optsIdx - 1].value != NULLP)
5473 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5474 /* cm_inet_c_001.main_62:Warning fix */
5475 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 1 in BuildRecvHopOptsArr\n");
5476 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET030, 0, prntBuf);
5477 #endif /* CMINETDBG */
5478 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5479 (Data *)hbhOptsArr->hbhOpts[optsIdx - 1].value,
5480 (Size)hbhOptsArr->hbhOpts[optsIdx - 1].length);
5483 /* clean up all CmInetIpv6HBHHdr structures allocated for all
5484 * arrived HBH options OR numOpts CmInetIpv6HBHHdr structures
5485 * allocated after counting numOpts */
5487 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5488 /* cm_inet_c_001.main_62:Warning fix */
5489 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 2 in BuildRecvHopOptsArr\n");
5490 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET031, 0, prntBuf);
5491 #endif /* CMINETDBG */
5492 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5493 (Data *)hbhOptsArr->hbhOpts, numOpts * sizeof(CmInetIpv6HBHHdr));
5494 hbhOptsArr->numHBHOpts = 0;
5495 hbhOptsArr->hbhOpts = NULLP;
5498 /* copy the value bytes */
5499 memcpy(hbhOptsArr->hbhOpts[optsIdx].value,
5500 (cmsgData + curDataIdx),
5501 hbhOptsArr->hbhOpts[optsIdx].length);
5502 curDataIdx += hbhOptsArr->hbhOpts[optsIdx].length;
5505 /* get next option */
5509 } /* end of cmInet6BuildRecvHopOptsArr() */
5514 * Fun: cmInet6BuildRecvRtHdr
5516 * Desc: This function fills up the Route Header in the cmInetIpv6HdrParm
5517 * from the recvd ancillary data from recvmsg system call.
5519 * Ret: ROK - successful
5528 static S16 cmInet6BuildRecvRtHdr
5530 uint8_t *cmsgData, /* flat buffer where to build Route hdr */
5531 uint32_t rtDataLen, /* byte len of cmsghdr struc+rtHdr ancil data */
5532 CmInetIpv6RtHdr0 *rtHdr0, /* rtHeader0 struct that precedes IPV6 addrss */
5533 CmInetIpv6RtHdr *rtOptsArr,/* IPv6 extensions headers */
5534 CmInetMemInfo *info /* Memory information */
5537 uint32_t curDataIdx; /* to keep track where we are in hbh Data */
5538 uint8_t i; /* loop counter */
5539 S16 ret; /* temporary return value */
5542 /* byte len of actual rtHdr ancil data */
5543 rtDataLen -= sizeof(struct cmsghdr);
5545 /* start from beginning */
5548 /* copy next header byte */
5549 rtHdr0->ip6r0_nextHdr = *(cmsgData + curDataIdx);
5552 /* copy header extension length byte */
5553 rtHdr0->ip6r0_hdrExtLen = *(cmsgData + curDataIdx);
5556 /* copy type byte (always 0) */
5557 rtHdr0->ip6r0_type = 0x00;
5560 /* copy segment left byte */
5561 rtHdr0->ip6r0_segLeft = *(cmsgData + curDataIdx);
5564 /* copy 1 reserve byte + 3 strict/loose bytes */
5565 memcpy((&rtOptsArr->slMap),
5566 (cmsgData + curDataIdx), 4);
5569 /* also save reserv byte + 3 sl bytes to rtHdro struc */
5570 rtHdr0->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5572 /* subtract 8 bytes for Next Hdr, Hdr Ext Len, .... + SL bit map */
5573 rtOptsArr->numAddrs = (rtDataLen - 8)/16;
5575 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool,
5576 (Data **)&rtOptsArr->ipv6Addrs,
5577 (Size)rtOptsArr->numAddrs * 16);
5581 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5582 /* cm_inet_c_001.main_62:Warning fix */
5583 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvRtHdr\n");
5584 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET032, 0, prntBuf);
5585 #endif /* CMINETDBG */
5589 /* copy all the ipv6 addresses */
5590 for(i=0; i < rtOptsArr->numAddrs; i++)
5592 memcpy((rtOptsArr->ipv6Addrs[i]),
5593 (cmsgData + curDataIdx), 16);
5598 } /* end of cmInet6BuildRecvRtHdr() */
5603 * Fun: cmInet6GetHopLimitValue
5605 * Desc: This function extracts the hop limit value(ttl) of from the
5606 * ancillary data received through recvmsg() call. Then this
5607 * hoplimit value will be passed to upper user as ipHdrParam.
5609 * Ret: ROK - successful
5617 static S16 cmInet6GetHopLimitValue
5619 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5620 uint32_t hopLimitDataLen, /* byte len of cmsghdr + hbh ancil data */
5621 CmInetIpv6HdrParm *ipv6HdrParam /* ipv6 header parameters */
5624 uint16_t curDataIdx; /* to keep track where we are in the ancillary Data */
5625 uint32_t *hopLimitValue; /* ttl/hoplimit value */
5627 hopLimitValue = NULL;
5630 /* get length of actual hbh ancillary data */
5631 hopLimitDataLen -= sizeof(struct cmsghdr);
5633 /* go to the first byte of hop limit which present after cmsghdr struc */
5634 curDataIdx += sizeof(struct cmsghdr);
5636 /* mark that hoplimit(ttl) is present */
5637 ipv6HdrParam->ttl.pres = TRUE;
5639 /* the first byte will be the HopLimit value */
5640 hopLimitValue = (uint32_t *)(cmsgData);
5641 ipv6HdrParam->ttl.val = (uint8_t)(*hopLimitValue);
5645 #endif /* IPV6_OPTS_SUPPORTED */
5650 * Fun: cmInetRecvMsg
5652 * Desc: Reads data from a socket into a message.
5653 * The buffers for the message are allocated within the
5654 * cmInetRead() function from the pool and region Id set in the
5656 * If the number of octets given by the paramter len is not
5657 * available the function immediately returns with RKDNA.
5658 * If the len parameter is set to CM_INET_READ_ANY, the currently
5659 * available data is read.
5660 * Values for flag parameter:
5662 * CM_INET_NO_FLAG - no additional control flag
5663 * CM_INET_MSG_PEEK - do not destroy data on receive buffer
5665 * Ret: ROK - successful
5666 * ROKDNA - ok, data not available
5667 * RCLOSED - connection closed by peer
5668 * ROUTRES - failed, out of resources
5678 CmInetFd *sockFd, /* socket file descriptor */
5679 CmInetAddr *fromAddr, /* sender Internet address/port */
5680 CmInetMemInfo *info, /* buffer allocation info */
5681 Buffer **mPtr, /* received buffer structure */
5682 MsgLen *len, /* number of octets to read */
5683 /* added for IPv6 */
5684 #ifdef IPV6_OPTS_SUPPORTED
5685 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
5686 #endif /* IPV6_OPTS_SUPPORTED */
5688 CmInetLocalInf *localIf, /* local interface on which pkt was recvd */
5689 #endif /* LOCAL_INTF */
5690 S32 flags /* additional control flags */
5693 #if (defined(WIN32) || defined(CMINETFLATBUF))
5694 S32 ret = 0; /* temporary return value */
5695 uint32_t pendLen =0; /* pending data length */
5696 S32 recvLen =0; /* number of received octets by recvmsg() */
5697 MsgLen bufLen =0; /* entire number of received octets */
5698 MsgLen curLen =0; /* current number of octets in buffer */
5699 Data *recvBuf =NULLP; /* receive buffer */
5700 Data *bufPtr =NULLP; /* current buffer position */
5701 Buffer *mBuf = NULLP; /* received message */
5702 uint32_t remAddrLen =0; /* length of remote address */
5703 struct sockaddr_in *remAddr = {0}; /* remote Internet address */
5704 #ifdef IPV6_SUPPORTED
5705 struct sockaddr_in6 *remAddr6 = {0}; /* remote Internet address */
5706 struct sockaddr_in6 remSockAddr ={0}; /* to get packet's source IP address */
5708 CmInetSockAddr remSockAddr ={0}; /* to get packet's source IP address */
5709 #endif /* IPV6_SUPPORTED */
5711 S32 ret =0; /* temporary return value */
5712 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
5713 uint16_t i =0; /* index */
5714 uint32_t pendLen =0; /* pending data length */
5715 S32 numBuf =0; /* number of allocated dBufs */
5716 S32 recvLen =0; /* number of received octets by recvmsg() */
5717 MsgLen bufLen =0; /* entire number of received octets */
5718 struct msghdr msg = {0}; /* message header */
5719 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5720 Buffer *tempMsg = NULLP; /* temporary message */
5721 CmInetIovec rxArr[CM_INET_MAX_DBUF]= {{0}}; /* dynamic gather array */
5722 Buffer **dBufs = NULLP; /* dynamic array with allocated dBufs */
5723 S16 numDBufs =0; /* number of allocated dBufs */
5725 /* cm_inet_c_001.main_55: As remAddrLen is only being used when
5726 * WIN32 or CMINETFLATBUF is defined, then Removed variable
5728 struct sockaddr_in *remAddr = {0}; /* remote Internet address */
5729 #ifdef IPV6_SUPPORTED
5730 struct sockaddr_in6 *remAddr6 ={0}; /* remote Internet address */
5731 struct sockaddr_in6 remSockAddr ={0};/* to get packet's source IP address */
5732 /* added for IPv6 ext headers support */
5733 #ifdef IPV6_OPTS_SUPPORTED
5734 CmInetIpv6RtHdr0 rtHdr0 ={0}; /* type 0 route header */
5735 #endif /* IPV6_OPTS_SUPPORTED */
5738 struct in6_pktinfo *pkt6Info = {0}; /* IPv6 IP_PKTINFO */
5739 #endif /* LOCAL_INTF */
5741 #if (defined(SS_LINUX) || defined(_XPG4_2))
5742 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
5743 /* from stack for IPv6 ancill data */
5746 CmInetSockAddr remSockAddr ={0}; /* to get packet's src IP address */
5747 #if (defined(SS_LINUX) || defined(_XPG4_2))
5748 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
5749 /* from stack for IPv4 ancill data */
5751 #endif /* IPV6_SUPPORTED */
5752 /* added new definitions */
5753 Bool allocFlatBuf; /* allocate a flat buffer */
5754 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5755 Data *recvBuf = NULLP; /* receive buffer */
5758 struct in_pktinfo *pkt4Info; /* IPv4 IP_PKTINFO */
5760 #endif /* SS_LINUX */
5761 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
5762 struct cmsghdr *cmsgptr;/* pointer to struct cmsghdr */
5764 #endif /* WIN32 | CMINETFLATBUF */
5765 /* used by getsockopt */
5767 /* cm_inet_c_001.main_55:Removed unused variables errValue and optLen */
5770 #if (ERRCLASS & ERRCLS_INT_PAR)
5771 /* error check on parameters */
5772 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
5773 (info == NULLP) || (mPtr == NULLP) || (len == NULLP))
5777 #endif /* ERRCLASS & ERRCLS_INT_PAR */
5781 /*cm_inet_c_001.main_48 variables declaration */
5782 #if !((defined(WIN32) || defined(CMINETFLATBUF)))
5787 #if (defined(WIN32) || defined(CMINETFLATBUF))
5789 #ifdef IPV6_SUPPORTED
5791 #endif /* IPV6_SUPPORTED */
5793 #ifdef IPV6_SUPPORTED
5796 #endif /* IPV6_SUPPORTED */
5798 #if (defined(SS_LINUX) || defined(_XPG4_2))
5799 memset(ancillData, 0, sizeof(ancillData));
5800 #endif /* SS_LINUX || _XPG4_2 */
5802 #endif /* (WIN32 | CMINETFLATBUF) */
5804 /* clear the structure */
5805 memset(&remSockAddr, 0, sizeof(remSockAddr));
5807 /* get number of pending data */
5808 /* removed 3rd arg memInfo. MemInfo is no longer
5809 needed as we call ioctl for all sockets */
5811 /* cm_inet_c_001.main_48 : call ioctl only for STREAM
5812 * sockets now. For Non-Stream sockets(Raw & UDP), fix
5813 * pending length to CM_INET_MAX_UDPRAW_MSGSIZE
5815 if(sockFd->type == CM_INET_STREAM)
5817 ret = cmInetGetNumRead(sockFd, &pendLen);
5820 /* ret may be RFAILED or ROUTRES */
5826 /* cm_inet_c_001.main_48 : pendLen is set 1 greater
5827 * than the #defined value. If recvFrom/recvMsg
5828 * returns the len == pendLen, we would drop the
5829 * message as the msg len is larger than the largest
5830 * msg we are willing to accept.
5832 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE+1;
5836 /* check if connection got closed */
5839 if (sockFd->type == CM_INET_STREAM)
5841 /* cm_inet_c_001.main_50:
5842 * cm_inet_c_001.main_56: Removed comment for cm_inet_c_001.main_50 as
5843 * the current patch changes its functionality */
5844 uint8_t readBuf[1]; /* declaration of variable for Peek */
5847 * cm_inet_c_001.main_56:
5848 * We are peeking the socket buffer again with peek as on some machines
5849 * like solaris, there is a latency observed in ioctl. In such cases,
5850 * ioctl may return 0, even though there are bytes available to read.
5851 * We reconfirm through peek whether 0 means EOF or its ioctl latency
5854 ret = cmInetPeekNew(sockFd, NULLP, info, 0, 1, readBuf);
5859 /* cm_inet_c_001.main_56:
5860 * Returning ROKDNA even cmInetPeekNew returns ROK. Because currently
5861 * we are not sure about pending length. Anyway socket FD already set,
5862 * we do another iteration to get exact pendLen value. We cannot call
5863 * cmInetGetNumRead at this point because of latency between the ioctl
5864 * call and recvfrom call issues on some machines ioctl call may
5865 * return ZERO even their a data to read. */
5869 /* cm_inet_c_001.main_52: Support for partial reception */
5870 /* cm_inet_c_001.main_59: Fix for compilation warning */
5871 if ((sockFd->type == CM_INET_STREAM) && (*len > (MsgLen)pendLen))
5873 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5874 *len = (MsgLen)pendLen;
5877 /* check if there are enough pending data to read */
5878 if ((*len == CM_INET_READ_ANY) || ((uint32_t)*len <= pendLen))
5880 if (*len == CM_INET_READ_ANY)
5882 /* added check for TCP socket. Pending data length in
5883 the socket recv buffer is determined by ioctl call in
5885 For TCP it can't be > CM_INET_MAX_MSG_LEN. */
5886 if (sockFd->type == CM_INET_STREAM)
5888 /* max message length is limited to control the memory usage */
5889 if (pendLen > CM_INET_MAX_MSG_LEN)
5890 pendLen = CM_INET_MAX_MSG_LEN;
5892 /* cm_inet_c_001.main_48 : removed the check for
5893 * Non Stream sockets (pendLen < MAX_UDPRAW_MSGSIZE)
5894 * as we are hardcoding pendLen for Non-Stream sockets.
5897 /* read all pending data */
5898 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5899 bufLen = (MsgLen)pendLen;
5900 *len = (MsgLen)pendLen;
5904 /* cm_inet_c_001.main_45- Returning CM_INET_MAX_MSG_LEN when input is larger than
5907 /* max message length is limited to control the memory usage */
5908 if ((*len) > CM_INET_MAX_MSG_LEN)
5910 (*len) = CM_INET_MAX_MSG_LEN;
5913 /* read data length given by user */
5917 #if (defined(WIN32) || defined(CMINETFLATBUF))
5919 /* set destination Internet address structure */
5920 if (fromAddr != NULLP)
5922 remAddrLen = sizeof(remSockAddr);
5929 /* allocate flat receive buffer */
5930 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &recvBuf, bufLen);
5939 * maybe needs more than one recvfrom() call to read an entire
5940 * message from a stream socket (TCP)
5944 /* added separate recvfrom calls different OS */
5946 /*cm_inet_c_001.main_42 1. In Vx-Works the 5th and 6th parameter of recvfrom
5947 system call are either NULL or should be valid pointer.*/
5948 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
5950 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5951 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
5953 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5954 NULLP, (int *)&remAddrLen);
5956 #if ( defined(SUNOS) || defined(SS_LINUX))
5958 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5959 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
5961 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5962 NULLP, (socklen_t *)&remAddrLen);
5965 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5966 &remSockAddr, (S32 *)&remAddrLen);
5968 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5969 NULLP, (S32 *)&remAddrLen);
5971 #endif /* defined(SUNOS) || defined(SS_LINUX) */
5972 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
5974 if (recvLen == INET_ERR)
5977 /* moved cleanup here */
5978 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
5980 /* added check ERR_WOULDBLOCK */
5981 if ((INET_ERR_CODE == ERR_AGAIN) ||
5982 (INET_ERR_CODE == ERR_WOULDBLOCK))
5989 /* In Windows the recvfrom function fails
5990 * with error code which maps to either WSAECONNABORTED. If
5991 * this happens then cmInetRecvMsg must return RCLOSED */
5992 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
5993 (INET_ERR_CODE == ERR_CONNRESET))
6001 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6002 /* cm_inet_c_001.main_62:Warning fix */
6003 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6004 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6005 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6007 /* cm_inet_c_001.main_62:Warning fix */
6008 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6009 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6010 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6011 #endif /*ALIGN_64BIT*/
6012 #endif /* CMINETDBG */
6020 * a message is always read atomically on a datagram socket,
6021 * therefore it's ok to read less than pending data!
6024 if ((sockFd->type == CM_INET_RAW) ||
6025 (sockFd->type == CM_INET_DGRAM))
6030 #else /* CM_INET2 */
6031 if (sockFd->type == CM_INET_DGRAM)
6036 #endif /* CM_INET2 */
6037 } /* while (curLen > 0) (only for stream sockets) */
6039 /* For UDP, it is possible to receive
6040 * a 0 byte datagram, in this case just return ROKDNA.
6043 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6046 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6049 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6053 /* cm_inet_c_001.main_48 : If Received
6054 * len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6058 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6059 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6061 if ((sockFd->type == CM_INET_DGRAM)
6062 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6067 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6068 /* cm_inet_c_001.main_62:Warning fix */
6069 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6070 " > than allowed(%lu), sockFd->fd(%ld) \n",
6071 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6072 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6074 /* cm_inet_c_001.main_62:Warning fix */
6075 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6076 " > than allowed(%lu), sockFd->fd(%d) \n",
6077 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6078 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6079 #endif /*ALIGN_64BIT*/
6081 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6085 /* cm_inet_c_001.main_48 : copy data to a message structure */
6086 ret = SGetMsg(info->region, info->pool, &mBuf);
6090 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6095 if ((sockFd->type == CM_INET_DGRAM) ||
6096 (sockFd->type == CM_INET_RAW))
6098 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6102 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6105 #else /* CM_INET2 */
6106 if (sockFd->type == CM_INET_DGRAM)
6108 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6112 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6114 #endif /* CM_INET2 */
6118 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6124 /* setup return destination Internet address */
6125 /* added the check of (remAddrLen > 0) */
6126 if ((fromAddr != NULLP) && (remAddrLen > 0))
6128 #ifdef IPV6_SUPPORTED
6129 if (remAddrLen == sizeof(struct sockaddr_in6))
6131 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6132 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6133 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6134 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6135 &remAddr6->sin6_addr);
6139 remAddr = (struct sockaddr_in *)&remSockAddr;
6140 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6141 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6142 fromAddr->u.ipv4Addr.address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6145 remAddr = (struct sockaddr_in *)&remSockAddr;
6146 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6147 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6148 #endif /* IPV6_SUPPORTED */
6152 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6154 #else /* end of Win NT/flat buffer specific part */
6156 /* Initialise variable */
6157 allocFlatBuf = FALSE;
6160 * maybe needs more than one recvmsg() call to read entire message
6161 * on a stream socket
6165 /* allocate gather vector, it's a dynamic array */
6166 numDBufs = CM_INET_MAX_DBUF;
6168 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data**)&dBufs,
6169 numDBufs*sizeof(Buffer*));
6175 /* Allocate dBufs for gather read */
6176 /* allocate dBufs for gathering read */
6177 if (sockFd->type == CM_INET_STREAM)
6178 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6181 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6185 /* check if the function returned RNA */
6188 /* Incase of UDP/RAW messages allocate a flat buffer. Incase
6189 * of TCP ignore this error condition. The user will call
6190 * cmInetRecvMsg again */
6191 /* cm_inet_c_001.main_62:Warning fix */
6192 if (sockFd->type != (uint8_t)CM_INET_STREAM)/* G++ */
6195 #ifdef T2K_MEM_LEAK_DBG
6196 char * file = __FILE__;
6197 uint32_t line = __LINE__;
6200 /* cleanup the dBuf array */
6201 for (i = 0; i < msg.msg_iovlen; i++)
6202 SPutDBuf(info->region, info->pool, dBufs[i]);
6204 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6205 numDBufs * sizeof(Buffer*));
6207 /* allocate flat receive buffer */
6208 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &recvBuf, bufLen);
6212 allocFlatBuf = TRUE;
6214 /* update the message structure */
6216 rxArr[0].iov_base = (Void*)recvBuf;
6217 rxArr[0].iov_len = (uint32_t)bufLen;
6219 rxArr[0].iov_base = (S8*)recvBuf;
6220 rxArr[0].iov_len = bufLen;
6221 #endif /* SS_LINUX */
6222 msg.msg_iov = rxArr;
6228 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6229 numDBufs*sizeof(Buffer*));
6234 numBuf = msg.msg_iovlen;
6236 /* setup destination Internet address structure */
6237 if (fromAddr != NULLP)
6240 msg.msg_name = (Void*)&remSockAddr;
6243 msg.msg_name = (char *)&remSockAddr;
6245 msg.msg_name = (caddr_t)&remSockAddr;
6247 #endif /* SS_LINUX */
6248 msg.msg_namelen = sizeof(remSockAddr);
6252 msg.msg_name = NULLP;
6253 msg.msg_namelen = 0;
6256 /* added defined(_XPG4_2). Also changed the
6258 #if (defined(SS_LINUX) || defined(_XPG4_2))
6259 msg.msg_control = ancillData;
6260 msg.msg_controllen = sizeof(ancillData);
6262 msg.msg_accrights = NULLP;
6263 msg.msg_accrightslen = 0;
6264 #endif /* SS_LINUX */
6266 recvLen = recvmsg(sockFd->fd, &msg, flags);
6267 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
6269 /* Moved up the cleanup precedures here before returning */
6270 /* Cleanup flat buffer if allocated */
6272 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6276 for (i = 0; i < numBuf; i++)
6278 #ifdef T2K_MEM_LEAK_DBG
6279 char * file = __FILE__;
6280 uint32_t line = __LINE__;
6283 SPutDBuf(info->region, info->pool, dBufs[i]);
6285 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6286 numDBufs*sizeof(Buffer*));
6289 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6290 * it has partially received data
6292 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
6293 added check ERR_WOULDBLOCK */
6294 if ((INET_ERR_CODE == ERR_AGAIN) ||
6295 (INET_ERR_CODE == ERR_WOULDBLOCK))
6297 /* cm_inet_c_001.main_50 : If message is read partially then just return
6298 * OK without freeing the mPtr. This will gaurd us
6299 * against unexpected WOULDBLOCKS observed in solaris
6307 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6308 * it has partially received data
6316 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6317 /* cm_inet_c_001.main_62:Warning fix */
6318 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6319 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6320 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6322 /* cm_inet_c_001.main_62:Warning fix */
6323 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6324 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6325 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6326 #endif /*ALIGN_64BIT*/
6327 #endif /* CMINETDBG */
6329 /* If this happens then cmInetRecvMsg must return RCLOSED.
6330 * Needed for getting icmp msgs */
6331 if (INET_ERR_CODE == ERR_CONNABORTED)
6341 /* added for IPv6 extn headers */
6342 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6344 /* check if ancillary data has been received.
6345 * Return the allocated memory when no ancillary data received */
6346 #if (defined(SS_LINUX) || defined(_XPG4_2))
6347 if (msg.msg_controllen)
6349 cmsgptr = CMSG_FIRSTHDR(&msg);
6355 #endif /* SS_LINUX || _XPG4_2 */
6357 if (cmsgptr != NULLP)
6359 #ifdef IPV6_OPTS_SUPPORTED
6360 if(ipHdrParams != NULLP)
6362 ipHdrParams->u.ipv6HdrParm.ttl.pres = FALSE;
6363 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt = FALSE;
6364 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt = FALSE;
6365 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt = FALSE;
6367 /* get all ancillary data objects recvd one by one */
6368 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6369 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6371 if (cmsgptr->cmsg_level == IPPROTO_IPV6)
6373 /* Initialise ipHdrParams properly */
6374 ipHdrParams->type = CM_INET_IPV6ADDR_TYPE;
6376 if (cmsgptr->cmsg_type == IPV6_HOPOPTS)
6378 /* build up HBH opt array from recvd ancillary data */
6379 ret = cmInet6BuildRecvHopOptsArr(
6380 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6381 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
6385 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt =
6389 else if(cmsgptr->cmsg_type == IPV6_DSTOPTS)
6391 else if ((cmsgptr->cmsg_type == IPV6_DSTOPTS) ||
6392 (cmsgptr->cmsg_type == IPV6_RTHDRDSTOPTS))
6393 #endif /* SS_LINUX */
6395 /* build up Dest opt array from recvd ancillary data */
6396 ret = cmInet6BuildRecvDstOptsArr(
6397 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6398 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr,
6402 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt =
6405 else if (cmsgptr->cmsg_type == IPV6_RTHDR)
6407 /* build up Route Hdr from recvd ancillary data */
6408 ret = cmInet6BuildRecvRtHdr(
6409 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, &rtHdr0,
6410 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
6414 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt =
6417 else if(cmsgptr->cmsg_type == IPV6_HOPLIMIT)
6419 /* get the received hoplimit */
6420 ret = cmInet6GetHopLimitValue((uint8_t *)CMSG_DATA(cmsgptr),
6421 cmsgptr->cmsg_len, &ipHdrParams->u.ipv6HdrParm);
6428 #endif /* IPV6_OPTS_SUPPORTED */
6430 #ifdef IPV6_SUPPORTED
6432 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6433 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6435 if(cmsgptr->cmsg_type == IPV6_PKTINFO)
6437 pkt6Info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
6438 localIf->intfPrsnt = TRUE;
6439 localIf->localIf = pkt6Info->ipi6_ifindex;
6440 localIf->localIfAddr.type = CM_INET_IPV6ADDR_TYPE;
6441 memcpy(&localIf->localIfAddr.u.ipv6NetAddr,
6442 &pkt6Info->ipi6_addr, 16);
6445 #endif /* LOCAL_INTF */
6448 #if (defined(SS_LINUX) && defined(LOCAL_INTF))
6449 #ifdef IPV6_SUPPORTED
6450 if(sockFd->protType == AF_INET)
6453 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
6454 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6456 if (cmsgptr->cmsg_level == IPPROTO_IP &&
6457 cmsgptr->cmsg_type == IP_PKTINFO)
6459 pkt4Info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
6460 localIf->intfPrsnt = TRUE;
6461 localIf->localIf = pkt4Info->ipi_ifindex;
6462 localIf->localIfAddr.type = CM_INET_IPV4ADDR_TYPE;
6463 localIf->localIfAddr.u.ipv4NetAddr =
6464 ntohl(*(int *)&pkt4Info->ipi_addr);
6467 #ifdef IPV6_SUPPORTED
6470 #endif /* SS_LINUX */
6472 #endif /* IPV6_OPTS_SUPPORTED || LOCAL_INTF */
6474 /* setup return destination Internet address */
6475 if (fromAddr != NULLP)
6477 #ifdef IPV6_SUPPORTED
6478 if (msg.msg_namelen == sizeof(struct sockaddr_in6))
6480 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6481 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6482 fromAddr->u.ipv6Addr.port =
6483 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6484 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6485 &remAddr6->sin6_addr);
6489 remAddr = (struct sockaddr_in *)&remSockAddr;
6490 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6491 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6492 fromAddr->u.ipv4Addr.address =
6493 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6496 remAddr = (struct sockaddr_in *)&remSockAddr;
6497 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6498 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6499 #endif /* IPV6_SUPPORTED */
6502 /* Incase a flat buffer was allocated get
6503 * a message to pass up */
6509 ret = SGetMsg(info->region, info->pool, &tempMsg);
6513 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6517 /* cm_inet_c_001.main_48 : A 0 len UDP packet could be received */
6520 ret = SAddPstMsgMult(recvBuf, recvLen, tempMsg);
6523 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6531 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
6532 /* cm_inet_c_001.main_48 :flat buffers are allocated
6533 * for non -TCP sockets. On these sockets we can receive
6534 * only one message at a time
6536 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6537 *len = (MsgLen)recvLen;
6542 /* build message out of dBufs */
6543 ret = buildRecvMsg(info, rxArr, numBuf, recvLen, dBufs, &tempMsg);
6546 /* Deallocate previously allocated
6550 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6551 numDBufs*sizeof(Buffer*));
6558 /* it's first recvmsg() call */
6563 /* concatenate messages */
6564 ret = SCatMsg(*mPtr, tempMsg, M1M2);
6570 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6571 numDBufs*sizeof(Buffer*));
6577 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, (Data*)dBufs,
6578 numDBufs*sizeof(Buffer*));
6581 * a message is always read atomically on a datagram socket,
6582 * therefore it's ok to read less than pending data!
6585 if ((sockFd->type == CM_INET_DGRAM) ||
6586 (sockFd->type == CM_INET_RAW))
6588 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6589 *len = (MsgLen)recvLen;
6592 #else /* CM_INET2 */
6593 if (sockFd->type == CM_INET_DGRAM)
6595 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6596 *len = (MsgLen)recvLen;
6599 #endif /* CM_INET2 */
6600 } /* while(bufLen > 0) (only for stream sockets) */
6602 /* cm_inet_c_001.main_48 : For UDP, it is possible to receive
6603 * a 0 byte datagram, in this case just return ROKDNA
6607 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6610 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6622 /* Received len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6627 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6628 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6630 if ((sockFd->type == CM_INET_DGRAM)
6631 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6642 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6643 /* cm_inet_c_001.main_62:Warning fix */
6644 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6645 " allowed(%d),sockFd->fd(%ld)\n",
6646 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6647 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6649 /* cm_inet_c_001.main_62:Warning fix */
6650 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6651 " allowed(%d),sockFd->fd(%d)\n",
6652 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6653 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6660 #endif /* WIN32 | CMINETFLATBUF */
6664 /* not enough data pending yet */
6669 } /* end of cmInetRecvMsg */
6672 /* cm_inet_c_001.main_56: Added new function cmInetPeekNew() */
6676 * Fun: cmInetPeekNew
6678 * Desc: Reads some data from the socket without destroying the socket
6680 * The data is specified by the byte positon (first byte is at
6681 * position 0) and the length.
6683 * Ret: ROK - successful
6684 * ROKDNA - ok, data not available
6685 * RCLOSED - connection closed by peer
6688 * Notes: Following are the differences from the cmInetPeek to cmInetPeekNew.
6689 * This primitive does not call the select function as this is already
6690 * taken care by the called primitive. This primitive will not use any
6691 * ioctl calls, because on some machines due to latency in ioctl call
6692 * length may return as ZERO, even there is some data to be read from
6693 * the socket and this primitive only peek buffer using recvfrom.
6695 * Caller of this function need to allocate the sufficient memory to hold
6696 * the data peeked from the socket i.e. dataPos + dataLen. Socket data
6697 * will be copied in the "data" starting from dataPos offset.
6699 * For example, caller passed the following values to this function.
6700 * dataPos = 2 and dataLen = 10,then size of data buffer received should
6701 * be minimum of (dataPos + dataLen)12 bytes and socket data will be
6702 * copied in the data buffer from offset 2 (dataPos) onwards.
6710 CmInetFd *sockFd, /* socket file descriptor */
6711 CmInetAddr *fromAddr, /* sender Internet address/port */
6712 CmInetMemInfo *info, /* buffer allocation info */
6713 MsgLen dataPos, /* position of data */
6714 MsgLen dataLen, /* length of read data */
6715 Data *data /* read data */
6718 /* cm_inet_c_001.main_57 - Fix for validation and compilation warning */
6719 S32 recvLen; /* number of received octets */
6720 S32 remAddrLen; /* length of remote address length */
6721 struct sockaddr_in *remAddr; /* remote Internet address */
6722 #ifdef IPV6_SUPPORTED
6723 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6724 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6726 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6727 #endif /* IPV6_SUPPORTED */
6730 #if (ERRCLASS & ERRCLS_INT_PAR)
6731 /* error check on parameters */
6732 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6733 (info == NULLP) || (data == NULLP) ||
6734 (dataPos < 0) || (dataLen < 0))
6738 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6740 /* check if fromAddr is present or not */
6741 if (fromAddr != NULLP)
6743 remAddrLen = sizeof(remSockAddr);
6750 /* added different recvfrom calls with different 6th arg for
6751 * different OS If remAddrLen is 0, pass NULLP */
6752 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
6754 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6755 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
6757 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6758 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
6760 #if ( defined(SUNOS) || defined(SS_LINUX))
6762 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6763 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
6764 (socklen_t *)&remAddrLen);
6766 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6767 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
6770 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6771 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
6773 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6774 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
6775 #endif /* defined(SUNOS) || defined(SS_LINUX) */
6776 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
6778 /* removed the check of returned remAddrLen */
6779 if (recvLen == INET_ERR)
6781 /* added check ERR_WOULDBLOCK */
6782 if ((INET_ERR_CODE == ERR_AGAIN) ||
6783 (INET_ERR_CODE == ERR_WOULDBLOCK))
6788 /* cm_inet_c_001.main_61: added host unreachable check */
6789 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
6790 (INET_ERR_CODE == ERR_CONNRESET) ||
6791 (INET_ERR_CODE == ERR_HOSTUNREACH) ||
6792 (INET_ERR_CODE == ERR_CONNREFUSED))
6799 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6800 /* cm_inet_c_001.main_62:Warning fix */
6801 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%ld)\n",
6802 INET_ERR_CODE, sockFd->fd);
6803 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6805 /* cm_inet_c_001.main_62:Warning fix */
6806 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%d)\n",
6807 INET_ERR_CODE, sockFd->fd);
6808 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6810 #endif /* CMINETDBG */
6814 else if (recvLen == 0)
6819 /* cm_inet_c_001.main_57 - Fix for validation */
6820 if (recvLen < (S32)dataLen) /* maybe happen */
6825 /* setup return destination Internet address */
6826 /* added the check of (remAddLen > 0) */
6827 if ((fromAddr != NULLP) && (remAddrLen > 0))
6829 #ifdef IPV6_SUPPORTED
6830 memset(fromAddr, 0, sizeof(fromAddr));
6831 if (remAddrLen == sizeof(struct sockaddr_in6))
6833 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6834 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6835 fromAddr->u.ipv6Addr.port =
6836 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6837 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6838 &remAddr6->sin6_addr);
6842 remAddr = (struct sockaddr_in *)&remSockAddr;
6843 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6844 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6845 fromAddr->u.ipv4Addr.address =
6846 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6849 remAddr = (struct sockaddr_in *)&remSockAddr;
6850 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6851 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6852 #endif /* IPV6_SUPPORTED */
6856 } /* end of cmInetPeeknew */
6863 * Desc: Reads some data from the socket without destroying the socket
6865 * The data is specified by the byte positon (first byte is at
6866 * position 0) and the length.
6868 * Ret: ROK - successful
6869 * ROKDNA - ok, data not available
6870 * RCLOSED - connection closed by peer
6881 CmInetFd *sockFd, /* socket file descriptor */
6882 CmInetAddr *fromAddr, /* sender Internet address/port */
6883 CmInetMemInfo *info, /* buffer allocation info */
6884 MsgLen dataPos, /* position of data */
6885 MsgLen dataLen, /* length of read data */
6886 Data *data /* read data */
6889 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6890 Data *recvBuf = NULLP; /* plain receive buffer */
6891 /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
6892 MsgLen bufLen; /* buffer length */
6893 MsgLen i; /* index */
6894 MsgLen j; /* index */
6895 S32 ret; /* temporary return value */
6896 uint32_t timeout; /* timeout for cmInetSelect() */
6897 uint32_t *timeoutPtr; /* pointer to timeout */
6898 S16 numFdS; /* number of ready descriptors */
6899 /* cm_inet_c_001.main_45 - fixing the UMR issue in 64bit linux */
6900 uint32_t pendLen = 0; /* pending data length */
6901 S32 recvLen; /* number of received octets */
6902 S32 remAddrLen; /* length of remote address length */
6903 CmInetFdSet readFdS; /* socket file descriptor set */
6904 struct sockaddr_in *remAddr; /* remote Internet address */
6905 #ifdef IPV6_SUPPORTED
6906 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6907 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6909 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6910 #endif /* IPV6_SUPPORTED */
6913 #if (ERRCLASS & ERRCLS_INT_PAR)
6914 /* error check on parameters */
6915 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6916 (info == NULLP) || (data == NULLP) ||
6917 (dataPos < 0) || (dataLen < 0))
6921 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6923 /* check if there are some datas */
6924 if (sockFd->blocking)
6931 /* poll (non-blocking) */
6933 timeoutPtr = &timeout;
6935 CM_INET_FD_ZERO(&readFdS);
6936 CM_INET_FD_SET(sockFd, &readFdS);
6938 ret = cmInetSelect(&readFdS, NULLP, timeoutPtr, &numFdS);
6939 if (CM_INET_FD_ISSET(sockFd, &readFdS))
6941 /* get number of pending data */
6942 /* removed 3rd arg memInfo. MemInfo is no longer needed as we
6943 call ioctl for all sockets */
6944 ret = cmInetGetNumRead(sockFd, &pendLen);
6947 /* cm_inet_c_001.main_50
6948 * Return RCLOSED if cmInetGetNumRead returns RCLOSED. For other
6949 * errors just return RFAILED.
6957 /* check if connection got closed */
6961 /* cm_inet_c_001.main_50
6962 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
6963 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
6964 * socket that select says is ready to read. This should not be
6965 * considered as connection closed. So return ROKDNA instead of
6966 * RCLOSED even for TCP sockets
6970 /* added check for TCP/UDP socket. Pending data len in the socket
6971 recv buffer is determined by ioctl call in cmInetGetNumRead.
6972 For TCP it can't be > CM_INET_MAX_MSG_LEN.
6973 For UDP it can't be > CM_INET_MAX_UDPRAW_MSGSIZE. */
6974 if (sockFd->type == CM_INET_STREAM)
6976 /* max message length is limited to control the memory usage */
6977 if (pendLen > CM_INET_MAX_MSG_LEN)
6978 pendLen = CM_INET_MAX_MSG_LEN;
6979 /* In STREAM remote address is not required */
6984 if (pendLen > CM_INET_MAX_UDPRAW_MSGSIZE)
6985 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE;
6987 remAddrLen = sizeof(CmInetSockAddr);
6990 /* check if there are enough pending data to read */
6991 bufLen = dataPos + dataLen;
6993 /* check if fromAddr is present or not */
6994 if (fromAddr != NULLP)
6996 remAddrLen = sizeof(remSockAddr);
7003 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
7004 if ((MsgLen)pendLen >= bufLen)
7006 /* allocate receive buffer (flat structure) */
7007 ret = SGetSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, &recvBuf, bufLen);
7013 /* added different recvfrom calls with
7014 * different 6th arg for different OS */
7016 /* If remAddrLen is 0, pass NULLP */
7017 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7019 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7020 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7022 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7023 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7025 #if ( defined(SUNOS) || defined(SS_LINUX))
7027 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7028 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7029 (socklen_t *)&remAddrLen);
7031 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7032 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7035 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7036 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7038 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7039 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7040 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7041 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7043 /* removed the check of returned remAddrLen */
7044 if (recvLen == INET_ERR)
7047 /* moved cleanup here */
7048 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
7050 /* added check ERR_WOULDBLOCK */
7051 if ((INET_ERR_CODE == ERR_AGAIN) ||
7052 (INET_ERR_CODE == ERR_WOULDBLOCK))
7058 /* moved up the cleanup */
7062 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7063 /* cm_inet_c_001.main_62:Warning fix */
7064 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%ld)\n",
7065 INET_ERR_CODE, sockFd->fd);
7066 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7068 /* cm_inet_c_001.main_62:Warning fix */
7069 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%d)\n",
7070 INET_ERR_CODE, sockFd->fd);
7071 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7073 #endif /* CMINETDBG */
7075 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7076 (INET_ERR_CODE == ERR_CONNRESET))
7084 if (recvLen < (S32)bufLen) /* maybe happen */
7087 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
7092 for (j = 0, i = dataPos; i < bufLen; j++, i++)
7093 data[j] = recvBuf[i];
7095 /* setup return destination Internet address */
7096 /* added the check of (remAddLen > 0) */
7097 if ((fromAddr != NULLP) && (remAddrLen > 0))
7099 #ifdef IPV6_SUPPORTED
7100 memset(fromAddr, 0, sizeof(fromAddr));
7101 if (remAddrLen == sizeof(struct sockaddr_in6))
7103 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7104 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7105 fromAddr->u.ipv6Addr.port =
7106 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
7107 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
7108 &remAddr6->sin6_addr);
7112 remAddr = (struct sockaddr_in *)&remSockAddr;
7113 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7114 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7115 fromAddr->u.ipv4Addr.address =
7116 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7119 remAddr = (struct sockaddr_in *)&remSockAddr;
7120 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7121 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7122 #endif /* IPV6_SUPPORTED */
7126 SPutSBufNewForDebug(__FILE__,__FUNCTION__,__LINE__,info->region, info->pool, recvBuf, bufLen);
7130 /* not enough data pending yet */
7136 /* no data pending */
7141 } /* end of cmInetPeek */
7148 * Desc: Close a socket gracefully.
7150 * Ret: ROK - successful
7161 CmInetFd *sockFd /* socket file descriptor */
7164 S32 ret; /* temporary return value */
7167 #if (ERRCLASS & ERRCLS_INT_PAR)
7168 /* error check on parameters */
7169 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7173 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7176 ret = closesocket(sockFd->fd);
7178 ret = close(sockFd->fd);
7180 if (ret == INET_ERR)
7184 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7185 /* cm_inet_c_001.main_62:Warning fix */
7186 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%ld)\n",
7187 INET_ERR_CODE, sockFd->fd);
7188 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7190 /* cm_inet_c_001.main_62:Warning fix */
7191 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%d)\n",
7192 INET_ERR_CODE, sockFd->fd);
7193 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7194 #endif /*ALIGN_64BIT*/
7195 #endif /* CMINETDBG */
7200 } /* end of cmInetClose */
7205 * Fun: cmInetShutdown
7207 * Desc: Close an Internet connection with more control over the data of
7208 * the full-duplex connection.
7209 * Values for the howTo parameter:
7211 * CM_INET_SHTDWN_RECV - discard data in receive buffer
7212 * CM_INET_SHTDWN_SEND - discard data in transmit buffer
7213 * CM_INET_SHTDWN_BOTH - discard data in receive and transmit buffer
7215 * Ret: ROK - successful
7218 * Notes: This function does not free the socket descriptor but only closes the
7219 * connection (cmInetClose() has to be called afterwards).
7220 * No error is returned if the socket is not connected while calling
7229 CmInetFd *sockFd, /* socket file descriptor */
7230 S32 howTo /* operation flag */
7233 S32 ret; /* temporary return value */
7236 #if (ERRCLASS & ERRCLS_INT_PAR)
7237 /* error check on parameters */
7238 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7242 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7244 ret = shutdown(sockFd->fd, howTo);
7245 if (ret == INET_ERR)
7247 if (INET_ERR_CODE == ERR_NOTCONN)
7249 /* socket is not connected */
7257 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7258 /* cm_inet_c_001.main_62:Warning fix */
7259 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7260 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
7261 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7263 /* cm_inet_c_001.main_62:Warning fix */
7264 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7265 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
7266 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7267 #endif /*ALIGN_64BIT*/
7268 #endif /* CMINETDBG */
7274 } /* end of cmInetShutdown */
7281 * Desc: Allows multiplex i/o requests among multiple sockets.
7282 * If the parameter mSecTimeout points to a value of zero the
7283 * call immediatley returns (poll), if it is a null pointer, the
7284 * timeout is set to infinit.
7285 * numFdS returns the number of ready file descriptors contained
7286 * in the file descriptor sets
7288 * Ret: ROK - successful
7289 * RTIMEOUT - timout expired
7300 CmInetFdSet *readFdS, /* read socket descriptor file set */
7301 CmInetFdSet *writeFdS, /* write socket descriptor file set */
7302 uint32_t *mSecTimeout, /* timeout in msecs */
7303 S16 *numFdS /* number of ready descriptors */
7306 S32 ret; /* temporary return value */
7307 struct timeval timeout; /* timeout structure */
7308 struct timeval *timeoutPtr;
7311 #if (ERRCLASS & ERRCLS_INT_PAR)
7312 /* error check on parameters */
7313 if (numFdS == NULLP)
7317 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7321 if (mSecTimeout != NULLP)
7323 timeout.tv_sec = *mSecTimeout / 1000;
7324 timeout.tv_usec = (*mSecTimeout % 1000) * 1000;
7325 timeoutPtr = &timeout;
7329 /* infinite timeout */
7335 timeout.tv_usec = 1;
7338 /* cm_inet_c_001.main_53 - Removed do-while loop */
7339 ret = select(FD_SETSIZE, readFdS, writeFdS, (fd_set*)0, timeoutPtr);
7341 /* cm_inet_c_001.main_53 - Return ROKDNA in case select was interrupted */
7342 if ((ret == INET_ERR) && (INET_ERR_CODE == ERR_EINTR))
7347 /* timeout occured */
7353 if (ret == INET_ERR)
7355 /* asa: Added a check for ERR_INVAL to return ROK
7356 * readFdS and writeFdS may be passed as NULL to
7357 * cmInetSelect() call
7359 switch(errCode = INET_ERR_CODE)
7366 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7367 /* cm_inet_c_001.main_62:Warning fix */
7368 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSelect() Failed : error(%d)\n",
7370 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET039, 0, prntBuf);
7371 #endif /* CMINETDBG */
7374 } /* end of switch */
7377 /* return number of ready file descriptors */
7378 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7382 } /* end of cmInetSelect */
7389 * Desc: Sets a socket option.
7390 * The function supports following options:
7392 * CM_INET_OPT_BLOCK:
7393 * value: CM_INET_OPT_DISABLE non-blocking
7394 * value: CM_INET_OPT_ENABLE blocking
7396 * CM_INET_OPT_REUSEADDR:
7397 * value: CM_INET_OPT_ENABLE reuse address
7399 * CM_INET_OPT_BROADCAST:
7400 * value: CM_INET_OPT_DISABLE
7401 * value: CM_INET_OPT_ENABLE
7403 * CM_INET_OPT_KEEPALIVE:
7404 * value: CM_INET_OPT_DISABLE
7405 * value: CM_INET_OPT_ENABLE
7407 * CM_INET_OPT_RX_BUF_SIZE:
7408 * value: receive buffer size in bytes
7410 * CM_INET_OPT_TX_BUF_SIZE:
7411 * value: transmitter buffer size in bytes
7413 * CM_INET_OPT_ADD_MCAST_MBR:
7414 * value: address of CmInetMCastInf structure
7416 * CM_INET_OPT_DRP_MCAST_MBR:
7417 * value: address of CmInetMCastInf structure
7419 * CM_INET_OPT_TCP_NODELAY:
7420 * value: CM_INET_OPT_DISABLE
7421 * value: CM_INET_OPT_ENABLE
7423 * CM_INET_OPT_BSD_COMPAT: For Linux only
7424 * value: CM_INET_OPT_ENABLE
7425 * value: CM_INET_OPT_DISABLE
7427 * CM_INET_OPT_HDR_INCLD:
7428 * value: CM_INET_ENABLE
7429 * value: CM_INET_DISABLE
7431 * CM_INET_OPT_DONT_FRAGMENT:
7432 * value: CM_INET_OPT_ENABLE
7433 * value: CM_INET_DISABLE
7436 * value: Type of Service.
7439 * value: Time To Live.
7441 * CM_INET_OPT_IP_OPTIONS:
7442 * value: IPv4 header option value
7445 * CM_INET_OPT_IP_ROUTER_ALERT:
7446 * value: CM_INET_OPT_DISABLE
7447 * value: CM_INET_OPT_ENABLE
7449 * CM_INET_OPT_IPV4_PKTINFO
7450 * value: CM_INET_OPT_ENABLE
7451 * value: CM_INET_OPT_DISABLE
7453 * CM_INET_OPT_MCAST_LOOP:
7454 * value: CM_INET_OPT_DISABLE
7455 * value: CM_INET_OPT_ENABLE
7457 * CM_INET_OPT_MCAST_IF:
7458 * value: Address of interface.
7460 * CM_INET_OPT_MCAST_TTL:
7461 * value: TTL of the outgoing multicast packet.
7463 * The next options are defined only if IPV6 is
7466 * CM_INET_OPT_ADD_MCAST6_MBR:
7467 * value: address of CmInetMCastInf6 structure
7469 * CM_INET_OPT_DRP_MCAST6_MBR:
7470 * value: address of CmInetMCastInf6 structure
7472 * CM_INET_OPT_MCAST6_LOOP:
7473 * value: CM_INET_OPT_DISABLE
7474 * value: CM_INET_OPT_ENABLE
7476 * CM_INET_OPT_MCAST6_IF:
7477 * value: Interface index
7479 * CM_INET_OPT_MCAST6_HOPS:
7480 * value: multicast hop limit
7482 * CM_INET_OPT_RECVIPV6_HOPLIM:
7483 * value: CM_INET_OPT_ENABLE hop limit will be returned
7485 * value: CM_INET_OPT_DISABLE hop limit wont be returned
7488 * CM_INET_OPT_RECVIPV6_HBHOPTS:
7489 * value: CM_INET_OPT_ENABLE HBH Options will be returned
7491 * value: CM_INET_OPT_DISABLE HBH Options wont be returned
7494 * CM_INET_OPT_RECVIPV6_DSTOPTS:
7495 * value: CM_INET_OPT_ENABLE Dest Options will be returned
7497 * value: CM_INET_OPT_DISABLE Dest Options wont be returned
7500 * CM_INET_OPT_RECVIPV6_RTHDR:
7501 * value: CM_INET_OPT_ENABLE Route Hdr Opt will be turned
7503 * value: CM_INET_OPT_DISABLE Route Hdr Opt will be turned
7504 * OFF on the socket.
7506 * CM_INET_OPT_IP_ROUTER_ALERT6
7507 * value: CM_INET_OPT_ENABLE
7508 * value: CM_INET_OPT_DISABLE
7510 * CM_INET_OPT_IPV6_PKTINFO
7511 * value: CM_INET_OPT_ENABLE Enable sending and receiving
7513 * value: CM_INET_OPT_DISABLE Disable sending and receiving
7516 * CM_INET_OPT_LINGER
7517 * value: address of CmInetSockLinger structure
7519 * CM_INET_OPT_SCTP_EVENTS
7520 * value: address of CmInetSctpSockEvent structure
7522 * CM_INET_OPT_SCTP_PRIM_ADDR
7523 * value: address of CmInetSctpPrimAddr structure
7525 * CM_INET_OPT_SCTP_PEERADDR_PARAMS
7526 * value: address of CmInetSctpPeerAddrParams structure
7529 * Ret: ROK - successful
7531 * RNA - failed, option not available
7532 * (Only when CM_INET2 is defined)
7534 * Notes: The send and receive buffer size may be system
7535 * specific. The cmInetSetOpt() call may return
7536 * successfuly although not the entire buffer size
7544 CmInetFd *sockFd, /* socket file descriptor */
7545 uint32_t level, /* option level */
7546 uint32_t type, /* option type */
7547 Ptr value /* option value */
7550 S32 ret = ROK; /* temporary return value */
7551 uint32_t disable = 0; /* disable option */
7552 uint32_t enable = 1; /* enable option */
7554 /* added for IPv4 options */
7555 #ifdef IPV4_OPTS_SUPPORTED
7556 #if((!defined (SS_VW)) && (!defined(SS_LINUX)))
7557 TknStr64 *tempTknStr64; /* points TknStr64 structure */
7558 /* which has value for IPv4 hdr options.*/
7559 #endif /* SS_VW && SS_LINUX */
7563 #endif /* IPV4_OPTS_SUPPORTED */
7565 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST)\
7567 uint8_t lpEnable = 1; /* multicast loop enable */
7568 uint8_t lpDisable = 0; /* multicast loop disable */
7569 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7572 BOOL boolEnable = TRUE; /* enable option */
7573 BOOL boolDisable = FALSE; /* disable option */
7576 #if (defined(SUNOS) || defined(WIN32) || defined(SS_PS) || \
7577 defined(SS_VW_MCAST) || defined(HPOS))
7578 struct ip_mreq stMreq;
7579 CmInetMCastInf *mCast;
7580 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7582 #ifdef IPV6_SUPPORTED
7583 uint32_t loopEna = 1; /* IPv6 multicast loop enable */
7584 uint32_t loopDis = 0; /* IPv6 multicast loop disable */
7585 struct ipv6_mreq *stMreq6Ptr;
7586 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
7587 this flag is gaurded under ICMPV6_FILTER_SUPPORTED. so if user want this
7588 support he has to enable the above flag.*/
7589 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
7590 * to support filteration of ICMP messages */
7591 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
7592 struct icmp6_filter *icmp6Filter;
7593 #endif /* ICMPV6_FILTER_SUPPORTED */
7594 #endif /* IPV6_SUPPORTED */
7596 /* cm_inet_c_001.main_58 : Added new local variables to support filteration
7597 * of ICMP messages */
7599 #ifdef CM_ICMP_FILTER_SUPPORT
7600 struct icmp_filter icmpFilter;
7604 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
7607 struct sctp_event_subscribe event;
7608 struct sctp_paddrparams addrParams;
7609 struct sctp_setprim setPrim;
7610 struct sockaddr_in *pAddr;
7611 struct sctp_assocparams assocParams;
7612 struct sctp_initmsg initmsg;
7613 struct sctp_rtoinfo rtoinfo;
7614 #ifdef IPV6_SUPPORTED
7615 struct sockaddr_in6 *pAddr6;
7616 #endif /* IPV6_SUPPORTED */
7618 CmInetSockLinger *pSockLinger;
7619 CmInetSctpSockEvent *pSctpEvent;
7620 CmInetSctpPrimAddr *pSctpPrimAddr;
7621 CmInetSctpPeerAddrParams *pSctpPAddrParams;
7622 CmInetSctpRtoInfo *pSctpRtoInfo;
7623 CmInetSctpInitMsg *pSctpInitMsg;
7624 CmInetSctpAssocParams *pSctpAssocParams;
7630 /* cm_inet_c_001.main_58 : Added NULL check for value field */
7636 #if (ERRCLASS & ERRCLS_INT_PAR)
7637 /* error check on parameters */
7638 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7642 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7646 case CM_INET_OPT_BLOCK:
7647 optVal = (uint32_t*)value;
7650 case CM_INET_OPT_ENABLE:
7653 /* cm_inet_c_001.main_59: Fix for compilation warning */
7654 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&disable);
7657 ret = ioctl(sockFd->fd, FIONBIO, (char*)&disable);
7660 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&disable);
7662 ret = ioctl(sockFd->fd, (S32)FIONBIO, &disable);
7667 sockFd->blocking = 1;
7670 case CM_INET_OPT_DISABLE:
7672 /* cm_inet_c_001.main_59: Fix for compilation warning */
7673 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&enable);
7676 ret = ioctl(sockFd->fd, FIONBIO, (char*)&enable);
7679 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&enable);
7681 ret = ioctl(sockFd->fd, (S32)FIONBIO, &enable);
7685 sockFd->blocking = 0;
7695 case CM_INET_OPT_REUSEADDR:
7696 optVal = (uint32_t*)value;
7697 if (*optVal == CM_INET_OPT_ENABLE)
7700 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7701 (char*)&boolEnable, sizeof(boolEnable));
7703 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7704 (char*)&enable, sizeof(enable));
7706 setsockopt(sockFd->fd, level, SO_REUSEPORT,
7707 (char*)&enable, sizeof(enable));
7711 else if (*optVal == CM_INET_OPT_DISABLE)
7714 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7715 (char*)&boolDisable, sizeof(boolDisable));
7717 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7718 (char*)&disable, sizeof(disable));
7720 ret = setsockopt(sockFd->fd, level, SO_REUSEPORT,
7721 (char*)&disable, sizeof(disable));
7727 case CM_INET_OPT_BROADCAST:
7728 optVal = (uint32_t*)value;
7729 if (*optVal == CM_INET_OPT_ENABLE)
7732 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7733 (char*)&boolEnable, sizeof(boolEnable));
7735 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7736 (char*)&enable, sizeof(enable));
7739 else if (*optVal == CM_INET_OPT_DISABLE)
7742 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7743 (char*)&boolDisable, sizeof(boolDisable));
7745 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7746 (char*)&disable, sizeof(disable));
7751 case CM_INET_OPT_KEEPALIVE:
7752 optVal = (uint32_t*)value;
7753 if (*optVal == CM_INET_OPT_ENABLE)
7756 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7757 (char*)&boolEnable, sizeof(boolEnable));
7759 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7760 (char*)&enable, sizeof(enable));
7763 else if (*optVal == CM_INET_OPT_DISABLE)
7766 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7767 (char*)&boolDisable, sizeof(boolDisable));
7769 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7770 (char*)&disable, sizeof(disable));
7775 case CM_INET_OPT_RX_BUF_SIZE:
7776 optVal = (uint32_t*)value;
7777 ret = setsockopt(sockFd->fd, level, SO_RCVBUF,
7778 (char*)optVal, sizeof(*optVal));
7781 case CM_INET_OPT_TX_BUF_SIZE:
7782 optVal = (uint32_t*)value;
7783 ret = setsockopt(sockFd->fd, level, SO_SNDBUF,
7784 (char*)optVal, sizeof(*optVal));
7787 case CM_INET_OPT_TCP_NODELAY:
7788 optVal = (uint32_t*)value;
7789 if (*optVal == CM_INET_OPT_ENABLE)
7793 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7794 (char*)&boolEnable, sizeof(boolEnable));
7795 #endif /* SS_WINCE */
7797 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7798 (char*)&enable, sizeof(enable));
7801 else if (*optVal == CM_INET_OPT_DISABLE)
7805 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7806 (char*)&boolDisable, sizeof(boolDisable));
7807 #endif /* SS_WINCE */
7809 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7810 (char*)&disable, sizeof(disable));
7815 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || \
7816 defined(SS_VW_MCAST) || defined(HPOS))
7818 case CM_INET_OPT_ADD_MCAST_MBR:
7819 mCast = (CmInetMCastInf*)value;
7821 /* Copy the addresses to stMreq structure */
7823 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7825 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7827 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7829 ret = setsockopt(sockFd->fd, level, IP_ADD_MEMBERSHIP,
7830 (char*)&stMreq, sizeof(stMreq));
7833 case CM_INET_OPT_DRP_MCAST_MBR:
7834 mCast = (CmInetMCastInf*)value;
7836 /* Copy the addresses to stMreq structure */
7838 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7840 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7842 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7844 ret = setsockopt(sockFd->fd, level, IP_DROP_MEMBERSHIP,
7845 (char*)&stMreq, sizeof(stMreq));
7848 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7851 /* cm_inet_c_001.main_37 - Enable CMINET_BSDCOMPAT flag if system doesnt
7852 support CM_INET_OPT_BSD_COMPAT */
7853 #ifndef CMINET_BSDCOMPAT
7854 case CM_INET_OPT_BSD_COMPAT:
7855 optVal = (uint32_t*)value;
7856 if (*optVal == CM_INET_OPT_ENABLE)
7858 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7859 &enable, sizeof(enable));
7861 else if (*optVal == CM_INET_OPT_DISABLE)
7863 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7864 &disable, sizeof(disable));
7867 #endif /* CMINET_BSDCOMPAT */
7868 #endif /* SS_LINUX */
7871 /* Added for support of Raw socket modify according to the
7872 * option available on different platform */
7873 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW) \
7875 case CM_INET_OPT_HDR_INCLD:
7876 optVal = (uint32_t*)value;
7877 if (*optVal == CM_INET_OPT_ENABLE)
7882 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7883 (char*)&enable, sizeof(enable));
7886 else if (*optVal == CM_INET_OPT_DISABLE)
7891 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7892 (char*)&disable, sizeof(disable));
7897 /* added new options */
7898 #ifdef IPV4_OPTS_SUPPORTED
7900 /* Linux: set Router Alert socket option to Intercept RAW RSVP
7901 packets at the Intermediate node(Router) with Router Alert SET.
7902 This socket option is MUST be set (when this server is opened)
7903 if the RSVP server wants to intercept raw RSVP packets. */
7904 case CM_INET_OPT_IP_ROUTER_ALERT:
7905 optVal = (uint32_t*)value;
7906 if (*optVal == CM_INET_OPT_ENABLE)
7908 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7909 (char*)&enable, sizeof(enable));
7913 else if (*optVal == CM_INET_OPT_DISABLE)
7915 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7916 (char*)&disable, sizeof(disable));
7921 #endif /* SS_LINUX */
7923 /* set Router Alert socket option */
7924 case CM_INET_OPT_IP_OPTIONS:
7925 #if (defined (SS_VW) || defined(SS_LINUX))
7928 tempTknStr64=(TknStr64 *)value;
7929 if (tempTknStr64->pres == TRUE)
7931 if (tempTknStr64->len == 0)
7933 /* disable the IP_OPTIONS for Router Alert. */
7935 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7936 (const char *)&disableOpt, sizeof(int));
7938 ret = setsockopt(sockFd->fd, level, IP_OPTIONS, NULL, 0);
7942 /* enable the IP_OPTIONS for Router Alert */
7943 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7944 (char *)tempTknStr64->val, tempTknStr64->len);
7947 return RFAILED; /* Trying to set IPv4 Hdr option
7948 * without giving option values*/
7949 #endif /* SS_VW || SS_LINUX */
7951 #endif /* IPV4_OPTS_SUPPORTED */
7953 /* added new options */
7954 #if (defined(SS_LINUX) && (!defined(SS_VW) && !defined(WIN32)))
7956 case CM_INET_OPT_IPV4_PKTINFO:
7957 optVal = (uint32_t*)value;
7958 if (*optVal == CM_INET_OPT_ENABLE)
7960 /* set IP_PKTINFO option when IP_ROUTER_ALERT is set in linux */
7961 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7962 (char*)&enable, sizeof(enable));
7967 else if (*optVal == CM_INET_OPT_DISABLE)
7969 /* disable IP_PKTINFO when IP_ROUTER_ALERT is set in linux */
7970 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7971 (char*)&disable, sizeof(disable));
7977 #endif /* LOCAL_INTF */
7978 #endif /* SS_LINUX */
7980 #endif /* SUNOS || WIN32 || SS_PS || SS_VW || HPOS */
7982 case CM_INET_OPT_DONTFRAGMENT:
7983 optVal = (uint32_t*)value;
7984 if (*optVal == CM_INET_OPT_ENABLE)
7987 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
7988 (char*)&boolEnable, sizeof(boolEnable));
7991 else if (*optVal == CM_INET_OPT_DISABLE)
7994 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
7995 (char*)&boolDisable, sizeof(boolDisable));
8000 /* also add these 2 options for VxWorks */
8001 #if (defined(SUNOS)|| defined(WIN32) || defined(HPOS) || defined(SS_VW))
8002 case CM_INET_OPT_TOS:
8003 optVal = (uint32_t*)value;
8004 ret = setsockopt(sockFd->fd, level, IP_TOS,
8005 (char*)optVal, sizeof(*optVal));
8008 case CM_INET_OPT_TTL:
8009 optVal = (uint32_t*)value;
8010 ret = setsockopt(sockFd->fd, level, IP_TTL,
8011 (char*)optVal, sizeof(*optVal));
8013 #endif /* SUNOS || WIN32 || HPOS || SS_VW */
8014 #endif /* CM_INET2 */
8016 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST) \
8018 case CM_INET_OPT_MCAST_LOOP:
8019 optVal = (uint32_t*)value;
8020 if (*optVal == CM_INET_OPT_ENABLE)
8023 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8024 (char *)&lpEnable, sizeof(lpEnable));
8026 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8027 (const char *)&lpEnable, sizeof(lpEnable));
8033 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8034 (char *)&lpDisable, sizeof(lpDisable));
8036 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8037 (const char *)&lpDisable, sizeof(lpDisable));
8042 case CM_INET_OPT_MCAST_IF:
8043 optVal = (uint32_t*)value;
8044 *optVal = CM_INET_HTON_UINT32((uint32_t)*optVal);
8045 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_IF,
8046 (char *)optVal, sizeof(struct in_addr));
8049 case CM_INET_OPT_MCAST_TTL:
8050 optVal = (uint32_t*)value;
8051 /* remove const in setsockopt for VW */
8053 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8054 (char *)optVal, sizeof(uint8_t));
8056 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8057 (const char *)optVal, sizeof(uint8_t));
8060 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8062 #ifdef IPV6_SUPPORTED
8063 case CM_INET_OPT_IPV6_TTL:
8064 optVal = (uint32_t*)value;
8065 ret = setsockopt(sockFd->fd, level, IPV6_UNICAST_HOPS,
8066 (char*)optVal, sizeof(*optVal));
8069 case CM_INET_OPT_ADD_MCAST6_MBR:
8070 stMreq6Ptr = (struct ipv6_mreq *)value;
8071 ret = setsockopt(sockFd->fd, level, IPV6_JOIN_GROUP,
8072 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8075 case CM_INET_OPT_DRP_MCAST6_MBR:
8076 stMreq6Ptr = (struct ipv6_mreq *)value;
8077 ret = setsockopt(sockFd->fd, level, IPV6_LEAVE_GROUP,
8078 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8081 case CM_INET_OPT_MCAST6_LOOP:
8082 optVal = (uint32_t*)value;
8083 if (*optVal == CM_INET_OPT_ENABLE)
8085 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8086 &loopEna, sizeof(loopEna));
8090 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8091 &loopDis, sizeof(loopDis));
8095 case CM_INET_OPT_MCAST6_IF:
8096 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_IF,
8097 (uint32_t *)value, sizeof(uint32_t));
8100 case CM_INET_OPT_MCAST6_HOPS:
8101 optVal = (uint32_t*)value;
8102 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_HOPS,
8103 (char *)optVal, sizeof(uint32_t));
8106 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
8107 this flag is gaurded under ICMPV6_SUPPORTED. so if user want this
8108 support he has to enable the above flag.*/
8109 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8110 * to support filteration of ICMP messages */
8111 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8112 case CM_INET_OPT_ICMP6_FILTER:
8113 icmp6Filter = (struct icmp6_filter *)value;
8114 ret = setsockopt(sockFd->fd, level, ICMP6_FILTER,
8115 (char *)icmp6Filter, sizeof(struct icmp6_filter));
8117 #endif /* ICMPV6_FILTER_SUPPORTED */
8119 /* added new options */
8120 #ifdef IPV6_OPTS_SUPPORTED
8121 case CM_INET_OPT_RECVIPV6_HOPLIM:
8122 optVal = (uint32_t*)value;
8124 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8125 (char *)optVal, sizeof(uint32_t));
8127 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8128 (char *)optVal, sizeof(uint32_t));
8129 /* enable the reception of IPv6 HopLimit value as ancillary data */
8130 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPLIMIT,
8131 (char*)&enable, sizeof(enable));
8132 #endif /* SS_LINUX */
8136 case CM_INET_OPT_RECVIPV6_HBHOPTS:
8137 optVal = (uint32_t*)value;
8139 ret = setsockopt(sockFd->fd, level, IPV6_HOPOPTS,
8140 (char *)optVal, sizeof(uint32_t));
8142 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPOPTS,
8143 (char *)optVal, sizeof(uint32_t));
8144 #endif /* SS_LINUX */
8147 case CM_INET_OPT_RECVIPV6_DSTOPTS:
8148 optVal = (uint32_t*)value;
8150 ret = setsockopt(sockFd->fd, level, IPV6_DSTOPTS,
8151 (char *)optVal, sizeof(uint32_t));
8153 ret = setsockopt(sockFd->fd, level, IPV6_RECVDSTOPTS,
8154 (char *)optVal, sizeof(uint32_t));
8155 #endif /* SS_LINUX */
8158 case CM_INET_OPT_RECVIPV6_RTHDR:
8159 optVal = (uint32_t*)value;
8161 ret = setsockopt(sockFd->fd, level, IPV6_RTHDR,
8162 (char *)optVal, sizeof(uint32_t));
8164 ret = setsockopt(sockFd->fd, level, IPV6_RECVRTHDR,
8165 (char *)optVal, sizeof(uint32_t));
8166 #endif /* SS_LINUX */
8169 /* works ONLY for IPPROTO_RAW type socket. so if it this socket
8170 * option is tried to set for IPPROTO_RSVP, then it is supposed
8171 * to fail with EINVAL according to net/ipv6/ipv6_sockglue.c
8173 * if HI_SRVC_RAW_RAW is not used during ServOpenReq as the server
8174 * type, then it will fail here due to above reason */
8176 case CM_INET_OPT_IP_ROUTER_ALERT6:
8177 optVal = (uint32_t*)value;
8178 if(*optVal == CM_INET_OPT_ENABLE)
8179 ret = setsockopt(sockFd->fd, IPPROTO_IPV6, IPV6_ROUTER_ALERT,
8180 (char *)&enable, sizeof(enable));
8182 ret = setsockopt(sockFd->fd, level, IPV6_ROUTER_ALERT,
8183 (char *)&disable, sizeof(disable));
8186 #endif /* SS_LINUX */
8187 #endif /* IPV6_OPTS_SUPPORTED */
8190 case CM_INET_OPT_IPV6_PKTINFO:
8191 optVal = (uint32_t*)value;
8193 ret = setsockopt(sockFd->fd, level, IPV6_PKTINFO,
8194 (char *)optVal, sizeof(uint32_t));
8196 ret = setsockopt(sockFd->fd, level, IPV6_RECVPKTINFO,
8197 (char *)&enable, sizeof(enable));
8198 #endif /* SS_LINUX */
8200 #endif /* LOCAL_INTF */
8202 #endif /* IPV6_SUPPORTED */
8204 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8206 case CM_INET_OPT_LINGER:
8207 pSockLinger = (CmInetSockLinger *)value;
8209 memset(&lngr, 0, sizeof(struct linger));
8211 if (pSockLinger->enable == TRUE)
8216 lngr.l_linger = pSockLinger->lingerTime;
8217 ret = setsockopt(sockFd->fd, level, SO_LINGER, &lngr, sizeof(lngr));
8220 case CM_INET_OPT_SCTP_EVENTS:
8221 pSctpEvent = (CmInetSctpSockEvent *)value;
8223 memset(&event, 0, sizeof(struct sctp_event_subscribe));
8225 if (pSctpEvent->dataIoEvent == TRUE)
8226 event.sctp_data_io_event = 1;
8228 if (pSctpEvent->associationEvent == TRUE)
8229 event.sctp_association_event = 1;
8231 if (pSctpEvent->addressEvent == TRUE)
8232 event.sctp_address_event = 1;
8234 if (pSctpEvent->sendFailureEvent == TRUE)
8235 event.sctp_send_failure_event = 1;
8237 if (pSctpEvent->peerErrorEvent == TRUE)
8238 event.sctp_peer_error_event = 1;
8240 if (pSctpEvent->shutdownEvent == TRUE)
8241 event.sctp_shutdown_event = 1;
8243 if (pSctpEvent->partialDeliveryEvent == TRUE)
8244 event.sctp_partial_delivery_event = 1;
8246 if (pSctpEvent->adaptationLayerEvent == TRUE)
8248 event.sctp_adaption_layer_event = 1;
8250 event.sctp_adaptation_layer_event = 1;
8253 ret = setsockopt(sockFd->fd, level, SCTP_EVENTS, &event, sizeof(event));
8256 case CM_INET_OPT_SCTP_PRIM_ADDR:
8257 pSctpPrimAddr = (CmInetSctpPrimAddr *)value;
8259 memset(&setPrim, 0, sizeof(struct sctp_setprim));
8261 #ifdef IPV6_SUPPORTED
8262 if (pSctpPrimAddr->addr.type == CM_INET_IPV6ADDR_TYPE)
8264 if (sockFd->protType == AF_INET)
8268 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8269 /* cm_inet_c_001.main_62:Warning fix */
8270 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8271 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8272 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8274 /* cm_inet_c_001.main_62:Warning fix */
8275 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8276 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8277 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8278 #endif /*ALIGN_64BIT*/
8279 #endif /* CMINETDBG */
8283 pAddr6 = (struct sockaddr_in6*)&(setPrim.ssp_addr);
8284 pAddr6->sin6_family = AF_INET6;
8285 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8286 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPrimAddr->addr.u.ipv6NetAddr);
8290 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8291 pAddr->sin_family = AF_INET;
8292 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8293 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8296 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8297 pAddr->sin_family = AF_INET;
8298 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8299 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8300 #endif /* IPV6_SUPPORTED */
8302 setPrim.ssp_assoc_id = pSctpPrimAddr->assocId;
8304 ret = setsockopt(sockFd->fd, level, SCTP_PRIMARY_ADDR, &setPrim, sizeof(setPrim));
8307 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
8308 pSctpPAddrParams = (CmInetSctpPeerAddrParams *)value;
8310 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
8313 if (pSctpPAddrParams->s.addrPres == TRUE)
8315 #ifdef IPV6_SUPPORTED
8316 if (pSctpPAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
8318 if (sockFd->protType == AF_INET)
8322 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8323 /* cm_inet_c_001.main_62:Warning fix */
8324 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8325 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8326 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8328 /* cm_inet_c_001.main_62:Warning fix */
8329 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8330 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8331 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8332 #endif /*ALIGN_64BIT*/
8333 #endif /* CMINETDBG */
8338 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
8339 pAddr6->sin6_family = AF_INET6;
8340 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8341 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPAddrParams->s.addr.u.ipv6NetAddr);
8345 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8346 pAddr->sin_family = AF_INET;
8347 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8348 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8351 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8352 pAddr->sin_family = AF_INET;
8353 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8354 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8355 #endif /* IPV6_SUPPORTED */
8359 #ifdef IPV6_SUPPORTED
8360 if (sockFd->protType == AF_INET6)
8361 addrParams.spp_address.ss_family = AF_INET6;
8363 addrParams.spp_address.ss_family = AF_INET;
8365 addrParams.spp_address.ss_family = AF_INET;
8369 /* Not validating the address, whether addr is a valid address or not */
8371 addrParams.spp_assoc_id = pSctpPAddrParams->assocId;
8372 /*cm_inet_c_001.main_58 : fix for klockwork issue */
8373 addrParams.spp_pathmaxrxt = (uint16_t)pSctpPAddrParams->pathMaxRxt;
8375 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8376 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8378 addrParams.spp_hbinterval = 0;
8381 addrParams.spp_flags = 0;
8383 if (pSctpPAddrParams->pmtudFlag == CM_INET_OPT_ENABLE)
8385 addrParams.spp_flags |= SPP_PMTUD_ENABLE;
8386 addrParams.spp_pathmtu = pSctpPAddrParams->pathMtu;
8388 else if(pSctpPAddrParams->pmtudFlag == CM_INET_OPT_DISABLE)
8389 addrParams.spp_flags |= SPP_PMTUD_DISABLE;
8391 if (pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_ENABLE)
8393 addrParams.spp_flags |= SPP_SACKDELAY_ENABLE;
8394 addrParams.spp_sackdelay = pSctpPAddrParams->sackDelay;
8396 else if(pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_DISABLE)
8397 addrParams.spp_flags |= SPP_SACKDELAY_DISABLE;
8399 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8401 addrParams.spp_flags |= SPP_HB_ENABLE;
8402 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8404 else if(pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_DISABLE)
8405 addrParams.spp_flags |= SPP_HB_DISABLE;
8407 ret = setsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, sizeof(addrParams));
8410 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
8411 pSctpAssocParams = (CmInetSctpAssocParams *)value;
8413 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
8415 assocParams.sasoc_cookie_life = pSctpAssocParams->cookieLife;
8416 assocParams.sasoc_asocmaxrxt = pSctpAssocParams->assocMaxReTx;
8417 assocParams.sasoc_assoc_id = pSctpAssocParams->assocId;
8418 assocParams.sasoc_number_peer_destinations = pSctpAssocParams->numberOfPeerDest;
8419 assocParams.sasoc_peer_rwnd = pSctpAssocParams->peerRwnd;
8420 assocParams.sasoc_local_rwnd = pSctpAssocParams->localRwnd;
8422 ret = setsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams));
8425 case CM_INET_OPT_SCTP_RTO_INFO:
8426 pSctpRtoInfo = (CmInetSctpRtoInfo *)value;
8428 memset(&rtoinfo, 0, sizeof(struct sctp_rtoinfo));
8430 rtoinfo.srto_assoc_id = pSctpRtoInfo->assocId;
8431 rtoinfo.srto_initial = pSctpRtoInfo->rtoInitial;
8432 rtoinfo.srto_max = pSctpRtoInfo->rtoMax;
8433 rtoinfo.srto_min = pSctpRtoInfo->rtoMin;
8435 ret = setsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
8438 case CM_INET_OPT_SCTP_INIT_MSG:
8439 pSctpInitMsg = (CmInetSctpInitMsg *)value;
8441 memset(&initmsg, 0, sizeof(struct sctp_initmsg));
8443 initmsg.sinit_max_attempts = pSctpInitMsg->maxInitReTx;
8444 initmsg.sinit_max_init_timeo = pSctpInitMsg->maxInitTimeout;
8445 initmsg.sinit_num_ostreams = pSctpInitMsg->numOstreams;
8446 initmsg.sinit_max_instreams = pSctpInitMsg->maxInstreams;
8448 ret = setsockopt(sockFd->fd, level, SCTP_INITMSG, &initmsg, sizeof(initmsg));
8451 #endif /*CM_LKSCTP*/
8453 /* cm_inet_c_001.main_58 : Added to support filteration of ICMP
8454 * messages and protected under CM_ICMP_FILTER_SUPPORT flag. Its a
8455 * partial implementaion for icmp filter done for TUCL */
8457 #ifdef CM_ICMP_FILTER_SUPPORT
8458 case CM_INET_OPT_ICMP_FILTER:
8459 optVal = (uint32_t*)value;
8460 ret = setsockopt(sockFd->fd, level, ICMP_FILTER,
8461 optVal, sizeof(icmpFilter));
8467 /* wrong socket option type */
8472 if (ret == INET_ERR)
8476 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8477 /* cm_inet_c_001.main_62:Warning fix */
8478 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%ld)\n",
8479 INET_ERR_CODE, sockFd->fd);
8480 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8482 /* cm_inet_c_001.main_62:Warning fix */
8483 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%d)\n",
8484 INET_ERR_CODE, sockFd->fd);
8485 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8486 #endif /*ALIGN_64BIT*/
8487 #endif /* CMINETDBG */
8491 } /* end of cmInetSetOpt */
8497 * Fun: cmInetGetNumRead
8499 * Desc: Gives the number of pending octets in the socket receive buffer.
8501 * Ret: ROK - successful
8510 S16 cmInetGetNumRead
8512 CmInetFd *sockFd, /* socket file descriptor */
8513 uint32_t *dataLen /* number of pending octets */
8514 /* removed 3rd argument memInfo */
8517 S32 ret; /* temporary return value */
8519 /* removed local variables added for recvfrom call */
8522 #if (ERRCLASS & ERRCLS_INT_PAR)
8523 /* error check on parameters */
8524 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
8531 /* use ioctl call for all types of socket to get length of
8532 pending data in the socket recv buffer */
8534 /* cm_inet_c_001.main_59: Fix for compilation warning */
8535 ret = ioctlsocket(sockFd->fd, FIONREAD, (uint32_t *)dataLen);
8538 ret = ioctl(sockFd->fd, FIOREAD, (char*)dataLen);
8541 ret = ioctl(sockFd->fd, FIONREAD, (S32)dataLen);
8543 ret = ioctl(sockFd->fd, FIONREAD, dataLen);
8548 /* For UDP socket assign the length of pending data in the
8549 socket recv buffer to largest datagram size.
8550 Removed recvfrom call & necessary processing for it. */
8552 if (ret == INET_ERR)
8554 /* removed error check CONABORTED added for recvfrom call.
8555 Also return value changed from RCLOSED to ROK */
8556 /* Check for reset connection */
8557 /* cm_inet_c_001.main_45: Close the TCP connection only when err is one of these*/
8558 if ((INET_ERR_CODE == ERR_CONNREFUSED) ||
8559 (INET_ERR_CODE == ERR_CONNABORTED) ||
8560 (INET_ERR_CODE == ERR_TIMEDOUT))
8564 /* cm_inet_c_001.main_50
8565 * Return RCLOSED instead of ROK to initiate connection closure.
8566 * ROK will be returned only if the ioctl call above returns ROK.
8567 * The routines calling this function have been modified to not
8568 * return RCLOSED when this function returns ROK with pending data
8569 * length value of 0. This modification is needed because:
8570 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
8571 * returns successfully with pend length as 0 on a TCP socket that
8572 * select says is ready to read. This should not be considered as
8573 * connection closed.
8578 /* removed error check ERR_WOULDBLOCK */
8579 /* cm_inet_c_001.main_45: Dont close the connection in case of ERR_CONNRESET */
8580 if ((INET_ERR_CODE == ERR_AGAIN) ||
8581 (INET_ERR_CODE == ERR_CONNRESET))
8588 /* cm_inet_c_001.main_45: Change 2048 to CM_INET_MAX_UDPRAW_MSGSIZE */
8589 *dataLen = CM_INET_MAX_UDPRAW_MSGSIZE;
8591 #endif /* SS_LINUX */
8593 /* removed error debug printing added for recvfrom call. */
8597 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8598 /* cm_inet_c_001.main_62:Warning fix */
8599 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8600 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
8601 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8603 /* cm_inet_c_001.main_62:Warning fix */
8604 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8605 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
8606 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8607 #endif /*ALIGN_64BIT*/
8608 #endif /* CMINETDBG */
8613 } /* end of cmInetGetNumRead */
8619 * Fun: cmInetGetHostByName
8621 * Desc: Resolves a host name into the appropriate 4 byte Internet
8624 * Ret: ROK - successful
8633 S16 cmInetGetHostByName
8635 S8 *hostName, /* host name */
8636 CmInetIpAddrTbl *addrTbl /* Address Table of IPV4 Addresses */
8640 uint8_t numAddrs; /* Number of Addresses */
8643 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8644 struct hostent *hostid; /* pointer to host information */
8647 struct hostent hostid; /* host information */
8648 S8 infoBuf[CM_INET_MAX_INFO]; /* info buffer */
8649 S32 err; /* error code */
8651 #endif /* WIN32 || SS_LINUX || HPOS */
8654 #if (ERRCLASS & ERRCLS_INT_PAR)
8655 /* error check on parameters */
8656 if ((hostName == NULLP) || (addrTbl == NULLP))
8660 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8669 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8670 hostid = gethostbyname(hostName);
8674 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8675 /* cm_inet_c_001.main_62:Warning fix */
8676 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8677 " hostName(%p)\n", INET_ERR_CODE, hostName);
8678 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET044, 0, prntBuf);
8679 #endif /* CMINETDBG */
8682 if (hostid->h_addrtype != AF_INET)
8685 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8686 /* cm_inet_c_001.main_62:Warning fix */
8687 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetHostByName() Failed : error(%d),"
8688 " hostName(%p), hostid->h_addrtype(%d)\n",
8689 INET_ERR_CODE, hostName, hostid->h_addrtype);
8690 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET045, 0, prntBuf);
8691 #endif /* CMINETDBG */
8696 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8697 (hostid->h_addr_list[numAddrs] != NULLP))
8699 addrTbl->netAddr[addrTbl->count++] =
8700 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8710 vwIpAddr = hostGetByName(hostName);
8711 if (vwIpAddr == INET_ERR)
8714 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8715 /* cm_inet_c_001.main_62:Warning fix */
8716 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8717 " hostName(%p)\n", INET_ERR_CODE, hostName);
8718 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET046, 0, prntBuf);
8719 #endif /* CMINETDBG */
8722 CM_COPY_VWIPADDR(vwIpAddr, &(addrTbl->netAddr[addrTbl->count]));
8727 err = 0; /* err is not reset by gethostnyname_r()! */
8729 gethostbyname_r(hostName, &hostid, infoBuf, CM_INET_MAX_INFO, (int*)&err);
8730 if ((hostid.h_addrtype != AF_INET) || (err < 0))
8733 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8734 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d), hostName(%p),"
8735 " hostid.h_addrtype(%d)\n",
8736 INET_ERR_CODE, hostName, hostid.h_addrtype);
8737 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET047, 0, prntBuf);
8738 #endif /* CMINETDBG */
8743 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8744 (hostid.h_addr_list[numAddrs] != NULLP))
8746 addrTbl->netAddr[addrTbl->count++] =
8747 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid.h_addr_list[numAddrs]));
8753 #endif /* WIN32 || SS_LINUX || HPOS */
8757 } /* end of cmInetGetHostByName */
8760 /* The getipnodebyname is not supported on all the Solaris Operating system
8761 * versions. This has to be supported on operating systems that support IPV6
8762 * as per the RFC on the IPV6 socket interface. Hence this function is moved
8763 * under the IPV6_SUPPORTED flag */
8765 /* This function now can be called for both IPv4 and IPv6. However, we will
8766 * call cmInetGetHostByName inside for IPv4. Move all flag dependencies
8767 * inside this function. */
8770 * Fun: cmInetGetIpNodeByName
8772 * Desc: Resolves a host name into the appropriate 4 byte Internet
8773 * address or into the appropriate 16 byte IPV6 address.
8774 * This function is expected to be thread safe and should be used
8775 * instead of the cmInetGetHostByName function.
8777 * Ret: ROK - successful
8785 S16 cmInetGetIpNodeByName
8787 S8 *hostName, /* host name */
8788 CmInetIpAddrArr *addrArr /* Array of addressed filled in */
8791 /* for return value from cmInetGetHostByName */
8792 #ifndef IPV6_SUPPORTED
8797 uint8_t numAddrs=0; /* Number of addresses */
8798 int err=0; /* error code */
8799 struct hostent *hostid; /* host information */
8800 #endif /* SS_LINUX */
8802 #endif /* IPV6_SUPPORTED */
8806 #if (ERRCLASS & ERRCLS_INT_PAR)
8807 /* error check on parameters */
8808 if ((hostName == NULLP) || (addrArr == NULLP))
8812 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8814 #ifdef IPV6_SUPPORTED
8818 #ifdef IPV6_SUPPORTED
8819 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8820 hostid = getipnodebyname(hostName, AF_INET6, 0, &err);
8822 #endif /* IPV6_SUPPORTED */
8823 hostid = getipnodebyname(hostName, AF_INET, 0, &err);
8827 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8828 /* cm_inet_c_001.main_62:Warning fix */
8829 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetIpNodeByName() Failed : error(%d),"
8830 " hostName(%p), addrArr->type(%d)n",
8831 err, hostName, addrArr->type);
8832 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET048, 0, prntBuf);
8833 #endif /* CMINETDBG */
8837 #ifdef IPV6_SUPPORTED
8838 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8840 if (hostid->h_addrtype == AF_INET6)
8842 while ((numAddrs < CM_INET_IPV6_NUM_ADDR) &&
8843 (hostid->h_addr_list[numAddrs] != NULLP))
8845 /* Use the cminet fill macro here */
8846 CM_INET_COPY_IPV6ADDR(&addrArr->u.ipv6AddrArr.netAddr[numAddrs],
8847 hostid->h_addr_list[numAddrs]);
8848 addrArr->u.ipv6AddrArr.count++;
8855 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8856 /* cm_inet_c_001.main_62:Warning fix */
8857 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8858 " hostName(%p), addrArr->type(%d),hostid->h_addrtype(%d) \n",
8859 err, hostName, addrArr->type, hostid->h_addrtype);
8860 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET049, 0, prntBuf);
8861 #endif /* CMINETDBG */
8866 #endif /* IPV6_SUPPORTED */
8868 if (hostid->h_addrtype == AF_INET)
8870 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8871 (hostid->h_addr_list[numAddrs] != NULLP))
8873 addrArr->u.ipv4AddrArr.count ++;
8874 addrArr->u.ipv4AddrArr.netAddr[numAddrs] =
8875 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8882 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8883 /* cm_inet_c_001.main_62:Warning fix */
8884 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8885 " hostName(%p), hostid->h_addrtype(%d), addrArr->type(%d)\n",
8886 err, hostName, hostid->h_addrtype, addrArr->type);
8887 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET050, 0, prntBuf);
8888 #endif /* CMINETDBG */
8892 #endif /* SS_LINUX */
8897 ret = cmInetGetHostByName(hostName, &addrArr->u.ipv4AddrArr);
8899 #endif /* IPV6_SUPPORTED */
8901 } /* end of cmInetGetIpNodeByName */
8908 * Desc: Converts an ASCII string containig an internet address
8909 * ("xxx.xxx.xxx.xxx") into a CmInetIpAddr (uint32_t) format.
8910 * This function is a wrapper for the inet_addr() call.
8912 * Ret: ROK - successful
8922 S8 *asciiAddr, /* ascii address representation */
8923 CmInetIpAddr *address /* 4 byte interent address */
8927 #if (ERRCLASS & ERRCLS_INT_PAR)
8928 /* error check on parameters */
8929 if (asciiAddr == NULLP)
8933 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8935 *address = inet_addr(asciiAddr);
8936 if (*address == (uint32_t)ERR_INADDRNONE)
8938 /* asciiAddr does not contain a valid internet address */
8950 * Desc: Converts an CmInetIPAddr based IP address into a string
8951 * of the format "xxx.xxx.xxx.xxx".
8952 * This function is a wrapper for the inet_ntoa() call.
8954 * Ret: ROK - successful
8957 * Notes: This function delivers a pointer to a static buffer
8958 * within the system. Therefore the string has to be copied
8959 * by the caller before another call is made!
8966 CmInetIpAddr address, /* 4 byte interent address */
8967 S8 **asciiAddr /* ascii address representation */
8970 struct in_addr inetAddr; /* internet address structure */
8973 #if (ERRCLASS & ERRCLS_INT_PAR)
8974 /* error check on parameters */
8975 if (asciiAddr == NULLP)
8979 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8981 inetAddr.s_addr = address;
8983 *asciiAddr = inet_ntoa(inetAddr);
8984 if (*asciiAddr == NULL)
8995 * Desc: Converts an network address into a string.
8996 * This function is a wrapper for the inet_ntop() call.
8998 * Ret: ROK - successful
9001 * Notes: This function copies the resulting string to the buffer pointed to
9002 * by asciiaddr,which must be a non NULL pointer.The caller specifies
9003 * the number of bytes available in this buffer in the argument len.
9010 uint8_t type, /* ip address type */
9011 Void *address, /* 4/16 byte interent address */
9012 S8 *asciiAddr, /* ascii adress representation */
9019 #if (ERRCLASS & ERRCLS_INT_PAR)
9020 /* error check on parameters */
9021 if (asciiAddr == NULLP || address == NULLP || len == 0 )
9026 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9029 case CM_INET_IPV4ADDR_TYPE :
9032 case CM_INET_IPV6ADDR_TYPE :
9036 if(inet_ntop(domain,address,asciiAddr,len) == NULL)
9045 /* The inet_pton is not supported on all the Solaris Operating system
9046 * versions. This has to be supported on operating systems that support
9047 * IPV6 as per the RFC on the IPV6 socket interface. Hence this function
9048 *is moved under the IPV6_SUPPORTED flag */
9049 #ifdef IPV6_SUPPORTED
9056 * Desc: Converts a IP address string to address.
9058 * Ret: ROK - successful
9068 CmInetIpAddr *address, /* 4 byte interent address */
9069 S8 *asciiAddr /* ascii address representation */
9075 #if (ERRCLASS & ERRCLS_INT_PAR)
9076 /* error check on parameters */
9077 if ((asciiAddr == NULLP) || (address == NULLP))
9081 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9083 ret = inet_pton(AF_INET, asciiAddr, (void *)address);
9090 } /* end of cmInetPton */
9092 #endif /* IPV6_SUPPORTED */
9094 #ifdef IPV6_SUPPORTED
9100 * Desc: Converts a IP address string to IPV6 address suitable
9101 * to be used in bind.
9103 * Ret: ROK - successful
9112 CmInetIpAddr6 *address6, /* 16 byte interent address */
9113 S8 *asciiAddr /* ascii address representation */
9119 struct sockaddr_storage ss;
9120 uint32_t sslen = sizeof(ss);
9123 #if (ERRCLASS & ERRCLS_INT_PAR)
9124 /* error check on parameters */
9125 if ((asciiAddr == NULLP) || (address6 == NULLP))
9129 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9132 ret = inet_pton(AF_INET6, asciiAddr, (void *)address6);
9138 /* cm_inet_c_001.main_44 : In windows inet_pton is not implemented. so we are using the below function
9139 * to convert the ipv6 address string to appropriate form */
9140 WSAStringToAddressA((LPTSTR)asciiAddr, AF_INET6, NULL, (struct sockaddr*)&ss, &sslen);
9141 memcpy(address6, &(((struct sockaddr_in6 *)&ss)->sin6_addr), sizeof(CmInetIpAddr6));
9145 } /* end of cmInetPton6 */
9146 #endif /* IPV6_SUPPORTED */
9152 * Fun: cmInetGetMemSize
9154 * Desc: This function gives the max number of static buffer space that
9155 * the internet library will allocate.
9157 * Ret: ROK - successful
9165 S16 cmInetGetMemSize(
9166 S32 *size /* max used memory size */
9170 /* max static memory size depends on max flat buffer size */
9171 *size = CM_INET_MAX_MSG_LEN;
9173 /* max static memory size depends on max flat buffer or iovect size */
9174 *size = CM_INET_MAX_MSG_LEN;
9186 * Desc: This function initializes the socket library.
9188 * Ret: ROK - successful
9190 * Notes: Required only for Winsock and not for 4.3BSD
9196 S16 cmInetInit(Void)
9203 version = MAKEWORD(CM_INET_HIGH_VER, CM_INET_LOW_VER);
9204 err = WSAStartup(version, &data);
9219 * Desc: This function de initializes the socket library. The
9220 * WINSOCK implementation de registers the application and
9221 * releases any resources allocated on behalf of the
9224 * Ret: ROK - successful
9226 * Notes: Required only for Winsock and not for 4.3BSD
9232 S16 cmInetDeInit(Void)
9245 }/* end of cmInetDeInit() */
9250 * Fun: cmInetGetSockName
9252 * Desc: This function is used to retireve the current name
9253 * for the specified socket descriptor. It returns the
9254 * local association(address and port) for the socket.
9256 * Ret: ROK - successful
9259 * Notes: Please note if the socket was bound to CM_INET_INADDR_ANY
9260 * cmInetGetSockName() will not necessarily return the local
9261 * address information unless the socket has been connected.
9267 S16 cmInetGetSockName
9269 CmInetFd *sockFd, /* socket file descriptor */
9273 struct sockaddr_in *sockAddr;
9274 #ifdef IPV6_SUPPORTED
9275 struct sockaddr_in6 *sockAddr6;
9276 struct sockaddr_in6 lclSockAddr;
9278 CmInetSockAddr lclSockAddr;
9279 #endif /* IPV6_SUPPORTED */
9284 #endif /* SS_LINUX */
9286 /*cm_inet_c_001.main_58 : fix for klockwork issue */
9290 #if (ERRCLASS & ERRCLS_INT_PAR)
9291 /* error check on parameters */
9292 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
9297 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9299 memset(&lclSockAddr, 0, sizeof(lclSockAddr));
9300 size = sizeof(lclSockAddr);
9303 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr,
9304 (socklen_t *)&size);
9306 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, (int*)&size);
9307 #endif /* SS_LINUX */
9311 switch(errCode = INET_ERR_CODE)
9314 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9315 #ifdef IPV6_SUPPORTED
9316 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9317 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9319 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9320 #endif /* IPV6_SUPPORTED */
9326 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9327 /* cm_inet_c_001.main_62:Warning fix */
9328 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9329 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9330 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9332 /* cm_inet_c_001.main_62:Warning fix */
9333 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9334 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9335 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9336 #endif /* ALIGN_64BIT */
9337 #endif /* CMINETDBG */
9339 }/* end of switch */
9343 /* Fill the returned address in to locAddr */
9344 #ifdef IPV6_SUPPORTED
9345 memset(locAddr, 0, sizeof(CmInetAddr));
9346 if (size == sizeof(struct sockaddr_in6))
9348 sockAddr6 = (struct sockaddr_in6 *)&lclSockAddr;
9349 locAddr->type = CM_INET_IPV6ADDR_TYPE;
9350 locAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(sockAddr6->sin6_port);
9351 CM_INET_COPY_IPV6ADDR(&locAddr->u.ipv6Addr.ipv6NetAddr,
9352 &sockAddr6->sin6_addr);
9356 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9357 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9358 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9359 locAddr->u.ipv4Addr.address =
9360 CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9363 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9364 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9365 locAddr->address = CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9366 #endif /* IPV6_SUPPORTED */
9368 }/* end of cmInetGetSockName() */
9370 /* New functions to peek into the file descriptor
9372 #if (defined(SUNOS) || defined(WIN32) || defined(SS_LINUX) || defined(SS_VW) \
9377 * Fun: cmInetFdSetInfoInit
9379 * Desc: This function is used to initialise operating system specific
9380 * data that will be used to peek into the file descriptor lists
9381 * to get the sockets that are set
9383 * Ret: ROK - successful
9392 S16 cmInetFdSetInfoInit
9394 CmInetFdSetInfo *fdSetInfo
9397 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW) || defined(HPOS))
9402 #endif /* SUNOS || SS_LINUX || SS_VW */
9404 #if (ERRCLASS & ERRCLS_INT_PAR)
9405 if (fdSetInfo == NULLP)
9407 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9409 if (fdSetInfo->initDone == TRUE)
9413 fdSetInfo->numFds = 0;
9416 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW)|| defined(HPOS))
9417 /* Check if we are on a big endian machine */
9419 if (*(uint8_t *)&arIdx)
9420 fdSetInfo->bigEndian = FALSE;
9422 fdSetInfo->bigEndian = TRUE;
9424 fdSetInfo->arIdx = 0;
9425 fdSetInfo->ar[0] = 0xff;
9427 /* Initialise the array */
9428 /* The array contains bit positions for the first bit
9429 * for each integer from 1 to 2^8.
9431 for (arIdx = 1; arIdx < 256; arIdx++)
9433 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9434 curByte = (uint8_t)arIdx;
9441 fdSetInfo->ar[arIdx] = bitPos;
9445 curByte = curByte >> 1;
9448 /* Calculate the number of array elements in this fd_set */
9449 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9450 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->__fds_bits[0]);
9452 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->fds_bits[0]);
9453 #endif /* SS_LINUX */
9454 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9456 fdSetInfo->initDone = TRUE;
9458 }/* end of cmInetFdSetInfoInit() */
9465 * Desc: This function is used to get the file descriptor from the
9466 * file descriptor set.
9468 * Ret: ROK - successful
9469 * ROKDNA - socket not found
9471 * RNA - failed, initialisation not done
9473 * Notes: If the application modifies fdSet between calls to this
9474 * function then the results are undefined. This function should
9475 * be called in a loop till either it returns - not ROK, or if
9476 * all sockets in the file descriptor set are processed.
9484 CmInetFdSetInfo *fdSetInfo,
9486 CmInetFdType *sockFd
9489 /*cm_inet_c_001.main_58 : Fix for klockwork issue */
9490 #if (!defined (WIN32))
9491 uint32_t sizOfFdSetArElem;
9492 uint8_t bytesScanned;
9497 #endif /* !defined (WIN32) */
9499 #if (ERRCLASS & ERRCLS_INT_PAR)
9500 if ((fdSetInfo == NULLP) || (fdSet == NULLP) || (sockFd == NULLP))
9503 if (fdSetInfo->initDone != TRUE)
9505 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9508 #if (ERRCLASS & ERRCLS_DEBUG)
9509 if (fdSetInfo->numFds > FD_SETSIZE)
9511 #endif /* ERRCLASS & ERRCLS_DEBUG */
9512 /* cm_inet_c_001.main_32 : Corrected check for number of fd set in
9514 if (fdSetInfo->numFds >= fdSet->fd_count)
9517 *sockFd = fdSet->fd_array[fdSetInfo->numFds];
9518 fdSetInfo->numFds += 1;
9522 /* cm_inet_c_001.main_59: Protected under if not defined WIN32 */
9523 #if (!defined (WIN32))
9524 /* Start with arIdx and continue upto number of array elements. */
9525 curIdx = fdSetInfo->arIdx;
9528 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9529 sizOfFdSetArElem = sizeof(fdSet->__fds_bits[0]);
9531 sizOfFdSetArElem = sizeof(fdSet->fds_bits[0]);
9532 #endif /* SS_LINUX */
9534 for (curIdx = fdSetInfo->arIdx; curIdx < fdSetInfo->numArElems;
9537 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9538 if (fdSet->__fds_bits[curIdx])
9540 if (fdSet->fds_bits[curIdx])
9541 #endif /* SS_LINUX */
9543 /* Walk through the bytes in this element */
9544 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9545 tempByte = (uint8_t *)&fdSet->__fds_bits[curIdx];
9547 tempByte = (uint8_t *)&fdSet->fds_bits[curIdx];
9548 #endif /* SS_LINUX */
9550 /* Set the starting byte offset */
9551 if (fdSetInfo->bigEndian)
9552 tempByte += sizOfFdSetArElem - 1;
9554 for (bytesScanned = 0; bytesScanned < sizOfFdSetArElem;
9559 bitPos = fdSetInfo->ar[*tempByte];
9560 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9561 fdSetInfo->arIdx = (uint16_t)curIdx;
9562 /* Calculate fd depending on where we are */
9563 *sockFd = ((bytesScanned << 3) + bitPos);
9564 *sockFd += (curIdx * (sizOfFdSetArElem << 3));
9565 /* Clear the file descriptor */
9566 *tempByte &= ~(1 << bitPos);
9569 if (fdSetInfo->bigEndian)
9582 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9583 } /* end of cmInetGetFd */
9585 #endif /* SUNOS || WIN32 || SS_LINUX || SS_VW || HPOS */
9588 /* add cmInetConvertStrToIpAddr and
9589 * cmInetAsciiToIpv4 functions */
9592 * Fun: cmInetConvertStrToIpAddr
9594 * Desc: This function parses the input string for an IPV4/IPV6 address.
9596 * 1) IPV4 in dot number format:
9598 * 2) IPV6, in uncompressed, compressed, and IPV4 embedded format
9599 * 10:20:30:40:502:610:70C:80ad
9601 * 45::AB:34:123.34.5.667
9603 * Ret: ROK - SUCCESS
9612 S16 cmInetConvertStrToIpAddr
9614 uint16_t len, /* Length of IP address */
9615 uint8_t *val, /* Domain Name String */
9616 CmInetNetAddr *address /* IP Address */
9619 uint8_t idx; /* Index for string*/
9620 uint8_t ipv4[CM_INET_IPV4ADDR_SIZE]; /* IPV4 Address bytes */
9621 #ifdef IPV6_SUPPORTED
9622 uint16_t *ipv6; /* IPV6 Address bytes */
9623 uint16_t ipv6Reg[8]; /* regular IPV6 Address bytes */
9624 uint16_t ipv6Cmp[8]; /* compressed IPV6 Address bytes */
9625 uint8_t numBlk; /* number of blocks in IPV6 addr */
9626 Bool compressed; /* IPV6 in compressed format */
9627 uint8_t ipv6Idx; /* counter for IPV6 */
9628 uint8_t blkBeginIdx; /* IPV6, char index for the
9629 beginning of the block */
9630 uint8_t i; /* counter for IPV6 */
9631 S16 retVal; /* return value */
9632 Bool embedIPV4 = FALSE; /* IPV4 embedded in IPV6 ? */
9633 #endif /* IPV6_SUPPORTED*/
9637 #ifdef IPV6_SUPPORTED
9642 ipv6 = ipv6Reg; /* assign pointer to IPV6 regular, uncompressed */
9643 memset(ipv6Reg, 0, CM_INET_IPV6ADDR_SIZE);
9644 memset(ipv6Cmp, 0, CM_INET_IPV6ADDR_SIZE);
9645 #endif /* IPV6_SUPPORTED*/
9647 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9649 /* Check for IP Address */
9650 while ((val[idx] != '.') && (val[idx] != ':') &&
9653 #if (ERRCLASS & ERRCLS_DEBUG)
9654 if (((val[idx] < '0') || (val[idx] > '9')) &&
9655 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9656 ((val[idx] < 'A') || (val[idx] > 'F')))
9661 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9663 /* Convert Ascii to integer */
9664 CM_INET_ATOI(ipv4[0], val[idx]);
9666 #ifdef IPV6_SUPPORTED
9667 /* convert Ascii to hex */
9668 CM_INET_ATOH(ipv6[0], val[idx]);
9669 #endif /* IPV6_SUPPORTED */
9671 idx++; /* move to the next character */
9672 } /* while, try to determine IPV4 or IPV6 */
9674 #if (ERRCLASS & ERRCLS_DEBUG)
9675 if ((val[idx] != '.') && (val[idx] != ':'))
9679 } /* if, couldn't determine IPV4 or IPV6 */
9680 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9683 if (val[idx] == '.')
9686 cmInetAsciiToIpv4(3, &(ipv4[1]), (uint16_t)(len - idx), &(val[idx]));
9688 address->type = CM_INET_IPV4ADDR_TYPE;
9689 CM_INET_GET_IPV4_ADDR_FRM_STRING(address->u.ipv4NetAddr, ipv4);
9691 #ifdef IPV6_SUPPORTED
9694 numBlk = 1; /* already converted the 1st block */
9696 while ((val[idx] != '\0') && (idx < len) && (numBlk <= 8))
9698 idx++; /* go to the next char, either a number or the 2nd : */
9699 if (val[idx] == ':')
9701 #if (ERRCLASS & ERRCLS_DEBUG)
9702 if (compressed == TRUE)
9704 /* can't have 2 :: */
9707 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9710 idx++; /* skip the : */
9713 } /* if, IPV6 in compressed format :: */
9717 } /* else, uncompressed, convert next block */
9719 numBlk++; /* increase number of blocks */
9721 /* assign the index the beginning of the block */
9724 while(val[idx] != ':' && val[idx] != '\0' && idx < len)
9726 if (val[idx] == '.')
9728 /* convert number to IPV4 */
9729 ipv6[ipv6Idx] = 0; /* clear out whatever we did */
9730 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9731 retVal = cmInetAsciiToIpv4(4, ipv4, len - blkBeginIdx,
9732 &(val[blkBeginIdx]));
9733 /* stop the loop, embedded IPV4 is the last part of
9741 } /* if, '.' means IPV4 address embedded in IPV6 */
9743 #if (ERRCLASS & ERRCLS_DEBUG)
9744 if (((val[idx] < '0') || (val[idx] > '9')) &&
9745 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9746 ((val[idx] < 'A') || (val[idx] > 'F')))
9751 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9753 /* Convert Ascii to integer */
9754 CM_INET_ATOH(ipv6[ipv6Idx], val[idx]);
9756 /* move to the next index */
9758 } /* while, convert a block of 16 bits Hex number */
9759 if (embedIPV4 == TRUE)
9761 ipv6Idx--; /* deccrease in case of compressed IPV6 */
9762 break; /* stop the while look */
9763 } /* if, IPV4 embedded in IPV6 */
9764 } /* while, IPV6 parsing */
9765 if (compressed == TRUE)
9767 if (embedIPV4 == TRUE)
9769 numBlk = 5; /* the last 2 blocks are IPV4 */
9770 } /* if, IPV4 embedded */
9773 numBlk = 7; /* copy from the last block */
9774 } /* else, no embedded IPV4 */
9776 /* type cast uint8_t over -1 becasue we want to copy the last block,
9779 for (i = ipv6Idx; i != (uint8_t) (-1); i --)
9781 ipv6Reg[numBlk] = ipv6Cmp[i];
9783 } /* for, copying compress IPV6 to regular IPV6 */
9784 } /* if, compressed format */
9786 if (embedIPV4 == TRUE)
9788 ipv6Reg[6] = PutHiByte(ipv6Reg[6], ipv4[0]);
9789 ipv6Reg[6] = PutLoByte(ipv6Reg[6], ipv4[1]);
9790 ipv6Reg[7] = PutHiByte(ipv6Reg[7], ipv4[2]);
9791 ipv6Reg[7] = PutLoByte(ipv6Reg[7], ipv4[3]);
9792 } /* if, IPV4 embedded */
9794 /* convert IPV6 to cmInetIpv6 */
9795 address->type = CM_INET_IPV6ADDR_TYPE;
9796 memcpy(address->u.ipv6NetAddr,
9797 ipv6Reg, CM_INET_IPV6ADDR_SIZE);
9799 #endif /* IPV6_SUPPORTED */
9802 } /* cmInetConvertStrToIpAddr */
9807 * Fun: cmInetAsciiToIpv4
9809 * Desc: This function parses the input string to an IPV4 address.
9810 * The input string can be
9811 * - the whole IPV4 address, '123.43.45.56', or
9812 * - a part of it. '34.56.454'
9813 * numBytes: number of bytes needs to be converted, IPV4 has
9814 * 4 bytes. If we are only converting the end of an
9815 * address, this number needs to be adjusted. For
9816 * example, when converting '34.56.454]', the number
9819 * Ret: ROK - SUCCESS
9827 S16 cmInetAsciiToIpv4
9829 uint8_t numBytes, /* number of Byte to convert */
9830 uint8_t *ipv4Addr, /* IPV4 Address */
9831 uint16_t len, /* Length of IP address */
9832 uint8_t *val /* Domain Name String */
9835 uint8_t byteCount; /* Byte Count */
9836 uint8_t idx; /* Index for string*/
9840 for (byteCount = 0; byteCount < numBytes; byteCount++)
9842 while((val[idx] != '.') && (idx < len))
9844 #if (ERRCLASS & ERRCLS_DEBUG)
9845 if (val[idx] < '0' || val[idx] > '9')
9850 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9852 /* Convert Ascii to integer */
9853 CM_INET_ATOI(ipv4Addr[byteCount], val[idx]);
9855 /* move to the next index */
9862 } /* cmInetAsciiToIpv4 */
9864 /* cm_inet_c_001.main_34:Added wrapper function for getaddrinfo and freeaddrinfo */
9865 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
9869 * Fun: cmInetGetAddrInfo
9871 * Desc: a socket file descriptor to a local Internet
9874 * Ret: Value returned by getaddrinfo
9882 S32 cmInetGetAddrInfo
9884 const S8 *node, /* Network addr which has to be resolved */
9885 const S8 *service, /* Sets the port number in network addr */
9886 const CmInetAddrInfo *hints, /* Specifies preferred socket type or protocol */
9887 CmInetAddrInfo **res /* Link list of addrInfo structure */
9893 #if (ERRCLASS & ERRCLS_INT_PAR)
9894 /* error check on parameters */
9895 if ((node == NULLP) || (hints == NULLP))
9899 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9901 ret = getaddrinfo(node,service,hints,res);
9906 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9907 /* cm_inet_c_001.main_62:Warning fix */
9908 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%ld), node(%p),"
9909 " service(%p)\n", ret, node, service);
9910 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET052, 0, prntBuf);
9912 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9913 /* cm_inet_c_001.main_62:Warning fix */
9914 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%d), node(%p),"
9915 " service(%p)\n ", ret, node, service);
9916 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET053, 0, prntBuf);
9917 #endif /* ALIGN_64BIT */
9918 #endif /* CMINETDBG */
9921 } /* end of cmInetGetAddrInfo */
9926 * Fun: cmInetFreeAddrInfo
9928 * Desc: Free the dynamically allocated addrinfo structure
9938 Void cmInetFreeAddrInfo
9940 CmInetAddrInfo *res /* Link list of addrInfo structure */
9944 #if (ERRCLASS & ERRCLS_INT_PAR)
9945 /* error check on parameters */
9948 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9951 } /* end of cmInetFreeAddrInfo */
9953 #endif /* SS_VW | SS_PS | WIN32*/
9955 /* cm_inet_c_001.main_36 : 1. Added new interface - cmInetFlushRecvBuf()
9956 to flush the data from socket receive buffer. */
9957 #ifdef CM_INET_FLUSH_RECV_BUF
9961 * Fun: cmInetFlushRcvBuf
9963 * Desc: Reads all the data from a socket and throw it!!
9964 * The buffers for the receive buffer for recvfrom() are allocated from the stack.
9966 * Ret: ROK - successful
9967 * ROKDNA - ok, data not available
9968 * RCLOSED - connection closed by peer
9969 * ROUTRES - failed, out of resources
9977 S16 cmInetFlushRecvBuf
9979 CmInetFd *sockFd, /* socket file descriptor */
9980 MsgLen *len, /* number of octects to be flushed */
9981 S32 flags /* additional control flags */
9985 Data recvTempBuf[CM_INET_MAX_BYTES_READ];
9987 #if (defined(WIN32) || defined(CMINETFLATBUF))
9988 S32 ret; /* temporary return value */
9989 uint32_t pendLen; /* pending data length */
9990 S32 recvLen; /* number of received octets by recvmsg() */
9991 MsgLen curLen; /* current number of octets in buffer */
9992 uint32_t remAddrLen; /* length of remote address */
9993 struct sockaddr_in *remAddr; /* remote Internet address */
9994 #ifdef IPV6_SUPPORTED
9995 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
9997 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
9998 #endif /* IPV6_SUPPORTED */
10000 S32 ret; /* temporary return value */
10001 MsgLen curLen; /* current number of octets in buffer */
10002 uint32_t pendLen; /* pending data length */
10003 S32 recvLen; /* number of received octets by recvmsg() */
10004 struct msghdr msg; /* message header */
10005 CmInetIovec rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
10006 uint32_t remAddrLen; /* length of remote address */
10007 #ifdef IPV6_SUPPORTED
10008 struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
10010 #if (defined(SS_LINUX) || defined(_XPG4_2))
10011 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
10012 /* from stack for IPv6 ancill data */
10015 CmInetSockAddr remSockAddr; /* to get packet's src IP address */
10016 #if (defined(SS_LINUX) || defined(_XPG4_2))
10017 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
10018 /* from stack for IPv4 ancill data */
10020 #endif /* IPV6_SUPPORTED */
10021 #endif /* WIN32 | CMINETFLATBUF */
10023 /* used by getsockopt */
10024 uint32_t errValue; /* error value */
10025 uint32_t optLen; /* option length */
10028 #if (ERRCLASS & ERRCLS_INT_PAR)
10029 /* error check on parameters */
10030 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
10034 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10037 #if (defined(WIN32) || defined(CMINETFLATBUF))
10039 #endif /* (WIN32 | CMINETFLATBUF) */
10041 /* clear the structure */
10042 memset(&remSockAddr, 0, sizeof(remSockAddr));
10044 /* get number of pending data */
10045 ret = cmInetGetNumRead(sockFd, &pendLen);
10048 /* ret may be RFAILED or ROUTRES */
10052 /* check if connection got closed */
10055 if (sockFd->type == CM_INET_STREAM)
10058 /* cm_inet_c_001.main_50
10059 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
10060 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
10061 * socket that select says is ready to read. This should not be
10062 * considered as connection closed. So return ROKDNA instead of
10068 /* clear error if there is any, because if there is internal error
10069 * here it will cause infinite loop in TUCL */
10072 optLen = sizeof(int);
10074 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10075 (char*)&errValue, (socklen_t *)&optLen);
10077 #if (defined(SS_VW) || defined(SS_PS))
10078 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10079 (char*)&errValue, (int *)&optLen);
10082 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10083 (char*)&errValue, (int *)&optLen);
10084 #endif /* SS_WINCE */
10086 #endif /* SS_LINUX */
10087 if (ret == INET_ERR)
10090 #ifndef ALIGN_64BIT
10091 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10092 /* cm_inet_c_001.main_62:Warning fix */
10093 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10094 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10095 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10097 /* cm_inet_c_001.main_62:Warning fix */
10098 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10099 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10100 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10101 #endif /*ALIGN_64BIT*/
10102 #endif /* CMINETDBG */
10108 /* added separate recvfrom calls different OS */
10109 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10110 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10111 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10113 #if ( defined(SUNOS) || defined(SS_LINUX))
10114 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10115 NULLP, (socklen_t *)&remAddrLen);
10117 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10118 NULLP, (S32 *)&remAddrLen);
10120 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10121 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10126 }/* if (pendLen == 0)*/
10129 if((*len == CM_INET_READ_THROW) || (*len >= CM_INET_MAX_BYTES_READ))
10131 curLen = CM_INET_MAX_BYTES_READ;
10135 curLen = *len; /*set to given number of messasges to be flushed */
10138 if((*len != CM_INET_READ_THROW) && (*len < pendLen))
10143 #if (defined(WIN32) || defined(CMINETFLATBUF))
10147 * maybe needs more than one recvfrom() call to read an entire
10152 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10153 /* added separate recvfrom calls different OS */
10155 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10156 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10157 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10159 #if ( defined(SUNOS) || defined(SS_LINUX))
10160 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10161 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
10163 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempbuf, curLen, 0,
10164 &remSockAddr, (S32 *)&remAddrLen);
10166 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10167 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10169 if (recvLen == INET_ERR)
10172 /* added check ERR_WOULDBLOCK */
10173 if ((INET_ERR_CODE == ERR_AGAIN) ||
10174 (INET_ERR_CODE == ERR_WOULDBLOCK))
10181 /* In Windows the recvfrom function fails
10182 * with error code which maps to either WSAECONNABORTED. If
10183 * this happens then cmInetFlushRecvBuf must return RCLOSED */
10184 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
10185 (INET_ERR_CODE == ERR_CONNRESET))
10192 #ifndef ALIGN_64BIT
10193 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10194 /* cm_inet_c_001.main_62:Warning fix */
10195 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10196 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10197 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10199 /* cm_inet_c_001.main_62:Warning fix */
10200 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10201 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10202 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10203 #endif /*ALIGN_64BIT*/
10204 #endif /* CMINETDBG */
10209 if(recvLen < curLen)
10212 pendLen -= recvLen;
10214 if(pendLen < curLen)
10217 } /* while (curLen > 0) */
10219 #else /* end of Win NT/flat buffer specific part */
10222 * maybe needs more than one recvmsg() call to read entire message
10223 * on a stream socket
10227 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10228 /* update the message structure */
10230 rxArr[0].iov_base = (Void*)recvTempBuf;
10231 rxArr[0].iov_len = (uint32_t)curLen;
10233 rxArr[0].iov_base = (S8*)recvTempBuf;
10234 rxArr[0].iov_len = curLen;
10235 #endif /* SS_LINUX */
10236 msg.msg_iov = rxArr;
10237 msg.msg_iovlen = 1;
10239 msg.msg_name = NULLP;
10240 msg.msg_namelen = 0;
10242 /* added defined(_XPG4_2). Also changed the
10244 #if (defined(SS_LINUX) || defined(_XPG4_2))
10245 msg.msg_control = ancillData;
10246 msg.msg_controllen = sizeof(ancillData);
10249 msg.msg_accrights = NULLP;
10250 msg.msg_accrightslen = 0;
10251 #endif /* SS_LINUX */
10253 recvLen = recvmsg(sockFd->fd, &msg, flags);
10254 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
10256 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
10257 added check ERR_WOULDBLOCK */
10258 if ((INET_ERR_CODE == ERR_AGAIN) ||
10259 (INET_ERR_CODE == ERR_WOULDBLOCK))
10266 #ifndef ALIGN_64BIT
10267 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
10268 /* cm_inet_c_001.main_62:Warning fix */
10269 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10270 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10271 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10273 /* cm_inet_c_001.main_62:Warning fix */
10274 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10275 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10276 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10277 #endif /*ALIGN_64BIT*/
10278 #endif /* CMINETDBG */
10280 /* If this happens then cmInetFlushRecvBuf must return RCLOSED.
10281 * Needed for getting icmp msgs */
10282 if (INET_ERR_CODE == ERR_CONNABORTED)
10288 }/* if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))*/
10290 if(recvLen < curLen)
10293 pendLen -= recvLen;
10295 if(pendLen < curLen)
10298 } /* while(curLen > 0) */
10300 #endif /* WIN32 | CMINETFLATBUF */
10304 } /* end of cmInetFlushRecvBuf */
10306 #endif /* CM_INET_FLUSH_RECV_BUF*/
10308 /**********************************************************************
10310 **********************************************************************/