1 /*******************************************************************************
2 ################################################################################
3 # Copyright (c) [2017-2019] [Radisys] #
5 # Licensed under the Apache License, Version 2.0 (the "License"); #
6 # you may not use this file except in compliance with the License. #
7 # You may obtain a copy of the License at #
9 # http://www.apache.org/licenses/LICENSE-2.0 #
11 # Unless required by applicable law or agreed to in writing, software #
12 # distributed under the License is distributed on an "AS IS" BASIS, #
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
14 # See the License for the specific language governing permissions and #
15 # limitations under the License. #
16 ################################################################################
17 *******************************************************************************/
20 /********************************************************************20**
22 Name: common Internet socket library
26 Desc: common library for Internet sockets,
27 always link this library with following libraries:
33 *********************************************************************21*/
37 * This software may be combined with the following TRILLIUM
40 * part no. description
41 * -------- ----------------------------------------------
42 * 1000151 TCAP over TCP/IP
46 /* header include files (.h) */
48 #include "envopt.h" /* environment options */
49 #include "envdep.h" /* environment dependent */
50 #include "envind.h" /* environment independent */
52 #include "gen.h" /* general */
53 #include "ssi.h" /* system services interface */
54 #include "cm_inet.h" /* socket library file */
56 /*cm_inet_c_001.main_35 : Updated for C++ compilation */
59 #endif /* __cplusplus */
61 /* environment dependent include files */
73 #if (!defined(SS_VW) && !defined(SS_PS))
80 #include <sys/types.h>
84 #include <sys/socket.h>
85 #include <sys/ioctl.h>
88 #include <sys/times.h>
91 #include <selectLib.h>
94 #if (!defined (SS_PS) && !defined(HPOS))
95 #include <sys/select.h>
100 #include <sys/filio.h>
101 #endif /* SS_LINUX */
102 #endif /* SS_PS && HPOS */
104 #include <sys/time.h>
108 #include <netinet/in.h>
109 #include <arpa/inet.h>
110 #include <netinet/tcp.h>
111 #ifdef IPV6_SUPPORTED
113 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 adding the new header includes */
114 #if (defined(SS_VW) && defined(SS_VW6_7))
115 #include <ipcom_inet.h>
116 #include <ipcom_sock6.h>
117 #include <netinet/icmp6.h>
119 #include <netinet/icmp6.h>
122 #endif /* IPV6_SUPPORTED */
126 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
128 #include <netinet/sctp.h>
131 /* cm_inet_c_001.main_58: Added new header files to support filteration
132 * of ICMP messages */
134 #ifdef CM_ICMP_FILTER_SUPPORT
135 #include <asm/types.h>
136 #include <linux/icmp.h>
139 /* cm_inet_c_001.main_62:Warning fix */
140 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
145 #endif /* __cplusplus */
146 /* header/extern include files (.x) */
148 #include "gen.x" /* general */
149 #include "ssi.x" /* system services interface */
150 #include "cm_inet.x" /* socket library file */
151 #include "cm_lib.x" /* lib library file */
160 /* BSD and Winsock error handling is different */
162 #define INET_ERR SOCKET_ERROR
163 #define INET_ERR_CODE WSAGetLastError()
164 #define ERR_INPROGRESS WSAEINPROGRESS
165 #define ERR_ISCONN WSAEISCONN
166 #define ERR_WOULDBLOCK WSAEWOULDBLOCK
167 #define ERR_INADDRNONE INADDR_NONE
168 #define ERR_NOTCONN WSAENOTCONN
169 #define ERR_ALREADY WSAEALREADY
170 #define ERR_AGAIN WSAEWOULDBLOCK
171 #define ERR_INVAL WSAEINVAL
172 #define ERR_CONNREFUSED WSAECONNREFUSED
173 #define ERR_PIPE WSAENOTCONN
174 /* Changed ERR_TIMEOUT for pSos compilation */
175 #define ERR_TIMEDOUT WSAETIMEDOUT
176 #define ERR_CONNRESET WSAECONNRESET
177 #define ERR_CONNABORTED WSAECONNABORTED
178 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
179 #define ERR_EINTR WSAEINTR
180 /* cm_inet_c_001.main_37 network unreacheble error is added */
181 #define ERR_NETUNREACH WSAENETUNREACH
182 /* cm_inet_c_001.main_61: host unreachable is added */
183 #define ERR_HOSTUNREACH WSAEHOSTUNREACH
186 #define INET_ERR_CODE errno
187 #define ERR_INPROGRESS EINPROGRESS
188 #define ERR_ISCONN EISCONN
189 #define ERR_WOULDBLOCK EWOULDBLOCK
190 #define ERR_INADDRNONE -1
191 #define ERR_NOTCONN ENOTCONN
192 #define ERR_ALREADY EALREADY
193 #define ERR_AGAIN EAGAIN
194 /* cm_inet_c_001.main_36 Do select again in case of interrupt */
195 #define ERR_EINTR EINTR
196 /* EINVAL is not mapped because it is a valid error code here */
198 #define ERR_CONNREFUSED ECONNREFUSED
199 #define ERR_PIPE EPIPE
200 /* Changed ERR_TIMEOUT for pSos compilation */
201 #define ERR_TIMEDOUT ETIMEDOUT
202 #define ERR_CONNRESET ECONNRESET
203 #define ERR_CONNABORTED ECONNABORTED
204 /* cm_inet_c_001.main_37 network unreacheble error is added */
205 #define ERR_NETUNREACH ENETUNREACH
206 /* cm_inet_c_001.main_61: host unreachable is added */
207 #define ERR_HOSTUNREACH EHOSTUNREACH
211 #define MIN_BACK_LOG 0
213 /* added a win2k specific defines in. */
216 #ifndef SIO_UDP_CONNRESET
217 #define SIO_UDP_CONNRESET _WSAIOW(IOC_VENDOR, 12)
220 #define MAX_BACK_LOG 1
222 #define MAX_BACK_LOG 5
225 #ifdef IPV6_OPTS_SUPPORTED
226 #ifndef IPV6_SUPPORTED
227 #error "Enable IPV6_SUPPORTED flag if IPV6_OPTS_SUPPORTED is defined."
229 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
230 #error "Enable _XPG4_2 or SS_LINUX if IPV6_OPTS_SUPPORTED is defined."
231 #endif /* SS_LINUX || _XPG4_2 */
232 #endif /* IPV6_OPTS_SUPPORTED */
235 #if (!defined(SS_LINUX) && !defined(_XPG4_2))
236 #error "Enable _XPG4_2 or SS_LINUX if LOCAL_INTF is defined."
237 #endif /* SS_LINUX || _XPG4_2 */
238 #endif /* LOCAL_INTF */
244 /* forward references */
246 /* added !(defined(CMINETFLATBUF) */
247 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
248 /* Added another function parameter */
249 static S16 buildRecvBuf ARGS((CmInetMemInfo *info, MsgLen len,
250 CmInetIovec rxArr[], Buffer *dBuf[], uint16_t maxSize,
251 struct msghdr *msg, Bool isStrmMsg));
252 static S16 buildRecvMsg ARGS((CmInetMemInfo *info, CmInetIovec rxArr[],
253 S16 numBduf, MsgLen msgLen, Buffer *dBufs[],
255 /* cm_inet_c_001.main_50 - Added parameter to get length of dbufs packed for partial
258 static S16 buildSendIovec ARGS((Buffer *mBuf, MsgLen msgLen,
259 CmInetIovec txArr[], S16 numDBuf,
260 S16 *numIovElems, uint32_t *strtEndDBufNum,
262 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
264 /* prototypes of new functions needed to send and
265 * process after receiving the extension headers through ancillary data */
267 #ifdef IPV6_SUPPORTED
268 #ifdef IPV6_OPTS_SUPPORTED
269 static S16 cmInet6BuildSendHBHOpts ARGS((CmInetIpv6HBHHdrArr *hbhOptsArr,
270 uint8_t *cmsgBuf, uint32_t *curMsgIdx,
272 static S16 cmInet6BuildSendRouteOpts ARGS((CmInetIpv6RtHdr *rtOptsArr,
273 uint8_t *cmsgBuf, uint32_t *curMsgIdx));
275 static S16 cmInet6BuildRecvRtHdr ARGS((uint8_t *cmsgData, uint32_t rtDataLen,
276 CmInetIpv6RtHdr0 *rtHdr0,
277 CmInetIpv6RtHdr *rtOptsArr,
278 CmInetMemInfo *info));
279 static S16 cmInet6BuildRecvHopOptsArr ARGS((uint8_t *cmsgData, uint32_t hbhDataLen,
280 CmInetIpv6HBHHdrArr *hbhOptsArr,
281 uint8_t hdrId, CmInetMemInfo *info));
282 static S16 cmInet6GetHopLimitValue ARGS((uint8_t *cmsgData, uint32_t hopLimitDataLen,
283 CmInetIpv6HdrParm *ipv6HdrParam));
286 static S16 cmInetBuildSendHoplimit ARGS((uint32_t hoplimit, uint8_t *cmsgBuf,
287 uint32_t *curMsgIdx));
288 #endif /* SS_LINUX */
290 static S16 cmInet6BuildSendPktinfo ARGS((CmInetIpAddr6 *srcAddr,
291 uint8_t *cmsgBuf, uint32_t *curMsgIdx,
293 #endif /* LOCAL_INTF */
294 #endif /* IPV6_OPTS_SUPPORTED */
295 #endif /* IPV6_SUPPORTED */
297 /* public variable declarations */
299 /* private variable declarations */
302 /* Global buffer for debug prints */
303 /*cm_inet_c_001.main_62:Warning fix*/
304 Txt prntBuf[CMINET_PRNT_BUF_SIZE];
305 #endif /* CMINETDBG */
307 /* cm_inet_c_001.main_60 POLL Specific Functions defined */
313 * Desc: Poll on pollfdarr
315 * Ret: Number of File Descriptor Selected
325 CmInetPollFd *pollFdArr, /* poll FD Array */
326 uint32_t numFds, /* Number of Fds to be monitored */
327 S16 *numRdyFds, /* number of ready descriptors */
328 uint32_t timeout /* timeout value for Poll */
336 if(numFds > CM_INET_POLL_MAXFDSUPP)
339 /* cm_inet_c_001.main_62:Warning fix */
341 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%lu) invalid \n",numFds);
343 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : number of file descriptor (%u) invalid \n",numFds);
345 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
346 #endif /* CMINETDBG */
350 #if (ERRCLASS & ERRCLS_INT_PAR)
351 /* error check on parameters */
352 if (pollFdArr == NULLP)
355 /* cm_inet_c_001.main_62:Warning fix */
356 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPoll() : Invalid Parameter (pollFdArr is NULL)");
357 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
358 #endif /* CMINETDBG */
361 #endif /* ERRCLASS & ERRCLS_INT_PAR */
363 ret = poll(pollFdArr,numFds,timeout);
370 switch(INET_ERR_CODE)
377 /* cm_inet_c_001.main_62:Warning fix */
378 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "File: %s, cmInetPoll() failed on line: %d \n\
379 error(%d)\n", __FILE__, __LINE__, INET_ERR_CODE);
381 #endif /* CMINETDBG */
384 } /* end of switch */
387 *numRdyFds = (S16)ret;
395 * Fun: cmInetPollSetFd
397 * Desc: Set the selected fd in pollFdArr with event eventMask
399 * Ret: RFAILED : if file descriptor is out of range
400 * ROK : if pollFdArr is set.
410 CmInetFd *sockFd, /* socket file descriptor */
411 CmInetPollFd *pollFdArr, /* poll FD Array */
412 S16 idx, /* poll Fd Array Index */
413 uint16_t eventMask /* Event Mask to be set */
418 if ((idx) >= CM_INET_POLL_MAXFDSUPP || (idx) < 0)
421 /* cm_inet_c_001.main_62:Warning fix */
422 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid idx(%d) \n",idx);
423 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
424 #endif /* CMINETDBG */
429 #if (ERRCLASS & ERRCLS_INT_PAR)
430 /* error check on parameters */
431 if (pollFdArr == NULLP)
434 /* cm_inet_c_001.main_62:Warning fix */
435 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() : Invalid Parameter (pollFdArr is NULL)");
436 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
437 #endif /* CMINETDBG */
440 #endif /* ERRCLASS & ERRCLS_INT_PAR */
444 /* cm_inet_c_001.main_62:Warning fix */
445 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,
446 "cmInetPollSetFd() Before Setting fd : sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set fd(%ld) event(%d) \n",
447 pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
448 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
450 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,
451 "cmInetPollSetFd() Before Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n Fd and event to be set fd(%d) event(%d) \n",
452 pollFdArr[idx].fd,idx, pollFdArr[idx].events,sockFd->fd,eventMask);
453 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
454 #endif /*ALIGN_64BIT */
455 #endif /* CMINETDBG */
457 /* Setting fd and events with eventMask */
458 pollFdArr[idx].fd = sockFd->fd;
459 pollFdArr[idx].events |= eventMask;
464 /* cm_inet_c_001.main_62:Warning fix */
465 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
466 pollFdArr[idx].fd,idx, pollFdArr[idx].events);
467 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
469 /* cm_inet_c_001.main_62:Warning fix */
470 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollSetFd() After Setting fd: sockFd->fd(%d) Index(%d) Event(%d) \n",
471 pollFdArr[idx].fd,idx, pollFdArr[idx].events);
472 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
473 #endif /*ALIGN_64BIT */
474 #endif /* CMINETDBG */
483 * Fun: cmInetPollFdIsSet
485 * Desc: Checks whether fd is selected
487 * Ret: TRUE : If Fd is Selected
488 * FALSE: If Fd is not Selected
496 S16 cmInetPollFdIsSet
498 CmInetPollFd *pollFdArr, /* poll FD Array */
499 S16 idx, /* poll Fd Array Index */
500 uint16_t eventMask /* Event Mask to be set */
506 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
509 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Index (%d) \n",idx);
510 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
511 #endif /* CMINETDBG */
515 #if (ERRCLASS & ERRCLS_INT_PAR)
516 /* error check on parameters */
517 if (pollFdArr == NULLP)
520 /* cm_inet_c_001.main_62:Warning fix */
521 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollFdIsSet() : Invalid Parameter (pollFdArr is NULL)");
522 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
523 #endif /* CMINETDBG */
526 #endif /* ERRCLASS & ERRCLS_INT_PAR */
528 ret = (pollFdArr[idx].revents & eventMask);
535 * Fun: cmInetPollClearFdREvent
537 * Desc: clears the reventMask in revent of the givent FD.
548 S16 cmInetPollClearFdREvent
550 CmInetPollFd *pollFdArr, /* poll FD Array */
551 S16 idx, /* poll Fd Array Index */
552 uint16_t eventMask /* Event Mask to be set */
558 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
561 /* cm_inet_c_001.main_62:Warning fix */
562 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Index (%d) \n",idx);
563 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
564 #endif /* CMINETDBG */
568 #if (ERRCLASS & ERRCLS_INT_PAR)
569 /* error check on parameters */
570 if (pollFdArr == NULLP)
573 /* cm_inet_c_001.main_62:Warning fix */
574 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() : Invalid Parameter (pollFdArr is NULL)");
575 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
576 #endif /* CMINETDBG */
579 #endif /* ERRCLASS & ERRCLS_INT_PAR */
583 /* cm_inet_c_001.main_62:Warning fix */
584 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
585 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
586 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
588 /* cm_inet_c_001.main_62:Warning fix */
589 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() Before clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
590 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
591 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
592 #endif /*ALIGN_64BIT */
593 #endif /* CMINETDBG */
595 /* Clearing the events with eventMask */
596 pollFdArr[idx].revents = (pollFdArr[idx].revents & (~(eventMask)));
600 /* cm_inet_c_001.main_62:Warning fix */
601 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
602 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
603 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
605 /* cm_inet_c_001.main_62:Warning fix */
606 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdREvent() After clearing fd revents with eventMask: \n sockFd->fd(%d) Index(%d) REvent(%d) EventMask(%d) \n",
607 pollFdArr[idx].fd,idx, pollFdArr[idx].revents,eventMask);
608 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
609 #endif /*ALIGN_64BIT */
610 #endif /* CMINETDBG */
619 * Fun: cmInetPollClearFdEvent
621 * Desc: clears the eventMask in event of the givent FD.
632 S16 cmInetPollClearFdEvent
634 CmInetPollFd *pollFdArr, /* poll FD Array */
635 S16 idx, /* poll Fd Array Index */
636 uint16_t eventMask /* Event Mask to be set */
642 if((idx < 0) || (idx > CM_INET_POLL_MAXFDSUPP))
645 /* cm_inet_c_001.main_62:Warning fix */
646 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Index (%d) \n",idx);
647 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
648 #endif /* CMINETDBG */
652 #if (ERRCLASS & ERRCLS_INT_PAR)
653 /* error check on parameters */
654 if (pollFdArr == NULLP)
657 /* cm_inet_c_001.main_62:Warning fix */
658 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() : Invalid Parameter (pollFdArr is NULL)");
659 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
660 #endif /* CMINETDBG */
663 #endif /* ERRCLASS & ERRCLS_INT_PAR */
667 /* cm_inet_c_001.main_62:Warning fix */
668 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask: \n sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
669 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
670 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
672 /* cm_inet_c_001.main_62:Warning fix */
673 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() Before clearing fd events with eventMask:\n sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
674 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
675 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
676 #endif /*ALIGN_64BIT */
677 #endif /* CMINETDBG */
679 /* Clearing events with eventMask */
680 pollFdArr[idx].events = (pollFdArr[idx].events & (~(eventMask)));
684 /* cm_inet_c_001.main_62:Warning fix */
685 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
686 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
687 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
689 /* cm_inet_c_001.main_62:Warning fix */
690 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollClearFdEvent() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
691 pollFdArr[idx].fd,idx, pollFdArr[idx].events,eventMask);
692 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
693 #endif /*ALIGN_64BIT */
694 #endif /* CMINETDBG */
703 * Fun: cmInetPollDelFd
705 * Desc: Delete the given FD from the pollFdArray
706 * delIdx : Poll Fd Array Index at which fd has to be deleted.
707 * lastIdx: Last index of poll fd array.
709 * It deletes fd from array by swapping lastIdx pollFd
710 * values to index to be deleted and deinitializes the
716 * Notes: It does not decrement the lastIdx and it has to be
717 * decremented by the caller of this function.
725 CmInetPollFd *pollFdArr, /* poll FD Array */
726 S16 delIdx, /* poll Fd Array Index for which fd has to be deleted*/
727 S16 lastIdx /* Last index of poll Fd Array */
732 if(lastIdx < delIdx || lastIdx < 0 || delIdx < 0)
735 /* cm_inet_c_001.main_62:Warning fix */
736 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Index \n Current Index (%d) Delete Index (%d) \n",lastIdx,delIdx);
737 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
738 #endif /* CMINETDBG */
743 #if (ERRCLASS & ERRCLS_INT_PAR)
744 /* error check on parameters */
745 if (pollFdArr == NULLP)
748 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() : Invalid Parameter (pollFdArr is NULL)");
749 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
750 #endif /* CMINETDBG */
753 #endif /* ERRCLASS & ERRCLS_INT_PAR */
757 /* cm_inet_c_001.main_62:Warning fix */
758 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() Deleting the sockFd->fd(%d) Index(%d) Event(%d) revent(%d) \n",
759 pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
760 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
762 /* cm_inet_c_001.main_62:Warning fix */
763 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollDelFd() After clearing fd events with eventMask: sockFd->fd(%d) Index(%d) Event(%d) EventMask(%d) \n",
764 pollFdArr[delIdx].fd,delIdx, pollFdArr[delIdx].events,pollFdArr[delIdx].revents);
765 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
766 #endif /*ALIGN_64BIT */
767 #endif /* CMINETDBG */
769 pollFdArr[delIdx].fd = pollFdArr[lastIdx].fd;
770 pollFdArr[delIdx].events = pollFdArr[lastIdx].events;
771 pollFdArr[delIdx].revents = pollFdArr[lastIdx].revents;
773 pollFdArr[lastIdx].fd = -1;
774 pollFdArr[lastIdx].events = 0;
775 pollFdArr[lastIdx].revents = 0;
783 * Fun: cmInetPollInitFdArr
785 * Desc: Cleans all elements of fd array.
790 * Notes: It does not allocates/deallocates memory for Poll Fd Array.
791 * Caller of function has to allocate/deallocate memory for
798 S16 cmInetPollInitFdArr
800 CmInetPollFd *pollFdArr /* poll FD Array */
805 /* Sets each element of pollFdArr to initial value
810 #if (ERRCLASS & ERRCLS_INT_PAR)
811 /* error check on parameters */
812 if (pollFdArr == NULLP)
815 /* cm_inet_c_001.main_62:Warning fix */
816 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetPollInitFdArr() : Invalid Parameter (pollFdArr is NULL)");
817 CMINETLOGERROR(ERRCLS_DEBUG, ECMINETXXX, 0, prntBuf);
818 #endif /* CMINETDBG */
821 #endif /* ERRCLASS & ERRCLS_INT_PAR */
823 for(idx=0; idx < CM_INET_POLL_MAXFDSUPP; idx++)
825 pollFdArr[idx].fd = -1;
826 pollFdArr[idx].events = 0;
827 pollFdArr[idx].revents = 0;
832 #if (!(defined(WIN32)) && !(defined(CMINETFLATBUF)))
837 * Desc: Allocates dBufs to receive an entire message.
839 * Ret: ROK - successful
841 * ROUTRES - failed, out of resources
849 static S16 buildRecvBuf
851 CmInetMemInfo *info, /* buffer allocation info */
852 MsgLen len, /* message length */
853 CmInetIovec rxArr[], /* gather array */
854 Buffer *dBuf[], /* allocated dBufs */
855 uint16_t maxSize, /* size of rxArr/dBuf array */
856 struct msghdr *msg, /* message header for recvmsg() */
857 Bool isStrmMsg /* Is a TCP message */
860 S16 ret; /* temporary return value */
861 uint16_t numBuf; /* number of dBufs */
862 uint16_t i; /* dBuf index counter */
863 Data *dPtr; /* data pointer */
864 /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
865 MsgLen bufLen; /* entire receive buffer length, if S16
866 could wrap to negative number */
867 MsgLen dLen; /* buffer length */
872 /* Initialise ret and part of msg here */
875 /* added defined(_XPG4_2) */
876 /* Moved initialisation of msg here. */
878 #if (defined(SS_LINUX) || defined(_XPG4_2))
879 msg->msg_control = NULLP;
880 msg->msg_controllen = 0;
882 msg->msg_accrights = NULLP;
883 msg->msg_accrightslen = 0;
884 #endif /* SS_LINUX */
886 /* Check if maxSize if enough to hold the entire message length before
887 * going into the loop. If the boolean isStrmMsg is TRUE then the recv
888 * buf is built even if the whole message cannot be accomodated. */
890 #ifdef T2K_MEM_LEAK_DBG
891 char * file = __FILE__;
892 uint32_t line = __LINE__;
893 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
895 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
900 /* Get the data part */
901 ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
904 numBuf++; /* because of cleanup */
910 /* The assumption here is that all dBuf's from a given region and
911 * pool have a constance size */
912 if (len > (maxSize * dLen))
915 numBuf++; /* because of cleanup */
921 rxArr[numBuf].iov_base = (Void*)dPtr;
922 rxArr[numBuf].iov_len = (uint32_t)dLen;
924 rxArr[numBuf].iov_base = (S8*)dPtr;
925 rxArr[numBuf].iov_len = dLen;
926 #endif /* SS_LINUX */
931 /* allocate buffer space for entire message length */
934 if (numBuf >= maxSize)
936 /* to big to fit in gather vector array */
940 ret = SGetDBuf(info->region, info->pool, &dBuf[numBuf]);
945 ret = SGetDataRx(dBuf[numBuf], 0, &dPtr, &dLen);
948 numBuf++; /* because of cleanup */
952 rxArr[numBuf].iov_base = (Void*)dPtr;
953 rxArr[numBuf].iov_len = (uint32_t)dLen;
955 rxArr[numBuf].iov_base = (S8*)dPtr;
956 rxArr[numBuf].iov_len = dLen;
957 #endif /* SS_LINUX */
962 /* adjust last buffer length */
963 /* check if we broke out because numBuf >= maxSize */
965 rxArr[numBuf - 1].iov_len = dLen;
967 rxArr[numBuf - 1].iov_len = dLen - (bufLen - len);
969 /* setup recvmsg() message header */
970 msg->msg_iov = rxArr;
971 msg->msg_iovlen = numBuf;
977 for (i = 0; i < numBuf; i++)
978 SPutDBuf(info->region, info->pool, dBuf[i]);
983 } /* end of buildRecvBuf */
989 * Desc: Builds a message out of the received dBufs.
991 * Ret: ROK - successful
993 * ROUTRES - failed, out of resources
1001 static S16 buildRecvMsg
1003 CmInetMemInfo *info, /* buffer allocation info */
1004 CmInetIovec rxArr[], /* scatter array */
1005 S16 numBuf, /* number of allocated dBufs */
1006 MsgLen msgLen, /* message length */
1007 Buffer *dBufs[], /* dBufs */
1008 Buffer **mPtr /* message built from dBufs */
1011 S16 ret; /* return value */
1012 S16 i; /* dBuf index counter */
1013 MsgLen bufLen; /* length of one particular dBuf */
1014 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
1015 Buffer *mBuf = NULLP; /* allocated message */
1021 ret = SGetMsg(info->region, info->pool, &mBuf);
1027 /* link buffers to message */
1030 /* cm_inet_c_001.main_58: fix for klockwork issue */
1031 bufLen = (MsgLen)rxArr[i].iov_len;
1032 if (msgLen < bufLen)
1036 ret = SUpdMsg(mBuf, dBufs[i], bufLen);
1054 /* cleanup unused buffers */
1057 #ifdef T2K_MEM_LEAK_DBG
1058 char * file = __FILE__;
1059 uint32_t line = __LINE__;
1060 SPutDBuf(info->region, info->pool, dBufs[i]);
1062 SPutDBuf(info->region, info->pool, dBufs[i]);
1068 } /* end of buildRecvMsg */
1074 * Fun: buildSendIovec
1076 * Desc: Builds a io vector to send a message.
1078 * Ret: ROK - successful
1080 * ROUTRES - failed, out of resources
1081 * RNA - failed, not available, indicates that the
1082 * maximum number of dBufs are not sufficient
1083 * to hold the entire message.
1090 static S16 buildSendIovec
1092 Buffer *mBuf, /* Message buffer */
1093 MsgLen msgLen, /* Length of mBuf */
1094 CmInetIovec txArr[], /* transmit scatter vector array */
1095 S16 numDBufs, /* Maximum number of dBufs to use */
1096 S16 *numIovElems, /* Number of iov elements in array */
1097 uint32_t *strtEndDBufNum, /* dBuf number to start and end */
1098 MsgLen *ioLen /* cm_inet_c_001.main_50 - Len of dbuf packed into IO-vector */
1107 uint32_t dBufsToSkip;
1109 /* Initialisations */
1114 /* cm_inet_c_001.main_50 - Intialize the newly added parameter */
1117 /* Set up vector for gathering send */
1118 ret = SInitNxtDBuf(mBuf);
1125 txArr[iovIdx].iov_len = 0;
1127 if ((*strtEndDBufNum != 0))
1129 /* Skip through the required number of dBufs */
1130 dBufsToSkip = *strtEndDBufNum;
1134 ret = SGetNxtDBuf(mBuf, &dBuf);
1143 ret = SGetNxtDBuf(mBuf, &dBuf);
1146 ret = SGetDataTx(dBuf, &dPtr, &dLen);
1153 txArr[iovIdx].iov_base = (S8 *)dPtr;
1154 txArr[iovIdx].iov_len = dLen;
1158 else if (ret == ROKDNA)
1171 if (iovIdx >= numDBufs)
1173 if (allocLen >= msgLen)
1181 (*numIovElems) = iovIdx;
1182 (*strtEndDBufNum) += iovIdx;
1184 /* cm_inet_c_001.main_50 - Assign the value of dbufs packed in IO-vector */
1189 } /* end of buildSendIovec */
1190 #endif /* (defined(WIN32)) && !(defined(CMINETFLATBUF)) */
1197 * Desc: Creates an Internet socket descriptor.
1198 * On default the socket is non-blocking ( can be changed
1199 * with the function cmInetSetOpt()).
1202 * CM_INET_STREAM (TCP)
1203 * CM_INET_DGRAM (UDP)
1205 * Ret: ROK - successful
1214 #ifdef IPV6_SUPPORTED
1217 uint8_t type, /* socket type */
1218 CmInetFd *sockFd, /* socket file descriptor */
1219 uint8_t protocol, /* protocol value */
1220 uint8_t domain /* domain */
1225 uint8_t type, /* socket type */
1226 CmInetFd *sockFd, /* socket file descriptor */
1227 uint8_t protocol /* protocol value */
1229 #endif /* IPV6_SUPPORTED */
1230 #else /* CM_INET2 */
1233 uint8_t type, /* socket type */
1234 CmInetFd *sockFd /* socket file descriptor */
1236 #endif /* CM_INET2 */
1238 S32 ret; /* temporary return value */
1242 #if (defined(WIN32) && defined(WIN2K))
1245 #endif /* WIN2K && WIN32 */
1248 #if (defined(WIN32) && defined(WIN2K))
1250 bNewBehavior = FALSE;
1251 #endif /* WIN32 && WIN2K */
1255 #ifdef IPV6_SUPPORTED
1256 sockFd->fd = socket(domain, type, protocol);
1258 sockFd->fd = socket(AF_INET, type, protocol);
1259 #endif /* IPV6_SUPPORTED */
1260 #else /* CM_INET2 */
1261 sockFd->fd = socket(AF_INET, type, 0);
1262 #endif /* CM_INET2 */
1263 if (CM_INET_INV_SOCK_FD(sockFd))
1267 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1268 /* cm_inet_c_001.main_62:Warning fix */
1269 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%ld)\n",
1270 INET_ERR_CODE, sockFd->fd);
1271 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1273 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSocket() Failed : errno(%d), sockFd->fd(%d)\n",
1274 INET_ERR_CODE, sockFd->fd);
1275 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET001, 0, prntBuf);
1276 #endif /*ALIGN_64BIT */
1277 #endif /* CMINETDBG */
1278 /* Set sockFd->fd to invalid socket */
1279 sockFd->fd = CM_INET_INV_SOCKFD;
1283 /* set socket type */
1284 sockFd->type = type;
1286 /* set socket protocol type (IPv4/IPv6) */
1287 #ifdef IPV6_SUPPORTED
1288 sockFd->protType = domain;
1289 #endif /* IPV6_SUPPORTED */
1291 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1293 if (protocol != IPPROTO_SCTP)
1296 /* set default options */
1297 optVal = CM_INET_OPT_DISABLE;
1298 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1301 ret = cmInetClose(sockFd);
1306 #ifndef CMINET_BSDCOMPAT
1307 optVal = CM_INET_OPT_ENABLE;
1308 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BSD_COMPAT, (Ptr)&optVal);
1311 ret = cmInetClose(sockFd);
1314 #endif /* CMINET_BSDCOMPAT */
1315 #endif /* SS_LINUX */
1317 #if (defined(WIN32) && defined(WIN2K))
1318 if(type == CM_INET_DGRAM)
1320 ret = WSAIoctl(sockFd->fd, SIO_UDP_CONNRESET, &bNewBehavior,
1321 sizeof(bNewBehavior), NULLP, 0, &bytesReturned,
1327 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1328 /* cm_inet_c_001.main_62:Warning fix */
1329 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%ld)\n",
1330 INET_ERR_CODE, sockFd->fd);
1331 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1333 /* cm_inet_c_001.main_62:Warning fix */
1334 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "WSAIoctl() Failed : error(%d), sockFd->fd(%d)\n",
1335 INET_ERR_CODE, sockFd->fd);
1336 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET002, 0, prntBuf);
1337 #endif /*ALIGN_64BIT*/
1338 #endif /* CMINETDBG */
1339 ret = cmInetClose(sockFd);
1343 #endif /* WIN2K && WIN32 */
1344 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1347 #ifdef CM_LKSCTP_NONBLOCK
1350 /* cm_inet_c_001.main_47:if non-blocking SCTP socket compile time
1351 * * flag is set then even for kernel SCTP make the socket
1354 optVal = CM_INET_OPT_DISABLE;
1355 ret = cmInetSetOpt(sockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, (Ptr)&optVal);
1358 ret = cmInetClose(sockFd);
1362 #endif /* CM_LKSCTP_NONBLOCK ends */
1365 } /* end of cmInetSocket */
1372 * Desc: Binds a socket file descriptor to a local Internet
1375 * Ret: ROK - successful
1386 CmInetFd *sockFd, /* socket file descriptor */
1387 CmInetAddr *myAddr /* locale Internet address/port */
1390 S32 ret; /* temporary return value */
1391 struct sockaddr_in srcAddr; /* local Internet address/port */
1392 #ifdef IPV6_SUPPORTED
1393 struct sockaddr_in6 srcAddr6; /* local IPV6 address/port */
1396 #endif /* CMINETDBG */
1397 #endif /* IPV6_SUPPORTED */
1398 uint32_t sizeOfAddr; /* sizeof address passed to the bind call */
1399 CmInetSockAddr *sockAddrPtr;
1402 #if (ERRCLASS & ERRCLS_INT_PAR)
1403 /* error check on parameters */
1404 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1409 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1411 #ifdef IPV6_SUPPORTED
1412 if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1414 memset(&srcAddr6, 0, sizeof(srcAddr6));
1415 srcAddr6.sin6_family = AF_INET6;
1416 srcAddr6.sin6_port = CM_INET_HTON_UINT16(myAddr->u.ipv6Addr.port);
1417 CM_INET_COPY_IPV6ADDR(&srcAddr6.sin6_addr,
1418 &myAddr->u.ipv6Addr.ipv6NetAddr);
1419 sizeOfAddr = sizeof(struct sockaddr_in6);
1420 sockAddrPtr = (CmInetSockAddr *)&srcAddr6;
1424 memset(&srcAddr, 0, sizeof(srcAddr));
1425 srcAddr.sin_family = AF_INET;
1426 srcAddr.sin_port = CM_INET_HTON_UINT16(myAddr->u.ipv4Addr.port);
1427 srcAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(myAddr->u.ipv4Addr.address);
1428 sizeOfAddr = sizeof(struct sockaddr_in);
1429 sockAddrPtr = (CmInetSockAddr *)&srcAddr;
1432 memset(&srcAddr, 0, sizeof(srcAddr));
1433 srcAddr.sin_family = AF_INET;
1434 srcAddr.sin_port = CM_INET_HTON_UINT16(myAddr->port);
1435 srcAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(myAddr->address);
1436 sizeOfAddr = sizeof(struct sockaddr_in);
1437 sockAddrPtr = (CmInetSockAddr *)&srcAddr;
1438 #endif /* IPV6_SUPPORTED */
1440 ret = bind(sockFd->fd, sockAddrPtr, sizeOfAddr);
1441 if (ret == INET_ERR)
1444 #ifdef IPV6_SUPPORTED
1445 if (myAddr->type == CM_INET_IPV6ADDR_TYPE)
1446 port = myAddr->u.ipv6Addr.port;
1448 port = myAddr->u.ipv4Addr.port;
1450 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1451 /* cm_inet_c_001.main_62:Warning fix */
1452 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d),"
1453 " port(%d), sockFd->fd(%ld)\n",
1454 INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1455 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1457 /* cm_inet_c_001.main_62:Warning fix */
1458 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addrType(%d),"
1459 " port(%d), sockFd->fd(%d)\n ",
1460 INET_ERR_CODE , myAddr->type, port, sockFd->fd);
1461 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET003, 0, prntBuf);
1462 #endif /*ALIGN_64BIT*/
1465 /* cm_inet_c_001.main_62:Warning fix */
1466 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%lx), port(%d),"
1467 "sockFd->fd(%ld)\n",
1468 INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1469 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1471 /* cm_inet_c_001.main_62:Warning fix */
1472 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetBind() Failed : error(%d), addr(0x%x), port(%d),"
1473 " sockFd->fd(%d)\n",
1474 INET_ERR_CODE , myAddr->address, myAddr->port, sockFd->fd);
1475 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET004, 0, prntBuf);
1476 #endif /*ALIGN_64BIT*/
1477 #endif /* IPV6_SUPPORTED */
1478 #endif /* CMINETDBG */
1483 } /* end of cmInetBind */
1485 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
1486 /* cm_inet_c_001.main_51 Added Ipv6 support to KSCtP implementation */
1490 * Fun: cmInetSctpBindx
1492 * Desc: Binds a SCTP socket file descriptor to local Internet
1495 * Ret: ROK - successful
1505 CmInetFd *sockFd, /* socket file descriptor */
1506 CmInetNetAddrLst *addrLst, /* local Internet address list */
1507 uint16_t port /* port number */
1510 S32 ret; /* temporary return value */
1513 uint32_t ipv4_array_size = 0;
1514 struct sockaddr_in addrs[CM_INET_NUM_NET_ADDR];
1515 #ifndef IPV6_SUPPORTED
1516 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1518 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1519 #endif /* IPV6_SUPPORTED */
1522 Data *tempAddrPtr = NULLP;
1524 uint32_t addresses_array_size = 0;
1525 #ifdef IPV6_SUPPORTED
1527 S8 *addrString = NULLP;
1528 uint32_t addrLen = 0;
1529 S8 ipv4Format[23] = "::ffff:";
1530 #endif /* SUN_KSCTP */
1532 uint32_t ipv6_array_size = 0;
1533 struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1534 #endif /* IPV6_SUPPORTED */
1535 struct sockaddr *sockAddrPtr = NULLP;
1536 uint32_t sockAddrLen = 0;
1538 #if (ERRCLASS & ERRCLS_INT_PAR)
1539 /* error check on parameters */
1540 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1546 if(addrLst->count > CM_INET_NUM_NET_ADDR)
1550 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1551 /* cm_inet_c_001.main_62:Warning fix */
1552 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1553 " sockFd->fd(%ld)\n",
1554 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1555 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);
1557 /* cm_inet_c_001.main_62:Warning fix */
1558 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1559 " sockFd->fd(%d)\n",
1560 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1561 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET005, 0, prntBuf);
1562 #endif /*ALIGN_64BIT*/
1563 #endif /* CMINETDBG */
1566 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1568 memset(&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1569 #ifdef IPV6_SUPPORTED
1570 memset(&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1571 #endif /* IPV6_SUPPORTED */
1573 for (idx = 0; idx < addrLst->count; idx++)
1575 #ifdef IPV6_SUPPORTED
1576 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1578 ipv6_array_size += sizeof(struct sockaddr_in6);
1579 addresses_array_size += sizeof(struct sockaddr_in6);
1580 if (sockFd->protType == AF_INET)
1584 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1585 /* cm_inet_c_001.main_62:Warning fix */
1586 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1587 " sockFd->fd(%ld)\n", sockFd->fd);
1588 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1590 /* cm_inet_c_001.main_62:Warning fix */
1591 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1592 " sockFd->fd(%d)\n", sockFd->fd);
1593 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET057, 0, prntBuf);
1594 #endif /*ALIGN_64BIT*/
1595 #endif /* CMINETDBG */
1599 addrs6[idx6].sin6_family = AF_INET6;
1600 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1601 CM_INET_COPY_IPV6ADDR((addrs6[idx6].sin6_addr.s6_addr), &(addrLst->addrs[idx].u.ipv6NetAddr));
1608 ipv6_array_size += sizeof(struct sockaddr_in6);
1609 addresses_array_size += sizeof(struct sockaddr_in6);
1610 if (sockFd->protType == AF_INET)
1614 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1615 /* cm_inet_c_001.main_62:Warning fix */
1616 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1617 " sockFd->fd(%ld)\n", sockFd->fd);
1618 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1620 /* cm_inet_c_001.main_62:Warning fix */
1621 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't bind IPV6 address on IPV4 socket,"
1622 " sockFd->fd(%d)\n", sockFd->fd);
1623 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET058, 0, prntBuf);
1624 #endif /*ALIGN_64BIT*/
1625 #endif /* CMINETDBG */
1629 addrs6[idx6].sin6_family = AF_INET6;
1630 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1631 addrLst->addrs[idx].u.ipv4NetAddr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
1632 cmInetNtoa(addrLst->addrs[idx].u.ipv4NetAddr, &addrString);
1633 addrLen = cmStrlen((uint8_t*)addrString);
1634 memcpy((ipv4Format+7), addrString, addrLen);
1635 ipv4Format[7+addrLen] = '\0';
1636 cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
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 /* SUN_KSCTP */
1648 ipv4_array_size += sizeof(struct sockaddr_in);
1649 addresses_array_size += sizeof(struct sockaddr_in);
1650 addrs[idx4].sin_family = AF_INET;
1651 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1652 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
1654 #endif /* IPV6_SUPPORTED */
1658 if(ipv4_array_size > 0)
1660 sockAddrPtr = (struct sockaddr*)address_array;
1661 sockAddrLen = sizeof(struct sockaddr_in);
1662 memcpy(address_array, addrs, ipv4_array_size);
1664 #ifdef IPV6_SUPPORTED
1667 sockAddrPtr = (struct sockaddr*)address_array;
1668 sockAddrLen = sizeof(struct sockaddr_in6);
1671 if(ipv6_array_size > 0)
1673 memcpy((address_array + ipv4_array_size), addrs6, ipv6_array_size);
1675 #endif /* IPV6_SUPPORTED */
1679 ret = bind(sockFd->fd, sockAddrPtr, sockAddrLen);
1680 if (ret == INET_ERR)
1685 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1686 /* cm_inet_c_001.main_62:Warning fix */
1687 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1688 " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1689 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1691 /* cm_inet_c_001.main_62:Warning fix */
1692 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1693 " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1694 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET006, 0, prntBuf);
1695 #endif /*ALIGN_64BIT*/
1696 #endif /* CMINETDBG */
1700 if (addrLst->count > 1)
1702 if(((struct sockaddr*)address_array)->sa_family == AF_INET)
1704 tempAddrPtr = address_array + (sizeof(struct sockaddr_in));
1706 else if(((struct sockaddr*)address_array)->sa_family == AF_INET6)
1708 tempAddrPtr = address_array + (sizeof(struct sockaddr_in6));
1714 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1715 /* cm_inet_c_001.main_62:Warning fix */
1716 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1717 " sockFd->fd(%ld), error(%d), port(%d)\n ",
1718 INET_ERR_CODE, port, sockFd->fd);
1719 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1721 /* cm_inet_c_001.main_62:Warning fix */
1722 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx(Invalid address Type) failed:"
1723 " sockFd->fd(%d), error(%d), port(%d)\n ",
1724 INET_ERR_CODE, port, sockFd->fd);
1725 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET059, 0, prntBuf);
1726 #endif /*ALIGN_64BIT*/
1727 #endif /* CMINETDBG */
1731 ret = sctp_bindx(sockFd->fd, (Void*)tempAddrPtr, addrLst->count - 1, SCTP_BINDX_ADD_ADDR);
1735 ret = sctp_bindx(sockFd->fd, (struct sockaddr*)address_array, addrLst->count, SCTP_BINDX_ADD_ADDR);
1736 UNUSED(sockAddrPtr);
1737 UNUSED(sockAddrLen);
1739 if (ret == INET_ERR)
1743 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1744 /* cm_inet_c_001.main_62:Warning fix */
1745 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1746 " sockFd->fd(%ld)\n",INET_ERR_CODE, port, sockFd->fd);
1747 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1749 /* cm_inet_c_001.main_62:Warning fix */
1750 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpBindx() Failed : error(%d), port(%d),"
1751 " sockFd->fd(%d)\n",INET_ERR_CODE, port, sockFd->fd);
1752 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET007, 0, prntBuf);
1753 #endif /*ALIGN_64BIT*/
1754 #endif /* CMINETDBG */
1763 * Fun: cmInetSctpConnectx
1765 * Desc: Establishes a sctp connection with remote addresses
1767 * Ret: ROK - successful
1775 S16 cmInetSctpConnectx
1777 CmInetFd *sockFd, /* socket file descriptor */
1778 CmInetNetAddr *primAddr, /* primary destination Internet address */
1779 CmInetNetAddrLst *addrLst, /* destination Internet address list */
1780 uint16_t port /* port number */
1785 /* cm_inet_c_001.main_46: Removed SS_LINUX flag */
1788 /* cm_inet_c_001.main_64: New variable used as an argument for sctp_connectx */
1789 #ifdef SCTP_CONNECTX_NEW
1790 uint32_t assocId = 0;
1792 uint32_t addresses_array_size = 0;
1794 struct sockaddr_in addrs[CM_INET_NUM_NET_ADDR];
1795 uint32_t ipv4_array_size = 0;
1797 #ifndef IPV6_SUPPORTED
1798 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in))];
1800 Data address_array[(CM_INET_NUM_NET_ADDR * sizeof(struct sockaddr_in6))];
1801 #endif /* IPV6_SUPPORTED */
1803 #ifdef IPV6_SUPPORTED
1805 S8 *addrString = NULLP;
1806 uint32_t addrLen = 0;
1807 S8 ipv4Format[23] = "::ffff:";
1808 CmInetIpAddr ipv4NetAddr;
1809 #endif /* SUN_KSCTP */
1811 struct sockaddr_in6 addrs6[CM_INET_NUM_NET_ADDR];
1812 uint32_t ipv6_array_size = 0;
1813 #endif /* IPV6_SUPPORTED */
1815 uint32_t sockAddrLen = 0;
1816 #endif /* sockAddrLen */
1819 CmInetSockAddr *sockAddrPtr = NULLP;
1820 #endif /* SS_LINUX */
1821 #if (ERRCLASS & ERRCLS_INT_PAR)
1822 /* error check on parameters */
1823 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
1824 (primAddr == NULLP))
1828 /* cm_inet_c_001.main_58 : Added check for addrLst to fix klockwork issue */
1829 if (addrLst == NULLP)
1833 /* cm_inet_c_001.main_46: Included check for no of address aginst max */
1834 if( addrLst->count > CM_INET_NUM_NET_ADDR )
1838 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1839 /* cm_inet_c_001.main_62:Warning fix */
1840 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1841 " sockFd->fd(%ld)\n",
1842 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1843 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1845 /* cm_inet_c_001.main_62:Warning fix */
1846 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "No of address(%d) is greater than Max(%d),"
1847 " sockFd->fd(%d)\n",
1848 addrLst->count, CM_INET_NUM_NET_ADDR, sockFd->fd);
1849 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET060, 0, prntBuf);
1850 #endif /*ALIGN_64BIT*/
1851 #endif /* CMINETDBG */
1854 #endif /* ERRCLASS & ERRCLS_INT_PAR */
1857 memset(&addrs, 0, (sizeof(struct sockaddr_in) * CM_INET_NUM_NET_ADDR));
1858 #ifdef IPV6_SUPPORTED
1859 memset(&addrs6, 0, (sizeof(struct sockaddr_in6) * CM_INET_NUM_NET_ADDR));
1860 #endif /* IPV6_SUPPORTED */
1864 #ifdef IPV6_SUPPORTED
1865 if (primAddr->type == CM_INET_IPV6ADDR_TYPE)
1867 if (sockFd->protType == AF_INET)
1871 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1872 /* cm_inet_c_001.main_62:Warning fix */
1873 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1874 " sockFd->fd(%ld)\n", sockFd->fd);
1875 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
1877 /* cm_inet_c_001.main_62:Warning fix */
1878 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1879 " sockFd->fd(%d)\n", sockFd->fd);
1880 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET008, 0, prntBuf);
1881 #endif /*ALIGN_64BIT*/
1882 #endif /* CMINETDBG */
1886 addrs6[idx6].sin6_family = AF_INET6;
1887 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1888 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr), &(primAddr->u.ipv6NetAddr));
1889 addresses_array_size += sizeof(struct sockaddr_in6);
1890 ipv6_array_size += sizeof(struct sockaddr_in6);
1896 if (sockFd->protType == AF_INET)
1900 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
1901 /* cm_inet_c_001.main_62:Warning fix */
1902 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
1903 " sockFd->fd(%ld)\n", sockFd->fd);
1904 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
1906 /* cm_inet_c_001.main_62:Warning fix */
1907 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
1908 " sockFd->fd(%d)\n", sockFd->fd);
1909 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET061, 0, prntBuf);
1910 #endif /*ALIGN_64BIT*/
1911 #endif /* CMINETDBG */
1914 addrs6[idx6].sin6_family = AF_INET6;
1915 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1916 ipv4NetAddr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1917 cmInetNtoa(ipv4NetAddr, &addrString);
1918 addrLen = cmStrlen((uint8_t*)addrString);
1919 memcpy((ipv4Format+7), addrString, addrLen);
1920 ipv4Format[7+addrLen] = '\0';
1921 cmInetPton6((CmInetIpAddr6*)&(addrs6[idx6].sin6_addr), ipv4Format);
1922 addresses_array_size += sizeof(struct sockaddr_in6);
1923 ipv6_array_size += sizeof(struct sockaddr_in6);
1926 addrs[idx4].sin_family = AF_INET;
1927 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1928 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1929 addresses_array_size += sizeof(struct sockaddr_in);
1930 ipv4_array_size += sizeof(struct sockaddr_in);
1935 addrs[idx4].sin_family = AF_INET;
1936 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
1937 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(primAddr->u.ipv4NetAddr);
1938 addresses_array_size += sizeof(struct sockaddr_in);
1939 ipv4_array_size += sizeof(struct sockaddr_in);
1941 #endif /* IPV6_SUPPORTED */
1945 /* cm_inet_c_001.main_46: Moved the SS_LINUX flag down,
1946 * copy addresses in Solaris also */
1947 if (addrLst != NULLP)
1949 for (idx = 0; idx < addrLst->count; idx++)
1952 /* cm_inet_c_001.main_46: Don't include the primary address
1953 * if its prersent in list */
1954 if ( addrLst->addrs[idx].type == CM_INET_IPV4ADDR_TYPE )
1956 if ( addrLst->addrs[idx].u.ipv4NetAddr == primAddr->u.ipv4NetAddr )
1961 #ifdef IPV6_SUPPORTED
1962 else if ( addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE )
1964 if (( cmMemcmp(addrLst->addrs[idx].u.ipv6NetAddr,
1965 primAddr->u.ipv6NetAddr, sizeof(CmInetIpAddr6) )) == 0 )
1971 if (addrLst->addrs[idx].type == CM_INET_IPV6ADDR_TYPE)
1973 if (sockFd->protType == AF_INET)
1977 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
1978 /* cm_inet_c_001.main_62:Warning fix */
1979 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1980 " sockFd->fd(%ld)\n", sockFd->fd);
1981 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
1983 /* cm_inet_c_001.main_62:Warning fix */
1984 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't connect to IPV6 address through IPV4 socket,"
1985 " sockFd->fd(%d)\n", sockFd->fd);
1986 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET009, 0, prntBuf);
1987 #endif /*ALIGN_64BIT*/
1988 #endif /* CMINETDBG */
1992 addrs6[idx6].sin6_family = AF_INET6;
1993 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
1994 CM_INET_COPY_IPV6ADDR(&(addrs6[idx6].sin6_addr.s6_addr),
1995 &(addrLst->addrs[idx].u.ipv6NetAddr));
1996 addresses_array_size += sizeof(struct sockaddr_in6);
1997 ipv6_array_size += sizeof(struct sockaddr_in6);
2003 if (sockFd->protType == AF_INET)
2007 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2008 /* cm_inet_c_001.main_62:Warning fix */
2009 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2010 " sockFd->fd(%ld)\n", sockFd->fd);
2011 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2013 /* cm_inet_c_001.main_62:Warning fix */
2014 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4 socket,"
2015 " sockFd->fd(%d)\n", sockFd->fd);
2016 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET062, 0, prntBuf);
2017 #endif /*ALIGN_64BIT*/
2018 #endif /* CMINETDBG */
2021 addrs6[idx6].sin6_family = AF_INET6;
2022 addrs6[idx6].sin6_port = CM_INET_HTON_UINT16(port);
2023 ipv4NetAddr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2024 cmInetNtoa(ipv4NetAddr, &addrString);
2025 addrLen = cmStrlen((uint8_t*)addrString);
2026 memcpy((ipv4Format+7), addrString, addrLen);
2027 ipv4Format[7+addrLen] = '\0';
2028 cmInetPton6((CmInetIpAddr6*)(addrs6[idx6].sin6_addr.s6_addr), ipv4Format);
2029 addresses_array_size += sizeof(struct sockaddr_in6);
2030 ipv6_array_size += sizeof(struct sockaddr_in6);
2033 addrs[idx4].sin_family = AF_INET;
2034 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
2035 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2036 addresses_array_size += sizeof(struct sockaddr_in);
2037 ipv4_array_size += sizeof(struct sockaddr_in);
2039 #endif /* SUN_KSCTP */
2042 addrs[idx4].sin_family = AF_INET;
2043 addrs[idx4].sin_port = CM_INET_HTON_UINT16(port);
2044 addrs[idx4].sin_addr.s_addr = CM_INET_HTON_UINT32(addrLst->addrs[idx].u.ipv4NetAddr);
2045 addresses_array_size += sizeof(struct sockaddr_in);
2046 ipv4_array_size += sizeof(struct sockaddr_in);
2048 #endif /* IPV6_SUPPORTED */
2049 /*cm_inet_c_001.main_39 */
2054 /* cm_inet_c_001.main_46: Moved SS_LINUX flag to here */
2056 /*cm_inet_c_001.main_58 : Added check array_size to fix klockwork issue */
2057 if((ipv4_array_size > 0) && (ipv4_array_size <= (CM_INET_NUM_NET_ADDR * \
2058 sizeof(struct sockaddr_in))))
2060 memcpy(address_array, &addrs[0], ipv4_array_size);
2067 #ifdef IPV6_SUPPORTED
2068 if((ipv6_array_size > 0) && (ipv6_array_size <= (CM_INET_NUM_NET_ADDR * \
2069 sizeof(struct sockaddr_in))))
2071 memcpy((address_array + ipv4_array_size), addrs6, ipv6_array_size);
2077 #endif /* IPV6_SUPPORTED */
2079 /* cm_inet_c_001.main_64: Support for new definition of sctp_connectx */
2080 #ifndef SCTP_CONNECTX_NEW
2081 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt);
2083 ret = sctp_connectx(sockFd->fd, (struct sockaddr*)address_array, cnt, (sctp_assoc_t *)&assocId);
2088 /* cm_inet_c_001.main_46: Use next provided address to connect if
2089 * first one fails */
2091 #ifdef CMINET_SUN_CONNECTX
2093 #ifdef IPV6_SUPPORTED
2095 #endif /* IPV6_SUPPORTED */
2096 for (idx = 0; idx < cnt; idx++)
2098 if( addrs[idx4].sin_family == AF_INET)
2100 sockAddrPtr = (CmInetSockAddr *)&addrs[idx4];
2101 sockAddrLen = sizeof(struct sockaddr_in);
2104 #ifdef IPV6_SUPPORTED
2107 sockAddrPtr = (CmInetSockAddr *)&addrs6[idx6];
2108 sockAddrLen = sizeof(struct sockaddr_in6);
2111 #endif/* IPV6_SUPPORTED */
2113 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2115 if ( ret != INET_ERR )
2121 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2122 /* cm_inet_c_001.main_62:Warning fix */
2123 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2124 " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2125 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2127 /* cm_inet_c_001.main_62:Warning fix */
2128 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpConnectx() failed:error(%d), port(0x%1x),"
2129 " sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2130 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET063, 0, prntBuf);
2131 #endif /*ALIGN_64BIT*/
2132 #endif /* CMINETDBG */
2137 if( addrs[0].sin_family == AF_INET)
2139 sockAddrPtr = (CmInetSockAddr*)&addrs[0];
2140 sockAddrLen = sizeof(struct sockaddr_in);
2143 #ifdef IPV6_SUPPORTED
2146 sockAddrPtr = (CmInetSockAddr*)&addrs6[0];
2147 sockAddrLen = sizeof(struct sockaddr_in6);
2150 #endif/* IPV6_SUPPORTED */
2152 ret = connect(sockFd->fd, sockAddrPtr, sockAddrLen);
2154 #endif /* CMINET_SUN_CONNECTX */
2155 #endif /* SS_LINUX */
2157 if (ret == INET_ERR)
2161 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2162 /* cm_inet_c_001.main_62:Warning fix */
2163 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "CmInetSctpConnectx() Failed : error(%d), port(0x%1x),"
2164 " sockFd->fd(%ld)\n", INET_ERR_CODE, port, sockFd->fd);
2165 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET010, 0, prntBuf);
2167 DU_LOG("\nCmInetSctpConnectx() Failed : error(%d), port(0x%1x),\
2168 sockFd->fd(%d)\n", INET_ERR_CODE, port, sockFd->fd);
2169 #endif /*ALIGN_64BIT*/
2170 #endif /* CMINETDBG */
2172 switch (INET_ERR_CODE)
2174 /* non-blocking: connection is in progress */
2175 case ERR_INPROGRESS:
2176 return (RINPROGRESS);
2180 * non-blocking: connection is established
2181 * blocking : connection is already established
2187 /* resource temporarily unavailable */
2188 case ERR_WOULDBLOCK:
2192 /* non-blocking: connection is in progress */
2194 return (RINPROGRESS);
2198 return (RINPROGRESS);
2201 /* Check for connection refused and timeout errors */
2202 case ERR_CONNREFUSED:
2207 /* it is a real error */
2219 * Fun: cmInetSctpPeelOff
2221 * Desc: Branches an existing sctp association off to a seperate socket
2223 * Ret: ROK - successful
2231 S16 cmInetSctpPeelOff
2233 CmInetFd *sockFd, /* socket file descriptor */
2234 uint32_t assocId, /* association id */
2235 CmInetFdType *assocFd /* association fd */
2240 #if (ERRCLASS & ERRCLS_INT_PAR)
2241 /* error check on parameters */
2242 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) || (assocFd == NULLP))
2246 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2249 ret = sctp_peeloff(sockFd->fd, assocId);
2250 if (ret == INET_ERR)
2254 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2255 /* cm_inet_c_001.main_62:Warning fix */
2256 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%ld),"
2257 " sockFd->fd(%ld)\n", INET_ERR_CODE, assocId, sockFd->fd);
2258 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2260 /* cm_inet_c_001.main_55: Fix for compilation warning */
2261 /* cm_inet_c_001.main_62:Warning fix */
2262 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpPeelOff() Failed : error(%d) assocId(%d),"
2263 " sockFd->fd(%d)\n", INET_ERR_CODE, assocId, sockFd->fd);
2264 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET011, 0, prntBuf);
2265 #endif /*ALIGN_64BIT*/
2266 #endif /* CMINETDBG */
2278 * Fun: cmInetSctpSendMsg
2280 * Desc: invokes sctp socket API to send message to the remote addresses
2282 * Ret: ROK - successful
2290 S16 cmInetSctpSendMsg
2292 CmInetFd *sockFd, /* socket file descriptor */
2293 CmInetNetAddr *dstAddr, /* destination Internet address/port */
2294 uint16_t port, /* destination port no. */
2295 CmInetMemInfo *info, /* buffer allocation info */
2296 Buffer *mBuf, /* buffer structure to send */
2297 MsgLen *len, /* number of actually sent octets */
2298 uint16_t strmId, /* sctp stream identifier */
2299 Bool unorderFlg, /* flag to enable the unordered delivery */
2300 uint16_t ttl, /* time to live */
2301 uint32_t ppId, /* opaque value passed along with the message */
2302 uint32_t context /* value to be passed back, if error occurs */
2306 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2307 MsgLen msgLen = 0; /* message length */
2308 MsgLen bufLen = 0; /* send buffer length */
2309 Data *sendBuf = NULLP; /* plain send buffer */
2311 CmInetSockAddr *sockAddrPtr = NULLP;
2312 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2313 MsgLen sockAddrLen = 0;
2314 struct sockaddr_in addr;
2315 #ifdef IPV6_SUPPORTED
2317 S8 *addrString = NULLP;
2318 uint32_t addrLen = 0;
2319 S8 ipv4Format[23] = "::ffff:";
2320 CmInetIpAddr ipv4NetAddr;
2321 #endif /* SUN_KSCTP */
2322 struct sockaddr_in6 addr6;
2323 #endif /* IPV6_SUPPORTED */
2325 #if (ERRCLASS & ERRCLS_INT_PAR)
2326 /* error check on parameters */
2327 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd)
2328 || (info == NULLP) || (mBuf == NULLP) || (len == NULLP))
2332 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2335 memset(&addr, 0, sizeof(struct sockaddr_in));
2336 #ifdef IPV6_SUPPORTED
2337 memset(&addr6, 0, sizeof(struct sockaddr_in6));
2338 #endif /* IPV6_SUPPORTED */
2340 /* copy message to a flat buffer */
2341 ret = SFndLenMsg(mBuf, &bufLen);
2346 /* max message length is limited to control the memory usage */
2347 /* casting bufLen to avoid warnings */
2348 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
2352 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
2357 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
2358 if ((ret != ROK) || (msgLen != bufLen))
2360 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2364 if ( dstAddr != NULLP)
2366 #ifdef IPV6_SUPPORTED
2367 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
2369 if (sockFd->protType == AF_INET)
2371 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2374 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2375 /* cm_inet_c_001.main_62:Warning fix */
2376 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2377 " IPV4 socket, sockFd->fd(%ld)\n", sockFd->fd);
2378 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2380 /* cm_inet_c_001.main_62:Warning fix */
2381 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2382 " IPV4 socket, sockFd->fd(%d)\n", sockFd->fd);
2383 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2384 #endif /*ALIGN_64BIT*/
2385 #endif /* CMINETDBG */
2389 addr6.sin6_family = AF_INET6;
2390 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2391 CM_INET_COPY_IPV6ADDR(&addr6.sin6_addr.s6_addr, &dstAddr->u.ipv6NetAddr);
2392 sockAddrLen = sizeof(struct sockaddr_in6);
2393 sockAddrPtr = (CmInetSockAddr*)&addr6;
2399 if (sockFd->protType == AF_INET)
2403 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2404 /* cm_inet_c_001.main_62:Warning fix */
2405 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2406 " socket, sockFd->fd(%ld)\n", sockFd->fd);
2407 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2409 /* cm_inet_c_001.main_62:Warning fix */
2410 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2411 " socket, sockFd->fd(%d)\n", sockFd->fd);
2412 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2413 #endif /*ALIGN_64BIT*/
2414 #endif /* CMINETDBG */
2417 addr6.sin6_family = AF_INET6;
2418 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2419 ipv4NetAddr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2420 cmInetNtoa(ipv4NetAddr, &addrString);
2421 addrLen = cmStrlen((uint8_t*)addrString);
2422 memcpy((ipv4Format+7), addrString, addrLen);
2423 ipv4Format[7+addrLen] = '\0';
2424 cmInetPton6((CmInetIpAddr6*)(addr6.sin6_addr.s6_addr), ipv4Format);
2425 sockAddrLen = sizeof(struct sockaddr_in6);
2426 sockAddrPtr = (CmInetSockAddr*)&addr6;
2428 addr.sin_family = AF_INET;
2429 addr.sin_port = CM_INET_HTON_UINT16(port);
2430 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2431 sockAddrLen = sizeof(struct sockaddr_in);
2432 sockAddrPtr = (CmInetSockAddr*)&addr;
2433 #endif /* SUN_KSCTP */
2436 addr.sin_family = AF_INET;
2437 addr.sin_port = CM_INET_HTON_UINT16(port);
2438 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2439 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2440 sockAddrLen = (MsgLen)sizeof(struct sockaddr_in);
2441 sockAddrPtr = (CmInetSockAddr*)&addr;
2442 #endif /* IPV6_SUPPORTED */
2449 sockAddrPtr = (CmInetSockAddr*)&addr;
2451 /* cm_inet_c_001.main_58 : initialized sockAddrLen properly */
2452 #ifdef IPV6_SUPPORTED
2453 sockAddrLen = sizeof(struct sockaddr_in6);
2455 sockAddrLen = sizeof(struct sockaddr_in);
2459 /* Not validating the address, whether addr is a valid address or not */
2464 if (unorderFlg == TRUE)
2467 flags |= MSG_UNORDERED;
2470 flags |= SCTP_UNORDERED;
2473 /*cm_inet_c_001.main_54: converting ppid to network*/
2474 ppId = CM_INET_HTON_UINT32(ppId);
2475 ret = sctp_sendmsg(sockFd->fd, (Void*)sendBuf, bufLen,
2476 (struct sockaddr*)sockAddrPtr, (size_t)sockAddrLen,
2477 ppId, flags, strmId, ttl, context);
2478 if (ret == INET_ERR)
2480 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2483 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2484 /* cm_inet_c_001.main_62:Warning fix */
2485 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%ld),"
2486 " strmId(%u),sockFd->fd(%ld)\n",
2487 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2488 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2490 /* cm_inet_c_001.main_55: Fix for compilation warning */
2491 /* cm_inet_c_001.main_62:Warning fix */
2492 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%d),"
2493 " strmId(%u),sockFd->fd(%d)\n",
2494 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2495 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2496 #endif /*ALIGN_64BIT*/
2497 #endif /* CMINETDBG */
2499 if ((INET_ERR_CODE == ERR_AGAIN) || (INET_ERR_CODE == ERR_WOULDBLOCK))
2500 return (RWOULDBLOCK);
2501 else if (INET_ERR_CODE == ERR_PIPE)
2507 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2511 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2518 * Fun: cmInetSctpRecvMsg
2520 * Desc: invokes sctp API to get the message received at sctp socket
2522 * Ret: ROK - successful
2530 S16 cmInetSctpRecvMsg
2532 CmInetFd *sockFd, /* socket file descriptor */
2533 CmInetNetAddr *srcAddr, /* source Internet address/port */
2534 uint16_t *port, /* source port no. */
2535 CmInetMemInfo *meminfo, /* buffer allocation info */
2536 Buffer **mBuf, /* buffer structure received */
2537 MsgLen *len, /* number of octets received */
2538 CmInetSctpSndRcvInfo *sinfo, /* sctp send-receive info */
2539 uint32_t *flag, /* flags */
2540 CmInetSctpNotification *ntfy /* notification parameters */
2545 struct sctp_sndrcvinfo info;
2546 struct sockaddr_storage addr;
2547 struct sockaddr_in *pAddr = NULLP;
2548 #ifdef IPV6_SUPPORTED
2549 struct sockaddr_in6 *pAddr6 = NULLP;
2552 Data *recvbuf = NULLP;
2554 union sctp_notification *sctpNtfy = NULLP;
2555 /* cm_inet_c_001.main_46: Defined new variable to store length of data */
2558 #endif /* SS_LINUX */
2560 #if (ERRCLASS & ERRCLS_INT_PAR)
2561 /* error check on parameters */
2562 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
2563 (srcAddr == NULLP) || (port == NULLP) || (meminfo == NULLP) ||
2564 (mBuf == NULLP) || (len == NULLP) || (sinfo == NULLP) || (flag == NULLP))
2568 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2573 memset(ntfy, 0, sizeof(CmInetSctpNotification));
2575 buflen = CM_INET_MAX_MSG_LEN;
2577 /* allocate flat receive buffer */
2578 ret = SGetSBuf(meminfo->region, meminfo->pool, &recvbuf, buflen);
2582 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2583 /* cm_inet_c_001.main_62:Warning fix */
2584 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failed to allocate memory\n");
2585 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET065, 0, prntBuf);
2586 #endif /* CMINETDBG */
2590 addrlen = sizeof(struct sockaddr_storage);
2592 memset(&addr, 0, sizeof(struct sockaddr_storage));
2593 memset(&info, 0, sizeof(struct sctp_sndrcvinfo));
2595 ret = sctp_recvmsg(sockFd->fd, (Void *)recvbuf, (size_t)buflen,
2596 (struct sockaddr*)&addr, &addrlen, &info,
2598 if (ret == INET_ERR)
2601 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2604 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2605 /* cm_inet_c_001.main_62:Warning fix */
2606 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2607 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
2608 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2610 DU_LOG("\ncmInetSctpRecvMsg() Failed : error(%d), sockFd->fd(%d)", \
2611 INET_ERR_CODE, sockFd->fd);
2612 #endif /*ALIGN_64BIT*/
2613 #endif /* CMINETDBG */
2618 /* save the length of the received message */
2619 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2622 #ifdef IPV6_SUPPORTED
2623 if (addr.ss_family == AF_INET6)
2625 uint8_t ipv4Format[12] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff};
2626 pAddr6 = (struct sockaddr_in6*)&addr;
2627 *port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
2629 if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
2631 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2632 memcpy(&srcAddr->u.ipv4NetAddr, ((pAddr6->sin6_addr.s6_addr) + 12), sizeof(uint32_t));
2633 srcAddr->u.ipv4NetAddr = CM_INET_HTON_uint32_t(srcAddr->u.ipv4NetAddr);
2638 srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2639 CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr);
2644 pAddr = (struct sockaddr_in*)&addr;
2645 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2646 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2647 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2650 pAddr = (struct sockaddr_in*)&addr;
2651 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2652 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2653 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2654 #endif /* IPV6_SUPPORTED */
2656 /* fill sndrcv info */
2657 sinfo->stream = info.sinfo_stream;
2658 sinfo->ssn = info.sinfo_ssn;
2659 sinfo->flags = info.sinfo_flags;
2660 /*cm_inet_c_001.main_54: converting ppid to host*/
2661 sinfo->ppid = CM_INET_NTOH_UINT32(info.sinfo_ppid);
2662 sinfo->context = info.sinfo_context;
2663 sinfo->timetolive = info.sinfo_timetolive;
2664 sinfo->tsn = info.sinfo_tsn;
2665 sinfo->cumtsn = info.sinfo_cumtsn;
2666 sinfo->assocId = info.sinfo_assoc_id;
2668 /* fill message flags */
2670 if ((msgFlags & MSG_EOR) != 0)
2671 *flag |= CM_INET_SCTP_MSG_EOR;
2673 if ((msgFlags & MSG_NOTIFICATION) != 0)
2675 *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2678 sctpNtfy = (union sctp_notification*)recvbuf;
2680 ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2681 ntfy->header.nLen = sctpNtfy->sn_header.sn_length;
2683 switch(sctpNtfy->sn_header.sn_type)
2685 case SCTP_ASSOC_CHANGE:
2686 ntfy->header.nType = CM_INET_SCTP_ASSOC_CHANGE;
2687 switch(sctpNtfy->sn_assoc_change.sac_state)
2690 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2692 case SCTP_COMM_LOST:
2693 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2696 ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2698 case SCTP_SHUTDOWN_COMP:
2699 ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2701 case SCTP_CANT_STR_ASSOC:
2702 ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
2707 ntfy->u.assocChange.error = sctpNtfy->sn_assoc_change.sac_error;
2708 ntfy->u.assocChange.outStreams = sctpNtfy->sn_assoc_change.sac_outbound_streams;
2709 ntfy->u.assocChange.inStreams = sctpNtfy->sn_assoc_change.sac_inbound_streams;
2710 ntfy->u.assocChange.assocId = sctpNtfy->sn_assoc_change.sac_assoc_id;
2712 ntfy->u.assocChange.info = sctpNtfy->sn_assoc_change.sac_info;
2715 case SCTP_PEER_ADDR_CHANGE:
2716 ntfy->header.nType = CM_INET_SCTP_PEER_ADDR_CHANGE;
2717 switch(sctpNtfy->sn_paddr_change.spc_state)
2719 case SCTP_ADDR_AVAILABLE:
2720 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2722 case SCTP_ADDR_UNREACHABLE:
2723 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2725 case SCTP_ADDR_REMOVED:
2726 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2728 case SCTP_ADDR_ADDED:
2729 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2731 case SCTP_ADDR_MADE_PRIM:
2732 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2735 case SCTP_ADDR_CONFIRMED:
2736 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2743 #ifdef IPV6_SUPPORTED
2744 if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
2746 pAddr6 = (struct sockaddr_in6*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2747 ntfy->u.paddrChange.addr.type = CM_INET_IPV6ADDR_TYPE;
2748 CM_INET_COPY_IPV6ADDR(&ntfy->u.paddrChange.addr.u.ipv6NetAddr,
2749 &pAddr6->sin6_addr.s6_addr);
2753 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2754 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2755 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2758 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2759 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2760 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2761 #endif /* IPV6_SUPPORTED */
2763 ntfy->u.paddrChange.error = sctpNtfy->sn_paddr_change.spc_error;
2764 ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2766 case SCTP_REMOTE_ERROR:
2767 ntfy->header.nType = CM_INET_SCTP_REMOTE_ERROR;
2769 ntfy->u.remoteErr.error = sctpNtfy->sn_remote_error.sre_error;
2770 ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2772 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2773 datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2775 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2776 &ntfy->u.remoteErr.data, datlen );
2779 ntfy->u.remoteErr.data = NULLP;
2782 memcpy(ntfy->u.remoteErr.data,\
2783 sctpNtfy->sn_remote_error.sre_data, datlen);
2786 case SCTP_SEND_FAILED:
2787 ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2789 ntfy->u.sndFailed.error = sctpNtfy->sn_send_failed.ssf_error;
2790 ntfy->u.sndFailed.assocId = sctpNtfy->sn_send_failed.ssf_assoc_id;
2792 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2793 datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2795 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2796 &ntfy->u.sndFailed.data, datlen );
2799 ntfy->u.sndFailed.data = NULLP;
2802 memcpy(ntfy->u.sndFailed.data,\
2803 sctpNtfy->sn_send_failed.ssf_data, datlen );
2805 ntfy->u.sndFailed.info.stream = sctpNtfy->sn_send_failed.ssf_info.sinfo_stream;
2806 ntfy->u.sndFailed.info.ssn = sctpNtfy->sn_send_failed.ssf_info.sinfo_ssn;
2807 ntfy->u.sndFailed.info.flags = sctpNtfy->sn_send_failed.ssf_info.sinfo_flags;
2808 ntfy->u.sndFailed.info.ppid = sctpNtfy->sn_send_failed.ssf_info.sinfo_ppid;
2809 ntfy->u.sndFailed.info.context = sctpNtfy->sn_send_failed.ssf_info.sinfo_context;
2810 ntfy->u.sndFailed.info.timetolive = sctpNtfy->sn_send_failed.ssf_info.sinfo_timetolive;
2811 ntfy->u.sndFailed.info.tsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_tsn;
2812 ntfy->u.sndFailed.info.cumtsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_cumtsn;
2813 ntfy->u.sndFailed.info.assocId = sctpNtfy->sn_send_failed.ssf_info.sinfo_assoc_id;
2815 case SCTP_SHUTDOWN_EVENT:
2816 ntfy->header.nType = CM_INET_SCTP_SHUTDOWN_EVENT;
2818 ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2821 case SCTP_ADAPTION_INDICATION :
2824 case SCTP_ADAPTATION_INDICATION :
2826 ntfy->header.nType = CM_INET_SCTP_ADAPTATION_INDICATION;
2829 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
2830 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaption_event.sai_assoc_id;
2833 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
2834 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaptation_event.sai_assoc_id;
2837 case SCTP_PARTIAL_DELIVERY_EVENT:
2838 ntfy->header.nType = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
2840 ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
2841 ntfy->u.pdapiEvt.assocId = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
2849 /* get a message buffer */
2850 ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
2853 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2857 ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
2861 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2867 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2874 * Fun: cmInetSctpGetPAddrs
2876 * Desc: returns the list of peer addresses
2878 * Ret: ROK - successful
2886 S16 cmInetSctpGetPAddrs
2888 CmInetFd *sockFd, /* socket file descriptor */
2889 uint32_t assocId, /* association id */
2890 CmInetNetAddrLst *addrlst /* peer address list */
2893 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2896 uint8_t *byteAddress;
2897 struct sockaddr *peerAddrList;
2898 struct sockaddr_in *pAddr;
2899 #ifdef IPV6_SUPPORTED
2900 struct sockaddr_in6 *pAddr6;
2901 #endif /* IPV6_SUPPORTED */
2904 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
2906 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
2911 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2912 /* cm_inet_c_001.main_62:Warning fix */
2913 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2914 " sockFd->fd(%ld), assocId(%ld)\n",
2915 INET_ERR_CODE, sockFd->fd, assocId);
2916 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2918 /* cm_inet_c_001.main_55: Fix for compilation warning */
2919 /* cm_inet_c_001.main_62:Warning fix */
2920 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2921 " sockFd->fd(%d),assocId(%d)\n",
2922 INET_ERR_CODE, sockFd->fd, assocId);
2923 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2924 #endif /*ALIGN_64BIT*/
2925 #endif /* CMINETDBG */
2930 byteAddress = (uint8_t*)peerAddrList;
2931 for (idx = 0; idx < cnt; idx++)
2933 #ifdef IPV6_SUPPORTED
2935 if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
2937 if (sockFd->protType == AF_INET)
2941 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2942 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2943 " sockFd->fd(%ld)", sockFd->fd);
2944 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2946 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2947 " sockFd->fd(%d)", sockFd->fd);
2948 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2949 #endif /*ALIGN_64BIT*/
2950 #endif /* CMINETDBG */
2952 sctp_freepaddrs(peerAddrList);
2956 pAddr6 = (struct sockaddr_in6*)byteAddress;
2958 addrlst->addrs[idx].type = CM_INET_IPV6ADDR_TYPE;
2959 CM_INET_COPY_IPV6ADDR(&(addrlst->addrs[idx].u.ipv6NetAddr), &(pAddr6->sin6_addr.s6_addr));
2960 byteAddress += sizeof(struct sockaddr_in6);
2964 pAddr = (struct sockaddr_in*)byteAddress;
2965 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2966 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2967 byteAddress += sizeof(struct sockaddr_in);
2970 pAddr = (struct sockaddr_in*)byteAddress;
2971 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2972 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2973 byteAddress += sizeof(struct sockaddr_in);
2974 #endif /* IPV6_SUPPORTED */
2977 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2978 addrlst->count = (uint8_t)cnt;
2980 sctp_freepaddrs(peerAddrList);
2989 * Desc: invokes socket API to retrive specified socket options
2991 * Ret: ROK - successful
3001 CmInetFd *sockFd, /* socket file descriptor */
3002 uint32_t level, /* option level */
3003 uint32_t type, /* option type */
3004 Ptr value /* option value */
3008 struct sctp_status status;
3009 struct sctp_paddrinfo addrInfo;
3010 struct sockaddr_in *pAddr;
3011 #ifdef IPV6_SUPPORTED
3012 struct sockaddr_in6 *pAddr6;
3013 #endif /* IPV6_SUPPORTED */
3014 struct sctp_assocparams assocParams;
3015 /*cm_inet_c_001.main_40 Updated for the support of configurable RTO parameters,
3016 HBeat value Max retransmissions (Init, Path, Association)*/
3017 struct sctp_initmsg initMsg;
3018 struct sctp_rtoinfo rtoInfo;
3019 struct sctp_paddrparams addrParams;
3020 CmInetSctpStatus *pSctpStatus;
3021 CmInetSctpPeerAddrInfo *pPeerAddrInfo;
3022 CmInetSctpInitMsg *pInitMsg;
3023 CmInetSctpAssocParams *pAssocParams;
3024 CmInetSctpRtoInfo *pRtoInfo;
3025 CmInetSctpPeerAddrParams *pPeerAddrParams;
3026 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3030 #if (ERRCLASS & ERRCLS_INT_PAR)
3031 /* error check on parameters */
3032 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3036 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3040 case CM_INET_OPT_SCTP_GET_ASSOC_STA:
3041 pSctpStatus = (CmInetSctpStatus*)value;
3042 memset(&status, 0, sizeof(struct sctp_status));
3043 len = sizeof(status);
3044 status.sstat_assoc_id = pSctpStatus->assocId;
3046 ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
3048 pSctpStatus->rwnd = status.sstat_rwnd;
3049 pSctpStatus->unackdata = status.sstat_unackdata;
3050 pSctpStatus->penddata = status.sstat_penddata;
3051 pSctpStatus->instrms = status.sstat_instrms;
3052 pSctpStatus->outstrms = status.sstat_outstrms;
3053 pSctpStatus->fragPoint = status.sstat_fragmentation_point;
3055 switch (status.sstat_state)
3065 pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3072 pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3078 case SCTPS_COOKIE_WAIT:
3080 case SCTP_COOKIE_WAIT:
3083 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3088 case SCTPS_COOKIE_ECHOED:
3090 case SCTP_COOKIE_ECHOED:
3093 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3098 case SCTPS_ESTABLISHED:
3100 case SCTP_ESTABLISHED:
3103 pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3108 case SCTPS_SHUTDOWN_PENDING:
3110 case SCTP_SHUTDOWN_PENDING:
3113 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3118 case SCTPS_SHUTDOWN_SENT:
3120 case SCTP_SHUTDOWN_SENT:
3123 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3128 case SCTPS_SHUTDOWN_RECEIVED:
3130 case SCTP_SHUTDOWN_RECEIVED:
3133 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3138 case SCTPS_SHUTDOWN_ACK_SENT:
3140 case SCTP_SHUTDOWN_ACK_SENT:
3143 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3154 #ifdef IPV6_SUPPORTED
3155 if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3157 pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3158 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
3160 pSctpStatus->primary.addr.type = CM_INET_IPV6ADDR_TYPE;
3161 CM_INET_COPY_IPV6ADDR(&pSctpStatus->primary.addr.u.ipv6NetAddr,
3162 &pAddr6->sin6_addr.s6_addr);
3166 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3167 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3168 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3169 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3172 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3173 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3174 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3175 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3176 #endif /* IPV6_SUPPORTED */
3178 pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3179 if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3180 pSctpStatus->primary.isActive = TRUE;
3183 pSctpStatus->primary.isActive = FALSE;
3184 pSctpStatus->primary.cwnd = status.sstat_primary.spinfo_cwnd;
3185 pSctpStatus->primary.srtt = status.sstat_primary.spinfo_srtt;
3186 pSctpStatus->primary.rto = status.sstat_primary.spinfo_rto;
3187 pSctpStatus->primary.mtu = status.sstat_primary.spinfo_mtu;
3191 case CM_INET_OPT_SCTP_GET_PADDR_INFO:
3192 pPeerAddrInfo = (CmInetSctpPeerAddrInfo*)value;
3193 memset(&addrInfo, 0, sizeof(struct sctp_paddrinfo));
3194 len = sizeof(addrInfo);
3195 addrInfo.spinfo_assoc_id = pPeerAddrInfo->assocId;
3197 #ifdef IPV6_SUPPORTED
3198 if (pPeerAddrInfo->addr.type == CM_INET_IPV6ADDR_TYPE)
3200 if (sockFd->protType == AF_INET)
3204 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3205 /* cm_inet_c_001.main_62:Warning fix */
3206 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3207 " sockFd->fd(%ld)\n", sockFd->fd);
3208 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3210 /* cm_inet_c_001.main_62:Warning fix */
3211 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3212 " sockFd->fd(%d)\n", sockFd->fd);
3213 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3214 #endif /*ALIGN_64BIT*/
3215 #endif /* CMINETDBG */
3219 pAddr6 = (struct sockaddr_in6*)&(addrInfo.spinfo_address);
3220 pAddr6->sin6_family = AF_INET6;
3221 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3222 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrInfo->addr.u.ipv6NetAddr);
3226 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3227 pAddr->sin_family = AF_INET;
3228 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3229 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3232 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3233 pAddr->sin_family = AF_INET;
3234 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3235 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3236 #endif /* IPV6_SUPPORTED */
3238 /* Not validating the address, whether Addr is a valid address or not */
3240 ret = getsockopt(sockFd->fd, level, SCTP_GET_PEER_ADDR_INFO, &addrInfo, &len);
3242 if (addrInfo.spinfo_state == SCTP_ACTIVE)
3243 pPeerAddrInfo->isActive = TRUE;
3245 pPeerAddrInfo->isActive = FALSE;
3246 pPeerAddrInfo->cwnd = addrInfo.spinfo_cwnd;
3247 pPeerAddrInfo->srtt = addrInfo.spinfo_srtt;
3248 pPeerAddrInfo->rto = addrInfo.spinfo_rto;
3249 pPeerAddrInfo->mtu = addrInfo.spinfo_mtu;
3252 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
3254 pPeerAddrParams = (CmInetSctpPeerAddrParams *)value;
3256 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
3258 addrParams.spp_assoc_id = pPeerAddrParams->assocId;
3260 if (pPeerAddrParams->s.addrPres == TRUE)
3262 #ifdef IPV6_SUPPORTED
3263 if (pPeerAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
3265 if (sockFd->protType == AF_INET)
3269 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3270 /* cm_inet_c_001.main_62:Warning fix */
3271 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%ld)\n",
3273 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3275 /* cm_inet_c_001.main_62:Warning fix */
3276 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%d)\n",
3278 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3279 #endif /*ALIGN_64BIT*/
3280 #endif /* CMINETDBG */
3284 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
3285 pAddr6->sin6_family = AF_INET6;
3286 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3287 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrParams->s.addr.u.ipv6NetAddr);
3291 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3292 pAddr->sin_family = AF_INET;
3293 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3294 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3297 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3298 pAddr->sin_family = AF_INET;
3299 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3300 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3301 #endif /* IPV6_SUPPORTED */
3305 #ifdef IPV6_SUPPORTED
3306 if (sockFd->protType == AF_INET6)
3307 addrParams.spp_address.ss_family = AF_INET6;
3309 addrParams.spp_address.ss_family = AF_INET;
3311 addrParams.spp_address.ss_family = AF_INET;
3315 len = sizeof(addrParams);
3317 ret = getsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, &len);
3318 /* cm_inet_c_001.main_41 : Fixed the Solaris compilation problem */
3321 pPeerAddrParams->hbInterval = addrParams.spp_hbinterval;
3322 pPeerAddrParams->pathMaxRxt = addrParams.spp_pathmaxrxt;
3323 pPeerAddrParams->assocId = addrParams.spp_assoc_id;
3324 pPeerAddrParams->pathMtu = addrParams.spp_pathmtu;
3325 pPeerAddrParams->sackDelay = addrParams.spp_sackdelay;
3327 if (addrParams.spp_flags & SPP_HB_ENABLE)
3328 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_ENABLE;
3330 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_DISABLE;
3332 if (addrParams.spp_flags & SPP_PMTUD_ENABLE)
3333 pPeerAddrParams->pmtudFlag = CM_INET_OPT_ENABLE;
3335 pPeerAddrParams->pmtudFlag = CM_INET_OPT_DISABLE;
3337 if (addrParams.spp_flags & SPP_SACKDELAY_ENABLE)
3338 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_ENABLE;
3340 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_DISABLE;
3345 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
3347 pAssocParams = (CmInetSctpAssocParams *)value;
3349 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
3351 assocParams.sasoc_assoc_id = pAssocParams->assocId;
3353 len = sizeof(assocParams);
3355 ret = getsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, &len);
3357 pAssocParams->assocMaxReTx = assocParams.sasoc_asocmaxrxt;
3358 pAssocParams->cookieLife = assocParams.sasoc_cookie_life;
3359 pAssocParams->assocId = assocParams.sasoc_assoc_id;
3360 pAssocParams->numberOfPeerDest = assocParams.sasoc_number_peer_destinations;
3361 pAssocParams->peerRwnd = assocParams.sasoc_peer_rwnd;
3362 pAssocParams->localRwnd = assocParams.sasoc_local_rwnd;
3366 case CM_INET_OPT_SCTP_RTO_INFO:
3368 pRtoInfo = (CmInetSctpRtoInfo *)value;
3370 memset(&rtoInfo, 0, sizeof(struct sctp_rtoinfo));
3372 len = sizeof(rtoInfo);
3374 ret = getsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoInfo, &len);
3376 pRtoInfo->assocId = rtoInfo.srto_assoc_id;
3377 pRtoInfo->rtoInitial = rtoInfo.srto_initial;
3378 pRtoInfo->rtoMax = rtoInfo.srto_max;
3379 pRtoInfo->rtoMin = rtoInfo.srto_min;
3383 case CM_INET_OPT_SCTP_INIT_MSG:
3385 pInitMsg = (CmInetSctpInitMsg *)value;
3387 memset(&initMsg, 0, sizeof(struct sctp_initmsg));
3389 len = sizeof(initMsg);
3391 ret = getsockopt(sockFd->fd, level, SCTP_INITMSG, &initMsg, &len);
3393 pInitMsg->maxInitReTx = initMsg.sinit_max_attempts;
3394 pInitMsg->maxInitTimeout = initMsg.sinit_max_init_timeo;
3395 pInitMsg->numOstreams = initMsg.sinit_num_ostreams;
3396 pInitMsg->maxInstreams = initMsg.sinit_max_instreams;
3404 if (ret == INET_ERR)
3408 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3409 /* cm_inet_c_001.main_62:Warning fix */
3410 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3411 " error(%d), sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3412 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3414 /* cm_inet_c_001.main_62:Warning fix */
3415 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3416 " error(%d), sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3417 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3418 #endif /*ALIGN_64BIT*/
3419 #endif /* CMINETDBG */
3426 /* cm_inet_c_001.main_54: Added new function cmInetShutDownSctp()*/
3429 * Fun: cmInetShutDownSctp
3431 * Desc: Shutdown the SCTP association gracefully.
3433 * Ret: ROK - successful
3441 S16 cmInetShutDownSctp
3443 CmInetFd *sockFd /* socket file descriptor */
3446 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3448 struct sctp_sndrcvinfo sndRcvInfo;
3451 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3454 sndRcvInfo.sinfo_flags = MSG_EOF;
3456 sndRcvInfo.sinfo_flags = SCTP_EOF;
3459 /* Call the sctp_send with flag set to termiante the association */
3461 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3467 /* cm_inet_c_001.main_62:Warning fix */
3468 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%ld)\n",
3469 INET_ERR_CODE, sockFd->fd);
3470 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3472 /* cm_inet_c_001.main_62:Warning fix */
3473 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%d)\n",
3474 INET_ERR_CODE, sockFd->fd);
3475 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3476 #endif /*ALIGN_64BIT*/
3477 #endif /* CMINETDBG */
3485 /* cm_inet_c_001.main_61: Added new function cmInetAbortSctpAssoc()*/
3488 * Fun: cmInetAbortSctpAssoc
3490 * Desc: ABORT the association.
3492 * Ret: ROK - successful
3500 S16 cmInetAbortSctpAssoc
3502 CmInetFd *sockFd, /* socket file descriptor */
3503 UConnId assocId /* Association ID */
3507 struct sctp_sndrcvinfo sndRcvInfo;
3510 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3513 sndRcvInfo.sinfo_flags = MSG_ABORT;
3515 sndRcvInfo.sinfo_flags = SCTP_ABORT;
3518 sndRcvInfo.sinfo_assoc_id = assocId;
3520 /* Call the sctp_send with flag set to termiante the association */
3522 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3528 /* cm_inet_c_001.main_62:Warning fix */
3529 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%ld)\n",
3530 INET_ERR_CODE, sockFd->fd);
3531 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3533 /* cm_inet_c_001.main_62:Warning fix */
3534 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%d)\n",
3535 INET_ERR_CODE, sockFd->fd);
3536 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3537 #endif /*ALIGN_64BIT*/
3538 #endif /* CMINETDBG */
3551 * Fun: cmInetConnect
3553 * Desc: Establishs a connection to a foreign address (TCP) or associates
3554 * a UDP socket to a foreign address.
3556 * Ret: ROK - successful
3557 * ROKDNA - resource temporarily unavaiable
3558 * RINPROGRESS - connection is in progress (only non-blocking)
3559 * RISCONN - connection is established (only non-blocking)
3570 CmInetFd *sockFd, /* socket file descriptor */
3571 CmInetAddr *servAddr /* foreign Internet address/port */
3574 S32 ret; /* temporary return value */
3575 struct sockaddr_in dstAddr; /* foreign Internet address/port */
3576 #ifdef IPV6_SUPPORTED
3577 struct sockaddr_in6 dstAddr6; /* foreign Internet IPV6 address/port */
3580 #endif /* CMINETDBG */
3581 #endif /* IPV6_SUPPORTED */
3583 CmInetSockAddr *sockAddrPtr;
3586 #if (ERRCLASS & ERRCLS_INT_PAR)
3587 /* error check on parameters */
3588 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3589 (servAddr == NULLP))
3593 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3595 #ifdef IPV6_SUPPORTED
3596 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3598 memset(&dstAddr6, 0, sizeof(dstAddr6));
3599 dstAddr6.sin6_family = AF_INET6;
3600 dstAddr6.sin6_port = CM_INET_HTON_UINT16(servAddr->u.ipv6Addr.port);
3601 CM_INET_COPY_IPV6ADDR(&dstAddr6.sin6_addr,
3602 &servAddr->u.ipv6Addr.ipv6NetAddr);
3603 sizeOfAddr = sizeof(struct sockaddr_in6);
3604 sockAddrPtr = (CmInetSockAddr *)&dstAddr6;
3608 memset(&dstAddr, 0, sizeof(dstAddr));
3609 dstAddr.sin_family = AF_INET;
3610 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->u.ipv4Addr.port);
3611 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->u.ipv4Addr.address);
3612 sizeOfAddr = sizeof(struct sockaddr_in);
3613 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3616 memset(&dstAddr, 0, sizeof(dstAddr));
3617 dstAddr.sin_family = AF_INET;
3618 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->port);
3619 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->address);
3620 sizeOfAddr = sizeof(struct sockaddr_in);
3621 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3622 #endif /* IPV6_SUPPORTED */
3624 ret = connect(sockFd->fd, sockAddrPtr, sizeOfAddr);
3625 if (ret == INET_ERR)
3627 switch (INET_ERR_CODE)
3629 /* non-blocking: connection is in progress */
3630 case ERR_INPROGRESS:
3631 return (RINPROGRESS);
3635 * non-blocking: connection is established
3636 * blocking : connection is already established
3642 /* resource temporarily unavailable */
3643 case ERR_WOULDBLOCK:
3647 /* non-blocking: connection is in progress */
3649 return (RINPROGRESS);
3653 return (RINPROGRESS);
3656 /* Check for connection refused and timeout errors */
3657 case ERR_CONNREFUSED:
3662 /* it is a real error */
3665 #ifdef IPV6_SUPPORTED
3666 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3667 port = servAddr->u.ipv6Addr.port;
3669 port = servAddr->u.ipv4Addr.port;
3671 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3673 /* cm_inet_c_001.main_62:Warning fix */
3674 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3675 " addrtype(0x%x), port(0x%1x), sockFd->fd(%ld)\n",
3676 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3677 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3679 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3680 " addrtype(0x%x), port(0x%1x), sockFd->fd(%d)\n",
3681 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3682 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3683 #endif /*ALIGN_64BIT*/
3686 /* cm_inet_c_001.main_62:Warning fix */
3687 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%lx),"
3688 "port(0x%1x), sockFd->fd(%ld)\n", INET_ERR_CODE ,
3689 servAddr->address, servAddr->port, sockFd->fd);
3690 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3692 /* cm_inet_c_001.main_62:Warning fix */
3693 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%x),"
3694 "port(0x%x), sockFd->fd(%d)\n", INET_ERR_CODE ,
3695 servAddr->address, servAddr->port, sockFd->fd);
3696 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3697 #endif /*ALIGN_64BIT*/
3698 #endif /* IPV6_SUPPORTED */
3699 #endif /* CMINETDBG */
3706 } /* end of cmInetConnect */
3713 * Desc: Indicates the willingness of a socket to listen for incomming
3714 * connection requests.
3716 * Ret: ROK - successful
3719 * Notes: The backLog value has to be within 0..5
3727 CmInetFd *sockFd, /* socket file descriptor */
3728 S16 backLog /* max. number of outstandig connections 0..5 */
3731 S32 ret; /* temporary return value */
3734 #if (ERRCLASS & ERRCLS_INT_PAR)
3735 /* error check on parameters */
3736 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3737 (backLog < MIN_BACK_LOG) || (backLog > MAX_BACK_LOG))
3741 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3743 ret = listen(sockFd->fd, backLog);
3744 if (ret == INET_ERR)
3748 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3749 /* cm_inet_c_001.main_62:Warning fix */
3750 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3751 " sockFd->fd(%ld)\n", INET_ERR_CODE, backLog, sockFd->fd);
3752 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3754 /* cm_inet_c_001.main_62:Warning fix */
3755 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3756 " sockFd->fd(%d)\n", INET_ERR_CODE, backLog, sockFd->fd);
3757 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3758 #endif /*ALIGN_64BIT*/
3759 #endif /* CMINETDBG */
3764 } /* end of cmInetListen */
3771 * Desc: Accepts an incoming connection.
3772 * On default the new socket is non-blocking. The options can be
3773 * changed with the function cmInetSetOpt().
3775 * Ret: ROK - successful
3776 * ROKDNA - there is no connection present to accept (only
3788 CmInetFd *sockFd, /* socket file descriptor */
3789 CmInetAddr *fromAddr, /* calling Internet address/port */
3790 CmInetFd *newSockFd /* socket file descriptor for new connection*/
3793 S32 ret; /* temporary return value */
3794 S32 addrLen; /* address structure length */
3795 struct sockaddr_in *peerAddr; /* calling Internet address/port */
3796 #ifdef IPV6_SUPPORTED
3797 struct sockaddr_in6 *peerAddr6; /* calling Internet address/port */
3798 struct sockaddr_in6 sockAddr;
3800 CmInetSockAddr sockAddr;
3801 #endif /* IPV6_SUPPORTED */
3807 #if (ERRCLASS & ERRCLS_INT_PAR)
3808 /* error check on parameters */
3809 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3813 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3815 /* change CmInetSockAddr to sockAddr */
3816 addrLen = sizeof(sockAddr);
3819 #if ( defined(SUNOS) || defined(SS_LINUX))
3820 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3821 (socklen_t *)&addrLen);
3823 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3825 #endif /* SUNOS || SS_LINUX */
3827 /* cm_inet_c_001.main_58: Moved setting of protType below */
3829 if (CM_INET_INV_SOCK_FD(newSockFd))
3831 if (INET_ERR_CODE == ERR_WOULDBLOCK)
3833 /* no connection present to accept */
3840 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3841 /* cm_inet_c_001.main_62:Warning fix */
3842 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3843 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3844 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3846 /* cm_inet_c_001.main_62:Warning fix */
3847 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3848 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3849 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3850 #endif /*ALIGN_64BIT*/
3851 #endif /* CMINETDBG */
3857 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
3858 /* added for IPv6/IPv4 socket distinguishing */
3859 #ifdef IPV6_SUPPORTED
3860 if (addrLen == sizeof(struct sockaddr_in))
3861 newSockFd->protType = AF_INET;
3862 else if(addrLen == sizeof(struct sockaddr_in6))
3863 newSockFd->protType = AF_INET6;
3868 /* cm_inet_c_001.main_62:Warning fix */
3869 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%ld)\n", sockFd->fd);
3870 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3872 /* cm_inet_c_001.main_62:Warning fix */
3873 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%d)\n", sockFd->fd);
3874 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3875 #endif /*ALIGN_64BIT*/
3876 #endif /* CMINETDBG */
3879 #endif /* IPV6_SUPPORTED */
3881 /* set the new socket file descriptor type */
3882 newSockFd->type = CM_INET_STREAM;
3884 /* set default options for new socket file descriptor */
3885 optVal = CM_INET_OPT_DISABLE;
3886 ret = cmInetSetOpt(newSockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, &optVal);
3889 ret = cmInetClose(newSockFd);
3893 #ifdef IPV6_SUPPORTED
3894 memset(fromAddr, 0, sizeof(fromAddr));
3895 if (addrLen == sizeof(struct sockaddr_in))
3897 peerAddr = (struct sockaddr_in *)&sockAddr;
3898 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
3899 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3900 fromAddr->u.ipv4Addr.address =
3901 CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3903 else if (addrLen == sizeof(struct sockaddr_in6))
3905 peerAddr6 = (struct sockaddr_in6 *)&sockAddr;
3906 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
3907 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(peerAddr6->sin6_port);
3908 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
3909 &peerAddr6->sin6_addr);
3912 peerAddr = (struct sockaddr_in *)&sockAddr;
3913 fromAddr->port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3914 fromAddr->address = CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3915 #endif /* IPV6_SUPPORTED */
3917 } /* end of cmInetAccept */
3922 * Fun: cmInet4FillTos
3924 * Desc: This function inserts tos (into ancillary data) which
3925 * will be used to fill tos value in ip header in outgoing IP packet
3926 * when sending that packet using sendmsg()function.
3936 static S16 cmInet4FillTos
3938 uint8_t tos, /* tos value to be filled in ipheader */
3939 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
3940 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
3943 struct cmsghdr *tempHdr;
3950 /* cmsghdr struc will appear before data in the ancillary data object.
3951 * So put cmsghdr struc in flat buffer first. */
3953 /* cmsghdr struc points to flat buffer's starting address */
3954 tempHdr = (struct cmsghdr *)cmsgBuf;
3956 /* fill up level & type of cmsghdr structure */
3957 tempHdr->cmsg_level = IPPROTO_IPV6;
3958 tempHdr->cmsg_type = IP_TOS;
3959 (*(uint8_t*)CMSG_DATA(tempHdr)) = tos;
3960 len = CMSG_SPACE(sizeof tos);
3963 /* fill up the length of cmsghdr structure */
3964 tempHdr->cmsg_len = len;
3969 }/* end of cmInet4FillTos */
3972 * Fun: cmInetSendDscpMsg
3974 * Desc: Sends the message data hold by mBuf.
3975 * The len paramter gives the actual written octets. If the socket
3976 * is non-blocking this value can be differ from the mBuf length
3977 * because there was not enough transmit buffer space available. If
3978 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
3980 * Values for flag parameter:
3982 * CM_INET_NO_FLAG - no additional control flag
3984 * Ret: ROK - successful
3985 * RWOULDBLOCK - no or not entire mBuf sent because would block
3986 * ROUTRES - failed, out of resources
3987 * RCLOSED - connection was closed by the peer
3990 * Notes: The successful completion of a send call does not indicate that
3991 * the data has been successfully delivered!
3993 * This function does not free any sent buffers.
4000 S16 cmInetSendDscpMsg
4002 CmInetFd *sockFd, /* socket file descriptor */
4003 CmInetAddr *dstAddr, /* destination Internet address/port */
4004 CmInetMemInfo *info, /* buffer allocation info */
4005 Buffer *mBuf, /* buffer structure to send */
4006 MsgLen *len, /* number of actually sent octets */
4007 /* added for IPv6 ext hdr */
4008 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4009 S16 flags /* additional control flags, unused */
4012 #if (defined(WIN32) || defined(CMINETFLATBUF))
4013 S32 ret; /* temporary return value */
4014 MsgLen msgLen; /* message length */
4015 MsgLen bufLen; /* send buffer length */
4016 Data *sendBuf; /* plain send buffer */
4018 S32 ret; /* temporary return value */
4019 S32 retVal; /* temporary return value */
4020 S16 i; /* loop index */
4021 CmInetIovec txArr[CM_INET_MAX_DBUF]; /* scatter vector */
4022 S16 numDBufs; /* number of dBufs in message */
4023 struct msghdr msg; /* sendmsg() message header */
4024 MsgLen msgLen; /* message length */
4025 uint32_t strtEndDBufNum; /* starting/ending DBuf number */
4026 MsgLen unSentLen; /* sent len */
4027 #ifdef IPV6_SUPPORTED
4028 uint32_t curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4029 /* added for IPv6 ext hdr */
4030 #if (defined(SS_LINUX) || defined(_XPG4_2))
4031 /* alloc from stack for IPv6 ancill data */
4032 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA];
4033 #endif /* SS_LINUX || _XPG4_2 */
4035 uint32_t curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4036 #if (defined(SS_LINUX) || defined(_XPG4_2))
4037 /* alloc from stack for IPv4 ancill data */
4038 uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA];
4039 #endif /* SS_LINUX || _XPG4_2 */
4040 #endif /* IPV6_SUPPORTED */
4041 #endif /* WIN32 | CMINETFLATBUF */
4043 struct sockaddr_in remAddr; /* remote Internet address */
4044 #ifdef IPV6_SUPPORTED
4045 struct sockaddr_in6 remAddr6; /* remote Internet address */
4046 #endif /* IPV8_SUPPORTED */
4047 CmInetSockAddr *sockAddrPtr;
4048 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4049 uint32_t sizeOfAddr;
4051 /* cm_inet_c_001.main_50 - Added for partial send handling */
4052 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4053 #if (!defined(WIN32))
4060 #if (ERRCLASS & ERRCLS_INT_PAR)
4061 /* error check on parameters */
4062 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4063 (info == NULLP) || (len == NULLP))
4067 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4069 /* added for IPv6 ext hdr */
4070 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4071 #if (defined(SS_LINUX) || defined(_XPG4_2))
4072 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4073 #endif /* SS_LINUX || _XPG4_2 */
4075 #endif /* WIN32 | CMINETFLATBUF */
4077 msgLen = 0; /* need by CC to pass without warning */
4078 sockAddrPtr = NULLP;
4081 /* setup remote address */
4082 if (dstAddr != NULLP)
4084 #ifdef IPV6_SUPPORTED
4085 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4087 memset(&remAddr6, 0, sizeof(remAddr6));
4088 remAddr6.sin6_family = AF_INET6;
4089 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4090 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4091 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4092 sizeOfAddr = sizeof(remAddr6);
4093 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4097 memset(&remAddr, 0, sizeof(remAddr));
4098 remAddr.sin_family = AF_INET;
4099 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4100 remAddr.sin_addr.s_addr =
4101 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4102 sizeOfAddr = sizeof(remAddr);
4103 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4106 /* memset(&remAddr, 0, sizeof(remAddr)); */
4107 remAddr.sin_family = AF_INET;
4108 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4109 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4110 sizeOfAddr = sizeof(remAddr);
4111 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4112 #endif /* IPV6_SUPPORTED */
4115 #if (defined(WIN32) || defined(CMINETFLATBUF))
4116 /* copy message to a flat buffer */
4117 ret = SFndLenMsg(mBuf, &bufLen);
4122 /* max message length is limited to control the memory usage */
4123 /* casting bufLen to avoid warnings */
4124 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4128 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4133 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4134 if ((ret != ROK) || (msgLen != bufLen))
4137 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4141 if (dstAddr == NULLP)
4143 /* VxWorks sendto has some problem
4144 * with connected UDP socket, use send */
4146 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4149 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4150 #endif /* end of SS_VW */
4153 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4155 #if (defined(SS_VW) && defined(SS_VW6_7))
4156 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4158 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4161 #endif /* end of SS_VW6_7 and SS_VW */
4163 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4164 sockAddrPtr, sizeOfAddr);
4167 if (ret == INET_ERR)
4170 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4172 if(INET_ERR_CODE == ERR_AGAIN)
4175 return (RWOULDBLOCK);
4178 /* Check for ERR_WOULDBLOCK */
4179 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4182 return (RWOULDBLOCK);
4187 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4188 /* cm_inet_c_001.main_62:Warning fix */
4189 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4190 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4191 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4193 /* cm_inet_c_001.main_62:Warning fix */
4194 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4195 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4196 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4197 #endif /*ALIGN_64BIT*/
4198 #endif /* CMINETDBG */
4200 /* cm_inet_c_001.main_37 network unreacheble error is added */
4201 /* check if network is reacheble*/
4202 if ((INET_ERR_CODE == ERR_NETUNREACH))
4204 return (RNETFAILED);
4208 /* Check if connection was closed */
4209 if ((INET_ERR_CODE == ERR_PIPE) ||
4210 (INET_ERR_CODE == ERR_CONNABORTED) ||
4211 (INET_ERR_CODE == ERR_CONNRESET))
4222 /* check if entire message could be sent */
4227 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4228 return (RWOULDBLOCK);
4232 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4234 #else /* end of Win NT/flat buffer specific part */
4235 ret = SFndLenMsg(mBuf, &msgLen);
4242 /* memset(&msg, 0, sizeof(msg)); */
4245 if (dstAddr != NULLP)
4248 msg.msg_name = (Void*)sockAddrPtr;
4251 msg.msg_name = (char *)sockAddrPtr;
4253 msg.msg_name = (caddr_t)sockAddrPtr;
4255 #endif /* SS_LINUX */
4256 msg.msg_namelen = sizeOfAddr;
4260 msg.msg_name = NULLP;
4261 msg.msg_namelen = 0;
4263 /* added defined(_XPG4_2) */
4264 #if (defined(SS_LINUX) || defined(_XPG4_2))
4265 msg.msg_control = NULLP;
4266 msg.msg_controllen = 0;
4268 msg.msg_accrights = 0;
4269 msg.msg_accrightslen = NULLP;
4270 #endif /* SS_LINUX */
4272 /* allocate scatter vector */
4273 numDBufs = CM_INET_MAX_DBUF;
4279 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV4ADDR_TYPE))
4280 if((ipHdrParams->u.hdrParmIpv4.tos.pres == TRUE)&& \
4281 (ipHdrParams->u.hdrParmIpv4.tos.val != 0))
4283 cmInet4FillTos(ipHdrParams->u.hdrParmIpv4.tos.val,
4284 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4285 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4286 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4288 /* if the sender wants to send Ipv6 exten. headers */
4289 #ifdef IPV6_OPTS_SUPPORTED
4290 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4293 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4295 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4296 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4298 #endif /* SS_LINUX */
4301 /* have to decide how to get the src addr to add in in6_pktinfo */
4302 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4304 cmInet6BuildSendPktinfo(
4305 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4306 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4309 #endif /* LOCAL_INTF */
4311 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4312 * cmsgData one by one. */
4314 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4315 /* build HBH ext header in cmsgData starting at indx 0 */
4316 cmInet6BuildSendHBHOpts(
4317 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4318 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4320 /* now copy the elements from the Destination Option array one by
4321 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4322 * which is the end of HBH hdr. */
4323 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4324 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4325 cmInet6BuildSendDestOpts(
4326 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4327 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4329 /* copy Route header to to the Flat Buffer cmsgData */
4330 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4331 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4332 cmInet6BuildSendRouteOpts(
4333 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4334 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4336 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4337 * will be the curMsgIdx */
4338 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4339 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4342 #endif /* IPV6_OPTS_SUPPORTED */
4344 /* Loop till all the data is sent or till the sendmsg call cannot send
4348 /* build the send vector */
4349 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4350 total length of the packed dbufs */
4351 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4352 &strtEndDBufNum, &ioLen);
4357 /* Incase of UDP/RAW messages call SCompressMsg. */
4358 if (sockFd->type != CM_INET_STREAM)
4360 /* Compress the message into a single dBuf */
4361 ret = SCompressMsg(mBuf);
4366 /* Rebuild the send vector */
4367 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4368 total length of the packed dbuf */
4369 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4370 &strtEndDBufNum, &ioLen);
4380 msg.msg_iov = txArr;
4387 if ( sockFd->fd >= 0xD001)
4388 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4390 ret = sendmsg(sockFd->fd, &msg, 0);
4393 ret = sendmsg(sockFd->fd, &msg, 0);
4395 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4396 if (ret == INET_ERR)
4398 if((INET_ERR_CODE == ERR_AGAIN) ||
4399 (INET_ERR_CODE == ERR_WOULDBLOCK))
4401 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4402 message was sent earlier */
4403 return (RWOULDBLOCK);
4407 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4408 /* cm_inet_c_001.main_62:Warning fix */
4409 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4410 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4411 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4413 /* cm_inet_c_001.main_62:Warning fix */
4414 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4415 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4416 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4417 #endif /*ALIGN_64BIT*/
4418 #endif /* CMINETDBG */
4420 /* cm_inet_c_001.main_37 network unreacheble error is added */
4421 /* check if network is reacheble or not */
4422 if ((INET_ERR_CODE == ERR_NETUNREACH))
4424 return (RNETFAILED);
4427 /* Check if connection was closed by the peer */
4428 if ((INET_ERR_CODE == ERR_PIPE) ||
4429 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4430 (INET_ERR_CODE == ERR_CONNABORTED))
4438 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4441 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4442 * to be sent, then return WOULDBLOCK
4445 return (RWOULDBLOCK);
4449 } while (*len < msgLen);
4450 #endif /* WIN32 | CMINETFLATBUF */
4454 } /* end of cmInetSendDscpMsg */
4458 * Fun: cmInetSendMsg
4460 * Desc: Sends the message data hold by mBuf.
4461 * The len paramter gives the actual written octets. If the socket
4462 * is non-blocking this value can be differ from the mBuf length
4463 * because there was not enough transmit buffer space available. If
4464 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4466 * Values for flag parameter:
4468 * CM_INET_NO_FLAG - no additional control flag
4470 * Ret: ROK - successful
4471 * RWOULDBLOCK - no or not entire mBuf sent because would block
4472 * ROUTRES - failed, out of resources
4473 * RCLOSED - connection was closed by the peer
4476 * Notes: The successful completion of a send call does not indicate that
4477 * the data has been successfully delivered!
4479 * This function does not free any sent buffers.
4488 CmInetFd *sockFd, /* socket file descriptor */
4489 CmInetAddr *dstAddr, /* destination Internet address/port */
4490 CmInetMemInfo *info, /* buffer allocation info */
4491 Buffer *mBuf, /* buffer structure to send */
4492 MsgLen *len, /* number of actually sent octets */
4493 /* added for IPv6 ext hdr */
4494 #ifdef IPV6_OPTS_SUPPORTED
4495 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4496 #endif /* IPV6_OPTS_SUPPORTED */
4497 S16 flags /* additional control flags, unused */
4500 #if (defined(WIN32) || defined(CMINETFLATBUF))
4501 S32 ret; /* temporary return value */
4502 MsgLen msgLen; /* message length */
4503 MsgLen bufLen; /* send buffer length */
4504 Data *sendBuf; /* plain send buffer */
4506 S32 ret; /* temporary return value */
4507 S32 retVal; /* temporary return value */
4508 S16 i; /* loop index */
4509 CmInetIovec txArr[CM_INET_MAX_DBUF]; /* scatter vector */
4510 S16 numDBufs; /* number of dBufs in message */
4511 struct msghdr msg; /* sendmsg() message header */
4512 MsgLen msgLen; /* message length */
4513 uint32_t strtEndDBufNum; /* starting/ending DBuf number */
4514 MsgLen unSentLen; /* sent len */
4515 #ifdef IPV6_SUPPORTED
4516 /* added for IPv6 ext hdr */
4517 #ifdef IPV6_OPTS_SUPPORTED
4518 uint32_t curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4519 #if (defined(SS_LINUX) || defined(_XPG4_2))
4520 /* alloc from stack for IPv6 ancill data */
4521 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA];
4522 #endif /* SS_LINUX || _XPG4_2 */
4523 #endif /* IPV6_OPTS_SUPPORTED */
4525 #if (defined(SS_LINUX) || defined(_XPG4_2))
4526 /* alloc from stack for IPv4 ancill data */
4527 /* uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA];*/
4528 #endif /* SS_LINUX || _XPG4_2 */
4529 #endif /* IPV6_SUPPORTED */
4530 #endif /* WIN32 | CMINETFLATBUF */
4532 struct sockaddr_in remAddr; /* remote Internet address */
4533 #ifdef IPV6_SUPPORTED
4534 struct sockaddr_in6 remAddr6; /* remote Internet address */
4535 #endif /* IPV8_SUPPORTED */
4536 CmInetSockAddr *sockAddrPtr;
4537 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4538 uint32_t sizeOfAddr;
4540 /* cm_inet_c_001.main_50 - Added for partial send handling */
4541 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4542 #if (!defined(WIN32))
4549 #if (ERRCLASS & ERRCLS_INT_PAR)
4550 /* error check on parameters */
4551 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4552 (info == NULLP) || (len == NULLP))
4556 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4558 /* added for IPv6 ext hdr */
4559 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4560 #if (defined(SS_LINUX) || defined(_XPG4_2))
4561 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4562 #endif /* SS_LINUX || _XPG4_2 */
4563 #ifdef IPV6_OPTS_SUPPORTED
4565 #endif /* IPV6_SUPPORTED */
4566 #endif /* WIN32 | CMINETFLATBUF */
4568 msgLen = 0; /* need by CC to pass without warning */
4569 sockAddrPtr = NULLP;
4572 /* setup remote address */
4573 if (dstAddr != NULLP)
4575 #ifdef IPV6_SUPPORTED
4576 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4578 memset(&remAddr6, 0, sizeof(remAddr6));
4579 remAddr6.sin6_family = AF_INET6;
4580 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4581 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4582 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4583 sizeOfAddr = sizeof(remAddr6);
4584 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4588 memset(&remAddr, 0, sizeof(remAddr));
4589 remAddr.sin_family = AF_INET;
4590 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4591 remAddr.sin_addr.s_addr =
4592 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4593 sizeOfAddr = sizeof(remAddr);
4594 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4597 /* memset(&remAddr, 0, sizeof(remAddr)); */
4598 remAddr.sin_family = AF_INET;
4599 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4600 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4601 sizeOfAddr = sizeof(remAddr);
4602 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4603 #endif /* IPV6_SUPPORTED */
4606 #if (defined(WIN32) || defined(CMINETFLATBUF))
4607 /* copy message to a flat buffer */
4608 ret = SFndLenMsg(mBuf, &bufLen);
4613 /* max message length is limited to control the memory usage */
4614 /* casting bufLen to avoid warnings */
4615 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4619 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4624 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4625 if ((ret != ROK) || (msgLen != bufLen))
4628 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4632 if (dstAddr == NULLP)
4634 /* VxWorks sendto has some problem
4635 * with connected UDP socket, use send */
4637 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4640 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4641 #endif /* end of SS_VW */
4644 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4646 #if (defined(SS_VW) && defined(SS_VW6_7))
4647 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4649 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4652 #endif /* end of SS_VW6_7 and SS_VW */
4654 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4655 sockAddrPtr, sizeOfAddr);
4658 if (ret == INET_ERR)
4661 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4663 if(INET_ERR_CODE == ERR_AGAIN)
4666 return (RWOULDBLOCK);
4669 /* Check for ERR_WOULDBLOCK */
4670 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4673 return (RWOULDBLOCK);
4678 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4679 /* cm_inet_c_001.main_62:Warning fix */
4680 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4681 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4682 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4684 /* cm_inet_c_001.main_62:Warning fix */
4685 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4686 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4687 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4688 #endif /*ALIGN_64BIT*/
4689 #endif /* CMINETDBG */
4691 /* cm_inet_c_001.main_37 network unreacheble error is added */
4692 /* check if network is reacheble*/
4693 if ((INET_ERR_CODE == ERR_NETUNREACH))
4695 return (RNETFAILED);
4699 /* Check if connection was closed */
4700 if ((INET_ERR_CODE == ERR_PIPE) ||
4701 (INET_ERR_CODE == ERR_CONNABORTED) ||
4702 (INET_ERR_CODE == ERR_CONNRESET))
4713 /* check if entire message could be sent */
4718 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4719 return (RWOULDBLOCK);
4723 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4725 #else /* end of Win NT/flat buffer specific part */
4726 ret = SFndLenMsg(mBuf, &msgLen);
4733 /* memset(&msg, 0, sizeof(msg)); */
4736 if (dstAddr != NULLP)
4739 msg.msg_name = (Void*)sockAddrPtr;
4742 msg.msg_name = (char *)sockAddrPtr;
4744 msg.msg_name = (caddr_t)sockAddrPtr;
4746 #endif /* SS_LINUX */
4747 msg.msg_namelen = sizeOfAddr;
4751 msg.msg_name = NULLP;
4752 msg.msg_namelen = 0;
4754 /* added defined(_XPG4_2) */
4755 #if (defined(SS_LINUX) || defined(_XPG4_2))
4756 msg.msg_control = NULLP;
4757 msg.msg_controllen = 0;
4759 msg.msg_accrights = 0;
4760 msg.msg_accrightslen = NULLP;
4761 #endif /* SS_LINUX */
4763 /* allocate scatter vector */
4764 numDBufs = CM_INET_MAX_DBUF;
4771 /* if the sender wants to send Ipv6 exten. headers */
4772 #ifdef IPV6_OPTS_SUPPORTED
4773 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4776 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4778 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4779 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4781 #endif /* SS_LINUX */
4784 /* have to decide how to get the src addr to add in in6_pktinfo */
4785 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4787 cmInet6BuildSendPktinfo(
4788 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4789 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4792 #endif /* LOCAL_INTF */
4794 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4795 * cmsgData one by one. */
4797 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4798 /* build HBH ext header in cmsgData starting at indx 0 */
4799 cmInet6BuildSendHBHOpts(
4800 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4801 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4803 /* now copy the elements from the Destination Option array one by
4804 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4805 * which is the end of HBH hdr. */
4806 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4807 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4808 cmInet6BuildSendDestOpts(
4809 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4810 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4812 /* copy Route header to to the Flat Buffer cmsgData */
4813 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4814 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4815 cmInet6BuildSendRouteOpts(
4816 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4817 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4819 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4820 * will be the curMsgIdx */
4821 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4822 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4825 #endif /* IPV6_OPTS_SUPPORTED */
4827 /* Loop till all the data is sent or till the sendmsg call cannot send
4831 /* build the send vector */
4832 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4833 total length of the packed dbufs */
4834 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4835 &strtEndDBufNum, &ioLen);
4840 /* Incase of UDP/RAW messages call SCompressMsg. */
4841 if (sockFd->type != CM_INET_STREAM)
4843 /* Compress the message into a single dBuf */
4844 ret = SCompressMsg(mBuf);
4849 /* Rebuild the send vector */
4850 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4851 total length of the packed dbuf */
4852 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4853 &strtEndDBufNum, &ioLen);
4863 msg.msg_iov = txArr;
4870 if ( sockFd->fd >= 0xD001)
4871 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4873 ret = sendmsg(sockFd->fd, &msg, 0);
4876 ret = sendmsg(sockFd->fd, &msg, 0);
4878 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4879 if (ret == INET_ERR)
4881 if((INET_ERR_CODE == ERR_AGAIN) ||
4882 (INET_ERR_CODE == ERR_WOULDBLOCK))
4884 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4885 message was sent earlier */
4886 return (RWOULDBLOCK);
4890 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4891 /* cm_inet_c_001.main_62:Warning fix */
4892 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4893 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4894 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4896 /* cm_inet_c_001.main_62:Warning fix */
4897 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4898 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4899 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4900 #endif /*ALIGN_64BIT*/
4901 #endif /* CMINETDBG */
4903 /* cm_inet_c_001.main_37 network unreacheble error is added */
4904 /* check if network is reacheble or not */
4905 if ((INET_ERR_CODE == ERR_NETUNREACH))
4907 return (RNETFAILED);
4910 /* Check if connection was closed by the peer */
4911 if ((INET_ERR_CODE == ERR_PIPE) ||
4912 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4913 (INET_ERR_CODE == ERR_CONNABORTED))
4921 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4924 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4925 * to be sent, then return WOULDBLOCK
4928 return (RWOULDBLOCK);
4932 } while (*len < msgLen);
4933 #endif /* WIN32 | CMINETFLATBUF */
4937 } /* end of cmInetSendMsg */
4940 /* added new functions for IPv6 extension headers */
4941 #ifdef IPV6_OPTS_SUPPORTED
4945 * Fun: cmInet6BuildSendPktinfo
4947 * Desc: This function inserts src address (into ancillary data) which
4948 * will be used as the src addr in outgoing IP packet when sending
4949 * that packet using sendmsg()function.
4959 static S16 cmInet6BuildSendPktinfo
4961 CmInetIpAddr6 *srcAddr, /* src ip addr to set on outgoing packet */
4962 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
4963 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4964 uint8_t protType /* whether IPv4/IPv6 socket */
4967 struct cmsghdr *tempHdr;
4968 struct in6_pktinfo *ipv6Pktinfo;
4969 struct in6_addr lpBkAddr;
4975 lpBkAddr = in6addr_loopback;
4977 /* cmsghdr struc will appear before data in the ancillary data object.
4978 * So put cmsghdr struc in flat buffer first. */
4980 /* cmsghdr struc points to flat buffer's starting address */
4981 tempHdr = (struct cmsghdr *)cmsgBuf;
4983 /* fill up level & type of cmsghdr structure */
4984 if (protType == AF_INET6)
4986 tempHdr->cmsg_level = IPPROTO_IPV6;
4987 tempHdr->cmsg_type = IPV6_PKTINFO;
4990 else if(protType == AF_INET)
4992 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4993 /* cm_inet_c_001.main_62:Warning fix */
4994 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
4995 "protType(%d)\n", protType);
4996 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET025, 0, prntBuf);
5000 /* skip length of cmsghdr structure - 12 bytes */
5001 len += sizeof(struct cmsghdr);
5003 if(protType == AF_INET6)
5004 ipv6Pktinfo = (struct in6_pktinfo *)(cmsgBuf + len);
5008 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5009 /* cm_inet_c_001.main_62:Warning fix */
5010 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5011 "protType(%d)\n", protType);
5012 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET026, 0, prntBuf);
5016 /* insert the hoplimit. This will override the kernel's
5017 * default hoplimit value */
5018 if(protType == AF_INET6)
5020 /* store ipv6 src addr */
5021 memcpy(&(ipv6Pktinfo->ipi6_addr), srcAddr, 16);
5024 /* store interface index */
5025 /* 0 is invalid intf indx it tells kernel to chose any intf it likes to
5026 * send this pkt. if we use nozero intf indx then kernel will send this
5027 * pkt only through that intf */
5028 ipv6Pktinfo->ipi6_ifindex = 0;
5032 else if(protType == AF_INET)
5034 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5035 /* cm_inet_c_001.main_62:Warning fix */
5036 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5037 "protType(%d)\n", protType);
5038 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET027, 0, prntBuf);
5042 /* fill up the length of cmsghdr structure */
5043 tempHdr->cmsg_len = len;
5048 }/* end of cmInet6BuildSendPktinfo */
5049 #endif /* LOCAL_INTF */
5055 * Fun: cmInetBuildSendHoplimit
5057 * Desc: This function inserts hoplimit value to be sent out by ancillary
5058 * data by calling sendmsg()function.
5068 static S16 cmInetBuildSendHoplimit
5070 uint32_t hoplimit, /* the hoplimit value to be set on outgoing packet */
5071 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5072 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5075 struct cmsghdr *tempHdr;
5081 /* cmsghdr struc will appear before data in the ancillary data object.
5082 * So put cmsghdr struc in flat buffer first. */
5084 /* cmsghdr struc points to flat buffer's starting address */
5085 tempHdr = (struct cmsghdr *)cmsgBuf;
5087 /* fill up level & type of cmsghdr structure */
5088 tempHdr->cmsg_level = IPPROTO_IPV6;
5089 tempHdr->cmsg_type = IPV6_HOPLIMIT;
5091 /* skip cmsghdr struc (length of cmsghdr structure) */
5092 len += sizeof(struct cmsghdr);
5094 /* insert the hoplimit. This will override the kernel's
5095 * default hoplimit value */
5096 *(cmsgBuf + len) = hoplimit;
5097 len += sizeof(hoplimit);
5099 /* fill up the length of cmsghdr structure */
5100 tempHdr->cmsg_len = len;
5104 } /* end of cmInetBuildSendHoplimit */
5105 #endif /* SS_LINUX */
5110 * Fun: cmInet6BuildSendHBHOpts
5112 * Desc: This function builds the HopByHop option which will be put
5113 * in the data portion of the ancillary data object. To build
5114 * the HopByHop option this function takes an array of
5115 * individual HopByHop option and fill them in a flat buffer.
5116 * cmsghdr struc always appear before HopBYHop Options, Dest
5117 * Options and Route header option.
5119 * The address of the flat Buffer *cmsgBuf is passed to this
5120 * function from cmInetSendMsg. This buffer will have all extension
5121 * headers. This buffer is passed as ancillary data by sendmsg()
5125 * Notes: This function will also be used for Destination options
5131 static S16 cmInet6BuildSendHBHOpts
5133 CmInetIpv6HBHHdrArr *hbhOptsArr,/* IPv6 extensions headers HBH/Dest opts */
5134 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5135 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5136 uint8_t hdrId /* 0: HBH hdr, 1:Dest Hdr */
5139 struct cmsghdr *tempHdr;
5147 /* cmsghdr struc will appear before data in the ancillary data object.
5148 * So put cmsghdr struc in flat buffer first. */
5150 /* cmsghdr struc points to flat buffer's starting address */
5151 tempHdr = (struct cmsghdr *)cmsgBuf;
5153 /* fill up level & type of cmsghdr structure */
5156 tempHdr->cmsg_level = IPPROTO_IPV6;
5157 tempHdr->cmsg_type = IPV6_HOPOPTS;
5159 else if (hdrId == 1)
5161 tempHdr->cmsg_level = IPPROTO_IPV6;
5162 tempHdr->cmsg_type = IPV6_DSTOPTS;
5165 /* skip cmsghdr struc (length of cmsghdr structure) */
5166 len += (sizeof(tempHdr->cmsg_level) + sizeof(tempHdr->cmsg_len) +
5167 sizeof(tempHdr->cmsg_type));
5169 /* Next Hdr: will be fill up accordingly by Kernel */
5170 *(cmsgBuf + len) = 0x00;
5173 /* Header Ext Length: will be fill up by us. In units of 8-byte excluding
5174 * first 8 bytes starting from Next Header field. */
5175 *(cmsgBuf + len) = 0x00;
5178 /* fillup all HBH/dest options' TLV. Here, we assume that all the HBH/dest
5179 * options are packed inside 1 HBH option header. */
5180 for (optsIdx = 0; optsIdx < hbhOptsArr->numHBHOpts;
5183 /* Copy the TLV into cmsgBuf data portion */
5184 /* copy type field of every HBH/dest option */
5185 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].type;
5186 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].type);
5188 /* copy length field of every HBH/dest option */
5189 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].length;
5190 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].length);
5192 /* copy all value bytes of current HBH/dest option to the flat buffer */
5193 memcpy((cmsgBuf + len),
5194 (hbhOptsArr->hbhOpts[optsIdx].value),
5195 hbhOptsArr->hbhOpts[optsIdx].length);
5196 len += hbhOptsArr->hbhOpts[optsIdx].length;
5199 /* cuMsgIdx will have the total length of HBH options array */
5200 /* add this length to the length of cmsgHdr struc */
5202 /* Padding: Different header has different padding requirement(xn+y). For
5203 * HBH Router Alert we need 2 bytes of padding. As this same function is
5204 * used for Destination option also and there is no option for it is yet
5205 * proposed, we are passing padN options - 6 bytes to make the Dest Option
5206 * hdr a multiple of 8 bytes. */
5208 /* HBH: padN of 2 bytes needed for Router Alert */
5209 /* This logic is present currently to support router alert which is the
5210 * only supported HBH option today. For other, generic method needed */
5213 *(cmsgBuf + len) = 0x01;
5215 *(cmsgBuf + len) = 0x00;
5219 /* fill up the length of cmsghdr structure */
5220 tempHdr->cmsg_len = len;
5224 } /* end of cmInet6BuildSendHBHOpts */
5229 * Fun: cmInet6BuildSendRouteOpts
5231 * Desc: This function transfers bytes from the Route hdr array to the
5232 * flat buffer. First the top cmsghdr structure will be filled in
5233 * the flat buffer, then route hdr type 0 will be added after
5234 * cmsghdr struc in the flat buffer. Then all IPV6 addresses will
5245 static S16 cmInet6BuildSendRouteOpts
5247 CmInetIpv6RtHdr *rtOptsArr, /* IPv6 destination options array */
5248 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5249 uint32_t *curMsgIdx /* idx in cmsgBuf where to start building RT hdr */
5252 struct cmsghdr *tempHdr;
5253 CmInetIpv6RtHdr0 *tempRtHdr;
5261 /* cmsghdr struc will appear before data in the ancillary data object.
5262 * So put cmsghdr struc in flat buffer first */
5264 /* cmsghdr struc points to flat buffer */
5265 tempHdr = (struct cmsghdr *)(cmsgBuf);
5267 tempHdr->cmsg_level = IPPROTO_IPV6;
5268 tempHdr->cmsg_type = IPV6_RTHDR;
5270 /* skip cmsghdr structure */
5271 len += sizeof(struct cmsghdr);
5273 /* we know the total size of Route hdr if we know the num of ipv6 addrs */
5274 tempHdr->cmsg_len = len + sizeof(CmInetIpv6RtHdr0)
5275 + rtOptsArr->numAddrs * sizeof(CmInetIpAddr6);
5277 /* attach route hdr type 0 after cmsghdr structure */
5278 tempRtHdr = (CmInetIpv6RtHdr0 *)(cmsgBuf + len);
5280 /* fill up fields of route hdr type 0 */
5282 /* will be filled up by Kernel */
5283 tempRtHdr->ip6r0_nextHdr = 0x00;
5285 tempRtHdr->ip6r0_hdrExtLen = (2 * rtOptsArr->numAddrs);
5287 /* only type supported today */
5288 tempRtHdr->ip6r0_type = 0x00;
5290 tempRtHdr->ip6r0_segLeft = rtOptsArr->numAddrs;
5292 /* Note: rfc 2292(1998) mentions 1 reserve byte & 3 strict/loose bytes
5293 * restricting total 23 ipv6 addresses can be added to the route header.
5294 * But rfc 2292(2002) mentions all 4 bytes are reserved which allows
5295 * as many ipv6 addresses as wishes to be added to the route header */
5297 tempRtHdr->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5299 /* move pointer in the flat buffer to the end of this structure */
5300 len += sizeof(CmInetIpv6RtHdr0);
5302 /* fill up all IPV6 addresses from rtOptsArr in the flat buffer */
5303 for (addrIdx = 0; addrIdx < rtOptsArr->numAddrs; addrIdx++)
5305 memcpy((cmsgBuf + len),
5306 (rtOptsArr->ipv6Addrs[addrIdx]), 16);
5312 } /* end of cmInet6BuildSendRouteOpts */
5317 * Fun: cmInet6BuildRecvHopOptsArr
5319 * Desc: This function fills up the HopByHop Array of ipHdrParam from
5320 * the ancillary data received through recvmsg() call. The memory
5321 * to hold the extension headers is allocated here. All received
5322 * ext hdr info will be passed to upper user as ipHdrParam.
5324 * Ret: ROK - successful
5333 static S16 cmInet6BuildRecvHopOptsArr
5335 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5336 uint32_t hbhDataLen, /* byte len of cmsghdr + hbh ancil data */
5337 CmInetIpv6HBHHdrArr *hbhOptsArr, /* IPv6 extensions headers */
5338 uint8_t hdrId, /* 0: HBH, 1: DEST */
5339 CmInetMemInfo *info /* Memory information */
5342 uint32_t curDataIdx; /* to keep track where we are in the hbh Data */
5343 uint8_t optsIdx; /* how many hbh opts present in data */
5344 uint8_t numOpts; /* number of hbh opts present in data */
5350 /* get length of actual hbh ancillary data */
5351 hbhDataLen -= sizeof(struct cmsghdr);
5357 /* skip Next Hdr byte & Hdr Ext Length byte */
5360 /* First find out how many hop-by-hop headers we need to allocate */
5363 /* break when all HBH data is copied to hbhOptsArr */
5364 if (curDataIdx >= hbhDataLen)
5370 tempType = *(uint8_t *)(cmsgData + curDataIdx);
5373 /* take care of pad1 option */
5376 /* not considering the pad1 as valid option */
5382 tempLen = *(uint8_t *)(cmsgData + curDataIdx);
5384 /* 1 is to skip length. tempLen to skip the value field */
5385 curDataIdx += (1 + tempLen);
5387 /* considering the padN as valid option for Dest Opt Hdr!!! As this is
5388 * the "only" valid option today. Ignore for HBH hdr */
5394 /* allocate mem needed to hold all HBH/Dest options */
5395 ret = SGetSBuf(info->region, info->pool,
5396 (Data **)&hbhOptsArr->hbhOpts,
5397 (Size)((sizeof(CmInetIpv6HBHHdr)) * numOpts));
5401 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5402 /* cm_inet_c_001.main_62:Warning fix */
5403 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvHopOptsArr\n");
5404 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET028, 0, prntBuf);
5405 #endif /* CMINETDBG */
5412 /* skip Next Hdr byte & Hdr Ext Length byte */
5415 hbhOptsArr->numHBHOpts = numOpts;
5417 /* fill up HBH/dest opt array from recvd ancillary data */
5420 /* break when all HBH data is copied to hbhOptsArr */
5421 if (curDataIdx >= hbhDataLen)
5424 /* only copy Router Alert HBH option part which has type 5. Otherwise,
5425 * skip it when it is a PAD1, PADN or Jumbogram option for HBH. But
5426 * consider padN as valid option for dest opt hdr. */
5428 /* get the type of current HBH/dest option */
5429 tempType = *(cmsgData + curDataIdx);
5432 /* ignore PAD1 for both HBH/dest by skipping to next option */
5436 /* calculate how much to skip for padN in case of HBH */
5441 /* get the length field of padN option */
5442 tempLen = *(cmsgData + curDataIdx);
5445 /* move pointer forward to skip value field */
5446 curDataIdx += tempLen;
5450 hbhOptsArr->hbhOpts[optsIdx].type = tempType;
5452 /* copy the length */
5453 hbhOptsArr->hbhOpts[optsIdx].length = *(cmsgData + curDataIdx);
5456 /* take care of PADN = 2 when value field empty. We also don't need
5457 * to allocate memory for empty value field */
5458 if (hbhOptsArr->hbhOpts[optsIdx].length == 0)
5459 hbhOptsArr->hbhOpts[optsIdx].value = NULLP;
5462 /* take care of all other options having valid value field
5463 * such as Router Alert, PADN >= 3 bytes and Jumbo */
5464 ret = SGetSBuf(info->region, info->pool,
5465 (Data **)&hbhOptsArr->hbhOpts[optsIdx].value,
5466 (Size)hbhOptsArr->hbhOpts[optsIdx].length);
5470 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5471 /* cm_inet_c_001.main_62:Warning fix */
5472 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 2 cmInet6BuildRecvHopOptsArr\n");
5473 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET029, 0, prntBuf);
5474 #endif /* CMINETDBG */
5475 /* now go inside every separate HBH option and free the memory
5476 * allocated for its value field */
5477 for (; optsIdx > 0; optsIdx --)
5479 if (hbhOptsArr->hbhOpts[optsIdx - 1].value != NULLP)
5482 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5483 /* cm_inet_c_001.main_62:Warning fix */
5484 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 1 in BuildRecvHopOptsArr\n");
5485 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET030, 0, prntBuf);
5486 #endif /* CMINETDBG */
5487 SPutSBuf(info->region, info->pool,
5488 (Data *)hbhOptsArr->hbhOpts[optsIdx - 1].value,
5489 (Size)hbhOptsArr->hbhOpts[optsIdx - 1].length);
5492 /* clean up all CmInetIpv6HBHHdr structures allocated for all
5493 * arrived HBH options OR numOpts CmInetIpv6HBHHdr structures
5494 * allocated after counting numOpts */
5496 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5497 /* cm_inet_c_001.main_62:Warning fix */
5498 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 2 in BuildRecvHopOptsArr\n");
5499 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET031, 0, prntBuf);
5500 #endif /* CMINETDBG */
5501 SPutSBuf(info->region, info->pool,
5502 (Data *)hbhOptsArr->hbhOpts, numOpts * sizeof(CmInetIpv6HBHHdr));
5503 hbhOptsArr->numHBHOpts = 0;
5504 hbhOptsArr->hbhOpts = NULLP;
5507 /* copy the value bytes */
5508 memcpy(hbhOptsArr->hbhOpts[optsIdx].value,
5509 (cmsgData + curDataIdx),
5510 hbhOptsArr->hbhOpts[optsIdx].length);
5511 curDataIdx += hbhOptsArr->hbhOpts[optsIdx].length;
5514 /* get next option */
5518 } /* end of cmInet6BuildRecvHopOptsArr() */
5523 * Fun: cmInet6BuildRecvRtHdr
5525 * Desc: This function fills up the Route Header in the cmInetIpv6HdrParm
5526 * from the recvd ancillary data from recvmsg system call.
5528 * Ret: ROK - successful
5537 static S16 cmInet6BuildRecvRtHdr
5539 uint8_t *cmsgData, /* flat buffer where to build Route hdr */
5540 uint32_t rtDataLen, /* byte len of cmsghdr struc+rtHdr ancil data */
5541 CmInetIpv6RtHdr0 *rtHdr0, /* rtHeader0 struct that precedes IPV6 addrss */
5542 CmInetIpv6RtHdr *rtOptsArr,/* IPv6 extensions headers */
5543 CmInetMemInfo *info /* Memory information */
5546 uint32_t curDataIdx; /* to keep track where we are in hbh Data */
5547 uint8_t i; /* loop counter */
5548 S16 ret; /* temporary return value */
5551 /* byte len of actual rtHdr ancil data */
5552 rtDataLen -= sizeof(struct cmsghdr);
5554 /* start from beginning */
5557 /* copy next header byte */
5558 rtHdr0->ip6r0_nextHdr = *(cmsgData + curDataIdx);
5561 /* copy header extension length byte */
5562 rtHdr0->ip6r0_hdrExtLen = *(cmsgData + curDataIdx);
5565 /* copy type byte (always 0) */
5566 rtHdr0->ip6r0_type = 0x00;
5569 /* copy segment left byte */
5570 rtHdr0->ip6r0_segLeft = *(cmsgData + curDataIdx);
5573 /* copy 1 reserve byte + 3 strict/loose bytes */
5574 memcpy((&rtOptsArr->slMap),
5575 (cmsgData + curDataIdx), 4);
5578 /* also save reserv byte + 3 sl bytes to rtHdro struc */
5579 rtHdr0->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5581 /* subtract 8 bytes for Next Hdr, Hdr Ext Len, .... + SL bit map */
5582 rtOptsArr->numAddrs = (rtDataLen - 8)/16;
5584 ret = SGetSBuf(info->region, info->pool,
5585 (Data **)&rtOptsArr->ipv6Addrs,
5586 (Size)rtOptsArr->numAddrs * 16);
5590 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5591 /* cm_inet_c_001.main_62:Warning fix */
5592 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvRtHdr\n");
5593 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET032, 0, prntBuf);
5594 #endif /* CMINETDBG */
5598 /* copy all the ipv6 addresses */
5599 for(i=0; i < rtOptsArr->numAddrs; i++)
5601 memcpy((rtOptsArr->ipv6Addrs[i]),
5602 (cmsgData + curDataIdx), 16);
5607 } /* end of cmInet6BuildRecvRtHdr() */
5612 * Fun: cmInet6GetHopLimitValue
5614 * Desc: This function extracts the hop limit value(ttl) of from the
5615 * ancillary data received through recvmsg() call. Then this
5616 * hoplimit value will be passed to upper user as ipHdrParam.
5618 * Ret: ROK - successful
5626 static S16 cmInet6GetHopLimitValue
5628 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5629 uint32_t hopLimitDataLen, /* byte len of cmsghdr + hbh ancil data */
5630 CmInetIpv6HdrParm *ipv6HdrParam /* ipv6 header parameters */
5633 uint16_t curDataIdx; /* to keep track where we are in the ancillary Data */
5634 uint32_t *hopLimitValue; /* ttl/hoplimit value */
5636 hopLimitValue = NULL;
5639 /* get length of actual hbh ancillary data */
5640 hopLimitDataLen -= sizeof(struct cmsghdr);
5642 /* go to the first byte of hop limit which present after cmsghdr struc */
5643 curDataIdx += sizeof(struct cmsghdr);
5645 /* mark that hoplimit(ttl) is present */
5646 ipv6HdrParam->ttl.pres = TRUE;
5648 /* the first byte will be the HopLimit value */
5649 hopLimitValue = (uint32_t *)(cmsgData);
5650 ipv6HdrParam->ttl.val = (uint8_t)(*hopLimitValue);
5654 #endif /* IPV6_OPTS_SUPPORTED */
5659 * Fun: cmInetRecvMsg
5661 * Desc: Reads data from a socket into a message.
5662 * The buffers for the message are allocated within the
5663 * cmInetRead() function from the pool and region Id set in the
5665 * If the number of octets given by the paramter len is not
5666 * available the function immediately returns with RKDNA.
5667 * If the len parameter is set to CM_INET_READ_ANY, the currently
5668 * available data is read.
5669 * Values for flag parameter:
5671 * CM_INET_NO_FLAG - no additional control flag
5672 * CM_INET_MSG_PEEK - do not destroy data on receive buffer
5674 * Ret: ROK - successful
5675 * ROKDNA - ok, data not available
5676 * RCLOSED - connection closed by peer
5677 * ROUTRES - failed, out of resources
5687 CmInetFd *sockFd, /* socket file descriptor */
5688 CmInetAddr *fromAddr, /* sender Internet address/port */
5689 CmInetMemInfo *info, /* buffer allocation info */
5690 Buffer **mPtr, /* received buffer structure */
5691 MsgLen *len, /* number of octets to read */
5692 /* added for IPv6 */
5693 #ifdef IPV6_OPTS_SUPPORTED
5694 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
5695 #endif /* IPV6_OPTS_SUPPORTED */
5697 CmInetLocalInf *localIf, /* local interface on which pkt was recvd */
5698 #endif /* LOCAL_INTF */
5699 S32 flags /* additional control flags */
5702 #if (defined(WIN32) || defined(CMINETFLATBUF))
5703 S32 ret; /* temporary return value */
5704 uint32_t pendLen; /* pending data length */
5705 S32 recvLen; /* number of received octets by recvmsg() */
5706 MsgLen bufLen; /* entire number of received octets */
5707 MsgLen curLen; /* current number of octets in buffer */
5708 Data *recvBuf; /* receive buffer */
5709 Data *bufPtr; /* current buffer position */
5710 Buffer *mBuf; /* received message */
5711 uint32_t remAddrLen; /* length of remote address */
5712 struct sockaddr_in *remAddr; /* remote Internet address */
5713 #ifdef IPV6_SUPPORTED
5714 struct sockaddr_in6 *remAddr6; /* remote Internet address */
5715 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
5717 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
5718 #endif /* IPV6_SUPPORTED */
5720 S32 ret; /* temporary return value */
5721 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
5722 uint16_t i; /* index */
5723 uint32_t pendLen; /* pending data length */
5724 S32 numBuf; /* number of allocated dBufs */
5725 S32 recvLen; /* number of received octets by recvmsg() */
5726 MsgLen bufLen; /* entire number of received octets */
5727 struct msghdr msg; /* message header */
5728 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5729 Buffer *tempMsg = NULLP; /* temporary message */
5730 CmInetIovec rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
5731 Buffer **dBufs = NULLP; /* dynamic array with allocated dBufs */
5732 S16 numDBufs; /* number of allocated dBufs */
5734 /* cm_inet_c_001.main_55: As remAddrLen is only being used when
5735 * WIN32 or CMINETFLATBUF is defined, then Removed variable
5737 struct sockaddr_in *remAddr; /* remote Internet address */
5738 #ifdef IPV6_SUPPORTED
5739 struct sockaddr_in6 *remAddr6; /* remote Internet address */
5740 struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
5741 /* added for IPv6 ext headers support */
5742 #ifdef IPV6_OPTS_SUPPORTED
5743 CmInetIpv6RtHdr0 rtHdr0; /* type 0 route header */
5744 #endif /* IPV6_OPTS_SUPPORTED */
5747 struct in6_pktinfo *pkt6Info; /* IPv6 IP_PKTINFO */
5748 #endif /* LOCAL_INTF */
5750 #if (defined(SS_LINUX) || defined(_XPG4_2))
5751 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
5752 /* from stack for IPv6 ancill data */
5755 CmInetSockAddr remSockAddr; /* to get packet's src IP address */
5756 #if (defined(SS_LINUX) || defined(_XPG4_2))
5757 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
5758 /* from stack for IPv4 ancill data */
5760 #endif /* IPV6_SUPPORTED */
5761 /* added new definitions */
5762 Bool allocFlatBuf; /* allocate a flat buffer */
5763 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5764 Data *recvBuf = NULLP; /* receive buffer */
5767 struct in_pktinfo *pkt4Info; /* IPv4 IP_PKTINFO */
5769 #endif /* SS_LINUX */
5770 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
5771 struct cmsghdr *cmsgptr;/* pointer to struct cmsghdr */
5773 #endif /* WIN32 | CMINETFLATBUF */
5774 /* used by getsockopt */
5776 /* cm_inet_c_001.main_55:Removed unused variables errValue and optLen */
5779 #if (ERRCLASS & ERRCLS_INT_PAR)
5780 /* error check on parameters */
5781 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
5782 (info == NULLP) || (mPtr == NULLP) || (len == NULLP))
5786 #endif /* ERRCLASS & ERRCLS_INT_PAR */
5790 /*cm_inet_c_001.main_48 variables declaration */
5791 #if !((defined(WIN32) || defined(CMINETFLATBUF)))
5796 #if (defined(WIN32) || defined(CMINETFLATBUF))
5798 #ifdef IPV6_SUPPORTED
5800 #endif /* IPV6_SUPPORTED */
5802 #ifdef IPV6_SUPPORTED
5805 #endif /* IPV6_SUPPORTED */
5807 #if (defined(SS_LINUX) || defined(_XPG4_2))
5808 memset(ancillData, 0, sizeof(ancillData));
5809 #endif /* SS_LINUX || _XPG4_2 */
5811 #endif /* (WIN32 | CMINETFLATBUF) */
5813 /* clear the structure */
5814 memset(&remSockAddr, 0, sizeof(remSockAddr));
5816 /* get number of pending data */
5817 /* removed 3rd arg memInfo. MemInfo is no longer
5818 needed as we call ioctl for all sockets */
5820 /* cm_inet_c_001.main_48 : call ioctl only for STREAM
5821 * sockets now. For Non-Stream sockets(Raw & UDP), fix
5822 * pending length to CM_INET_MAX_UDPRAW_MSGSIZE
5824 if(sockFd->type == CM_INET_STREAM)
5826 ret = cmInetGetNumRead(sockFd, &pendLen);
5829 /* ret may be RFAILED or ROUTRES */
5835 /* cm_inet_c_001.main_48 : pendLen is set 1 greater
5836 * than the #defined value. If recvFrom/recvMsg
5837 * returns the len == pendLen, we would drop the
5838 * message as the msg len is larger than the largest
5839 * msg we are willing to accept.
5841 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE+1;
5845 /* check if connection got closed */
5848 if (sockFd->type == CM_INET_STREAM)
5850 /* cm_inet_c_001.main_50:
5851 * cm_inet_c_001.main_56: Removed comment for cm_inet_c_001.main_50 as
5852 * the current patch changes its functionality */
5853 uint8_t readBuf[1]; /* declaration of variable for Peek */
5856 * cm_inet_c_001.main_56:
5857 * We are peeking the socket buffer again with peek as on some machines
5858 * like solaris, there is a latency observed in ioctl. In such cases,
5859 * ioctl may return 0, even though there are bytes available to read.
5860 * We reconfirm through peek whether 0 means EOF or its ioctl latency
5863 ret = cmInetPeekNew(sockFd, NULLP, info, 0, 1, readBuf);
5868 /* cm_inet_c_001.main_56:
5869 * Returning ROKDNA even cmInetPeekNew returns ROK. Because currently
5870 * we are not sure about pending length. Anyway socket FD already set,
5871 * we do another iteration to get exact pendLen value. We cannot call
5872 * cmInetGetNumRead at this point because of latency between the ioctl
5873 * call and recvfrom call issues on some machines ioctl call may
5874 * return ZERO even their a data to read. */
5878 /* cm_inet_c_001.main_52: Support for partial reception */
5879 /* cm_inet_c_001.main_59: Fix for compilation warning */
5880 if ((sockFd->type == CM_INET_STREAM) && (*len > (MsgLen)pendLen))
5882 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5883 *len = (MsgLen)pendLen;
5886 /* check if there are enough pending data to read */
5887 if ((*len == CM_INET_READ_ANY) || ((uint32_t)*len <= pendLen))
5889 if (*len == CM_INET_READ_ANY)
5891 /* added check for TCP socket. Pending data length in
5892 the socket recv buffer is determined by ioctl call in
5894 For TCP it can't be > CM_INET_MAX_MSG_LEN. */
5895 if (sockFd->type == CM_INET_STREAM)
5897 /* max message length is limited to control the memory usage */
5898 if (pendLen > CM_INET_MAX_MSG_LEN)
5899 pendLen = CM_INET_MAX_MSG_LEN;
5901 /* cm_inet_c_001.main_48 : removed the check for
5902 * Non Stream sockets (pendLen < MAX_UDPRAW_MSGSIZE)
5903 * as we are hardcoding pendLen for Non-Stream sockets.
5906 /* read all pending data */
5907 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5908 bufLen = (MsgLen)pendLen;
5909 *len = (MsgLen)pendLen;
5913 /* cm_inet_c_001.main_45- Returning CM_INET_MAX_MSG_LEN when input is larger than
5916 /* max message length is limited to control the memory usage */
5917 if ((*len) > CM_INET_MAX_MSG_LEN)
5919 (*len) = CM_INET_MAX_MSG_LEN;
5922 /* read data length given by user */
5926 #if (defined(WIN32) || defined(CMINETFLATBUF))
5928 /* set destination Internet address structure */
5929 if (fromAddr != NULLP)
5931 remAddrLen = sizeof(remSockAddr);
5938 /* allocate flat receive buffer */
5939 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
5948 * maybe needs more than one recvfrom() call to read an entire
5949 * message from a stream socket (TCP)
5953 /* added separate recvfrom calls different OS */
5955 /*cm_inet_c_001.main_42 1. In Vx-Works the 5th and 6th parameter of recvfrom
5956 system call are either NULL or should be valid pointer.*/
5957 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
5959 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5960 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
5962 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5963 NULLP, (int *)&remAddrLen);
5965 #if ( defined(SUNOS) || defined(SS_LINUX))
5967 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5968 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
5970 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5971 NULLP, (socklen_t *)&remAddrLen);
5974 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5975 &remSockAddr, (S32 *)&remAddrLen);
5977 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5978 NULLP, (S32 *)&remAddrLen);
5980 #endif /* defined(SUNOS) || defined(SS_LINUX) */
5981 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
5983 if (recvLen == INET_ERR)
5986 /* moved cleanup here */
5987 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
5989 /* added check ERR_WOULDBLOCK */
5990 if ((INET_ERR_CODE == ERR_AGAIN) ||
5991 (INET_ERR_CODE == ERR_WOULDBLOCK))
5998 /* In Windows the recvfrom function fails
5999 * with error code which maps to either WSAECONNABORTED. If
6000 * this happens then cmInetRecvMsg must return RCLOSED */
6001 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
6002 (INET_ERR_CODE == ERR_CONNRESET))
6010 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6011 /* cm_inet_c_001.main_62:Warning fix */
6012 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6013 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6014 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6016 /* cm_inet_c_001.main_62:Warning fix */
6017 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6018 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6019 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6020 #endif /*ALIGN_64BIT*/
6021 #endif /* CMINETDBG */
6029 * a message is always read atomically on a datagram socket,
6030 * therefore it's ok to read less than pending data!
6033 if ((sockFd->type == CM_INET_RAW) ||
6034 (sockFd->type == CM_INET_DGRAM))
6039 #else /* CM_INET2 */
6040 if (sockFd->type == CM_INET_DGRAM)
6045 #endif /* CM_INET2 */
6046 } /* while (curLen > 0) (only for stream sockets) */
6048 /* For UDP, it is possible to receive
6049 * a 0 byte datagram, in this case just return ROKDNA.
6052 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6055 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6058 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6062 /* cm_inet_c_001.main_48 : If Received
6063 * len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6067 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6068 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6070 if ((sockFd->type == CM_INET_DGRAM)
6071 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6076 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6077 /* cm_inet_c_001.main_62:Warning fix */
6078 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6079 " > than allowed(%lu), sockFd->fd(%ld) \n",
6080 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6081 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6083 /* cm_inet_c_001.main_62:Warning fix */
6084 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6085 " > than allowed(%lu), sockFd->fd(%d) \n",
6086 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6087 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6088 #endif /*ALIGN_64BIT*/
6090 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6094 /* cm_inet_c_001.main_48 : copy data to a message structure */
6095 ret = SGetMsg(info->region, info->pool, &mBuf);
6099 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6104 if ((sockFd->type == CM_INET_DGRAM) ||
6105 (sockFd->type == CM_INET_RAW))
6107 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6111 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6114 #else /* CM_INET2 */
6115 if (sockFd->type == CM_INET_DGRAM)
6117 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6121 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6123 #endif /* CM_INET2 */
6127 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6133 /* setup return destination Internet address */
6134 /* added the check of (remAddrLen > 0) */
6135 if ((fromAddr != NULLP) && (remAddrLen > 0))
6137 #ifdef IPV6_SUPPORTED
6138 if (remAddrLen == sizeof(struct sockaddr_in6))
6140 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6141 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6142 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6143 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6144 &remAddr6->sin6_addr);
6148 remAddr = (struct sockaddr_in *)&remSockAddr;
6149 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6150 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6151 fromAddr->u.ipv4Addr.address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6154 remAddr = (struct sockaddr_in *)&remSockAddr;
6155 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6156 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6157 #endif /* IPV6_SUPPORTED */
6161 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6163 #else /* end of Win NT/flat buffer specific part */
6165 /* Initialise variable */
6166 allocFlatBuf = FALSE;
6169 * maybe needs more than one recvmsg() call to read entire message
6170 * on a stream socket
6174 /* allocate gather vector, it's a dynamic array */
6175 numDBufs = CM_INET_MAX_DBUF;
6177 ret = SGetSBuf(info->region, info->pool, (Data**)&dBufs,
6178 numDBufs*sizeof(Buffer*));
6184 /* Allocate dBufs for gather read */
6185 /* allocate dBufs for gathering read */
6186 if (sockFd->type == CM_INET_STREAM)
6187 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6190 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6194 /* check if the function returned RNA */
6197 /* Incase of UDP/RAW messages allocate a flat buffer. Incase
6198 * of TCP ignore this error condition. The user will call
6199 * cmInetRecvMsg again */
6200 /* cm_inet_c_001.main_62:Warning fix */
6201 if (sockFd->type != (uint8_t)CM_INET_STREAM)/* G++ */
6204 #ifdef T2K_MEM_LEAK_DBG
6205 char * file = __FILE__;
6206 uint32_t line = __LINE__;
6209 /* cleanup the dBuf array */
6210 for (i = 0; i < msg.msg_iovlen; i++)
6211 SPutDBuf(info->region, info->pool, dBufs[i]);
6213 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6214 numDBufs * sizeof(Buffer*));
6216 /* allocate flat receive buffer */
6217 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6221 allocFlatBuf = TRUE;
6223 /* update the message structure */
6225 rxArr[0].iov_base = (Void*)recvBuf;
6226 rxArr[0].iov_len = (uint32_t)bufLen;
6228 rxArr[0].iov_base = (S8*)recvBuf;
6229 rxArr[0].iov_len = bufLen;
6230 #endif /* SS_LINUX */
6231 msg.msg_iov = rxArr;
6237 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6238 numDBufs*sizeof(Buffer*));
6243 numBuf = msg.msg_iovlen;
6245 /* setup destination Internet address structure */
6246 if (fromAddr != NULLP)
6249 msg.msg_name = (Void*)&remSockAddr;
6252 msg.msg_name = (char *)&remSockAddr;
6254 msg.msg_name = (caddr_t)&remSockAddr;
6256 #endif /* SS_LINUX */
6257 msg.msg_namelen = sizeof(remSockAddr);
6261 msg.msg_name = NULLP;
6262 msg.msg_namelen = 0;
6265 /* added defined(_XPG4_2). Also changed the
6267 #if (defined(SS_LINUX) || defined(_XPG4_2))
6268 msg.msg_control = ancillData;
6269 msg.msg_controllen = sizeof(ancillData);
6271 msg.msg_accrights = NULLP;
6272 msg.msg_accrightslen = 0;
6273 #endif /* SS_LINUX */
6275 recvLen = recvmsg(sockFd->fd, &msg, flags);
6276 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
6278 /* Moved up the cleanup precedures here before returning */
6279 /* Cleanup flat buffer if allocated */
6281 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6285 for (i = 0; i < numBuf; i++)
6287 #ifdef T2K_MEM_LEAK_DBG
6288 char * file = __FILE__;
6289 uint32_t line = __LINE__;
6292 SPutDBuf(info->region, info->pool, dBufs[i]);
6294 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6295 numDBufs*sizeof(Buffer*));
6298 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6299 * it has partially received data
6301 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
6302 added check ERR_WOULDBLOCK */
6303 if ((INET_ERR_CODE == ERR_AGAIN) ||
6304 (INET_ERR_CODE == ERR_WOULDBLOCK))
6306 /* cm_inet_c_001.main_50 : If message is read partially then just return
6307 * OK without freeing the mPtr. This will gaurd us
6308 * against unexpected WOULDBLOCKS observed in solaris
6316 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6317 * it has partially received data
6325 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6326 /* cm_inet_c_001.main_62:Warning fix */
6327 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6328 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6329 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6331 /* cm_inet_c_001.main_62:Warning fix */
6332 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6333 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6334 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6335 #endif /*ALIGN_64BIT*/
6336 #endif /* CMINETDBG */
6338 /* If this happens then cmInetRecvMsg must return RCLOSED.
6339 * Needed for getting icmp msgs */
6340 if (INET_ERR_CODE == ERR_CONNABORTED)
6350 /* added for IPv6 extn headers */
6351 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6353 /* check if ancillary data has been received.
6354 * Return the allocated memory when no ancillary data received */
6355 #if (defined(SS_LINUX) || defined(_XPG4_2))
6356 if (msg.msg_controllen)
6358 cmsgptr = CMSG_FIRSTHDR(&msg);
6364 #endif /* SS_LINUX || _XPG4_2 */
6366 if (cmsgptr != NULLP)
6368 #ifdef IPV6_OPTS_SUPPORTED
6369 if(ipHdrParams != NULLP)
6371 ipHdrParams->u.ipv6HdrParm.ttl.pres = FALSE;
6372 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt = FALSE;
6373 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt = FALSE;
6374 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt = FALSE;
6376 /* get all ancillary data objects recvd one by one */
6377 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6378 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6380 if (cmsgptr->cmsg_level == IPPROTO_IPV6)
6382 /* Initialise ipHdrParams properly */
6383 ipHdrParams->type = CM_INET_IPV6ADDR_TYPE;
6385 if (cmsgptr->cmsg_type == IPV6_HOPOPTS)
6387 /* build up HBH opt array from recvd ancillary data */
6388 ret = cmInet6BuildRecvHopOptsArr(
6389 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6390 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
6394 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt =
6398 else if(cmsgptr->cmsg_type == IPV6_DSTOPTS)
6400 else if ((cmsgptr->cmsg_type == IPV6_DSTOPTS) ||
6401 (cmsgptr->cmsg_type == IPV6_RTHDRDSTOPTS))
6402 #endif /* SS_LINUX */
6404 /* build up Dest opt array from recvd ancillary data */
6405 ret = cmInet6BuildRecvDstOptsArr(
6406 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6407 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr,
6411 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt =
6414 else if (cmsgptr->cmsg_type == IPV6_RTHDR)
6416 /* build up Route Hdr from recvd ancillary data */
6417 ret = cmInet6BuildRecvRtHdr(
6418 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, &rtHdr0,
6419 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
6423 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt =
6426 else if(cmsgptr->cmsg_type == IPV6_HOPLIMIT)
6428 /* get the received hoplimit */
6429 ret = cmInet6GetHopLimitValue((uint8_t *)CMSG_DATA(cmsgptr),
6430 cmsgptr->cmsg_len, &ipHdrParams->u.ipv6HdrParm);
6437 #endif /* IPV6_OPTS_SUPPORTED */
6439 #ifdef IPV6_SUPPORTED
6441 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6442 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6444 if(cmsgptr->cmsg_type == IPV6_PKTINFO)
6446 pkt6Info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
6447 localIf->intfPrsnt = TRUE;
6448 localIf->localIf = pkt6Info->ipi6_ifindex;
6449 localIf->localIfAddr.type = CM_INET_IPV6ADDR_TYPE;
6450 memcpy(&localIf->localIfAddr.u.ipv6NetAddr,
6451 &pkt6Info->ipi6_addr, 16);
6454 #endif /* LOCAL_INTF */
6457 #if (defined(SS_LINUX) && defined(LOCAL_INTF))
6458 #ifdef IPV6_SUPPORTED
6459 if(sockFd->protType == AF_INET)
6462 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
6463 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6465 if (cmsgptr->cmsg_level == IPPROTO_IP &&
6466 cmsgptr->cmsg_type == IP_PKTINFO)
6468 pkt4Info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
6469 localIf->intfPrsnt = TRUE;
6470 localIf->localIf = pkt4Info->ipi_ifindex;
6471 localIf->localIfAddr.type = CM_INET_IPV4ADDR_TYPE;
6472 localIf->localIfAddr.u.ipv4NetAddr =
6473 ntohl(*(int *)&pkt4Info->ipi_addr);
6476 #ifdef IPV6_SUPPORTED
6479 #endif /* SS_LINUX */
6481 #endif /* IPV6_OPTS_SUPPORTED || LOCAL_INTF */
6483 /* setup return destination Internet address */
6484 if (fromAddr != NULLP)
6486 #ifdef IPV6_SUPPORTED
6487 if (msg.msg_namelen == sizeof(struct sockaddr_in6))
6489 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6490 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6491 fromAddr->u.ipv6Addr.port =
6492 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6493 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6494 &remAddr6->sin6_addr);
6498 remAddr = (struct sockaddr_in *)&remSockAddr;
6499 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6500 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6501 fromAddr->u.ipv4Addr.address =
6502 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6505 remAddr = (struct sockaddr_in *)&remSockAddr;
6506 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6507 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6508 #endif /* IPV6_SUPPORTED */
6511 /* Incase a flat buffer was allocated get
6512 * a message to pass up */
6518 ret = SGetMsg(info->region, info->pool, &tempMsg);
6522 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6526 /* cm_inet_c_001.main_48 : A 0 len UDP packet could be received */
6529 ret = SAddPstMsgMult(recvBuf, recvLen, tempMsg);
6532 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6540 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6541 /* cm_inet_c_001.main_48 :flat buffers are allocated
6542 * for non -TCP sockets. On these sockets we can receive
6543 * only one message at a time
6545 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6546 *len = (MsgLen)recvLen;
6551 /* build message out of dBufs */
6552 ret = buildRecvMsg(info, rxArr, numBuf, recvLen, dBufs, &tempMsg);
6555 /* Deallocate previously allocated
6559 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6560 numDBufs*sizeof(Buffer*));
6567 /* it's first recvmsg() call */
6572 /* concatenate messages */
6573 ret = SCatMsg(*mPtr, tempMsg, M1M2);
6579 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6580 numDBufs*sizeof(Buffer*));
6586 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6587 numDBufs*sizeof(Buffer*));
6590 * a message is always read atomically on a datagram socket,
6591 * therefore it's ok to read less than pending data!
6594 if ((sockFd->type == CM_INET_DGRAM) ||
6595 (sockFd->type == CM_INET_RAW))
6597 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6598 *len = (MsgLen)recvLen;
6601 #else /* CM_INET2 */
6602 if (sockFd->type == CM_INET_DGRAM)
6604 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6605 *len = (MsgLen)recvLen;
6608 #endif /* CM_INET2 */
6609 } /* while(bufLen > 0) (only for stream sockets) */
6611 /* cm_inet_c_001.main_48 : For UDP, it is possible to receive
6612 * a 0 byte datagram, in this case just return ROKDNA
6616 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6619 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6631 /* Received len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6636 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6637 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6639 if ((sockFd->type == CM_INET_DGRAM)
6640 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6651 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6652 /* cm_inet_c_001.main_62:Warning fix */
6653 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6654 " allowed(%d),sockFd->fd(%ld)\n",
6655 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6656 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6658 /* cm_inet_c_001.main_62:Warning fix */
6659 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6660 " allowed(%d),sockFd->fd(%d)\n",
6661 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6662 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6669 #endif /* WIN32 | CMINETFLATBUF */
6673 /* not enough data pending yet */
6678 } /* end of cmInetRecvMsg */
6681 /* cm_inet_c_001.main_56: Added new function cmInetPeekNew() */
6685 * Fun: cmInetPeekNew
6687 * Desc: Reads some data from the socket without destroying the socket
6689 * The data is specified by the byte positon (first byte is at
6690 * position 0) and the length.
6692 * Ret: ROK - successful
6693 * ROKDNA - ok, data not available
6694 * RCLOSED - connection closed by peer
6697 * Notes: Following are the differences from the cmInetPeek to cmInetPeekNew.
6698 * This primitive does not call the select function as this is already
6699 * taken care by the called primitive. This primitive will not use any
6700 * ioctl calls, because on some machines due to latency in ioctl call
6701 * length may return as ZERO, even there is some data to be read from
6702 * the socket and this primitive only peek buffer using recvfrom.
6704 * Caller of this function need to allocate the sufficient memory to hold
6705 * the data peeked from the socket i.e. dataPos + dataLen. Socket data
6706 * will be copied in the "data" starting from dataPos offset.
6708 * For example, caller passed the following values to this function.
6709 * dataPos = 2 and dataLen = 10,then size of data buffer received should
6710 * be minimum of (dataPos + dataLen)12 bytes and socket data will be
6711 * copied in the data buffer from offset 2 (dataPos) onwards.
6719 CmInetFd *sockFd, /* socket file descriptor */
6720 CmInetAddr *fromAddr, /* sender Internet address/port */
6721 CmInetMemInfo *info, /* buffer allocation info */
6722 MsgLen dataPos, /* position of data */
6723 MsgLen dataLen, /* length of read data */
6724 Data *data /* read data */
6727 /* cm_inet_c_001.main_57 - Fix for validation and compilation warning */
6728 S32 recvLen; /* number of received octets */
6729 S32 remAddrLen; /* length of remote address length */
6730 struct sockaddr_in *remAddr; /* remote Internet address */
6731 #ifdef IPV6_SUPPORTED
6732 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6733 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6735 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6736 #endif /* IPV6_SUPPORTED */
6739 #if (ERRCLASS & ERRCLS_INT_PAR)
6740 /* error check on parameters */
6741 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6742 (info == NULLP) || (data == NULLP) ||
6743 (dataPos < 0) || (dataLen < 0))
6747 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6749 /* check if fromAddr is present or not */
6750 if (fromAddr != NULLP)
6752 remAddrLen = sizeof(remSockAddr);
6759 /* added different recvfrom calls with different 6th arg for
6760 * different OS If remAddrLen is 0, pass NULLP */
6761 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
6763 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6764 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
6766 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6767 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
6769 #if ( defined(SUNOS) || defined(SS_LINUX))
6771 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6772 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
6773 (socklen_t *)&remAddrLen);
6775 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6776 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
6779 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6780 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
6782 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6783 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
6784 #endif /* defined(SUNOS) || defined(SS_LINUX) */
6785 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
6787 /* removed the check of returned remAddrLen */
6788 if (recvLen == INET_ERR)
6790 /* added check ERR_WOULDBLOCK */
6791 if ((INET_ERR_CODE == ERR_AGAIN) ||
6792 (INET_ERR_CODE == ERR_WOULDBLOCK))
6797 /* cm_inet_c_001.main_61: added host unreachable check */
6798 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
6799 (INET_ERR_CODE == ERR_CONNRESET) ||
6800 (INET_ERR_CODE == ERR_HOSTUNREACH) ||
6801 (INET_ERR_CODE == ERR_CONNREFUSED))
6808 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6809 /* cm_inet_c_001.main_62:Warning fix */
6810 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%ld)\n",
6811 INET_ERR_CODE, sockFd->fd);
6812 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6814 /* cm_inet_c_001.main_62:Warning fix */
6815 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%d)\n",
6816 INET_ERR_CODE, sockFd->fd);
6817 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6819 #endif /* CMINETDBG */
6823 else if (recvLen == 0)
6828 /* cm_inet_c_001.main_57 - Fix for validation */
6829 if (recvLen < (S32)dataLen) /* maybe happen */
6834 /* setup return destination Internet address */
6835 /* added the check of (remAddLen > 0) */
6836 if ((fromAddr != NULLP) && (remAddrLen > 0))
6838 #ifdef IPV6_SUPPORTED
6839 memset(fromAddr, 0, sizeof(fromAddr));
6840 if (remAddrLen == sizeof(struct sockaddr_in6))
6842 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6843 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6844 fromAddr->u.ipv6Addr.port =
6845 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6846 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6847 &remAddr6->sin6_addr);
6851 remAddr = (struct sockaddr_in *)&remSockAddr;
6852 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6853 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6854 fromAddr->u.ipv4Addr.address =
6855 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6858 remAddr = (struct sockaddr_in *)&remSockAddr;
6859 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6860 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6861 #endif /* IPV6_SUPPORTED */
6865 } /* end of cmInetPeeknew */
6872 * Desc: Reads some data from the socket without destroying the socket
6874 * The data is specified by the byte positon (first byte is at
6875 * position 0) and the length.
6877 * Ret: ROK - successful
6878 * ROKDNA - ok, data not available
6879 * RCLOSED - connection closed by peer
6890 CmInetFd *sockFd, /* socket file descriptor */
6891 CmInetAddr *fromAddr, /* sender Internet address/port */
6892 CmInetMemInfo *info, /* buffer allocation info */
6893 MsgLen dataPos, /* position of data */
6894 MsgLen dataLen, /* length of read data */
6895 Data *data /* read data */
6898 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6899 Data *recvBuf = NULLP; /* plain receive buffer */
6900 /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
6901 MsgLen bufLen; /* buffer length */
6902 MsgLen i; /* index */
6903 MsgLen j; /* index */
6904 S32 ret; /* temporary return value */
6905 uint32_t timeout; /* timeout for cmInetSelect() */
6906 uint32_t *timeoutPtr; /* pointer to timeout */
6907 S16 numFdS; /* number of ready descriptors */
6908 /* cm_inet_c_001.main_45 - fixing the UMR issue in 64bit linux */
6909 uint32_t pendLen = 0; /* pending data length */
6910 S32 recvLen; /* number of received octets */
6911 S32 remAddrLen; /* length of remote address length */
6912 CmInetFdSet readFdS; /* socket file descriptor set */
6913 struct sockaddr_in *remAddr; /* remote Internet address */
6914 #ifdef IPV6_SUPPORTED
6915 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6916 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6918 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6919 #endif /* IPV6_SUPPORTED */
6922 #if (ERRCLASS & ERRCLS_INT_PAR)
6923 /* error check on parameters */
6924 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6925 (info == NULLP) || (data == NULLP) ||
6926 (dataPos < 0) || (dataLen < 0))
6930 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6932 /* check if there are some datas */
6933 if (sockFd->blocking)
6940 /* poll (non-blocking) */
6942 timeoutPtr = &timeout;
6944 CM_INET_FD_ZERO(&readFdS);
6945 CM_INET_FD_SET(sockFd, &readFdS);
6947 ret = cmInetSelect(&readFdS, NULLP, timeoutPtr, &numFdS);
6948 if (CM_INET_FD_ISSET(sockFd, &readFdS))
6950 /* get number of pending data */
6951 /* removed 3rd arg memInfo. MemInfo is no longer needed as we
6952 call ioctl for all sockets */
6953 ret = cmInetGetNumRead(sockFd, &pendLen);
6956 /* cm_inet_c_001.main_50
6957 * Return RCLOSED if cmInetGetNumRead returns RCLOSED. For other
6958 * errors just return RFAILED.
6966 /* check if connection got closed */
6970 /* cm_inet_c_001.main_50
6971 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
6972 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
6973 * socket that select says is ready to read. This should not be
6974 * considered as connection closed. So return ROKDNA instead of
6975 * RCLOSED even for TCP sockets
6979 /* added check for TCP/UDP socket. Pending data len in the socket
6980 recv buffer is determined by ioctl call in cmInetGetNumRead.
6981 For TCP it can't be > CM_INET_MAX_MSG_LEN.
6982 For UDP it can't be > CM_INET_MAX_UDPRAW_MSGSIZE. */
6983 if (sockFd->type == CM_INET_STREAM)
6985 /* max message length is limited to control the memory usage */
6986 if (pendLen > CM_INET_MAX_MSG_LEN)
6987 pendLen = CM_INET_MAX_MSG_LEN;
6988 /* In STREAM remote address is not required */
6993 if (pendLen > CM_INET_MAX_UDPRAW_MSGSIZE)
6994 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE;
6996 remAddrLen = sizeof(CmInetSockAddr);
6999 /* check if there are enough pending data to read */
7000 bufLen = dataPos + dataLen;
7002 /* check if fromAddr is present or not */
7003 if (fromAddr != NULLP)
7005 remAddrLen = sizeof(remSockAddr);
7012 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
7013 if ((MsgLen)pendLen >= bufLen)
7015 /* allocate receive buffer (flat structure) */
7016 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
7022 /* added different recvfrom calls with
7023 * different 6th arg for different OS */
7025 /* If remAddrLen is 0, pass NULLP */
7026 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7028 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7029 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7031 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7032 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7034 #if ( defined(SUNOS) || defined(SS_LINUX))
7036 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7037 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7038 (socklen_t *)&remAddrLen);
7040 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7041 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7044 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7045 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7047 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7048 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7049 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7050 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7052 /* removed the check of returned remAddrLen */
7053 if (recvLen == INET_ERR)
7056 /* moved cleanup here */
7057 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7059 /* added check ERR_WOULDBLOCK */
7060 if ((INET_ERR_CODE == ERR_AGAIN) ||
7061 (INET_ERR_CODE == ERR_WOULDBLOCK))
7067 /* moved up the cleanup */
7071 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7072 /* cm_inet_c_001.main_62:Warning fix */
7073 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%ld)\n",
7074 INET_ERR_CODE, sockFd->fd);
7075 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7077 /* cm_inet_c_001.main_62:Warning fix */
7078 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%d)\n",
7079 INET_ERR_CODE, sockFd->fd);
7080 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7082 #endif /* CMINETDBG */
7084 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7085 (INET_ERR_CODE == ERR_CONNRESET))
7093 if (recvLen < (S32)bufLen) /* maybe happen */
7096 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7101 for (j = 0, i = dataPos; i < bufLen; j++, i++)
7102 data[j] = recvBuf[i];
7104 /* setup return destination Internet address */
7105 /* added the check of (remAddLen > 0) */
7106 if ((fromAddr != NULLP) && (remAddrLen > 0))
7108 #ifdef IPV6_SUPPORTED
7109 memset(fromAddr, 0, sizeof(fromAddr));
7110 if (remAddrLen == sizeof(struct sockaddr_in6))
7112 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7113 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7114 fromAddr->u.ipv6Addr.port =
7115 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
7116 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
7117 &remAddr6->sin6_addr);
7121 remAddr = (struct sockaddr_in *)&remSockAddr;
7122 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7123 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7124 fromAddr->u.ipv4Addr.address =
7125 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7128 remAddr = (struct sockaddr_in *)&remSockAddr;
7129 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7130 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7131 #endif /* IPV6_SUPPORTED */
7135 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7139 /* not enough data pending yet */
7145 /* no data pending */
7150 } /* end of cmInetPeek */
7157 * Desc: Close a socket gracefully.
7159 * Ret: ROK - successful
7170 CmInetFd *sockFd /* socket file descriptor */
7173 S32 ret; /* temporary return value */
7176 #if (ERRCLASS & ERRCLS_INT_PAR)
7177 /* error check on parameters */
7178 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7182 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7185 ret = closesocket(sockFd->fd);
7187 ret = close(sockFd->fd);
7189 if (ret == INET_ERR)
7193 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7194 /* cm_inet_c_001.main_62:Warning fix */
7195 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%ld)\n",
7196 INET_ERR_CODE, sockFd->fd);
7197 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7199 /* cm_inet_c_001.main_62:Warning fix */
7200 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%d)\n",
7201 INET_ERR_CODE, sockFd->fd);
7202 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7203 #endif /*ALIGN_64BIT*/
7204 #endif /* CMINETDBG */
7209 } /* end of cmInetClose */
7214 * Fun: cmInetShutdown
7216 * Desc: Close an Internet connection with more control over the data of
7217 * the full-duplex connection.
7218 * Values for the howTo parameter:
7220 * CM_INET_SHTDWN_RECV - discard data in receive buffer
7221 * CM_INET_SHTDWN_SEND - discard data in transmit buffer
7222 * CM_INET_SHTDWN_BOTH - discard data in receive and transmit buffer
7224 * Ret: ROK - successful
7227 * Notes: This function does not free the socket descriptor but only closes the
7228 * connection (cmInetClose() has to be called afterwards).
7229 * No error is returned if the socket is not connected while calling
7238 CmInetFd *sockFd, /* socket file descriptor */
7239 S32 howTo /* operation flag */
7242 S32 ret; /* temporary return value */
7245 #if (ERRCLASS & ERRCLS_INT_PAR)
7246 /* error check on parameters */
7247 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7251 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7253 ret = shutdown(sockFd->fd, howTo);
7254 if (ret == INET_ERR)
7256 if (INET_ERR_CODE == ERR_NOTCONN)
7258 /* socket is not connected */
7266 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7267 /* cm_inet_c_001.main_62:Warning fix */
7268 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7269 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
7270 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7272 /* cm_inet_c_001.main_62:Warning fix */
7273 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7274 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
7275 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7276 #endif /*ALIGN_64BIT*/
7277 #endif /* CMINETDBG */
7283 } /* end of cmInetShutdown */
7290 * Desc: Allows multiplex i/o requests among multiple sockets.
7291 * If the parameter mSecTimeout points to a value of zero the
7292 * call immediatley returns (poll), if it is a null pointer, the
7293 * timeout is set to infinit.
7294 * numFdS returns the number of ready file descriptors contained
7295 * in the file descriptor sets
7297 * Ret: ROK - successful
7298 * RTIMEOUT - timout expired
7309 CmInetFdSet *readFdS, /* read socket descriptor file set */
7310 CmInetFdSet *writeFdS, /* write socket descriptor file set */
7311 uint32_t *mSecTimeout, /* timeout in msecs */
7312 S16 *numFdS /* number of ready descriptors */
7315 S32 ret; /* temporary return value */
7316 struct timeval timeout; /* timeout structure */
7317 struct timeval *timeoutPtr;
7320 #if (ERRCLASS & ERRCLS_INT_PAR)
7321 /* error check on parameters */
7322 if (numFdS == NULLP)
7326 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7330 if (mSecTimeout != NULLP)
7332 timeout.tv_sec = *mSecTimeout / 1000;
7333 timeout.tv_usec = (*mSecTimeout % 1000) * 1000;
7334 timeoutPtr = &timeout;
7338 /* infinite timeout */
7344 timeout.tv_usec = 1;
7347 /* cm_inet_c_001.main_53 - Removed do-while loop */
7348 ret = select(FD_SETSIZE, readFdS, writeFdS, (fd_set*)0, timeoutPtr);
7350 /* cm_inet_c_001.main_53 - Return ROKDNA in case select was interrupted */
7351 if ((ret == INET_ERR) && (INET_ERR_CODE == ERR_EINTR))
7356 /* timeout occured */
7362 if (ret == INET_ERR)
7364 /* asa: Added a check for ERR_INVAL to return ROK
7365 * readFdS and writeFdS may be passed as NULL to
7366 * cmInetSelect() call
7368 switch(errCode = INET_ERR_CODE)
7375 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7376 /* cm_inet_c_001.main_62:Warning fix */
7377 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSelect() Failed : error(%d)\n",
7379 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET039, 0, prntBuf);
7380 #endif /* CMINETDBG */
7383 } /* end of switch */
7386 /* return number of ready file descriptors */
7387 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7391 } /* end of cmInetSelect */
7398 * Desc: Sets a socket option.
7399 * The function supports following options:
7401 * CM_INET_OPT_BLOCK:
7402 * value: CM_INET_OPT_DISABLE non-blocking
7403 * value: CM_INET_OPT_ENABLE blocking
7405 * CM_INET_OPT_REUSEADDR:
7406 * value: CM_INET_OPT_ENABLE reuse address
7408 * CM_INET_OPT_BROADCAST:
7409 * value: CM_INET_OPT_DISABLE
7410 * value: CM_INET_OPT_ENABLE
7412 * CM_INET_OPT_KEEPALIVE:
7413 * value: CM_INET_OPT_DISABLE
7414 * value: CM_INET_OPT_ENABLE
7416 * CM_INET_OPT_RX_BUF_SIZE:
7417 * value: receive buffer size in bytes
7419 * CM_INET_OPT_TX_BUF_SIZE:
7420 * value: transmitter buffer size in bytes
7422 * CM_INET_OPT_ADD_MCAST_MBR:
7423 * value: address of CmInetMCastInf structure
7425 * CM_INET_OPT_DRP_MCAST_MBR:
7426 * value: address of CmInetMCastInf structure
7428 * CM_INET_OPT_TCP_NODELAY:
7429 * value: CM_INET_OPT_DISABLE
7430 * value: CM_INET_OPT_ENABLE
7432 * CM_INET_OPT_BSD_COMPAT: For Linux only
7433 * value: CM_INET_OPT_ENABLE
7434 * value: CM_INET_OPT_DISABLE
7436 * CM_INET_OPT_HDR_INCLD:
7437 * value: CM_INET_ENABLE
7438 * value: CM_INET_DISABLE
7440 * CM_INET_OPT_DONT_FRAGMENT:
7441 * value: CM_INET_OPT_ENABLE
7442 * value: CM_INET_DISABLE
7445 * value: Type of Service.
7448 * value: Time To Live.
7450 * CM_INET_OPT_IP_OPTIONS:
7451 * value: IPv4 header option value
7454 * CM_INET_OPT_IP_ROUTER_ALERT:
7455 * value: CM_INET_OPT_DISABLE
7456 * value: CM_INET_OPT_ENABLE
7458 * CM_INET_OPT_IPV4_PKTINFO
7459 * value: CM_INET_OPT_ENABLE
7460 * value: CM_INET_OPT_DISABLE
7462 * CM_INET_OPT_MCAST_LOOP:
7463 * value: CM_INET_OPT_DISABLE
7464 * value: CM_INET_OPT_ENABLE
7466 * CM_INET_OPT_MCAST_IF:
7467 * value: Address of interface.
7469 * CM_INET_OPT_MCAST_TTL:
7470 * value: TTL of the outgoing multicast packet.
7472 * The next options are defined only if IPV6 is
7475 * CM_INET_OPT_ADD_MCAST6_MBR:
7476 * value: address of CmInetMCastInf6 structure
7478 * CM_INET_OPT_DRP_MCAST6_MBR:
7479 * value: address of CmInetMCastInf6 structure
7481 * CM_INET_OPT_MCAST6_LOOP:
7482 * value: CM_INET_OPT_DISABLE
7483 * value: CM_INET_OPT_ENABLE
7485 * CM_INET_OPT_MCAST6_IF:
7486 * value: Interface index
7488 * CM_INET_OPT_MCAST6_HOPS:
7489 * value: multicast hop limit
7491 * CM_INET_OPT_RECVIPV6_HOPLIM:
7492 * value: CM_INET_OPT_ENABLE hop limit will be returned
7494 * value: CM_INET_OPT_DISABLE hop limit wont be returned
7497 * CM_INET_OPT_RECVIPV6_HBHOPTS:
7498 * value: CM_INET_OPT_ENABLE HBH Options will be returned
7500 * value: CM_INET_OPT_DISABLE HBH Options wont be returned
7503 * CM_INET_OPT_RECVIPV6_DSTOPTS:
7504 * value: CM_INET_OPT_ENABLE Dest Options will be returned
7506 * value: CM_INET_OPT_DISABLE Dest Options wont be returned
7509 * CM_INET_OPT_RECVIPV6_RTHDR:
7510 * value: CM_INET_OPT_ENABLE Route Hdr Opt will be turned
7512 * value: CM_INET_OPT_DISABLE Route Hdr Opt will be turned
7513 * OFF on the socket.
7515 * CM_INET_OPT_IP_ROUTER_ALERT6
7516 * value: CM_INET_OPT_ENABLE
7517 * value: CM_INET_OPT_DISABLE
7519 * CM_INET_OPT_IPV6_PKTINFO
7520 * value: CM_INET_OPT_ENABLE Enable sending and receiving
7522 * value: CM_INET_OPT_DISABLE Disable sending and receiving
7525 * CM_INET_OPT_LINGER
7526 * value: address of CmInetSockLinger structure
7528 * CM_INET_OPT_SCTP_EVENTS
7529 * value: address of CmInetSctpSockEvent structure
7531 * CM_INET_OPT_SCTP_PRIM_ADDR
7532 * value: address of CmInetSctpPrimAddr structure
7534 * CM_INET_OPT_SCTP_PEERADDR_PARAMS
7535 * value: address of CmInetSctpPeerAddrParams structure
7538 * Ret: ROK - successful
7540 * RNA - failed, option not available
7541 * (Only when CM_INET2 is defined)
7543 * Notes: The send and receive buffer size may be system
7544 * specific. The cmInetSetOpt() call may return
7545 * successfuly although not the entire buffer size
7553 CmInetFd *sockFd, /* socket file descriptor */
7554 uint32_t level, /* option level */
7555 uint32_t type, /* option type */
7556 Ptr value /* option value */
7559 S32 ret = ROK; /* temporary return value */
7560 uint32_t disable = 0; /* disable option */
7561 uint32_t enable = 1; /* enable option */
7563 /* added for IPv4 options */
7564 #ifdef IPV4_OPTS_SUPPORTED
7565 #if((!defined (SS_VW)) && (!defined(SS_LINUX)))
7566 TknStr64 *tempTknStr64; /* points TknStr64 structure */
7567 /* which has value for IPv4 hdr options.*/
7568 #endif /* SS_VW && SS_LINUX */
7572 #endif /* IPV4_OPTS_SUPPORTED */
7574 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST)\
7576 uint8_t lpEnable = 1; /* multicast loop enable */
7577 uint8_t lpDisable = 0; /* multicast loop disable */
7578 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7581 BOOL boolEnable = TRUE; /* enable option */
7582 BOOL boolDisable = FALSE; /* disable option */
7585 #if (defined(SUNOS) || defined(WIN32) || defined(SS_PS) || \
7586 defined(SS_VW_MCAST) || defined(HPOS))
7587 struct ip_mreq stMreq;
7588 CmInetMCastInf *mCast;
7589 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7591 #ifdef IPV6_SUPPORTED
7592 uint32_t loopEna = 1; /* IPv6 multicast loop enable */
7593 uint32_t loopDis = 0; /* IPv6 multicast loop disable */
7594 struct ipv6_mreq *stMreq6Ptr;
7595 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
7596 this flag is gaurded under ICMPV6_FILTER_SUPPORTED. so if user want this
7597 support he has to enable the above flag.*/
7598 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
7599 * to support filteration of ICMP messages */
7600 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
7601 struct icmp6_filter *icmp6Filter;
7602 #endif /* ICMPV6_FILTER_SUPPORTED */
7603 #endif /* IPV6_SUPPORTED */
7605 /* cm_inet_c_001.main_58 : Added new local variables to support filteration
7606 * of ICMP messages */
7608 #ifdef CM_ICMP_FILTER_SUPPORT
7609 struct icmp_filter icmpFilter;
7613 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
7616 struct sctp_event_subscribe event;
7617 struct sctp_paddrparams addrParams;
7618 struct sctp_setprim setPrim;
7619 struct sockaddr_in *pAddr;
7620 struct sctp_assocparams assocParams;
7621 struct sctp_initmsg initmsg;
7622 struct sctp_rtoinfo rtoinfo;
7623 #ifdef IPV6_SUPPORTED
7624 struct sockaddr_in6 *pAddr6;
7625 #endif /* IPV6_SUPPORTED */
7627 CmInetSockLinger *pSockLinger;
7628 CmInetSctpSockEvent *pSctpEvent;
7629 CmInetSctpPrimAddr *pSctpPrimAddr;
7630 CmInetSctpPeerAddrParams *pSctpPAddrParams;
7631 CmInetSctpRtoInfo *pSctpRtoInfo;
7632 CmInetSctpInitMsg *pSctpInitMsg;
7633 CmInetSctpAssocParams *pSctpAssocParams;
7639 /* cm_inet_c_001.main_58 : Added NULL check for value field */
7645 #if (ERRCLASS & ERRCLS_INT_PAR)
7646 /* error check on parameters */
7647 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7651 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7655 case CM_INET_OPT_BLOCK:
7656 optVal = (uint32_t*)value;
7659 case CM_INET_OPT_ENABLE:
7662 /* cm_inet_c_001.main_59: Fix for compilation warning */
7663 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&disable);
7666 ret = ioctl(sockFd->fd, FIONBIO, (char*)&disable);
7669 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&disable);
7671 ret = ioctl(sockFd->fd, (S32)FIONBIO, &disable);
7676 sockFd->blocking = 1;
7679 case CM_INET_OPT_DISABLE:
7681 /* cm_inet_c_001.main_59: Fix for compilation warning */
7682 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&enable);
7685 ret = ioctl(sockFd->fd, FIONBIO, (char*)&enable);
7688 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&enable);
7690 ret = ioctl(sockFd->fd, (S32)FIONBIO, &enable);
7694 sockFd->blocking = 0;
7704 case CM_INET_OPT_REUSEADDR:
7705 optVal = (uint32_t*)value;
7706 if (*optVal == CM_INET_OPT_ENABLE)
7709 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7710 (char*)&boolEnable, sizeof(boolEnable));
7712 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7713 (char*)&enable, sizeof(enable));
7715 setsockopt(sockFd->fd, level, SO_REUSEPORT,
7716 (char*)&enable, sizeof(enable));
7720 else if (*optVal == CM_INET_OPT_DISABLE)
7723 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7724 (char*)&boolDisable, sizeof(boolDisable));
7726 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7727 (char*)&disable, sizeof(disable));
7729 ret = setsockopt(sockFd->fd, level, SO_REUSEPORT,
7730 (char*)&disable, sizeof(disable));
7736 case CM_INET_OPT_BROADCAST:
7737 optVal = (uint32_t*)value;
7738 if (*optVal == CM_INET_OPT_ENABLE)
7741 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7742 (char*)&boolEnable, sizeof(boolEnable));
7744 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7745 (char*)&enable, sizeof(enable));
7748 else if (*optVal == CM_INET_OPT_DISABLE)
7751 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7752 (char*)&boolDisable, sizeof(boolDisable));
7754 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7755 (char*)&disable, sizeof(disable));
7760 case CM_INET_OPT_KEEPALIVE:
7761 optVal = (uint32_t*)value;
7762 if (*optVal == CM_INET_OPT_ENABLE)
7765 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7766 (char*)&boolEnable, sizeof(boolEnable));
7768 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7769 (char*)&enable, sizeof(enable));
7772 else if (*optVal == CM_INET_OPT_DISABLE)
7775 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7776 (char*)&boolDisable, sizeof(boolDisable));
7778 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7779 (char*)&disable, sizeof(disable));
7784 case CM_INET_OPT_RX_BUF_SIZE:
7785 optVal = (uint32_t*)value;
7786 ret = setsockopt(sockFd->fd, level, SO_RCVBUF,
7787 (char*)optVal, sizeof(*optVal));
7790 case CM_INET_OPT_TX_BUF_SIZE:
7791 optVal = (uint32_t*)value;
7792 ret = setsockopt(sockFd->fd, level, SO_SNDBUF,
7793 (char*)optVal, sizeof(*optVal));
7796 case CM_INET_OPT_TCP_NODELAY:
7797 optVal = (uint32_t*)value;
7798 if (*optVal == CM_INET_OPT_ENABLE)
7802 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7803 (char*)&boolEnable, sizeof(boolEnable));
7804 #endif /* SS_WINCE */
7806 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7807 (char*)&enable, sizeof(enable));
7810 else if (*optVal == CM_INET_OPT_DISABLE)
7814 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7815 (char*)&boolDisable, sizeof(boolDisable));
7816 #endif /* SS_WINCE */
7818 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7819 (char*)&disable, sizeof(disable));
7824 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || \
7825 defined(SS_VW_MCAST) || defined(HPOS))
7827 case CM_INET_OPT_ADD_MCAST_MBR:
7828 mCast = (CmInetMCastInf*)value;
7830 /* Copy the addresses to stMreq structure */
7832 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7834 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7836 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7838 ret = setsockopt(sockFd->fd, level, IP_ADD_MEMBERSHIP,
7839 (char*)&stMreq, sizeof(stMreq));
7842 case CM_INET_OPT_DRP_MCAST_MBR:
7843 mCast = (CmInetMCastInf*)value;
7845 /* Copy the addresses to stMreq structure */
7847 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7849 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7851 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7853 ret = setsockopt(sockFd->fd, level, IP_DROP_MEMBERSHIP,
7854 (char*)&stMreq, sizeof(stMreq));
7857 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7860 /* cm_inet_c_001.main_37 - Enable CMINET_BSDCOMPAT flag if system doesnt
7861 support CM_INET_OPT_BSD_COMPAT */
7862 #ifndef CMINET_BSDCOMPAT
7863 case CM_INET_OPT_BSD_COMPAT:
7864 optVal = (uint32_t*)value;
7865 if (*optVal == CM_INET_OPT_ENABLE)
7867 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7868 &enable, sizeof(enable));
7870 else if (*optVal == CM_INET_OPT_DISABLE)
7872 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7873 &disable, sizeof(disable));
7876 #endif /* CMINET_BSDCOMPAT */
7877 #endif /* SS_LINUX */
7880 /* Added for support of Raw socket modify according to the
7881 * option available on different platform */
7882 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW) \
7884 case CM_INET_OPT_HDR_INCLD:
7885 optVal = (uint32_t*)value;
7886 if (*optVal == CM_INET_OPT_ENABLE)
7891 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7892 (char*)&enable, sizeof(enable));
7895 else if (*optVal == CM_INET_OPT_DISABLE)
7900 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7901 (char*)&disable, sizeof(disable));
7906 /* added new options */
7907 #ifdef IPV4_OPTS_SUPPORTED
7909 /* Linux: set Router Alert socket option to Intercept RAW RSVP
7910 packets at the Intermediate node(Router) with Router Alert SET.
7911 This socket option is MUST be set (when this server is opened)
7912 if the RSVP server wants to intercept raw RSVP packets. */
7913 case CM_INET_OPT_IP_ROUTER_ALERT:
7914 optVal = (uint32_t*)value;
7915 if (*optVal == CM_INET_OPT_ENABLE)
7917 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7918 (char*)&enable, sizeof(enable));
7922 else if (*optVal == CM_INET_OPT_DISABLE)
7924 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7925 (char*)&disable, sizeof(disable));
7930 #endif /* SS_LINUX */
7932 /* set Router Alert socket option */
7933 case CM_INET_OPT_IP_OPTIONS:
7934 #if (defined (SS_VW) || defined(SS_LINUX))
7937 tempTknStr64=(TknStr64 *)value;
7938 if (tempTknStr64->pres == TRUE)
7940 if (tempTknStr64->len == 0)
7942 /* disable the IP_OPTIONS for Router Alert. */
7944 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7945 (const char *)&disableOpt, sizeof(int));
7947 ret = setsockopt(sockFd->fd, level, IP_OPTIONS, NULL, 0);
7951 /* enable the IP_OPTIONS for Router Alert */
7952 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7953 (char *)tempTknStr64->val, tempTknStr64->len);
7956 return RFAILED; /* Trying to set IPv4 Hdr option
7957 * without giving option values*/
7958 #endif /* SS_VW || SS_LINUX */
7960 #endif /* IPV4_OPTS_SUPPORTED */
7962 /* added new options */
7963 #if (defined(SS_LINUX) && (!defined(SS_VW) && !defined(WIN32)))
7965 case CM_INET_OPT_IPV4_PKTINFO:
7966 optVal = (uint32_t*)value;
7967 if (*optVal == CM_INET_OPT_ENABLE)
7969 /* set IP_PKTINFO option when IP_ROUTER_ALERT is set in linux */
7970 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7971 (char*)&enable, sizeof(enable));
7976 else if (*optVal == CM_INET_OPT_DISABLE)
7978 /* disable IP_PKTINFO when IP_ROUTER_ALERT is set in linux */
7979 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7980 (char*)&disable, sizeof(disable));
7986 #endif /* LOCAL_INTF */
7987 #endif /* SS_LINUX */
7989 #endif /* SUNOS || WIN32 || SS_PS || SS_VW || HPOS */
7991 case CM_INET_OPT_DONTFRAGMENT:
7992 optVal = (uint32_t*)value;
7993 if (*optVal == CM_INET_OPT_ENABLE)
7996 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
7997 (char*)&boolEnable, sizeof(boolEnable));
8000 else if (*optVal == CM_INET_OPT_DISABLE)
8003 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8004 (char*)&boolDisable, sizeof(boolDisable));
8009 /* also add these 2 options for VxWorks */
8010 #if (defined(SUNOS)|| defined(WIN32) || defined(HPOS) || defined(SS_VW))
8011 case CM_INET_OPT_TOS:
8012 optVal = (uint32_t*)value;
8013 ret = setsockopt(sockFd->fd, level, IP_TOS,
8014 (char*)optVal, sizeof(*optVal));
8017 case CM_INET_OPT_TTL:
8018 optVal = (uint32_t*)value;
8019 ret = setsockopt(sockFd->fd, level, IP_TTL,
8020 (char*)optVal, sizeof(*optVal));
8022 #endif /* SUNOS || WIN32 || HPOS || SS_VW */
8023 #endif /* CM_INET2 */
8025 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST) \
8027 case CM_INET_OPT_MCAST_LOOP:
8028 optVal = (uint32_t*)value;
8029 if (*optVal == CM_INET_OPT_ENABLE)
8032 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8033 (char *)&lpEnable, sizeof(lpEnable));
8035 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8036 (const char *)&lpEnable, sizeof(lpEnable));
8042 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8043 (char *)&lpDisable, sizeof(lpDisable));
8045 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8046 (const char *)&lpDisable, sizeof(lpDisable));
8051 case CM_INET_OPT_MCAST_IF:
8052 optVal = (uint32_t*)value;
8053 *optVal = CM_INET_HTON_UINT32((uint32_t)*optVal);
8054 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_IF,
8055 (char *)optVal, sizeof(struct in_addr));
8058 case CM_INET_OPT_MCAST_TTL:
8059 optVal = (uint32_t*)value;
8060 /* remove const in setsockopt for VW */
8062 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8063 (char *)optVal, sizeof(uint8_t));
8065 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8066 (const char *)optVal, sizeof(uint8_t));
8069 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8071 #ifdef IPV6_SUPPORTED
8072 case CM_INET_OPT_IPV6_TTL:
8073 optVal = (uint32_t*)value;
8074 ret = setsockopt(sockFd->fd, level, IPV6_UNICAST_HOPS,
8075 (char*)optVal, sizeof(*optVal));
8078 case CM_INET_OPT_ADD_MCAST6_MBR:
8079 stMreq6Ptr = (struct ipv6_mreq *)value;
8080 ret = setsockopt(sockFd->fd, level, IPV6_JOIN_GROUP,
8081 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8084 case CM_INET_OPT_DRP_MCAST6_MBR:
8085 stMreq6Ptr = (struct ipv6_mreq *)value;
8086 ret = setsockopt(sockFd->fd, level, IPV6_LEAVE_GROUP,
8087 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8090 case CM_INET_OPT_MCAST6_LOOP:
8091 optVal = (uint32_t*)value;
8092 if (*optVal == CM_INET_OPT_ENABLE)
8094 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8095 &loopEna, sizeof(loopEna));
8099 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8100 &loopDis, sizeof(loopDis));
8104 case CM_INET_OPT_MCAST6_IF:
8105 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_IF,
8106 (uint32_t *)value, sizeof(uint32_t));
8109 case CM_INET_OPT_MCAST6_HOPS:
8110 optVal = (uint32_t*)value;
8111 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_HOPS,
8112 (char *)optVal, sizeof(uint32_t));
8115 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
8116 this flag is gaurded under ICMPV6_SUPPORTED. so if user want this
8117 support he has to enable the above flag.*/
8118 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8119 * to support filteration of ICMP messages */
8120 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8121 case CM_INET_OPT_ICMP6_FILTER:
8122 icmp6Filter = (struct icmp6_filter *)value;
8123 ret = setsockopt(sockFd->fd, level, ICMP6_FILTER,
8124 (char *)icmp6Filter, sizeof(struct icmp6_filter));
8126 #endif /* ICMPV6_FILTER_SUPPORTED */
8128 /* added new options */
8129 #ifdef IPV6_OPTS_SUPPORTED
8130 case CM_INET_OPT_RECVIPV6_HOPLIM:
8131 optVal = (uint32_t*)value;
8133 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8134 (char *)optVal, sizeof(uint32_t));
8136 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8137 (char *)optVal, sizeof(uint32_t));
8138 /* enable the reception of IPv6 HopLimit value as ancillary data */
8139 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPLIMIT,
8140 (char*)&enable, sizeof(enable));
8141 #endif /* SS_LINUX */
8145 case CM_INET_OPT_RECVIPV6_HBHOPTS:
8146 optVal = (uint32_t*)value;
8148 ret = setsockopt(sockFd->fd, level, IPV6_HOPOPTS,
8149 (char *)optVal, sizeof(uint32_t));
8151 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPOPTS,
8152 (char *)optVal, sizeof(uint32_t));
8153 #endif /* SS_LINUX */
8156 case CM_INET_OPT_RECVIPV6_DSTOPTS:
8157 optVal = (uint32_t*)value;
8159 ret = setsockopt(sockFd->fd, level, IPV6_DSTOPTS,
8160 (char *)optVal, sizeof(uint32_t));
8162 ret = setsockopt(sockFd->fd, level, IPV6_RECVDSTOPTS,
8163 (char *)optVal, sizeof(uint32_t));
8164 #endif /* SS_LINUX */
8167 case CM_INET_OPT_RECVIPV6_RTHDR:
8168 optVal = (uint32_t*)value;
8170 ret = setsockopt(sockFd->fd, level, IPV6_RTHDR,
8171 (char *)optVal, sizeof(uint32_t));
8173 ret = setsockopt(sockFd->fd, level, IPV6_RECVRTHDR,
8174 (char *)optVal, sizeof(uint32_t));
8175 #endif /* SS_LINUX */
8178 /* works ONLY for IPPROTO_RAW type socket. so if it this socket
8179 * option is tried to set for IPPROTO_RSVP, then it is supposed
8180 * to fail with EINVAL according to net/ipv6/ipv6_sockglue.c
8182 * if HI_SRVC_RAW_RAW is not used during ServOpenReq as the server
8183 * type, then it will fail here due to above reason */
8185 case CM_INET_OPT_IP_ROUTER_ALERT6:
8186 optVal = (uint32_t*)value;
8187 if(*optVal == CM_INET_OPT_ENABLE)
8188 ret = setsockopt(sockFd->fd, IPPROTO_IPV6, IPV6_ROUTER_ALERT,
8189 (char *)&enable, sizeof(enable));
8191 ret = setsockopt(sockFd->fd, level, IPV6_ROUTER_ALERT,
8192 (char *)&disable, sizeof(disable));
8195 #endif /* SS_LINUX */
8196 #endif /* IPV6_OPTS_SUPPORTED */
8199 case CM_INET_OPT_IPV6_PKTINFO:
8200 optVal = (uint32_t*)value;
8202 ret = setsockopt(sockFd->fd, level, IPV6_PKTINFO,
8203 (char *)optVal, sizeof(uint32_t));
8205 ret = setsockopt(sockFd->fd, level, IPV6_RECVPKTINFO,
8206 (char *)&enable, sizeof(enable));
8207 #endif /* SS_LINUX */
8209 #endif /* LOCAL_INTF */
8211 #endif /* IPV6_SUPPORTED */
8213 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8215 case CM_INET_OPT_LINGER:
8216 pSockLinger = (CmInetSockLinger *)value;
8218 memset(&lngr, 0, sizeof(struct linger));
8220 if (pSockLinger->enable == TRUE)
8225 lngr.l_linger = pSockLinger->lingerTime;
8226 ret = setsockopt(sockFd->fd, level, SO_LINGER, &lngr, sizeof(lngr));
8229 case CM_INET_OPT_SCTP_EVENTS:
8230 pSctpEvent = (CmInetSctpSockEvent *)value;
8232 memset(&event, 0, sizeof(struct sctp_event_subscribe));
8234 if (pSctpEvent->dataIoEvent == TRUE)
8235 event.sctp_data_io_event = 1;
8237 if (pSctpEvent->associationEvent == TRUE)
8238 event.sctp_association_event = 1;
8240 if (pSctpEvent->addressEvent == TRUE)
8241 event.sctp_address_event = 1;
8243 if (pSctpEvent->sendFailureEvent == TRUE)
8244 event.sctp_send_failure_event = 1;
8246 if (pSctpEvent->peerErrorEvent == TRUE)
8247 event.sctp_peer_error_event = 1;
8249 if (pSctpEvent->shutdownEvent == TRUE)
8250 event.sctp_shutdown_event = 1;
8252 if (pSctpEvent->partialDeliveryEvent == TRUE)
8253 event.sctp_partial_delivery_event = 1;
8255 if (pSctpEvent->adaptationLayerEvent == TRUE)
8257 event.sctp_adaption_layer_event = 1;
8259 event.sctp_adaptation_layer_event = 1;
8262 ret = setsockopt(sockFd->fd, level, SCTP_EVENTS, &event, sizeof(event));
8265 case CM_INET_OPT_SCTP_PRIM_ADDR:
8266 pSctpPrimAddr = (CmInetSctpPrimAddr *)value;
8268 memset(&setPrim, 0, sizeof(struct sctp_setprim));
8270 #ifdef IPV6_SUPPORTED
8271 if (pSctpPrimAddr->addr.type == CM_INET_IPV6ADDR_TYPE)
8273 if (sockFd->protType == AF_INET)
8277 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8278 /* cm_inet_c_001.main_62:Warning fix */
8279 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8280 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8281 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8283 /* cm_inet_c_001.main_62:Warning fix */
8284 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8285 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8286 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8287 #endif /*ALIGN_64BIT*/
8288 #endif /* CMINETDBG */
8292 pAddr6 = (struct sockaddr_in6*)&(setPrim.ssp_addr);
8293 pAddr6->sin6_family = AF_INET6;
8294 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8295 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPrimAddr->addr.u.ipv6NetAddr);
8299 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8300 pAddr->sin_family = AF_INET;
8301 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8302 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8305 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8306 pAddr->sin_family = AF_INET;
8307 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8308 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8309 #endif /* IPV6_SUPPORTED */
8311 setPrim.ssp_assoc_id = pSctpPrimAddr->assocId;
8313 ret = setsockopt(sockFd->fd, level, SCTP_PRIMARY_ADDR, &setPrim, sizeof(setPrim));
8316 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
8317 pSctpPAddrParams = (CmInetSctpPeerAddrParams *)value;
8319 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
8322 if (pSctpPAddrParams->s.addrPres == TRUE)
8324 #ifdef IPV6_SUPPORTED
8325 if (pSctpPAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
8327 if (sockFd->protType == AF_INET)
8331 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8332 /* cm_inet_c_001.main_62:Warning fix */
8333 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8334 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8335 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8337 /* cm_inet_c_001.main_62:Warning fix */
8338 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8339 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8340 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8341 #endif /*ALIGN_64BIT*/
8342 #endif /* CMINETDBG */
8347 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
8348 pAddr6->sin6_family = AF_INET6;
8349 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8350 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPAddrParams->s.addr.u.ipv6NetAddr);
8354 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8355 pAddr->sin_family = AF_INET;
8356 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8357 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8360 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8361 pAddr->sin_family = AF_INET;
8362 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8363 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8364 #endif /* IPV6_SUPPORTED */
8368 #ifdef IPV6_SUPPORTED
8369 if (sockFd->protType == AF_INET6)
8370 addrParams.spp_address.ss_family = AF_INET6;
8372 addrParams.spp_address.ss_family = AF_INET;
8374 addrParams.spp_address.ss_family = AF_INET;
8378 /* Not validating the address, whether addr is a valid address or not */
8380 addrParams.spp_assoc_id = pSctpPAddrParams->assocId;
8381 /*cm_inet_c_001.main_58 : fix for klockwork issue */
8382 addrParams.spp_pathmaxrxt = (uint16_t)pSctpPAddrParams->pathMaxRxt;
8384 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8385 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8387 addrParams.spp_hbinterval = 0;
8390 addrParams.spp_flags = 0;
8392 if (pSctpPAddrParams->pmtudFlag == CM_INET_OPT_ENABLE)
8394 addrParams.spp_flags |= SPP_PMTUD_ENABLE;
8395 addrParams.spp_pathmtu = pSctpPAddrParams->pathMtu;
8397 else if(pSctpPAddrParams->pmtudFlag == CM_INET_OPT_DISABLE)
8398 addrParams.spp_flags |= SPP_PMTUD_DISABLE;
8400 if (pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_ENABLE)
8402 addrParams.spp_flags |= SPP_SACKDELAY_ENABLE;
8403 addrParams.spp_sackdelay = pSctpPAddrParams->sackDelay;
8405 else if(pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_DISABLE)
8406 addrParams.spp_flags |= SPP_SACKDELAY_DISABLE;
8408 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8410 addrParams.spp_flags |= SPP_HB_ENABLE;
8411 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8413 else if(pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_DISABLE)
8414 addrParams.spp_flags |= SPP_HB_DISABLE;
8416 ret = setsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, sizeof(addrParams));
8419 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
8420 pSctpAssocParams = (CmInetSctpAssocParams *)value;
8422 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
8424 assocParams.sasoc_cookie_life = pSctpAssocParams->cookieLife;
8425 assocParams.sasoc_asocmaxrxt = pSctpAssocParams->assocMaxReTx;
8426 assocParams.sasoc_assoc_id = pSctpAssocParams->assocId;
8427 assocParams.sasoc_number_peer_destinations = pSctpAssocParams->numberOfPeerDest;
8428 assocParams.sasoc_peer_rwnd = pSctpAssocParams->peerRwnd;
8429 assocParams.sasoc_local_rwnd = pSctpAssocParams->localRwnd;
8431 ret = setsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams));
8434 case CM_INET_OPT_SCTP_RTO_INFO:
8435 pSctpRtoInfo = (CmInetSctpRtoInfo *)value;
8437 memset(&rtoinfo, 0, sizeof(struct sctp_rtoinfo));
8439 rtoinfo.srto_assoc_id = pSctpRtoInfo->assocId;
8440 rtoinfo.srto_initial = pSctpRtoInfo->rtoInitial;
8441 rtoinfo.srto_max = pSctpRtoInfo->rtoMax;
8442 rtoinfo.srto_min = pSctpRtoInfo->rtoMin;
8444 ret = setsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
8447 case CM_INET_OPT_SCTP_INIT_MSG:
8448 pSctpInitMsg = (CmInetSctpInitMsg *)value;
8450 memset(&initmsg, 0, sizeof(struct sctp_initmsg));
8452 initmsg.sinit_max_attempts = pSctpInitMsg->maxInitReTx;
8453 initmsg.sinit_max_init_timeo = pSctpInitMsg->maxInitTimeout;
8454 initmsg.sinit_num_ostreams = pSctpInitMsg->numOstreams;
8455 initmsg.sinit_max_instreams = pSctpInitMsg->maxInstreams;
8457 ret = setsockopt(sockFd->fd, level, SCTP_INITMSG, &initmsg, sizeof(initmsg));
8460 #endif /*CM_LKSCTP*/
8462 /* cm_inet_c_001.main_58 : Added to support filteration of ICMP
8463 * messages and protected under CM_ICMP_FILTER_SUPPORT flag. Its a
8464 * partial implementaion for icmp filter done for TUCL */
8466 #ifdef CM_ICMP_FILTER_SUPPORT
8467 case CM_INET_OPT_ICMP_FILTER:
8468 optVal = (uint32_t*)value;
8469 ret = setsockopt(sockFd->fd, level, ICMP_FILTER,
8470 optVal, sizeof(icmpFilter));
8476 /* wrong socket option type */
8481 if (ret == INET_ERR)
8485 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8486 /* cm_inet_c_001.main_62:Warning fix */
8487 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%ld)\n",
8488 INET_ERR_CODE, sockFd->fd);
8489 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8491 /* cm_inet_c_001.main_62:Warning fix */
8492 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%d)\n",
8493 INET_ERR_CODE, sockFd->fd);
8494 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8495 #endif /*ALIGN_64BIT*/
8496 #endif /* CMINETDBG */
8500 } /* end of cmInetSetOpt */
8506 * Fun: cmInetGetNumRead
8508 * Desc: Gives the number of pending octets in the socket receive buffer.
8510 * Ret: ROK - successful
8519 S16 cmInetGetNumRead
8521 CmInetFd *sockFd, /* socket file descriptor */
8522 uint32_t *dataLen /* number of pending octets */
8523 /* removed 3rd argument memInfo */
8526 S32 ret; /* temporary return value */
8528 /* removed local variables added for recvfrom call */
8531 #if (ERRCLASS & ERRCLS_INT_PAR)
8532 /* error check on parameters */
8533 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
8540 /* use ioctl call for all types of socket to get length of
8541 pending data in the socket recv buffer */
8543 /* cm_inet_c_001.main_59: Fix for compilation warning */
8544 ret = ioctlsocket(sockFd->fd, FIONREAD, (uint32_t *)dataLen);
8547 ret = ioctl(sockFd->fd, FIOREAD, (char*)dataLen);
8550 ret = ioctl(sockFd->fd, FIONREAD, (S32)dataLen);
8552 ret = ioctl(sockFd->fd, FIONREAD, dataLen);
8557 /* For UDP socket assign the length of pending data in the
8558 socket recv buffer to largest datagram size.
8559 Removed recvfrom call & necessary processing for it. */
8561 if (ret == INET_ERR)
8563 /* removed error check CONABORTED added for recvfrom call.
8564 Also return value changed from RCLOSED to ROK */
8565 /* Check for reset connection */
8566 /* cm_inet_c_001.main_45: Close the TCP connection only when err is one of these*/
8567 if ((INET_ERR_CODE == ERR_CONNREFUSED) ||
8568 (INET_ERR_CODE == ERR_CONNABORTED) ||
8569 (INET_ERR_CODE == ERR_TIMEDOUT))
8573 /* cm_inet_c_001.main_50
8574 * Return RCLOSED instead of ROK to initiate connection closure.
8575 * ROK will be returned only if the ioctl call above returns ROK.
8576 * The routines calling this function have been modified to not
8577 * return RCLOSED when this function returns ROK with pending data
8578 * length value of 0. This modification is needed because:
8579 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
8580 * returns successfully with pend length as 0 on a TCP socket that
8581 * select says is ready to read. This should not be considered as
8582 * connection closed.
8587 /* removed error check ERR_WOULDBLOCK */
8588 /* cm_inet_c_001.main_45: Dont close the connection in case of ERR_CONNRESET */
8589 if ((INET_ERR_CODE == ERR_AGAIN) ||
8590 (INET_ERR_CODE == ERR_CONNRESET))
8597 /* cm_inet_c_001.main_45: Change 2048 to CM_INET_MAX_UDPRAW_MSGSIZE */
8598 *dataLen = CM_INET_MAX_UDPRAW_MSGSIZE;
8600 #endif /* SS_LINUX */
8602 /* removed error debug printing added for recvfrom call. */
8606 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8607 /* cm_inet_c_001.main_62:Warning fix */
8608 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8609 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
8610 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8612 /* cm_inet_c_001.main_62:Warning fix */
8613 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8614 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
8615 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8616 #endif /*ALIGN_64BIT*/
8617 #endif /* CMINETDBG */
8622 } /* end of cmInetGetNumRead */
8628 * Fun: cmInetGetHostByName
8630 * Desc: Resolves a host name into the appropriate 4 byte Internet
8633 * Ret: ROK - successful
8642 S16 cmInetGetHostByName
8644 S8 *hostName, /* host name */
8645 CmInetIpAddrTbl *addrTbl /* Address Table of IPV4 Addresses */
8649 uint8_t numAddrs; /* Number of Addresses */
8652 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8653 struct hostent *hostid; /* pointer to host information */
8656 struct hostent hostid; /* host information */
8657 S8 infoBuf[CM_INET_MAX_INFO]; /* info buffer */
8658 S32 err; /* error code */
8660 #endif /* WIN32 || SS_LINUX || HPOS */
8663 #if (ERRCLASS & ERRCLS_INT_PAR)
8664 /* error check on parameters */
8665 if ((hostName == NULLP) || (addrTbl == NULLP))
8669 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8678 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8679 hostid = gethostbyname(hostName);
8683 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8684 /* cm_inet_c_001.main_62:Warning fix */
8685 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8686 " hostName(%p)\n", INET_ERR_CODE, hostName);
8687 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET044, 0, prntBuf);
8688 #endif /* CMINETDBG */
8691 if (hostid->h_addrtype != AF_INET)
8694 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8695 /* cm_inet_c_001.main_62:Warning fix */
8696 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetHostByName() Failed : error(%d),"
8697 " hostName(%p), hostid->h_addrtype(%d)\n",
8698 INET_ERR_CODE, hostName, hostid->h_addrtype);
8699 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET045, 0, prntBuf);
8700 #endif /* CMINETDBG */
8705 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8706 (hostid->h_addr_list[numAddrs] != NULLP))
8708 addrTbl->netAddr[addrTbl->count++] =
8709 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8719 vwIpAddr = hostGetByName(hostName);
8720 if (vwIpAddr == INET_ERR)
8723 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8724 /* cm_inet_c_001.main_62:Warning fix */
8725 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8726 " hostName(%p)\n", INET_ERR_CODE, hostName);
8727 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET046, 0, prntBuf);
8728 #endif /* CMINETDBG */
8731 CM_COPY_VWIPADDR(vwIpAddr, &(addrTbl->netAddr[addrTbl->count]));
8736 err = 0; /* err is not reset by gethostnyname_r()! */
8738 gethostbyname_r(hostName, &hostid, infoBuf, CM_INET_MAX_INFO, (int*)&err);
8739 if ((hostid.h_addrtype != AF_INET) || (err < 0))
8742 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8743 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d), hostName(%p),"
8744 " hostid.h_addrtype(%d)\n",
8745 INET_ERR_CODE, hostName, hostid.h_addrtype);
8746 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET047, 0, prntBuf);
8747 #endif /* CMINETDBG */
8752 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8753 (hostid.h_addr_list[numAddrs] != NULLP))
8755 addrTbl->netAddr[addrTbl->count++] =
8756 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid.h_addr_list[numAddrs]));
8762 #endif /* WIN32 || SS_LINUX || HPOS */
8766 } /* end of cmInetGetHostByName */
8769 /* The getipnodebyname is not supported on all the Solaris Operating system
8770 * versions. This has to be supported on operating systems that support IPV6
8771 * as per the RFC on the IPV6 socket interface. Hence this function is moved
8772 * under the IPV6_SUPPORTED flag */
8774 /* This function now can be called for both IPv4 and IPv6. However, we will
8775 * call cmInetGetHostByName inside for IPv4. Move all flag dependencies
8776 * inside this function. */
8779 * Fun: cmInetGetIpNodeByName
8781 * Desc: Resolves a host name into the appropriate 4 byte Internet
8782 * address or into the appropriate 16 byte IPV6 address.
8783 * This function is expected to be thread safe and should be used
8784 * instead of the cmInetGetHostByName function.
8786 * Ret: ROK - successful
8794 S16 cmInetGetIpNodeByName
8796 S8 *hostName, /* host name */
8797 CmInetIpAddrArr *addrArr /* Array of addressed filled in */
8800 /* for return value from cmInetGetHostByName */
8801 #ifndef IPV6_SUPPORTED
8806 uint8_t numAddrs=0; /* Number of addresses */
8807 int err=0; /* error code */
8808 struct hostent *hostid; /* host information */
8809 #endif /* SS_LINUX */
8811 #endif /* IPV6_SUPPORTED */
8815 #if (ERRCLASS & ERRCLS_INT_PAR)
8816 /* error check on parameters */
8817 if ((hostName == NULLP) || (addrArr == NULLP))
8821 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8823 #ifdef IPV6_SUPPORTED
8827 #ifdef IPV6_SUPPORTED
8828 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8829 hostid = getipnodebyname(hostName, AF_INET6, 0, &err);
8831 #endif /* IPV6_SUPPORTED */
8832 hostid = getipnodebyname(hostName, AF_INET, 0, &err);
8836 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8837 /* cm_inet_c_001.main_62:Warning fix */
8838 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetIpNodeByName() Failed : error(%d),"
8839 " hostName(%p), addrArr->type(%d)n",
8840 err, hostName, addrArr->type);
8841 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET048, 0, prntBuf);
8842 #endif /* CMINETDBG */
8846 #ifdef IPV6_SUPPORTED
8847 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8849 if (hostid->h_addrtype == AF_INET6)
8851 while ((numAddrs < CM_INET_IPV6_NUM_ADDR) &&
8852 (hostid->h_addr_list[numAddrs] != NULLP))
8854 /* Use the cminet fill macro here */
8855 CM_INET_COPY_IPV6ADDR(&addrArr->u.ipv6AddrArr.netAddr[numAddrs],
8856 hostid->h_addr_list[numAddrs]);
8857 addrArr->u.ipv6AddrArr.count++;
8864 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8865 /* cm_inet_c_001.main_62:Warning fix */
8866 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8867 " hostName(%p), addrArr->type(%d),hostid->h_addrtype(%d) \n",
8868 err, hostName, addrArr->type, hostid->h_addrtype);
8869 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET049, 0, prntBuf);
8870 #endif /* CMINETDBG */
8875 #endif /* IPV6_SUPPORTED */
8877 if (hostid->h_addrtype == AF_INET)
8879 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8880 (hostid->h_addr_list[numAddrs] != NULLP))
8882 addrArr->u.ipv4AddrArr.count ++;
8883 addrArr->u.ipv4AddrArr.netAddr[numAddrs] =
8884 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8891 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8892 /* cm_inet_c_001.main_62:Warning fix */
8893 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8894 " hostName(%p), hostid->h_addrtype(%d), addrArr->type(%d)\n",
8895 err, hostName, hostid->h_addrtype, addrArr->type);
8896 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET050, 0, prntBuf);
8897 #endif /* CMINETDBG */
8901 #endif /* SS_LINUX */
8906 ret = cmInetGetHostByName(hostName, &addrArr->u.ipv4AddrArr);
8908 #endif /* IPV6_SUPPORTED */
8910 } /* end of cmInetGetIpNodeByName */
8917 * Desc: Converts an ASCII string containig an internet address
8918 * ("xxx.xxx.xxx.xxx") into a CmInetIpAddr (uint32_t) format.
8919 * This function is a wrapper for the inet_addr() call.
8921 * Ret: ROK - successful
8931 S8 *asciiAddr, /* ascii address representation */
8932 CmInetIpAddr *address /* 4 byte interent address */
8936 #if (ERRCLASS & ERRCLS_INT_PAR)
8937 /* error check on parameters */
8938 if (asciiAddr == NULLP)
8942 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8944 *address = inet_addr(asciiAddr);
8945 if (*address == (uint32_t)ERR_INADDRNONE)
8947 /* asciiAddr does not contain a valid internet address */
8959 * Desc: Converts an CmInetIPAddr based IP address into a string
8960 * of the format "xxx.xxx.xxx.xxx".
8961 * This function is a wrapper for the inet_ntoa() call.
8963 * Ret: ROK - successful
8966 * Notes: This function delivers a pointer to a static buffer
8967 * within the system. Therefore the string has to be copied
8968 * by the caller before another call is made!
8975 CmInetIpAddr address, /* 4 byte interent address */
8976 S8 **asciiAddr /* ascii address representation */
8979 struct in_addr inetAddr; /* internet address structure */
8982 #if (ERRCLASS & ERRCLS_INT_PAR)
8983 /* error check on parameters */
8984 if (asciiAddr == NULLP)
8988 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8990 inetAddr.s_addr = address;
8992 *asciiAddr = inet_ntoa(inetAddr);
8993 if (*asciiAddr == NULL)
9004 * Desc: Converts an network address into a string.
9005 * This function is a wrapper for the inet_ntop() call.
9007 * Ret: ROK - successful
9010 * Notes: This function copies the resulting string to the buffer pointed to
9011 * by asciiaddr,which must be a non NULL pointer.The caller specifies
9012 * the number of bytes available in this buffer in the argument len.
9019 uint8_t type, /* ip address type */
9020 Void *address, /* 4/16 byte interent address */
9021 S8 *asciiAddr, /* ascii adress representation */
9028 #if (ERRCLASS & ERRCLS_INT_PAR)
9029 /* error check on parameters */
9030 if (asciiAddr == NULLP || address == NULLP || len == 0 )
9035 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9038 case CM_INET_IPV4ADDR_TYPE :
9041 case CM_INET_IPV6ADDR_TYPE :
9045 if(inet_ntop(domain,address,asciiAddr,len) == NULL)
9054 /* The inet_pton is not supported on all the Solaris Operating system
9055 * versions. This has to be supported on operating systems that support
9056 * IPV6 as per the RFC on the IPV6 socket interface. Hence this function
9057 *is moved under the IPV6_SUPPORTED flag */
9058 #ifdef IPV6_SUPPORTED
9065 * Desc: Converts a IP address string to address.
9067 * Ret: ROK - successful
9077 CmInetIpAddr *address, /* 4 byte interent address */
9078 S8 *asciiAddr /* ascii address representation */
9084 #if (ERRCLASS & ERRCLS_INT_PAR)
9085 /* error check on parameters */
9086 if ((asciiAddr == NULLP) || (address == NULLP))
9090 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9092 ret = inet_pton(AF_INET, asciiAddr, (void *)address);
9099 } /* end of cmInetPton */
9101 #endif /* IPV6_SUPPORTED */
9103 #ifdef IPV6_SUPPORTED
9109 * Desc: Converts a IP address string to IPV6 address suitable
9110 * to be used in bind.
9112 * Ret: ROK - successful
9121 CmInetIpAddr6 *address6, /* 16 byte interent address */
9122 S8 *asciiAddr /* ascii address representation */
9128 struct sockaddr_storage ss;
9129 uint32_t sslen = sizeof(ss);
9132 #if (ERRCLASS & ERRCLS_INT_PAR)
9133 /* error check on parameters */
9134 if ((asciiAddr == NULLP) || (address6 == NULLP))
9138 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9141 ret = inet_pton(AF_INET6, asciiAddr, (void *)address6);
9147 /* cm_inet_c_001.main_44 : In windows inet_pton is not implemented. so we are using the below function
9148 * to convert the ipv6 address string to appropriate form */
9149 WSAStringToAddressA((LPTSTR)asciiAddr, AF_INET6, NULL, (struct sockaddr*)&ss, &sslen);
9150 memcpy(address6, &(((struct sockaddr_in6 *)&ss)->sin6_addr), sizeof(CmInetIpAddr6));
9154 } /* end of cmInetPton6 */
9155 #endif /* IPV6_SUPPORTED */
9161 * Fun: cmInetGetMemSize
9163 * Desc: This function gives the max number of static buffer space that
9164 * the internet library will allocate.
9166 * Ret: ROK - successful
9174 S16 cmInetGetMemSize(
9175 S32 *size /* max used memory size */
9179 /* max static memory size depends on max flat buffer size */
9180 *size = CM_INET_MAX_MSG_LEN;
9182 /* max static memory size depends on max flat buffer or iovect size */
9183 *size = CM_INET_MAX_MSG_LEN;
9195 * Desc: This function initializes the socket library.
9197 * Ret: ROK - successful
9199 * Notes: Required only for Winsock and not for 4.3BSD
9205 S16 cmInetInit(Void)
9212 version = MAKEWORD(CM_INET_HIGH_VER, CM_INET_LOW_VER);
9213 err = WSAStartup(version, &data);
9228 * Desc: This function de initializes the socket library. The
9229 * WINSOCK implementation de registers the application and
9230 * releases any resources allocated on behalf of the
9233 * Ret: ROK - successful
9235 * Notes: Required only for Winsock and not for 4.3BSD
9241 S16 cmInetDeInit(Void)
9254 }/* end of cmInetDeInit() */
9259 * Fun: cmInetGetSockName
9261 * Desc: This function is used to retireve the current name
9262 * for the specified socket descriptor. It returns the
9263 * local association(address and port) for the socket.
9265 * Ret: ROK - successful
9268 * Notes: Please note if the socket was bound to CM_INET_INADDR_ANY
9269 * cmInetGetSockName() will not necessarily return the local
9270 * address information unless the socket has been connected.
9276 S16 cmInetGetSockName
9278 CmInetFd *sockFd, /* socket file descriptor */
9282 struct sockaddr_in *sockAddr;
9283 #ifdef IPV6_SUPPORTED
9284 struct sockaddr_in6 *sockAddr6;
9285 struct sockaddr_in6 lclSockAddr;
9287 CmInetSockAddr lclSockAddr;
9288 #endif /* IPV6_SUPPORTED */
9293 #endif /* SS_LINUX */
9295 /*cm_inet_c_001.main_58 : fix for klockwork issue */
9299 #if (ERRCLASS & ERRCLS_INT_PAR)
9300 /* error check on parameters */
9301 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
9306 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9308 memset(&lclSockAddr, 0, sizeof(lclSockAddr));
9309 size = sizeof(lclSockAddr);
9312 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr,
9313 (socklen_t *)&size);
9315 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, (int*)&size);
9316 #endif /* SS_LINUX */
9320 switch(errCode = INET_ERR_CODE)
9323 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9324 #ifdef IPV6_SUPPORTED
9325 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9326 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9328 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9329 #endif /* IPV6_SUPPORTED */
9335 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9336 /* cm_inet_c_001.main_62:Warning fix */
9337 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9338 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9339 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9341 /* cm_inet_c_001.main_62:Warning fix */
9342 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9343 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9344 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9345 #endif /* ALIGN_64BIT */
9346 #endif /* CMINETDBG */
9348 }/* end of switch */
9352 /* Fill the returned address in to locAddr */
9353 #ifdef IPV6_SUPPORTED
9354 memset(locAddr, 0, sizeof(CmInetAddr));
9355 if (size == sizeof(struct sockaddr_in6))
9357 sockAddr6 = (struct sockaddr_in6 *)&lclSockAddr;
9358 locAddr->type = CM_INET_IPV6ADDR_TYPE;
9359 locAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(sockAddr6->sin6_port);
9360 CM_INET_COPY_IPV6ADDR(&locAddr->u.ipv6Addr.ipv6NetAddr,
9361 &sockAddr6->sin6_addr);
9365 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9366 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9367 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9368 locAddr->u.ipv4Addr.address =
9369 CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9372 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9373 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9374 locAddr->address = CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9375 #endif /* IPV6_SUPPORTED */
9377 }/* end of cmInetGetSockName() */
9379 /* New functions to peek into the file descriptor
9381 #if (defined(SUNOS) || defined(WIN32) || defined(SS_LINUX) || defined(SS_VW) \
9386 * Fun: cmInetFdSetInfoInit
9388 * Desc: This function is used to initialise operating system specific
9389 * data that will be used to peek into the file descriptor lists
9390 * to get the sockets that are set
9392 * Ret: ROK - successful
9401 S16 cmInetFdSetInfoInit
9403 CmInetFdSetInfo *fdSetInfo
9406 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW) || defined(HPOS))
9411 #endif /* SUNOS || SS_LINUX || SS_VW */
9413 #if (ERRCLASS & ERRCLS_INT_PAR)
9414 if (fdSetInfo == NULLP)
9416 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9418 if (fdSetInfo->initDone == TRUE)
9422 fdSetInfo->numFds = 0;
9425 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW)|| defined(HPOS))
9426 /* Check if we are on a big endian machine */
9428 if (*(uint8_t *)&arIdx)
9429 fdSetInfo->bigEndian = FALSE;
9431 fdSetInfo->bigEndian = TRUE;
9433 fdSetInfo->arIdx = 0;
9434 fdSetInfo->ar[0] = 0xff;
9436 /* Initialise the array */
9437 /* The array contains bit positions for the first bit
9438 * for each integer from 1 to 2^8.
9440 for (arIdx = 1; arIdx < 256; arIdx++)
9442 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9443 curByte = (uint8_t)arIdx;
9450 fdSetInfo->ar[arIdx] = bitPos;
9454 curByte = curByte >> 1;
9457 /* Calculate the number of array elements in this fd_set */
9458 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9459 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->__fds_bits[0]);
9461 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->fds_bits[0]);
9462 #endif /* SS_LINUX */
9463 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9465 fdSetInfo->initDone = TRUE;
9467 }/* end of cmInetFdSetInfoInit() */
9474 * Desc: This function is used to get the file descriptor from the
9475 * file descriptor set.
9477 * Ret: ROK - successful
9478 * ROKDNA - socket not found
9480 * RNA - failed, initialisation not done
9482 * Notes: If the application modifies fdSet between calls to this
9483 * function then the results are undefined. This function should
9484 * be called in a loop till either it returns - not ROK, or if
9485 * all sockets in the file descriptor set are processed.
9493 CmInetFdSetInfo *fdSetInfo,
9495 CmInetFdType *sockFd
9498 /*cm_inet_c_001.main_58 : Fix for klockwork issue */
9499 #if (!defined (WIN32))
9500 uint32_t sizOfFdSetArElem;
9501 uint8_t bytesScanned;
9506 #endif /* !defined (WIN32) */
9508 #if (ERRCLASS & ERRCLS_INT_PAR)
9509 if ((fdSetInfo == NULLP) || (fdSet == NULLP) || (sockFd == NULLP))
9512 if (fdSetInfo->initDone != TRUE)
9514 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9517 #if (ERRCLASS & ERRCLS_DEBUG)
9518 if (fdSetInfo->numFds > FD_SETSIZE)
9520 #endif /* ERRCLASS & ERRCLS_DEBUG */
9521 /* cm_inet_c_001.main_32 : Corrected check for number of fd set in
9523 if (fdSetInfo->numFds >= fdSet->fd_count)
9526 *sockFd = fdSet->fd_array[fdSetInfo->numFds];
9527 fdSetInfo->numFds += 1;
9531 /* cm_inet_c_001.main_59: Protected under if not defined WIN32 */
9532 #if (!defined (WIN32))
9533 /* Start with arIdx and continue upto number of array elements. */
9534 curIdx = fdSetInfo->arIdx;
9537 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9538 sizOfFdSetArElem = sizeof(fdSet->__fds_bits[0]);
9540 sizOfFdSetArElem = sizeof(fdSet->fds_bits[0]);
9541 #endif /* SS_LINUX */
9543 for (curIdx = fdSetInfo->arIdx; curIdx < fdSetInfo->numArElems;
9546 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9547 if (fdSet->__fds_bits[curIdx])
9549 if (fdSet->fds_bits[curIdx])
9550 #endif /* SS_LINUX */
9552 /* Walk through the bytes in this element */
9553 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9554 tempByte = (uint8_t *)&fdSet->__fds_bits[curIdx];
9556 tempByte = (uint8_t *)&fdSet->fds_bits[curIdx];
9557 #endif /* SS_LINUX */
9559 /* Set the starting byte offset */
9560 if (fdSetInfo->bigEndian)
9561 tempByte += sizOfFdSetArElem - 1;
9563 for (bytesScanned = 0; bytesScanned < sizOfFdSetArElem;
9568 bitPos = fdSetInfo->ar[*tempByte];
9569 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9570 fdSetInfo->arIdx = (uint16_t)curIdx;
9571 /* Calculate fd depending on where we are */
9572 *sockFd = ((bytesScanned << 3) + bitPos);
9573 *sockFd += (curIdx * (sizOfFdSetArElem << 3));
9574 /* Clear the file descriptor */
9575 *tempByte &= ~(1 << bitPos);
9578 if (fdSetInfo->bigEndian)
9591 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9592 } /* end of cmInetGetFd */
9594 #endif /* SUNOS || WIN32 || SS_LINUX || SS_VW || HPOS */
9597 /* add cmInetConvertStrToIpAddr and
9598 * cmInetAsciiToIpv4 functions */
9601 * Fun: cmInetConvertStrToIpAddr
9603 * Desc: This function parses the input string for an IPV4/IPV6 address.
9605 * 1) IPV4 in dot number format:
9607 * 2) IPV6, in uncompressed, compressed, and IPV4 embedded format
9608 * 10:20:30:40:502:610:70C:80ad
9610 * 45::AB:34:123.34.5.667
9612 * Ret: ROK - SUCCESS
9621 S16 cmInetConvertStrToIpAddr
9623 uint16_t len, /* Length of IP address */
9624 uint8_t *val, /* Domain Name String */
9625 CmInetNetAddr *address /* IP Address */
9628 uint8_t idx; /* Index for string*/
9629 uint8_t ipv4[CM_INET_IPV4ADDR_SIZE]; /* IPV4 Address bytes */
9630 #ifdef IPV6_SUPPORTED
9631 uint16_t *ipv6; /* IPV6 Address bytes */
9632 uint16_t ipv6Reg[8]; /* regular IPV6 Address bytes */
9633 uint16_t ipv6Cmp[8]; /* compressed IPV6 Address bytes */
9634 uint8_t numBlk; /* number of blocks in IPV6 addr */
9635 Bool compressed; /* IPV6 in compressed format */
9636 uint8_t ipv6Idx; /* counter for IPV6 */
9637 uint8_t blkBeginIdx; /* IPV6, char index for the
9638 beginning of the block */
9639 uint8_t i; /* counter for IPV6 */
9640 S16 retVal; /* return value */
9641 Bool embedIPV4 = FALSE; /* IPV4 embedded in IPV6 ? */
9642 #endif /* IPV6_SUPPORTED*/
9646 #ifdef IPV6_SUPPORTED
9651 ipv6 = ipv6Reg; /* assign pointer to IPV6 regular, uncompressed */
9652 memset(ipv6Reg, 0, CM_INET_IPV6ADDR_SIZE);
9653 memset(ipv6Cmp, 0, CM_INET_IPV6ADDR_SIZE);
9654 #endif /* IPV6_SUPPORTED*/
9656 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9658 /* Check for IP Address */
9659 while ((val[idx] != '.') && (val[idx] != ':') &&
9662 #if (ERRCLASS & ERRCLS_DEBUG)
9663 if (((val[idx] < '0') || (val[idx] > '9')) &&
9664 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9665 ((val[idx] < 'A') || (val[idx] > 'F')))
9670 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9672 /* Convert Ascii to integer */
9673 CM_INET_ATOI(ipv4[0], val[idx]);
9675 #ifdef IPV6_SUPPORTED
9676 /* convert Ascii to hex */
9677 CM_INET_ATOH(ipv6[0], val[idx]);
9678 #endif /* IPV6_SUPPORTED */
9680 idx++; /* move to the next character */
9681 } /* while, try to determine IPV4 or IPV6 */
9683 #if (ERRCLASS & ERRCLS_DEBUG)
9684 if ((val[idx] != '.') && (val[idx] != ':'))
9688 } /* if, couldn't determine IPV4 or IPV6 */
9689 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9692 if (val[idx] == '.')
9695 cmInetAsciiToIpv4(3, &(ipv4[1]), (uint16_t)(len - idx), &(val[idx]));
9697 address->type = CM_INET_IPV4ADDR_TYPE;
9698 CM_INET_GET_IPV4_ADDR_FRM_STRING(address->u.ipv4NetAddr, ipv4);
9700 #ifdef IPV6_SUPPORTED
9703 numBlk = 1; /* already converted the 1st block */
9705 while ((val[idx] != '\0') && (idx < len) && (numBlk <= 8))
9707 idx++; /* go to the next char, either a number or the 2nd : */
9708 if (val[idx] == ':')
9710 #if (ERRCLASS & ERRCLS_DEBUG)
9711 if (compressed == TRUE)
9713 /* can't have 2 :: */
9716 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9719 idx++; /* skip the : */
9722 } /* if, IPV6 in compressed format :: */
9726 } /* else, uncompressed, convert next block */
9728 numBlk++; /* increase number of blocks */
9730 /* assign the index the beginning of the block */
9733 while(val[idx] != ':' && val[idx] != '\0' && idx < len)
9735 if (val[idx] == '.')
9737 /* convert number to IPV4 */
9738 ipv6[ipv6Idx] = 0; /* clear out whatever we did */
9739 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9740 retVal = cmInetAsciiToIpv4(4, ipv4, len - blkBeginIdx,
9741 &(val[blkBeginIdx]));
9742 /* stop the loop, embedded IPV4 is the last part of
9750 } /* if, '.' means IPV4 address embedded in IPV6 */
9752 #if (ERRCLASS & ERRCLS_DEBUG)
9753 if (((val[idx] < '0') || (val[idx] > '9')) &&
9754 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9755 ((val[idx] < 'A') || (val[idx] > 'F')))
9760 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9762 /* Convert Ascii to integer */
9763 CM_INET_ATOH(ipv6[ipv6Idx], val[idx]);
9765 /* move to the next index */
9767 } /* while, convert a block of 16 bits Hex number */
9768 if (embedIPV4 == TRUE)
9770 ipv6Idx--; /* deccrease in case of compressed IPV6 */
9771 break; /* stop the while look */
9772 } /* if, IPV4 embedded in IPV6 */
9773 } /* while, IPV6 parsing */
9774 if (compressed == TRUE)
9776 if (embedIPV4 == TRUE)
9778 numBlk = 5; /* the last 2 blocks are IPV4 */
9779 } /* if, IPV4 embedded */
9782 numBlk = 7; /* copy from the last block */
9783 } /* else, no embedded IPV4 */
9785 /* type cast uint8_t over -1 becasue we want to copy the last block,
9788 for (i = ipv6Idx; i != (uint8_t) (-1); i --)
9790 ipv6Reg[numBlk] = ipv6Cmp[i];
9792 } /* for, copying compress IPV6 to regular IPV6 */
9793 } /* if, compressed format */
9795 if (embedIPV4 == TRUE)
9797 ipv6Reg[6] = PutHiByte(ipv6Reg[6], ipv4[0]);
9798 ipv6Reg[6] = PutLoByte(ipv6Reg[6], ipv4[1]);
9799 ipv6Reg[7] = PutHiByte(ipv6Reg[7], ipv4[2]);
9800 ipv6Reg[7] = PutLoByte(ipv6Reg[7], ipv4[3]);
9801 } /* if, IPV4 embedded */
9803 /* convert IPV6 to cmInetIpv6 */
9804 address->type = CM_INET_IPV6ADDR_TYPE;
9805 memcpy(address->u.ipv6NetAddr,
9806 ipv6Reg, CM_INET_IPV6ADDR_SIZE);
9808 #endif /* IPV6_SUPPORTED */
9811 } /* cmInetConvertStrToIpAddr */
9816 * Fun: cmInetAsciiToIpv4
9818 * Desc: This function parses the input string to an IPV4 address.
9819 * The input string can be
9820 * - the whole IPV4 address, '123.43.45.56', or
9821 * - a part of it. '34.56.454'
9822 * numBytes: number of bytes needs to be converted, IPV4 has
9823 * 4 bytes. If we are only converting the end of an
9824 * address, this number needs to be adjusted. For
9825 * example, when converting '34.56.454]', the number
9828 * Ret: ROK - SUCCESS
9836 S16 cmInetAsciiToIpv4
9838 uint8_t numBytes, /* number of Byte to convert */
9839 uint8_t *ipv4Addr, /* IPV4 Address */
9840 uint16_t len, /* Length of IP address */
9841 uint8_t *val /* Domain Name String */
9844 uint8_t byteCount; /* Byte Count */
9845 uint8_t idx; /* Index for string*/
9849 for (byteCount = 0; byteCount < numBytes; byteCount++)
9851 while((val[idx] != '.') && (idx < len))
9853 #if (ERRCLASS & ERRCLS_DEBUG)
9854 if (val[idx] < '0' || val[idx] > '9')
9859 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9861 /* Convert Ascii to integer */
9862 CM_INET_ATOI(ipv4Addr[byteCount], val[idx]);
9864 /* move to the next index */
9871 } /* cmInetAsciiToIpv4 */
9873 /* cm_inet_c_001.main_34:Added wrapper function for getaddrinfo and freeaddrinfo */
9874 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
9878 * Fun: cmInetGetAddrInfo
9880 * Desc: a socket file descriptor to a local Internet
9883 * Ret: Value returned by getaddrinfo
9891 S32 cmInetGetAddrInfo
9893 const S8 *node, /* Network addr which has to be resolved */
9894 const S8 *service, /* Sets the port number in network addr */
9895 const CmInetAddrInfo *hints, /* Specifies preferred socket type or protocol */
9896 CmInetAddrInfo **res /* Link list of addrInfo structure */
9902 #if (ERRCLASS & ERRCLS_INT_PAR)
9903 /* error check on parameters */
9904 if ((node == NULLP) || (hints == NULLP))
9908 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9910 ret = getaddrinfo(node,service,hints,res);
9915 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9916 /* cm_inet_c_001.main_62:Warning fix */
9917 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%ld), node(%p),"
9918 " service(%p)\n", ret, node, service);
9919 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET052, 0, prntBuf);
9921 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9922 /* cm_inet_c_001.main_62:Warning fix */
9923 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%d), node(%p),"
9924 " service(%p)\n ", ret, node, service);
9925 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET053, 0, prntBuf);
9926 #endif /* ALIGN_64BIT */
9927 #endif /* CMINETDBG */
9930 } /* end of cmInetGetAddrInfo */
9935 * Fun: cmInetFreeAddrInfo
9937 * Desc: Free the dynamically allocated addrinfo structure
9947 Void cmInetFreeAddrInfo
9949 CmInetAddrInfo *res /* Link list of addrInfo structure */
9953 #if (ERRCLASS & ERRCLS_INT_PAR)
9954 /* error check on parameters */
9957 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9960 } /* end of cmInetFreeAddrInfo */
9962 #endif /* SS_VW | SS_PS | WIN32*/
9964 /* cm_inet_c_001.main_36 : 1. Added new interface - cmInetFlushRecvBuf()
9965 to flush the data from socket receive buffer. */
9966 #ifdef CM_INET_FLUSH_RECV_BUF
9970 * Fun: cmInetFlushRcvBuf
9972 * Desc: Reads all the data from a socket and throw it!!
9973 * The buffers for the receive buffer for recvfrom() are allocated from the stack.
9975 * Ret: ROK - successful
9976 * ROKDNA - ok, data not available
9977 * RCLOSED - connection closed by peer
9978 * ROUTRES - failed, out of resources
9986 S16 cmInetFlushRecvBuf
9988 CmInetFd *sockFd, /* socket file descriptor */
9989 MsgLen *len, /* number of octects to be flushed */
9990 S32 flags /* additional control flags */
9994 Data recvTempBuf[CM_INET_MAX_BYTES_READ];
9996 #if (defined(WIN32) || defined(CMINETFLATBUF))
9997 S32 ret; /* temporary return value */
9998 uint32_t pendLen; /* pending data length */
9999 S32 recvLen; /* number of received octets by recvmsg() */
10000 MsgLen curLen; /* current number of octets in buffer */
10001 uint32_t remAddrLen; /* length of remote address */
10002 struct sockaddr_in *remAddr; /* remote Internet address */
10003 #ifdef IPV6_SUPPORTED
10004 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
10006 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
10007 #endif /* IPV6_SUPPORTED */
10009 S32 ret; /* temporary return value */
10010 MsgLen curLen; /* current number of octets in buffer */
10011 uint32_t pendLen; /* pending data length */
10012 S32 recvLen; /* number of received octets by recvmsg() */
10013 struct msghdr msg; /* message header */
10014 CmInetIovec rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
10015 uint32_t remAddrLen; /* length of remote address */
10016 #ifdef IPV6_SUPPORTED
10017 struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
10019 #if (defined(SS_LINUX) || defined(_XPG4_2))
10020 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
10021 /* from stack for IPv6 ancill data */
10024 CmInetSockAddr remSockAddr; /* to get packet's src IP address */
10025 #if (defined(SS_LINUX) || defined(_XPG4_2))
10026 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
10027 /* from stack for IPv4 ancill data */
10029 #endif /* IPV6_SUPPORTED */
10030 #endif /* WIN32 | CMINETFLATBUF */
10032 /* used by getsockopt */
10033 uint32_t errValue; /* error value */
10034 uint32_t optLen; /* option length */
10037 #if (ERRCLASS & ERRCLS_INT_PAR)
10038 /* error check on parameters */
10039 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
10043 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10046 #if (defined(WIN32) || defined(CMINETFLATBUF))
10048 #endif /* (WIN32 | CMINETFLATBUF) */
10050 /* clear the structure */
10051 memset(&remSockAddr, 0, sizeof(remSockAddr));
10053 /* get number of pending data */
10054 ret = cmInetGetNumRead(sockFd, &pendLen);
10057 /* ret may be RFAILED or ROUTRES */
10061 /* check if connection got closed */
10064 if (sockFd->type == CM_INET_STREAM)
10067 /* cm_inet_c_001.main_50
10068 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
10069 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
10070 * socket that select says is ready to read. This should not be
10071 * considered as connection closed. So return ROKDNA instead of
10077 /* clear error if there is any, because if there is internal error
10078 * here it will cause infinite loop in TUCL */
10081 optLen = sizeof(int);
10083 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10084 (char*)&errValue, (socklen_t *)&optLen);
10086 #if (defined(SS_VW) || defined(SS_PS))
10087 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10088 (char*)&errValue, (int *)&optLen);
10091 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10092 (char*)&errValue, (int *)&optLen);
10093 #endif /* SS_WINCE */
10095 #endif /* SS_LINUX */
10096 if (ret == INET_ERR)
10099 #ifndef ALIGN_64BIT
10100 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10101 /* cm_inet_c_001.main_62:Warning fix */
10102 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10103 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10104 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10106 /* cm_inet_c_001.main_62:Warning fix */
10107 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10108 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10109 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10110 #endif /*ALIGN_64BIT*/
10111 #endif /* CMINETDBG */
10117 /* added separate recvfrom calls different OS */
10118 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10119 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10120 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10122 #if ( defined(SUNOS) || defined(SS_LINUX))
10123 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10124 NULLP, (socklen_t *)&remAddrLen);
10126 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10127 NULLP, (S32 *)&remAddrLen);
10129 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10130 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10135 }/* if (pendLen == 0)*/
10138 if((*len == CM_INET_READ_THROW) || (*len >= CM_INET_MAX_BYTES_READ))
10140 curLen = CM_INET_MAX_BYTES_READ;
10144 curLen = *len; /*set to given number of messasges to be flushed */
10147 if((*len != CM_INET_READ_THROW) && (*len < pendLen))
10152 #if (defined(WIN32) || defined(CMINETFLATBUF))
10156 * maybe needs more than one recvfrom() call to read an entire
10161 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10162 /* added separate recvfrom calls different OS */
10164 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10165 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10166 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10168 #if ( defined(SUNOS) || defined(SS_LINUX))
10169 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10170 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
10172 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempbuf, curLen, 0,
10173 &remSockAddr, (S32 *)&remAddrLen);
10175 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10176 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10178 if (recvLen == INET_ERR)
10181 /* added check ERR_WOULDBLOCK */
10182 if ((INET_ERR_CODE == ERR_AGAIN) ||
10183 (INET_ERR_CODE == ERR_WOULDBLOCK))
10190 /* In Windows the recvfrom function fails
10191 * with error code which maps to either WSAECONNABORTED. If
10192 * this happens then cmInetFlushRecvBuf must return RCLOSED */
10193 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
10194 (INET_ERR_CODE == ERR_CONNRESET))
10201 #ifndef ALIGN_64BIT
10202 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10203 /* cm_inet_c_001.main_62:Warning fix */
10204 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10205 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10206 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10208 /* cm_inet_c_001.main_62:Warning fix */
10209 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10210 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10211 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10212 #endif /*ALIGN_64BIT*/
10213 #endif /* CMINETDBG */
10218 if(recvLen < curLen)
10221 pendLen -= recvLen;
10223 if(pendLen < curLen)
10226 } /* while (curLen > 0) */
10228 #else /* end of Win NT/flat buffer specific part */
10231 * maybe needs more than one recvmsg() call to read entire message
10232 * on a stream socket
10236 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10237 /* update the message structure */
10239 rxArr[0].iov_base = (Void*)recvTempBuf;
10240 rxArr[0].iov_len = (uint32_t)curLen;
10242 rxArr[0].iov_base = (S8*)recvTempBuf;
10243 rxArr[0].iov_len = curLen;
10244 #endif /* SS_LINUX */
10245 msg.msg_iov = rxArr;
10246 msg.msg_iovlen = 1;
10248 msg.msg_name = NULLP;
10249 msg.msg_namelen = 0;
10251 /* added defined(_XPG4_2). Also changed the
10253 #if (defined(SS_LINUX) || defined(_XPG4_2))
10254 msg.msg_control = ancillData;
10255 msg.msg_controllen = sizeof(ancillData);
10258 msg.msg_accrights = NULLP;
10259 msg.msg_accrightslen = 0;
10260 #endif /* SS_LINUX */
10262 recvLen = recvmsg(sockFd->fd, &msg, flags);
10263 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
10265 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
10266 added check ERR_WOULDBLOCK */
10267 if ((INET_ERR_CODE == ERR_AGAIN) ||
10268 (INET_ERR_CODE == ERR_WOULDBLOCK))
10275 #ifndef ALIGN_64BIT
10276 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
10277 /* cm_inet_c_001.main_62:Warning fix */
10278 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10279 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10280 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10282 /* cm_inet_c_001.main_62:Warning fix */
10283 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10284 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10285 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10286 #endif /*ALIGN_64BIT*/
10287 #endif /* CMINETDBG */
10289 /* If this happens then cmInetFlushRecvBuf must return RCLOSED.
10290 * Needed for getting icmp msgs */
10291 if (INET_ERR_CODE == ERR_CONNABORTED)
10297 }/* if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))*/
10299 if(recvLen < curLen)
10302 pendLen -= recvLen;
10304 if(pendLen < curLen)
10307 } /* while(curLen > 0) */
10309 #endif /* WIN32 | CMINETFLATBUF */
10313 } /* end of cmInetFlushRecvBuf */
10315 #endif /* CM_INET_FLUSH_RECV_BUF*/
10317 /**********************************************************************
10319 **********************************************************************/