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 ={0};
2315 #ifdef IPV6_SUPPORTED
2317 S8 *addrString = NULLP;
2318 uint32_t addrLen = 0;
2319 S8 ipv4Format[23] = "::ffff:";
2320 CmInetIpAddr ipv4NetAddr = {0};
2321 #endif /* SUN_KSCTP */
2322 struct sockaddr_in6 addr6 ={0};
2323 #endif /* IPV6_SUPPORTED */
2324 #if (ERRCLASS & ERRCLS_INT_PAR)
2325 /* error check on parameters */
2326 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd)
2327 || (info == NULLP) || (mBuf == NULLP) || (len == NULLP))
2331 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2334 memset(&addr, 0, sizeof(struct sockaddr_in));
2335 #ifdef IPV6_SUPPORTED
2336 memset(&addr6, 0, sizeof(struct sockaddr_in6));
2337 #endif /* IPV6_SUPPORTED */
2339 /* copy message to a flat buffer */
2340 ret = SFndLenMsg(mBuf, &bufLen);
2345 /* max message length is limited to control the memory usage */
2346 /* casting bufLen to avoid warnings */
2347 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
2351 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
2356 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
2357 if ((ret != ROK) || (msgLen != bufLen))
2359 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2363 if ( dstAddr != NULLP)
2365 #ifdef IPV6_SUPPORTED
2366 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
2368 if (sockFd->protType == AF_INET)
2370 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2373 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2374 /* cm_inet_c_001.main_62:Warning fix */
2375 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2376 " IPV4 socket, sockFd->fd(%ld)\n", sockFd->fd);
2377 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2379 /* cm_inet_c_001.main_62:Warning fix */
2380 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Can't send message to IPV6 address through"
2381 " IPV4 socket, sockFd->fd(%d)\n", sockFd->fd);
2382 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET012, 0, prntBuf);
2383 #endif /*ALIGN_64BIT*/
2384 #endif /* CMINETDBG */
2388 addr6.sin6_family = AF_INET6;
2389 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2390 CM_INET_COPY_IPV6ADDR(&addr6.sin6_addr.s6_addr, &dstAddr->u.ipv6NetAddr);
2391 sockAddrLen = sizeof(struct sockaddr_in6);
2392 sockAddrPtr = (CmInetSockAddr*)&addr6;
2398 if (sockFd->protType == AF_INET)
2402 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2403 /* cm_inet_c_001.main_62:Warning fix */
2404 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2405 " socket, sockFd->fd(%ld)\n", sockFd->fd);
2406 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2408 /* cm_inet_c_001.main_62:Warning fix */
2409 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "can't connect to IPV6 address through IPV4"
2410 " socket, sockFd->fd(%d)\n", sockFd->fd);
2411 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET064, 0, prntBuf);
2412 #endif /*ALIGN_64BIT*/
2413 #endif /* CMINETDBG */
2416 addr6.sin6_family = AF_INET6;
2417 addr6.sin6_port = CM_INET_HTON_UINT16(port);
2418 ipv4NetAddr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2419 cmInetNtoa(ipv4NetAddr, &addrString);
2420 addrLen = cmStrlen((uint8_t*)addrString);
2421 memcpy((ipv4Format+7), addrString, addrLen);
2422 ipv4Format[7+addrLen] = '\0';
2423 cmInetPton6((CmInetIpAddr6*)(addr6.sin6_addr.s6_addr), ipv4Format);
2424 sockAddrLen = sizeof(struct sockaddr_in6);
2425 sockAddrPtr = (CmInetSockAddr*)&addr6;
2427 addr.sin_family = AF_INET;
2428 addr.sin_port = CM_INET_HTON_UINT16(port);
2429 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2430 sockAddrLen = sizeof(struct sockaddr_in);
2431 sockAddrPtr = (CmInetSockAddr*)&addr;
2432 #endif /* SUN_KSCTP */
2435 addr.sin_family = AF_INET;
2436 addr.sin_port = CM_INET_HTON_UINT16(port);
2437 addr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->u.ipv4NetAddr);
2438 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2439 sockAddrLen = (MsgLen)sizeof(struct sockaddr_in);
2440 sockAddrPtr = (CmInetSockAddr*)&addr;
2441 #endif /* IPV6_SUPPORTED */
2448 sockAddrPtr = (CmInetSockAddr*)&addr;
2450 /* cm_inet_c_001.main_58 : initialized sockAddrLen properly */
2451 #ifdef IPV6_SUPPORTED
2452 sockAddrLen = sizeof(struct sockaddr_in6);
2454 sockAddrLen = sizeof(struct sockaddr_in);
2458 /* Not validating the address, whether addr is a valid address or not */
2463 if (unorderFlg == TRUE)
2466 flags |= MSG_UNORDERED;
2469 flags |= SCTP_UNORDERED;
2472 /*cm_inet_c_001.main_54: converting ppid to network*/
2473 ppId = CM_INET_HTON_UINT32(ppId);
2474 ret = sctp_sendmsg(sockFd->fd, (Void*)sendBuf, bufLen,
2475 (struct sockaddr*)sockAddrPtr, (size_t)sockAddrLen,
2476 ppId, flags, strmId, ttl, context);
2477 if (ret == INET_ERR)
2479 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2482 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2483 /* cm_inet_c_001.main_62:Warning fix */
2484 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%ld),"
2485 " strmId(%u),sockFd->fd(%ld)\n",
2486 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2487 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2489 /* cm_inet_c_001.main_55: Fix for compilation warning */
2490 /* cm_inet_c_001.main_62:Warning fix */
2491 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpSendMsg() Failed : error(%d) ppId(%d),"
2492 " strmId(%u),sockFd->fd(%d)\n",
2493 INET_ERR_CODE, ppId, strmId, sockFd->fd);
2494 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET013, 0, prntBuf);
2495 #endif /*ALIGN_64BIT*/
2496 #endif /* CMINETDBG */
2498 if ((INET_ERR_CODE == ERR_AGAIN) || (INET_ERR_CODE == ERR_WOULDBLOCK))
2499 return (RWOULDBLOCK);
2500 else if (INET_ERR_CODE == ERR_PIPE)
2506 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2510 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
2517 * Fun: cmInetSctpRecvMsg
2519 * Desc: invokes sctp API to get the message received at sctp socket
2521 * Ret: ROK - successful
2529 S16 cmInetSctpRecvMsg
2531 CmInetFd *sockFd, /* socket file descriptor */
2532 CmInetNetAddr *srcAddr, /* source Internet address/port */
2533 uint16_t *port, /* source port no. */
2534 CmInetMemInfo *meminfo, /* buffer allocation info */
2535 Buffer **mBuf, /* buffer structure received */
2536 MsgLen *len, /* number of octets received */
2537 CmInetSctpSndRcvInfo *sinfo, /* sctp send-receive info */
2538 uint32_t *flag, /* flags */
2539 CmInetSctpNotification *ntfy /* notification parameters */
2544 struct sctp_sndrcvinfo info;
2545 struct sockaddr_storage addr;
2546 struct sockaddr_in *pAddr = NULLP;
2547 #ifdef IPV6_SUPPORTED
2548 struct sockaddr_in6 *pAddr6 = NULLP;
2551 Data *recvbuf = NULLP;
2553 union sctp_notification *sctpNtfy = NULLP;
2554 /* cm_inet_c_001.main_46: Defined new variable to store length of data */
2557 #endif /* SS_LINUX */
2559 #if (ERRCLASS & ERRCLS_INT_PAR)
2560 /* error check on parameters */
2561 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
2562 (srcAddr == NULLP) || (port == NULLP) || (meminfo == NULLP) ||
2563 (mBuf == NULLP) || (len == NULLP) || (sinfo == NULLP) || (flag == NULLP))
2567 #endif /* ERRCLASS & ERRCLS_INT_PAR */
2572 memset(ntfy, 0, sizeof(CmInetSctpNotification));
2574 buflen = CM_INET_MAX_MSG_LEN;
2576 /* allocate flat receive buffer */
2577 ret = SGetSBuf(meminfo->region, meminfo->pool, &recvbuf, buflen);
2581 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2582 /* cm_inet_c_001.main_62:Warning fix */
2583 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failed to allocate memory\n");
2584 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET065, 0, prntBuf);
2585 #endif /* CMINETDBG */
2589 addrlen = sizeof(struct sockaddr_storage);
2591 memset(&addr, 0, sizeof(struct sockaddr_storage));
2592 memset(&info, 0, sizeof(struct sctp_sndrcvinfo));
2594 ret = sctp_recvmsg(sockFd->fd, (Void *)recvbuf, (size_t)buflen,
2595 (struct sockaddr*)&addr, &addrlen, &info,
2597 if (ret == INET_ERR)
2600 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2603 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2604 /* cm_inet_c_001.main_62:Warning fix */
2605 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpRecvMsg() Failed : error(%d),"
2606 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
2607 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET014, 0, prntBuf);
2609 DU_LOG("\ncmInetSctpRecvMsg() Failed : error(%d), sockFd->fd(%d)", \
2610 INET_ERR_CODE, sockFd->fd);
2611 #endif /*ALIGN_64BIT*/
2612 #endif /* CMINETDBG */
2617 /* save the length of the received message */
2618 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2621 #ifdef IPV6_SUPPORTED
2622 if (addr.ss_family == AF_INET6)
2624 uint8_t ipv4Format[12] = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff};
2625 pAddr6 = (struct sockaddr_in6*)&addr;
2626 *port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
2628 if((cmMemcmp(ipv4Format, pAddr6->sin6_addr.s6_addr, 12)) == 0)
2630 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2631 memcpy(&srcAddr->u.ipv4NetAddr, ((pAddr6->sin6_addr.s6_addr) + 12), sizeof(uint32_t));
2632 srcAddr->u.ipv4NetAddr = CM_INET_HTON_uint32_t(srcAddr->u.ipv4NetAddr);
2637 srcAddr->type = CM_INET_IPV6ADDR_TYPE;
2638 CM_INET_COPY_IPV6ADDR(&srcAddr->u.ipv6NetAddr, &pAddr6->sin6_addr.s6_addr);
2643 pAddr = (struct sockaddr_in*)&addr;
2644 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2645 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2646 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2649 pAddr = (struct sockaddr_in*)&addr;
2650 *port = CM_INET_NTOH_UINT16(pAddr->sin_port);
2651 srcAddr->type = CM_INET_IPV4ADDR_TYPE;
2652 srcAddr->u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2653 #endif /* IPV6_SUPPORTED */
2655 /* fill sndrcv info */
2656 sinfo->stream = info.sinfo_stream;
2657 sinfo->ssn = info.sinfo_ssn;
2658 sinfo->flags = info.sinfo_flags;
2659 /*cm_inet_c_001.main_54: converting ppid to host*/
2660 sinfo->ppid = CM_INET_NTOH_UINT32(info.sinfo_ppid);
2661 sinfo->context = info.sinfo_context;
2662 sinfo->timetolive = info.sinfo_timetolive;
2663 sinfo->tsn = info.sinfo_tsn;
2664 sinfo->cumtsn = info.sinfo_cumtsn;
2665 sinfo->assocId = info.sinfo_assoc_id;
2667 /* fill message flags */
2669 if ((msgFlags & MSG_EOR) != 0)
2670 *flag |= CM_INET_SCTP_MSG_EOR;
2672 if ((msgFlags & MSG_NOTIFICATION) != 0)
2674 *flag |= CM_INET_SCTP_MSG_NOTIFICATION;
2677 sctpNtfy = (union sctp_notification*)recvbuf;
2679 ntfy->header.nFlags = sctpNtfy->sn_header.sn_flags;
2680 ntfy->header.nLen = sctpNtfy->sn_header.sn_length;
2682 switch(sctpNtfy->sn_header.sn_type)
2684 case SCTP_ASSOC_CHANGE:
2685 ntfy->header.nType = CM_INET_SCTP_ASSOC_CHANGE;
2686 switch(sctpNtfy->sn_assoc_change.sac_state)
2689 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_UP;
2691 case SCTP_COMM_LOST:
2692 ntfy->u.assocChange.state = CM_INET_SCTP_COMM_LOST;
2695 ntfy->u.assocChange.state = CM_INET_SCTP_RESTART;
2697 case SCTP_SHUTDOWN_COMP:
2698 ntfy->u.assocChange.state = CM_INET_SCTP_SHUTDOWN_COMP;
2700 case SCTP_CANT_STR_ASSOC:
2701 ntfy->u.assocChange.state = CM_INET_SCTP_CANT_STR_ASSOC;
2706 ntfy->u.assocChange.error = sctpNtfy->sn_assoc_change.sac_error;
2707 ntfy->u.assocChange.outStreams = sctpNtfy->sn_assoc_change.sac_outbound_streams;
2708 ntfy->u.assocChange.inStreams = sctpNtfy->sn_assoc_change.sac_inbound_streams;
2709 ntfy->u.assocChange.assocId = sctpNtfy->sn_assoc_change.sac_assoc_id;
2711 ntfy->u.assocChange.info = sctpNtfy->sn_assoc_change.sac_info;
2714 case SCTP_PEER_ADDR_CHANGE:
2715 ntfy->header.nType = CM_INET_SCTP_PEER_ADDR_CHANGE;
2716 switch(sctpNtfy->sn_paddr_change.spc_state)
2718 case SCTP_ADDR_AVAILABLE:
2719 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_AVAILABLE;
2721 case SCTP_ADDR_UNREACHABLE:
2722 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_UNREACHABLE;
2724 case SCTP_ADDR_REMOVED:
2725 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_REMOVED;
2727 case SCTP_ADDR_ADDED:
2728 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_ADDED;
2730 case SCTP_ADDR_MADE_PRIM:
2731 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_MADE_PRIM;
2734 case SCTP_ADDR_CONFIRMED:
2735 ntfy->u.paddrChange.state = CM_INET_SCTP_ADDR_CONFIRMED;
2742 #ifdef IPV6_SUPPORTED
2743 if (sctpNtfy->sn_paddr_change.spc_aaddr.ss_family == AF_INET6)
2745 pAddr6 = (struct sockaddr_in6*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2746 ntfy->u.paddrChange.addr.type = CM_INET_IPV6ADDR_TYPE;
2747 CM_INET_COPY_IPV6ADDR(&ntfy->u.paddrChange.addr.u.ipv6NetAddr,
2748 &pAddr6->sin6_addr.s6_addr);
2752 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2753 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2754 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2757 pAddr = (struct sockaddr_in*)&(sctpNtfy->sn_paddr_change.spc_aaddr);
2758 ntfy->u.paddrChange.addr.type = CM_INET_IPV4ADDR_TYPE;
2759 ntfy->u.paddrChange.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2760 #endif /* IPV6_SUPPORTED */
2762 ntfy->u.paddrChange.error = sctpNtfy->sn_paddr_change.spc_error;
2763 ntfy->u.paddrChange.assocId = sctpNtfy->sn_paddr_change.spc_assoc_id;
2765 case SCTP_REMOTE_ERROR:
2766 ntfy->header.nType = CM_INET_SCTP_REMOTE_ERROR;
2768 ntfy->u.remoteErr.error = sctpNtfy->sn_remote_error.sre_error;
2769 ntfy->u.remoteErr.assocId = sctpNtfy->sn_remote_error.sre_assoc_id;
2771 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2772 datlen = cmStrlen(sctpNtfy->sn_remote_error.sre_data) + 1;
2774 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2775 &ntfy->u.remoteErr.data, datlen );
2778 ntfy->u.remoteErr.data = NULLP;
2781 memcpy(ntfy->u.remoteErr.data,\
2782 sctpNtfy->sn_remote_error.sre_data, datlen);
2785 case SCTP_SEND_FAILED:
2786 ntfy->header.nType = CM_INET_SCTP_SEND_FAILED;
2788 ntfy->u.sndFailed.error = sctpNtfy->sn_send_failed.ssf_error;
2789 ntfy->u.sndFailed.assocId = sctpNtfy->sn_send_failed.ssf_assoc_id;
2791 /* cm_inet_c_001.main_46: Allocate memory for data before copying */
2792 datlen = cmStrlen(sctpNtfy->sn_send_failed.ssf_data) + 1;
2794 ret = SGetSBuf( meminfo->region, meminfo->pool, \
2795 &ntfy->u.sndFailed.data, datlen );
2798 ntfy->u.sndFailed.data = NULLP;
2801 memcpy(ntfy->u.sndFailed.data,\
2802 sctpNtfy->sn_send_failed.ssf_data, datlen );
2804 ntfy->u.sndFailed.info.stream = sctpNtfy->sn_send_failed.ssf_info.sinfo_stream;
2805 ntfy->u.sndFailed.info.ssn = sctpNtfy->sn_send_failed.ssf_info.sinfo_ssn;
2806 ntfy->u.sndFailed.info.flags = sctpNtfy->sn_send_failed.ssf_info.sinfo_flags;
2807 ntfy->u.sndFailed.info.ppid = sctpNtfy->sn_send_failed.ssf_info.sinfo_ppid;
2808 ntfy->u.sndFailed.info.context = sctpNtfy->sn_send_failed.ssf_info.sinfo_context;
2809 ntfy->u.sndFailed.info.timetolive = sctpNtfy->sn_send_failed.ssf_info.sinfo_timetolive;
2810 ntfy->u.sndFailed.info.tsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_tsn;
2811 ntfy->u.sndFailed.info.cumtsn = sctpNtfy->sn_send_failed.ssf_info.sinfo_cumtsn;
2812 ntfy->u.sndFailed.info.assocId = sctpNtfy->sn_send_failed.ssf_info.sinfo_assoc_id;
2814 case SCTP_SHUTDOWN_EVENT:
2815 ntfy->header.nType = CM_INET_SCTP_SHUTDOWN_EVENT;
2817 ntfy->u.shutdownEvt.assocId = sctpNtfy->sn_shutdown_event.sse_assoc_id;
2820 case SCTP_ADAPTION_INDICATION :
2823 case SCTP_ADAPTATION_INDICATION :
2825 ntfy->header.nType = CM_INET_SCTP_ADAPTATION_INDICATION;
2828 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaption_event.sai_adaption_ind;
2829 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaption_event.sai_assoc_id;
2832 ntfy->u.adaptationEvt.adaptationInd = sctpNtfy->sn_adaptation_event.sai_adaptation_ind;
2833 ntfy->u.adaptationEvt.assocId = sctpNtfy->sn_adaptation_event.sai_assoc_id;
2836 case SCTP_PARTIAL_DELIVERY_EVENT:
2837 ntfy->header.nType = CM_INET_SCTP_PARTIAL_DELIVERY_EVENT;
2839 ntfy->u.pdapiEvt.indication = sctpNtfy->sn_pdapi_event.pdapi_indication;
2840 ntfy->u.pdapiEvt.assocId = sctpNtfy->sn_pdapi_event.pdapi_assoc_id;
2848 /* get a message buffer */
2849 ret = SGetMsg(meminfo->region, meminfo->pool, mBuf);
2852 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2856 ret = SAddPstMsgMult(recvbuf, *len, *mBuf);
2860 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2866 SPutSBuf(meminfo->region, meminfo->pool, recvbuf, buflen);
2873 * Fun: cmInetSctpGetPAddrs
2875 * Desc: returns the list of peer addresses
2877 * Ret: ROK - successful
2885 S16 cmInetSctpGetPAddrs
2887 CmInetFd *sockFd, /* socket file descriptor */
2888 uint32_t assocId, /* association id */
2889 CmInetNetAddrLst *addrlst /* peer address list */
2892 /* cm_inet_c_001.main_58 : Fix for Klockwork issue */
2895 uint8_t *byteAddress;
2896 struct sockaddr *peerAddrList;
2897 struct sockaddr_in *pAddr;
2898 #ifdef IPV6_SUPPORTED
2899 struct sockaddr_in6 *pAddr6;
2900 #endif /* IPV6_SUPPORTED */
2903 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, (Void**)&peerAddrList)) == -1)
2905 if((cnt = sctp_getpaddrs(sockFd->fd, assocId, &peerAddrList)) == -1)
2910 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
2911 /* cm_inet_c_001.main_62:Warning fix */
2912 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2913 " sockFd->fd(%ld), assocId(%ld)\n",
2914 INET_ERR_CODE, sockFd->fd, assocId);
2915 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2917 /* cm_inet_c_001.main_55: Fix for compilation warning */
2918 /* cm_inet_c_001.main_62:Warning fix */
2919 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSctpGetPAddrs() Failed : error(%d),"
2920 " sockFd->fd(%d),assocId(%d)\n",
2921 INET_ERR_CODE, sockFd->fd, assocId);
2922 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET015, 0, prntBuf);
2923 #endif /*ALIGN_64BIT*/
2924 #endif /* CMINETDBG */
2929 byteAddress = (uint8_t*)peerAddrList;
2930 for (idx = 0; idx < cnt; idx++)
2932 #ifdef IPV6_SUPPORTED
2934 if (((struct sockaddr*)byteAddress)->sa_family == AF_INET6)
2936 if (sockFd->protType == AF_INET)
2940 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
2941 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2942 " sockFd->fd(%ld)", sockFd->fd);
2943 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2945 sprintf(prntBuf, "cmInetSctpGetPAddrs() Failed : Invalid address"
2946 " sockFd->fd(%d)", sockFd->fd);
2947 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET016, 0, prntBuf);
2948 #endif /*ALIGN_64BIT*/
2949 #endif /* CMINETDBG */
2951 sctp_freepaddrs(peerAddrList);
2955 pAddr6 = (struct sockaddr_in6*)byteAddress;
2957 addrlst->addrs[idx].type = CM_INET_IPV6ADDR_TYPE;
2958 CM_INET_COPY_IPV6ADDR(&(addrlst->addrs[idx].u.ipv6NetAddr), &(pAddr6->sin6_addr.s6_addr));
2959 byteAddress += sizeof(struct sockaddr_in6);
2963 pAddr = (struct sockaddr_in*)byteAddress;
2964 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2965 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2966 byteAddress += sizeof(struct sockaddr_in);
2969 pAddr = (struct sockaddr_in*)byteAddress;
2970 addrlst->addrs[idx].type = CM_INET_IPV4ADDR_TYPE;
2971 addrlst->addrs[idx].u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
2972 byteAddress += sizeof(struct sockaddr_in);
2973 #endif /* IPV6_SUPPORTED */
2976 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
2977 addrlst->count = (uint8_t)cnt;
2979 sctp_freepaddrs(peerAddrList);
2988 * Desc: invokes socket API to retrive specified socket options
2990 * Ret: ROK - successful
3000 CmInetFd *sockFd, /* socket file descriptor */
3001 uint32_t level, /* option level */
3002 uint32_t type, /* option type */
3003 Ptr value /* option value */
3007 struct sctp_status status;
3008 struct sctp_paddrinfo addrInfo;
3009 struct sockaddr_in *pAddr;
3010 #ifdef IPV6_SUPPORTED
3011 struct sockaddr_in6 *pAddr6;
3012 #endif /* IPV6_SUPPORTED */
3013 struct sctp_assocparams assocParams;
3014 /*cm_inet_c_001.main_40 Updated for the support of configurable RTO parameters,
3015 HBeat value Max retransmissions (Init, Path, Association)*/
3016 struct sctp_initmsg initMsg;
3017 struct sctp_rtoinfo rtoInfo;
3018 struct sctp_paddrparams addrParams;
3019 CmInetSctpStatus *pSctpStatus;
3020 CmInetSctpPeerAddrInfo *pPeerAddrInfo;
3021 CmInetSctpInitMsg *pInitMsg;
3022 CmInetSctpAssocParams *pAssocParams;
3023 CmInetSctpRtoInfo *pRtoInfo;
3024 CmInetSctpPeerAddrParams *pPeerAddrParams;
3025 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3029 #if (ERRCLASS & ERRCLS_INT_PAR)
3030 /* error check on parameters */
3031 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3035 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3039 case CM_INET_OPT_SCTP_GET_ASSOC_STA:
3040 pSctpStatus = (CmInetSctpStatus*)value;
3041 memset(&status, 0, sizeof(struct sctp_status));
3042 len = sizeof(status);
3043 status.sstat_assoc_id = pSctpStatus->assocId;
3045 ret = getsockopt(sockFd->fd, level, SCTP_STATUS, &status, &len);
3047 pSctpStatus->rwnd = status.sstat_rwnd;
3048 pSctpStatus->unackdata = status.sstat_unackdata;
3049 pSctpStatus->penddata = status.sstat_penddata;
3050 pSctpStatus->instrms = status.sstat_instrms;
3051 pSctpStatus->outstrms = status.sstat_outstrms;
3052 pSctpStatus->fragPoint = status.sstat_fragmentation_point;
3054 switch (status.sstat_state)
3064 pSctpStatus->state = CM_INET_SCTP_STA_EMPTY;
3071 pSctpStatus->state = CM_INET_SCTP_STA_CLOSED;
3077 case SCTPS_COOKIE_WAIT:
3079 case SCTP_COOKIE_WAIT:
3082 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_WAIT;
3087 case SCTPS_COOKIE_ECHOED:
3089 case SCTP_COOKIE_ECHOED:
3092 pSctpStatus->state = CM_INET_SCTP_STA_COOKIE_ECHOED;
3097 case SCTPS_ESTABLISHED:
3099 case SCTP_ESTABLISHED:
3102 pSctpStatus->state = CM_INET_SCTP_STA_ESTABLISHED;
3107 case SCTPS_SHUTDOWN_PENDING:
3109 case SCTP_SHUTDOWN_PENDING:
3112 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_PENDING;
3117 case SCTPS_SHUTDOWN_SENT:
3119 case SCTP_SHUTDOWN_SENT:
3122 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_SENT;
3127 case SCTPS_SHUTDOWN_RECEIVED:
3129 case SCTP_SHUTDOWN_RECEIVED:
3132 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_RECEIVED;
3137 case SCTPS_SHUTDOWN_ACK_SENT:
3139 case SCTP_SHUTDOWN_ACK_SENT:
3142 pSctpStatus->state = CM_INET_SCTP_STA_SHUTDOWN_ACK_SENT;
3153 #ifdef IPV6_SUPPORTED
3154 if (status.sstat_primary.spinfo_address.ss_family == AF_INET6)
3156 pAddr6 = (struct sockaddr_in6*)&(status.sstat_primary.spinfo_address);
3157 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr6->sin6_port);
3159 pSctpStatus->primary.addr.type = CM_INET_IPV6ADDR_TYPE;
3160 CM_INET_COPY_IPV6ADDR(&pSctpStatus->primary.addr.u.ipv6NetAddr,
3161 &pAddr6->sin6_addr.s6_addr);
3165 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3166 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3167 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3168 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3171 pAddr = (struct sockaddr_in*)&(status.sstat_primary.spinfo_address);
3172 pSctpStatus->primary.port = CM_INET_NTOH_UINT16(pAddr->sin_port);
3173 pSctpStatus->primary.addr.type = CM_INET_IPV4ADDR_TYPE;
3174 pSctpStatus->primary.addr.u.ipv4NetAddr = CM_INET_NTOH_UINT32(pAddr->sin_addr.s_addr);
3175 #endif /* IPV6_SUPPORTED */
3177 pSctpStatus->primary.assocId = status.sstat_primary.spinfo_assoc_id;
3178 if (status.sstat_primary.spinfo_state == SCTP_ACTIVE)
3179 pSctpStatus->primary.isActive = TRUE;
3182 pSctpStatus->primary.isActive = FALSE;
3183 pSctpStatus->primary.cwnd = status.sstat_primary.spinfo_cwnd;
3184 pSctpStatus->primary.srtt = status.sstat_primary.spinfo_srtt;
3185 pSctpStatus->primary.rto = status.sstat_primary.spinfo_rto;
3186 pSctpStatus->primary.mtu = status.sstat_primary.spinfo_mtu;
3190 case CM_INET_OPT_SCTP_GET_PADDR_INFO:
3191 pPeerAddrInfo = (CmInetSctpPeerAddrInfo*)value;
3192 memset(&addrInfo, 0, sizeof(struct sctp_paddrinfo));
3193 len = sizeof(addrInfo);
3194 addrInfo.spinfo_assoc_id = pPeerAddrInfo->assocId;
3196 #ifdef IPV6_SUPPORTED
3197 if (pPeerAddrInfo->addr.type == CM_INET_IPV6ADDR_TYPE)
3199 if (sockFd->protType == AF_INET)
3203 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3204 /* cm_inet_c_001.main_62:Warning fix */
3205 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3206 " sockFd->fd(%ld)\n", sockFd->fd);
3207 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3209 /* cm_inet_c_001.main_62:Warning fix */
3210 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() Failed : Invalid address,"
3211 " sockFd->fd(%d)\n", sockFd->fd);
3212 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET017, 0, prntBuf);
3213 #endif /*ALIGN_64BIT*/
3214 #endif /* CMINETDBG */
3218 pAddr6 = (struct sockaddr_in6*)&(addrInfo.spinfo_address);
3219 pAddr6->sin6_family = AF_INET6;
3220 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3221 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrInfo->addr.u.ipv6NetAddr);
3225 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3226 pAddr->sin_family = AF_INET;
3227 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3228 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3231 pAddr = (struct sockaddr_in*)&(addrInfo.spinfo_address);
3232 pAddr->sin_family = AF_INET;
3233 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrInfo->port);
3234 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrInfo->addr.u.ipv4NetAddr);
3235 #endif /* IPV6_SUPPORTED */
3237 /* Not validating the address, whether Addr is a valid address or not */
3239 ret = getsockopt(sockFd->fd, level, SCTP_GET_PEER_ADDR_INFO, &addrInfo, &len);
3241 if (addrInfo.spinfo_state == SCTP_ACTIVE)
3242 pPeerAddrInfo->isActive = TRUE;
3244 pPeerAddrInfo->isActive = FALSE;
3245 pPeerAddrInfo->cwnd = addrInfo.spinfo_cwnd;
3246 pPeerAddrInfo->srtt = addrInfo.spinfo_srtt;
3247 pPeerAddrInfo->rto = addrInfo.spinfo_rto;
3248 pPeerAddrInfo->mtu = addrInfo.spinfo_mtu;
3251 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
3253 pPeerAddrParams = (CmInetSctpPeerAddrParams *)value;
3255 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
3257 addrParams.spp_assoc_id = pPeerAddrParams->assocId;
3259 if (pPeerAddrParams->s.addrPres == TRUE)
3261 #ifdef IPV6_SUPPORTED
3262 if (pPeerAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
3264 if (sockFd->protType == AF_INET)
3268 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3269 /* cm_inet_c_001.main_62:Warning fix */
3270 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%ld)\n",
3272 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3274 /* cm_inet_c_001.main_62:Warning fix */
3275 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "invalid address line:sockFd->fd(%d)\n",
3277 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET066, 0, prntBuf);
3278 #endif /*ALIGN_64BIT*/
3279 #endif /* CMINETDBG */
3283 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
3284 pAddr6->sin6_family = AF_INET6;
3285 pAddr6->sin6_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3286 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pPeerAddrParams->s.addr.u.ipv6NetAddr);
3290 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3291 pAddr->sin_family = AF_INET;
3292 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3293 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3296 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
3297 pAddr->sin_family = AF_INET;
3298 pAddr->sin_port = CM_INET_HTON_UINT16(pPeerAddrParams->s.port);
3299 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pPeerAddrParams->s.addr.u.ipv4NetAddr);
3300 #endif /* IPV6_SUPPORTED */
3304 #ifdef IPV6_SUPPORTED
3305 if (sockFd->protType == AF_INET6)
3306 addrParams.spp_address.ss_family = AF_INET6;
3308 addrParams.spp_address.ss_family = AF_INET;
3310 addrParams.spp_address.ss_family = AF_INET;
3314 len = sizeof(addrParams);
3316 ret = getsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, &len);
3317 /* cm_inet_c_001.main_41 : Fixed the Solaris compilation problem */
3320 pPeerAddrParams->hbInterval = addrParams.spp_hbinterval;
3321 pPeerAddrParams->pathMaxRxt = addrParams.spp_pathmaxrxt;
3322 pPeerAddrParams->assocId = addrParams.spp_assoc_id;
3323 pPeerAddrParams->pathMtu = addrParams.spp_pathmtu;
3324 pPeerAddrParams->sackDelay = addrParams.spp_sackdelay;
3326 if (addrParams.spp_flags & SPP_HB_ENABLE)
3327 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_ENABLE;
3329 pPeerAddrParams->hbEnblFlag = CM_INET_OPT_DISABLE;
3331 if (addrParams.spp_flags & SPP_PMTUD_ENABLE)
3332 pPeerAddrParams->pmtudFlag = CM_INET_OPT_ENABLE;
3334 pPeerAddrParams->pmtudFlag = CM_INET_OPT_DISABLE;
3336 if (addrParams.spp_flags & SPP_SACKDELAY_ENABLE)
3337 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_ENABLE;
3339 pPeerAddrParams->sackDelayFlag = CM_INET_OPT_DISABLE;
3344 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
3346 pAssocParams = (CmInetSctpAssocParams *)value;
3348 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
3350 assocParams.sasoc_assoc_id = pAssocParams->assocId;
3352 len = sizeof(assocParams);
3354 ret = getsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, &len);
3356 pAssocParams->assocMaxReTx = assocParams.sasoc_asocmaxrxt;
3357 pAssocParams->cookieLife = assocParams.sasoc_cookie_life;
3358 pAssocParams->assocId = assocParams.sasoc_assoc_id;
3359 pAssocParams->numberOfPeerDest = assocParams.sasoc_number_peer_destinations;
3360 pAssocParams->peerRwnd = assocParams.sasoc_peer_rwnd;
3361 pAssocParams->localRwnd = assocParams.sasoc_local_rwnd;
3365 case CM_INET_OPT_SCTP_RTO_INFO:
3367 pRtoInfo = (CmInetSctpRtoInfo *)value;
3369 memset(&rtoInfo, 0, sizeof(struct sctp_rtoinfo));
3371 len = sizeof(rtoInfo);
3373 ret = getsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoInfo, &len);
3375 pRtoInfo->assocId = rtoInfo.srto_assoc_id;
3376 pRtoInfo->rtoInitial = rtoInfo.srto_initial;
3377 pRtoInfo->rtoMax = rtoInfo.srto_max;
3378 pRtoInfo->rtoMin = rtoInfo.srto_min;
3382 case CM_INET_OPT_SCTP_INIT_MSG:
3384 pInitMsg = (CmInetSctpInitMsg *)value;
3386 memset(&initMsg, 0, sizeof(struct sctp_initmsg));
3388 len = sizeof(initMsg);
3390 ret = getsockopt(sockFd->fd, level, SCTP_INITMSG, &initMsg, &len);
3392 pInitMsg->maxInitReTx = initMsg.sinit_max_attempts;
3393 pInitMsg->maxInitTimeout = initMsg.sinit_max_init_timeo;
3394 pInitMsg->numOstreams = initMsg.sinit_num_ostreams;
3395 pInitMsg->maxInstreams = initMsg.sinit_max_instreams;
3403 if (ret == INET_ERR)
3407 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3408 /* cm_inet_c_001.main_62:Warning fix */
3409 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3410 " error(%d), sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3411 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3413 /* cm_inet_c_001.main_62:Warning fix */
3414 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetOpt() failed on line:"
3415 " error(%d), sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3416 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET067, 0, prntBuf);
3417 #endif /*ALIGN_64BIT*/
3418 #endif /* CMINETDBG */
3425 /* cm_inet_c_001.main_54: Added new function cmInetShutDownSctp()*/
3428 * Fun: cmInetShutDownSctp
3430 * Desc: Shutdown the SCTP association gracefully.
3432 * Ret: ROK - successful
3440 S16 cmInetShutDownSctp
3442 CmInetFd *sockFd /* socket file descriptor */
3445 /*cm_inet_c_001.main_58 : fix for klockwork issue */
3447 struct sctp_sndrcvinfo sndRcvInfo;
3450 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3453 sndRcvInfo.sinfo_flags = MSG_EOF;
3455 sndRcvInfo.sinfo_flags = SCTP_EOF;
3458 /* Call the sctp_send with flag set to termiante the association */
3460 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3466 /* cm_inet_c_001.main_62:Warning fix */
3467 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%ld)\n",
3468 INET_ERR_CODE, sockFd->fd);
3469 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3471 /* cm_inet_c_001.main_62:Warning fix */
3472 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutDownSctp() Failed : error(%d), sockFd->fd(%d)\n",
3473 INET_ERR_CODE, sockFd->fd);
3474 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3475 #endif /*ALIGN_64BIT*/
3476 #endif /* CMINETDBG */
3484 /* cm_inet_c_001.main_61: Added new function cmInetAbortSctpAssoc()*/
3487 * Fun: cmInetAbortSctpAssoc
3489 * Desc: ABORT the association.
3491 * Ret: ROK - successful
3499 S16 cmInetAbortSctpAssoc
3501 CmInetFd *sockFd, /* socket file descriptor */
3502 UConnId assocId /* Association ID */
3506 struct sctp_sndrcvinfo sndRcvInfo;
3509 memset(&sndRcvInfo, 0, sizeof(sndRcvInfo));
3512 sndRcvInfo.sinfo_flags = MSG_ABORT;
3514 sndRcvInfo.sinfo_flags = SCTP_ABORT;
3517 sndRcvInfo.sinfo_assoc_id = assocId;
3519 /* Call the sctp_send with flag set to termiante the association */
3521 ret = sctp_send(sockFd->fd, NULLP, 0, &sndRcvInfo, sndRcvInfo.sinfo_flags);
3527 /* cm_inet_c_001.main_62:Warning fix */
3528 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%ld)\n",
3529 INET_ERR_CODE, sockFd->fd);
3530 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3532 /* cm_inet_c_001.main_62:Warning fix */
3533 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAbortSctpAssoc() Failed : error(%d), sockFd->fd(%d)\n",
3534 INET_ERR_CODE, sockFd->fd);
3535 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET018, 0, prntBuf);
3536 #endif /*ALIGN_64BIT*/
3537 #endif /* CMINETDBG */
3550 * Fun: cmInetConnect
3552 * Desc: Establishs a connection to a foreign address (TCP) or associates
3553 * a UDP socket to a foreign address.
3555 * Ret: ROK - successful
3556 * ROKDNA - resource temporarily unavaiable
3557 * RINPROGRESS - connection is in progress (only non-blocking)
3558 * RISCONN - connection is established (only non-blocking)
3569 CmInetFd *sockFd, /* socket file descriptor */
3570 CmInetAddr *servAddr /* foreign Internet address/port */
3573 S32 ret; /* temporary return value */
3574 struct sockaddr_in dstAddr; /* foreign Internet address/port */
3575 #ifdef IPV6_SUPPORTED
3576 struct sockaddr_in6 dstAddr6; /* foreign Internet IPV6 address/port */
3579 #endif /* CMINETDBG */
3580 #endif /* IPV6_SUPPORTED */
3582 CmInetSockAddr *sockAddrPtr;
3585 #if (ERRCLASS & ERRCLS_INT_PAR)
3586 /* error check on parameters */
3587 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3588 (servAddr == NULLP))
3592 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3594 #ifdef IPV6_SUPPORTED
3595 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3597 memset(&dstAddr6, 0, sizeof(dstAddr6));
3598 dstAddr6.sin6_family = AF_INET6;
3599 dstAddr6.sin6_port = CM_INET_HTON_UINT16(servAddr->u.ipv6Addr.port);
3600 CM_INET_COPY_IPV6ADDR(&dstAddr6.sin6_addr,
3601 &servAddr->u.ipv6Addr.ipv6NetAddr);
3602 sizeOfAddr = sizeof(struct sockaddr_in6);
3603 sockAddrPtr = (CmInetSockAddr *)&dstAddr6;
3607 memset(&dstAddr, 0, sizeof(dstAddr));
3608 dstAddr.sin_family = AF_INET;
3609 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->u.ipv4Addr.port);
3610 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->u.ipv4Addr.address);
3611 sizeOfAddr = sizeof(struct sockaddr_in);
3612 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3615 memset(&dstAddr, 0, sizeof(dstAddr));
3616 dstAddr.sin_family = AF_INET;
3617 dstAddr.sin_port = CM_INET_HTON_UINT16(servAddr->port);
3618 dstAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(servAddr->address);
3619 sizeOfAddr = sizeof(struct sockaddr_in);
3620 sockAddrPtr = (CmInetSockAddr *)&dstAddr;
3621 #endif /* IPV6_SUPPORTED */
3623 ret = connect(sockFd->fd, sockAddrPtr, sizeOfAddr);
3624 if (ret == INET_ERR)
3626 switch (INET_ERR_CODE)
3628 /* non-blocking: connection is in progress */
3629 case ERR_INPROGRESS:
3630 return (RINPROGRESS);
3634 * non-blocking: connection is established
3635 * blocking : connection is already established
3641 /* resource temporarily unavailable */
3642 case ERR_WOULDBLOCK:
3646 /* non-blocking: connection is in progress */
3648 return (RINPROGRESS);
3652 return (RINPROGRESS);
3655 /* Check for connection refused and timeout errors */
3656 case ERR_CONNREFUSED:
3661 /* it is a real error */
3664 #ifdef IPV6_SUPPORTED
3665 if (servAddr->type == CM_INET_IPV6ADDR_TYPE)
3666 port = servAddr->u.ipv6Addr.port;
3668 port = servAddr->u.ipv4Addr.port;
3670 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3672 /* cm_inet_c_001.main_62:Warning fix */
3673 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3674 " addrtype(0x%x), port(0x%1x), sockFd->fd(%ld)\n",
3675 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3676 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3678 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d),"
3679 " addrtype(0x%x), port(0x%1x), sockFd->fd(%d)\n",
3680 INET_ERR_CODE, servAddr->type, port, sockFd->fd);
3681 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET019, 0, prntBuf);
3682 #endif /*ALIGN_64BIT*/
3685 /* cm_inet_c_001.main_62:Warning fix */
3686 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%lx),"
3687 "port(0x%1x), sockFd->fd(%ld)\n", INET_ERR_CODE ,
3688 servAddr->address, servAddr->port, sockFd->fd);
3689 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3691 /* cm_inet_c_001.main_62:Warning fix */
3692 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetConnect() Failed : error(%d), addr(0x%x),"
3693 "port(0x%x), sockFd->fd(%d)\n", INET_ERR_CODE ,
3694 servAddr->address, servAddr->port, sockFd->fd);
3695 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET020, 0, prntBuf);
3696 #endif /*ALIGN_64BIT*/
3697 #endif /* IPV6_SUPPORTED */
3698 #endif /* CMINETDBG */
3705 } /* end of cmInetConnect */
3712 * Desc: Indicates the willingness of a socket to listen for incomming
3713 * connection requests.
3715 * Ret: ROK - successful
3718 * Notes: The backLog value has to be within 0..5
3726 CmInetFd *sockFd, /* socket file descriptor */
3727 S16 backLog /* max. number of outstandig connections 0..5 */
3730 S32 ret; /* temporary return value */
3733 #if (ERRCLASS & ERRCLS_INT_PAR)
3734 /* error check on parameters */
3735 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
3736 (backLog < MIN_BACK_LOG) || (backLog > MAX_BACK_LOG))
3740 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3742 ret = listen(sockFd->fd, backLog);
3743 if (ret == INET_ERR)
3747 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
3748 /* cm_inet_c_001.main_62:Warning fix */
3749 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3750 " sockFd->fd(%ld)\n", INET_ERR_CODE, backLog, sockFd->fd);
3751 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3753 /* cm_inet_c_001.main_62:Warning fix */
3754 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetListen() Failed : error(%d), backLog(%d),"
3755 " sockFd->fd(%d)\n", INET_ERR_CODE, backLog, sockFd->fd);
3756 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET021, 0, prntBuf);
3757 #endif /*ALIGN_64BIT*/
3758 #endif /* CMINETDBG */
3763 } /* end of cmInetListen */
3770 * Desc: Accepts an incoming connection.
3771 * On default the new socket is non-blocking. The options can be
3772 * changed with the function cmInetSetOpt().
3774 * Ret: ROK - successful
3775 * ROKDNA - there is no connection present to accept (only
3787 CmInetFd *sockFd, /* socket file descriptor */
3788 CmInetAddr *fromAddr, /* calling Internet address/port */
3789 CmInetFd *newSockFd /* socket file descriptor for new connection*/
3792 S32 ret; /* temporary return value */
3793 S32 addrLen; /* address structure length */
3794 struct sockaddr_in *peerAddr; /* calling Internet address/port */
3795 #ifdef IPV6_SUPPORTED
3796 struct sockaddr_in6 *peerAddr6; /* calling Internet address/port */
3797 struct sockaddr_in6 sockAddr;
3799 CmInetSockAddr sockAddr;
3800 #endif /* IPV6_SUPPORTED */
3806 #if (ERRCLASS & ERRCLS_INT_PAR)
3807 /* error check on parameters */
3808 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
3812 #endif /* ERRCLASS & ERRCLS_INT_PAR */
3814 /* change CmInetSockAddr to sockAddr */
3815 addrLen = sizeof(sockAddr);
3818 #if ( defined(SUNOS) || defined(SS_LINUX))
3819 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3820 (socklen_t *)&addrLen);
3822 newSockFd->fd = accept(sockFd->fd, (CmInetSockAddr*)&sockAddr,
3824 #endif /* SUNOS || SS_LINUX */
3826 /* cm_inet_c_001.main_58: Moved setting of protType below */
3828 if (CM_INET_INV_SOCK_FD(newSockFd))
3830 if (INET_ERR_CODE == ERR_WOULDBLOCK)
3832 /* no connection present to accept */
3839 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
3840 /* cm_inet_c_001.main_62:Warning fix */
3841 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3842 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
3843 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3845 /* cm_inet_c_001.main_62:Warning fix */
3846 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : error(%d),"
3847 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
3848 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET022, 0, prntBuf);
3849 #endif /*ALIGN_64BIT*/
3850 #endif /* CMINETDBG */
3856 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
3857 /* added for IPv6/IPv4 socket distinguishing */
3858 #ifdef IPV6_SUPPORTED
3859 if (addrLen == sizeof(struct sockaddr_in))
3860 newSockFd->protType = AF_INET;
3861 else if(addrLen == sizeof(struct sockaddr_in6))
3862 newSockFd->protType = AF_INET6;
3867 /* cm_inet_c_001.main_62:Warning fix */
3868 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%ld)\n", sockFd->fd);
3869 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3871 /* cm_inet_c_001.main_62:Warning fix */
3872 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetAccept() Failed : sockFd->fd(%d)\n", sockFd->fd);
3873 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET071, 0, prntBuf);
3874 #endif /*ALIGN_64BIT*/
3875 #endif /* CMINETDBG */
3878 #endif /* IPV6_SUPPORTED */
3880 /* set the new socket file descriptor type */
3881 newSockFd->type = CM_INET_STREAM;
3883 /* set default options for new socket file descriptor */
3884 optVal = CM_INET_OPT_DISABLE;
3885 ret = cmInetSetOpt(newSockFd, SOL_SOCKET, CM_INET_OPT_BLOCK, &optVal);
3888 ret = cmInetClose(newSockFd);
3892 #ifdef IPV6_SUPPORTED
3893 memset(fromAddr, 0, sizeof(fromAddr));
3894 if (addrLen == sizeof(struct sockaddr_in))
3896 peerAddr = (struct sockaddr_in *)&sockAddr;
3897 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
3898 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3899 fromAddr->u.ipv4Addr.address =
3900 CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3902 else if (addrLen == sizeof(struct sockaddr_in6))
3904 peerAddr6 = (struct sockaddr_in6 *)&sockAddr;
3905 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
3906 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(peerAddr6->sin6_port);
3907 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
3908 &peerAddr6->sin6_addr);
3911 peerAddr = (struct sockaddr_in *)&sockAddr;
3912 fromAddr->port = CM_INET_NTOH_UINT16(peerAddr->sin_port);
3913 fromAddr->address = CM_INET_NTOH_UINT32(peerAddr->sin_addr.s_addr);
3914 #endif /* IPV6_SUPPORTED */
3916 } /* end of cmInetAccept */
3921 * Fun: cmInet4FillTos
3923 * Desc: This function inserts tos (into ancillary data) which
3924 * will be used to fill tos value in ip header in outgoing IP packet
3925 * when sending that packet using sendmsg()function.
3935 static S16 cmInet4FillTos
3937 uint8_t tos, /* tos value to be filled in ipheader */
3938 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
3939 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
3942 struct cmsghdr *tempHdr;
3949 /* cmsghdr struc will appear before data in the ancillary data object.
3950 * So put cmsghdr struc in flat buffer first. */
3952 /* cmsghdr struc points to flat buffer's starting address */
3953 tempHdr = (struct cmsghdr *)cmsgBuf;
3955 /* fill up level & type of cmsghdr structure */
3956 tempHdr->cmsg_level = IPPROTO_IPV6;
3957 tempHdr->cmsg_type = IP_TOS;
3958 (*(uint8_t*)CMSG_DATA(tempHdr)) = tos;
3959 len = CMSG_SPACE(sizeof tos);
3962 /* fill up the length of cmsghdr structure */
3963 tempHdr->cmsg_len = len;
3968 }/* end of cmInet4FillTos */
3971 * Fun: cmInetSendDscpMsg
3973 * Desc: Sends the message data hold by mBuf.
3974 * The len paramter gives the actual written octets. If the socket
3975 * is non-blocking this value can be differ from the mBuf length
3976 * because there was not enough transmit buffer space available. If
3977 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
3979 * Values for flag parameter:
3981 * CM_INET_NO_FLAG - no additional control flag
3983 * Ret: ROK - successful
3984 * RWOULDBLOCK - no or not entire mBuf sent because would block
3985 * ROUTRES - failed, out of resources
3986 * RCLOSED - connection was closed by the peer
3989 * Notes: The successful completion of a send call does not indicate that
3990 * the data has been successfully delivered!
3992 * This function does not free any sent buffers.
3999 S16 cmInetSendDscpMsg
4001 CmInetFd *sockFd, /* socket file descriptor */
4002 CmInetAddr *dstAddr, /* destination Internet address/port */
4003 CmInetMemInfo *info, /* buffer allocation info */
4004 Buffer *mBuf, /* buffer structure to send */
4005 MsgLen *len, /* number of actually sent octets */
4006 /* added for IPv6 ext hdr */
4007 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4008 S16 flags /* additional control flags, unused */
4011 #if (defined(WIN32) || defined(CMINETFLATBUF))
4012 S32 ret =0; /* temporary return value */
4013 MsgLen msgLen =0; /* message length */
4014 MsgLen bufLen =0; /* send buffer length */
4015 Data *sendBuf =0; /* plain send buffer */
4017 S32 ret =0; /* temporary return value */
4018 S32 retVal =0; /* temporary return value */
4019 S16 i =0; /* loop index */
4020 CmInetIovec txArr[CM_INET_MAX_DBUF] = {{0}}; /* scatter vector */
4021 S16 numDBufs =0; /* number of dBufs in message */
4022 struct msghdr msg ={0}; /* sendmsg() message header */
4023 MsgLen msgLen =0; /* message length */
4024 uint32_t strtEndDBufNum =0; /* starting/ending DBuf number */
4025 MsgLen unSentLen =0; /* sent len */
4026 #ifdef IPV6_SUPPORTED
4027 uint32_t curMsgIdx =0; /* indx in cmsgData where to write an ext hdr */
4028 /* added for IPv6 ext hdr */
4029 #if (defined(SS_LINUX) || defined(_XPG4_2))
4030 /* alloc from stack for IPv6 ancill data */
4031 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA]= {0};
4032 #endif /* SS_LINUX || _XPG4_2 */
4034 uint32_t curMsgIdx =0; /* indx in cmsgData where to write an ext hdr */
4035 #if (defined(SS_LINUX) || defined(_XPG4_2))
4036 /* alloc from stack for IPv4 ancill data */
4037 uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA]={0};
4038 #endif /* SS_LINUX || _XPG4_2 */
4039 #endif /* IPV6_SUPPORTED */
4040 #endif /* WIN32 | CMINETFLATBUF */
4042 struct sockaddr_in remAddr ={0}; /* remote Internet address */
4043 #ifdef IPV6_SUPPORTED
4044 struct sockaddr_in6 remAddr6 = {0}; /* remote Internet address */
4045 #endif /* IPV8_SUPPORTED */
4046 CmInetSockAddr *sockAddrPtr = NULLP;
4047 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4048 uint32_t sizeOfAddr =0;
4050 /* cm_inet_c_001.main_50 - Added for partial send handling */
4051 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4052 #if (!defined(WIN32))
4059 #if (ERRCLASS & ERRCLS_INT_PAR)
4060 /* error check on parameters */
4061 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4062 (info == NULLP) || (len == NULLP))
4066 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4068 /* added for IPv6 ext hdr */
4069 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4070 #if (defined(SS_LINUX) || defined(_XPG4_2))
4071 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4072 #endif /* SS_LINUX || _XPG4_2 */
4074 #endif /* WIN32 | CMINETFLATBUF */
4076 msgLen = 0; /* need by CC to pass without warning */
4077 sockAddrPtr = NULLP;
4080 /* setup remote address */
4081 if (dstAddr != NULLP)
4083 #ifdef IPV6_SUPPORTED
4084 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4086 memset(&remAddr6, 0, sizeof(remAddr6));
4087 remAddr6.sin6_family = AF_INET6;
4088 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4089 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4090 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4091 sizeOfAddr = sizeof(remAddr6);
4092 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4096 memset(&remAddr, 0, sizeof(remAddr));
4097 remAddr.sin_family = AF_INET;
4098 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4099 remAddr.sin_addr.s_addr =
4100 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4101 sizeOfAddr = sizeof(remAddr);
4102 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4105 /* memset(&remAddr, 0, sizeof(remAddr)); */
4106 remAddr.sin_family = AF_INET;
4107 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4108 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4109 sizeOfAddr = sizeof(remAddr);
4110 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4111 #endif /* IPV6_SUPPORTED */
4114 #if (defined(WIN32) || defined(CMINETFLATBUF))
4115 /* copy message to a flat buffer */
4116 ret = SFndLenMsg(mBuf, &bufLen);
4121 /* max message length is limited to control the memory usage */
4122 /* casting bufLen to avoid warnings */
4123 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4127 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4132 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4133 if ((ret != ROK) || (msgLen != bufLen))
4136 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4140 if (dstAddr == NULLP)
4142 /* VxWorks sendto has some problem
4143 * with connected UDP socket, use send */
4145 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4148 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4149 #endif /* end of SS_VW */
4152 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4154 #if (defined(SS_VW) && defined(SS_VW6_7))
4155 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4157 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4160 #endif /* end of SS_VW6_7 and SS_VW */
4162 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4163 sockAddrPtr, sizeOfAddr);
4166 if (ret == INET_ERR)
4169 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4171 if(INET_ERR_CODE == ERR_AGAIN)
4174 return (RWOULDBLOCK);
4177 /* Check for ERR_WOULDBLOCK */
4178 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4181 return (RWOULDBLOCK);
4186 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4187 /* cm_inet_c_001.main_62:Warning fix */
4188 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4189 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4190 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4192 /* cm_inet_c_001.main_62:Warning fix */
4193 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d), msgLen(%d),"
4194 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4195 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4196 #endif /*ALIGN_64BIT*/
4197 #endif /* CMINETDBG */
4199 /* cm_inet_c_001.main_37 network unreacheble error is added */
4200 /* check if network is reacheble*/
4201 if ((INET_ERR_CODE == ERR_NETUNREACH))
4203 return (RNETFAILED);
4207 /* Check if connection was closed */
4208 if ((INET_ERR_CODE == ERR_PIPE) ||
4209 (INET_ERR_CODE == ERR_CONNABORTED) ||
4210 (INET_ERR_CODE == ERR_CONNRESET))
4221 /* check if entire message could be sent */
4226 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4227 return (RWOULDBLOCK);
4231 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4233 #else /* end of Win NT/flat buffer specific part */
4234 ret = SFndLenMsg(mBuf, &msgLen);
4241 /* memset(&msg, 0, sizeof(msg)); */
4244 if (dstAddr != NULLP)
4247 msg.msg_name = (Void*)sockAddrPtr;
4250 msg.msg_name = (char *)sockAddrPtr;
4252 msg.msg_name = (caddr_t)sockAddrPtr;
4254 #endif /* SS_LINUX */
4255 msg.msg_namelen = sizeOfAddr;
4259 msg.msg_name = NULLP;
4260 msg.msg_namelen = 0;
4262 /* added defined(_XPG4_2) */
4263 #if (defined(SS_LINUX) || defined(_XPG4_2))
4264 msg.msg_control = NULLP;
4265 msg.msg_controllen = 0;
4267 msg.msg_accrights = 0;
4268 msg.msg_accrightslen = NULLP;
4269 #endif /* SS_LINUX */
4271 /* allocate scatter vector */
4272 numDBufs = CM_INET_MAX_DBUF;
4278 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV4ADDR_TYPE))
4279 if((ipHdrParams->u.hdrParmIpv4.tos.pres == TRUE)&& \
4280 (ipHdrParams->u.hdrParmIpv4.tos.val != 0))
4282 cmInet4FillTos(ipHdrParams->u.hdrParmIpv4.tos.val,
4283 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4284 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4285 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4287 /* if the sender wants to send Ipv6 exten. headers */
4288 #ifdef IPV6_OPTS_SUPPORTED
4289 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4292 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4294 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4295 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4297 #endif /* SS_LINUX */
4300 /* have to decide how to get the src addr to add in in6_pktinfo */
4301 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4303 cmInet6BuildSendPktinfo(
4304 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4305 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4308 #endif /* LOCAL_INTF */
4310 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4311 * cmsgData one by one. */
4313 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4314 /* build HBH ext header in cmsgData starting at indx 0 */
4315 cmInet6BuildSendHBHOpts(
4316 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4317 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4319 /* now copy the elements from the Destination Option array one by
4320 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4321 * which is the end of HBH hdr. */
4322 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4323 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4324 cmInet6BuildSendDestOpts(
4325 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4326 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4328 /* copy Route header to to the Flat Buffer cmsgData */
4329 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4330 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4331 cmInet6BuildSendRouteOpts(
4332 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4333 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4335 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4336 * will be the curMsgIdx */
4337 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4338 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4341 #endif /* IPV6_OPTS_SUPPORTED */
4343 /* Loop till all the data is sent or till the sendmsg call cannot send
4347 /* build the send vector */
4348 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4349 total length of the packed dbufs */
4350 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4351 &strtEndDBufNum, &ioLen);
4356 /* Incase of UDP/RAW messages call SCompressMsg. */
4357 if (sockFd->type != CM_INET_STREAM)
4359 /* Compress the message into a single dBuf */
4360 ret = SCompressMsg(mBuf);
4365 /* Rebuild the send vector */
4366 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4367 total length of the packed dbuf */
4368 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4369 &strtEndDBufNum, &ioLen);
4379 msg.msg_iov = txArr;
4386 if ( sockFd->fd >= 0xD001)
4387 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4389 ret = sendmsg(sockFd->fd, &msg, 0);
4392 ret = sendmsg(sockFd->fd, &msg, 0);
4394 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4395 if (ret == INET_ERR)
4397 if((INET_ERR_CODE == ERR_AGAIN) ||
4398 (INET_ERR_CODE == ERR_WOULDBLOCK))
4400 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4401 message was sent earlier */
4402 return (RWOULDBLOCK);
4406 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4407 /* cm_inet_c_001.main_62:Warning fix */
4408 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4409 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4410 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4412 /* cm_inet_c_001.main_62:Warning fix */
4413 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendDscpMsg() Failed : error(%d),"
4414 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4415 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4416 #endif /*ALIGN_64BIT*/
4417 #endif /* CMINETDBG */
4419 /* cm_inet_c_001.main_37 network unreacheble error is added */
4420 /* check if network is reacheble or not */
4421 if ((INET_ERR_CODE == ERR_NETUNREACH))
4423 return (RNETFAILED);
4426 /* Check if connection was closed by the peer */
4427 if ((INET_ERR_CODE == ERR_PIPE) ||
4428 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4429 (INET_ERR_CODE == ERR_CONNABORTED))
4437 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4440 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4441 * to be sent, then return WOULDBLOCK
4444 return (RWOULDBLOCK);
4448 } while (*len < msgLen);
4449 #endif /* WIN32 | CMINETFLATBUF */
4453 } /* end of cmInetSendDscpMsg */
4457 * Fun: cmInetSendMsg
4459 * Desc: Sends the message data hold by mBuf.
4460 * The len paramter gives the actual written octets. If the socket
4461 * is non-blocking this value can be differ from the mBuf length
4462 * because there was not enough transmit buffer space available. If
4463 * this occurs, RWOULDBLOCK is returned and only a part of the mBuf
4465 * Values for flag parameter:
4467 * CM_INET_NO_FLAG - no additional control flag
4469 * Ret: ROK - successful
4470 * RWOULDBLOCK - no or not entire mBuf sent because would block
4471 * ROUTRES - failed, out of resources
4472 * RCLOSED - connection was closed by the peer
4475 * Notes: The successful completion of a send call does not indicate that
4476 * the data has been successfully delivered!
4478 * This function does not free any sent buffers.
4487 CmInetFd *sockFd, /* socket file descriptor */
4488 CmInetAddr *dstAddr, /* destination Internet address/port */
4489 CmInetMemInfo *info, /* buffer allocation info */
4490 Buffer *mBuf, /* buffer structure to send */
4491 MsgLen *len, /* number of actually sent octets */
4492 /* added for IPv6 ext hdr */
4493 #ifdef IPV6_OPTS_SUPPORTED
4494 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
4495 #endif /* IPV6_OPTS_SUPPORTED */
4496 S16 flags /* additional control flags, unused */
4499 #if (defined(WIN32) || defined(CMINETFLATBUF))
4500 S32 ret; /* temporary return value */
4501 MsgLen msgLen; /* message length */
4502 MsgLen bufLen; /* send buffer length */
4503 Data *sendBuf; /* plain send buffer */
4505 S32 ret; /* temporary return value */
4506 S32 retVal; /* temporary return value */
4507 S16 i; /* loop index */
4508 CmInetIovec txArr[CM_INET_MAX_DBUF] ={{0}}; /* scatter vector */
4509 S16 numDBufs; /* number of dBufs in message */
4510 struct msghdr msg; /* sendmsg() message header */
4511 MsgLen msgLen; /* message length */
4512 uint32_t strtEndDBufNum; /* starting/ending DBuf number */
4513 MsgLen unSentLen; /* sent len */
4514 #ifdef IPV6_SUPPORTED
4515 /* added for IPv6 ext hdr */
4516 #ifdef IPV6_OPTS_SUPPORTED
4517 uint32_t curMsgIdx; /* indx in cmsgData where to write an ext hdr */
4518 #if (defined(SS_LINUX) || defined(_XPG4_2))
4519 /* alloc from stack for IPv6 ancill data */
4520 uint8_t cmsgData[CM_INET_IPV6_ANCIL_DATA];
4521 #endif /* SS_LINUX || _XPG4_2 */
4522 #endif /* IPV6_OPTS_SUPPORTED */
4524 #if (defined(SS_LINUX) || defined(_XPG4_2))
4525 /* alloc from stack for IPv4 ancill data */
4526 /* uint8_t cmsgData[CM_INET_IPV4_ANCIL_DATA];*/
4527 #endif /* SS_LINUX || _XPG4_2 */
4528 #endif /* IPV6_SUPPORTED */
4529 #endif /* WIN32 | CMINETFLATBUF */
4531 struct sockaddr_in remAddr; /* remote Internet address */
4532 #ifdef IPV6_SUPPORTED
4533 struct sockaddr_in6 remAddr6; /* remote Internet address */
4534 #endif /* IPV8_SUPPORTED */
4535 CmInetSockAddr *sockAddrPtr;
4536 /* cm_inet_c_001.main_58 : Fix for klockwork issue */
4537 uint32_t sizeOfAddr;
4539 /* cm_inet_c_001.main_50 - Added for partial send handling */
4540 /* cm_inet_c_001.main_59: Protected under if not defined WIN32*/
4541 #if (!defined(WIN32))
4548 #if (ERRCLASS & ERRCLS_INT_PAR)
4549 /* error check on parameters */
4550 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
4551 (info == NULLP) || (len == NULLP))
4555 #endif /* ERRCLASS & ERRCLS_INT_PAR */
4557 /* added for IPv6 ext hdr */
4558 #if !(defined(WIN32) || defined(CMINETFLATBUF))
4559 #if (defined(SS_LINUX) || defined(_XPG4_2))
4560 /* memset(cmsgData, 0, sizeof(cmsgData)); */
4561 #endif /* SS_LINUX || _XPG4_2 */
4562 #ifdef IPV6_OPTS_SUPPORTED
4564 #endif /* IPV6_SUPPORTED */
4565 #endif /* WIN32 | CMINETFLATBUF */
4567 msgLen = 0; /* need by CC to pass without warning */
4568 sockAddrPtr = NULLP;
4571 /* setup remote address */
4572 if (dstAddr != NULLP)
4574 #ifdef IPV6_SUPPORTED
4575 if (dstAddr->type == CM_INET_IPV6ADDR_TYPE)
4577 memset(&remAddr6, 0, sizeof(remAddr6));
4578 remAddr6.sin6_family = AF_INET6;
4579 remAddr6.sin6_port = CM_INET_HTON_UINT16(dstAddr->u.ipv6Addr.port);
4580 CM_INET_COPY_IPV6ADDR(&remAddr6.sin6_addr,
4581 &dstAddr->u.ipv6Addr.ipv6NetAddr);
4582 sizeOfAddr = sizeof(remAddr6);
4583 sockAddrPtr = (CmInetSockAddr *)&remAddr6;
4587 memset(&remAddr, 0, sizeof(remAddr));
4588 remAddr.sin_family = AF_INET;
4589 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->u.ipv4Addr.port);
4590 remAddr.sin_addr.s_addr =
4591 CM_INET_HTON_UINT32(dstAddr->u.ipv4Addr.address);
4592 sizeOfAddr = sizeof(remAddr);
4593 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4596 /* memset(&remAddr, 0, sizeof(remAddr)); */
4597 remAddr.sin_family = AF_INET;
4598 remAddr.sin_port = CM_INET_HTON_UINT16(dstAddr->port);
4599 remAddr.sin_addr.s_addr = CM_INET_HTON_UINT32(dstAddr->address);
4600 sizeOfAddr = sizeof(remAddr);
4601 sockAddrPtr = (CmInetSockAddr *)&remAddr;
4602 #endif /* IPV6_SUPPORTED */
4605 #if (defined(WIN32) || defined(CMINETFLATBUF))
4606 /* copy message to a flat buffer */
4607 ret = SFndLenMsg(mBuf, &bufLen);
4612 /* max message length is limited to control the memory usage */
4613 /* casting bufLen to avoid warnings */
4614 if ((bufLen > 0) && ((uint32_t)bufLen > CM_INET_MAX_MSG_LEN))
4618 ret = SGetSBuf(info->region, info->pool, &sendBuf, bufLen);
4623 ret = SCpyMsgFix(mBuf, 0, bufLen, sendBuf, &msgLen);
4624 if ((ret != ROK) || (msgLen != bufLen))
4627 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4631 if (dstAddr == NULLP)
4633 /* VxWorks sendto has some problem
4634 * with connected UDP socket, use send */
4636 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4639 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4640 #endif /* end of SS_VW */
4643 /* cm_inet_c_001.main_54: Fix for vxworks 6.7 sending data on TCP sockets */
4645 #if (defined(SS_VW) && defined(SS_VW6_7))
4646 if ((sockFd->type == CM_INET_STREAM) || (sockFd->type == SOCK_RDM) )
4648 ret = send(sockFd->fd, (S8 *)sendBuf, bufLen, 0);
4651 #endif /* end of SS_VW6_7 and SS_VW */
4653 ret = sendto(sockFd->fd, (S8 *)sendBuf, bufLen, 0,
4654 sockAddrPtr, sizeOfAddr);
4657 if (ret == INET_ERR)
4660 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4662 if(INET_ERR_CODE == ERR_AGAIN)
4665 return (RWOULDBLOCK);
4668 /* Check for ERR_WOULDBLOCK */
4669 if(INET_ERR_CODE == ERR_WOULDBLOCK)
4672 return (RWOULDBLOCK);
4677 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4678 /* cm_inet_c_001.main_62:Warning fix */
4679 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4680 " sockFd->fd(%ld)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4681 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4683 /* cm_inet_c_001.main_62:Warning fix */
4684 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d), msgLen(%d),"
4685 " sockFd->fd(%d)\n", INET_ERR_CODE, bufLen, sockFd->fd);
4686 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET023, 0, prntBuf);
4687 #endif /*ALIGN_64BIT*/
4688 #endif /* CMINETDBG */
4690 /* cm_inet_c_001.main_37 network unreacheble error is added */
4691 /* check if network is reacheble*/
4692 if ((INET_ERR_CODE == ERR_NETUNREACH))
4694 return (RNETFAILED);
4698 /* Check if connection was closed */
4699 if ((INET_ERR_CODE == ERR_PIPE) ||
4700 (INET_ERR_CODE == ERR_CONNABORTED) ||
4701 (INET_ERR_CODE == ERR_CONNRESET))
4712 /* check if entire message could be sent */
4717 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4718 return (RWOULDBLOCK);
4722 SPutSBuf(info->region, info->pool, sendBuf, bufLen);
4724 #else /* end of Win NT/flat buffer specific part */
4725 ret = SFndLenMsg(mBuf, &msgLen);
4732 /* memset(&msg, 0, sizeof(msg)); */
4735 if (dstAddr != NULLP)
4738 msg.msg_name = (Void*)sockAddrPtr;
4741 msg.msg_name = (char *)sockAddrPtr;
4743 msg.msg_name = (caddr_t)sockAddrPtr;
4745 #endif /* SS_LINUX */
4746 msg.msg_namelen = sizeOfAddr;
4750 msg.msg_name = NULLP;
4751 msg.msg_namelen = 0;
4753 /* added defined(_XPG4_2) */
4754 #if (defined(SS_LINUX) || defined(_XPG4_2))
4755 msg.msg_control = NULLP;
4756 msg.msg_controllen = 0;
4758 msg.msg_accrights = 0;
4759 msg.msg_accrightslen = NULLP;
4760 #endif /* SS_LINUX */
4762 /* allocate scatter vector */
4763 numDBufs = CM_INET_MAX_DBUF;
4770 /* if the sender wants to send Ipv6 exten. headers */
4771 #ifdef IPV6_OPTS_SUPPORTED
4772 if (ipHdrParams != NULLP && (ipHdrParams->type == CM_INET_IPV6ADDR_TYPE))
4775 if(ipHdrParams->u.ipv6HdrParm.ttl.pres == TRUE)
4777 cmInetBuildSendHoplimit((uint32_t)ipHdrParams->u.ipv6HdrParm.ttl.val,
4778 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4780 #endif /* SS_LINUX */
4783 /* have to decide how to get the src addr to add in in6_pktinfo */
4784 if(ipHdrParams->u.ipv6HdrParm.srcAddr6.type == 6)
4786 cmInet6BuildSendPktinfo(
4787 &ipHdrParams->u.ipv6HdrParm.srcAddr6.u.ipv6NetAddr,
4788 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx,
4791 #endif /* LOCAL_INTF */
4793 /* copy each ipv6 ext header from ipHdrParams to the flat buffer
4794 * cmsgData one by one. */
4796 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt == TRUE)
4797 /* build HBH ext header in cmsgData starting at indx 0 */
4798 cmInet6BuildSendHBHOpts(
4799 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
4800 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 0);
4802 /* now copy the elements from the Destination Option array one by
4803 * one to the Flat Buffer cmsgData. Start filling at indx curMsgIdx
4804 * which is the end of HBH hdr. */
4805 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt == TRUE)
4806 /* build Dest opt hdr starting at (cmsgData + curMsgIdx) */
4807 cmInet6BuildSendDestOpts(
4808 &(ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr),
4809 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx, 1);
4811 /* copy Route header to to the Flat Buffer cmsgData */
4812 if (ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt == TRUE)
4813 /* curMsgIdx will be the indx where Dest opt ends in cmsgData */
4814 cmInet6BuildSendRouteOpts(
4815 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
4816 (uint8_t *)(cmsgData + curMsgIdx), &curMsgIdx);
4818 /* msghrd struc's msg_control will point cmsgData and msg_controllen
4819 * will be the curMsgIdx */
4820 msg.msg_control = cmsgData; /* pointer to Ancillary Data */
4821 msg.msg_controllen = curMsgIdx; /* total length of ancillary Data */
4824 #endif /* IPV6_OPTS_SUPPORTED */
4826 /* Loop till all the data is sent or till the sendmsg call cannot send
4830 /* build the send vector */
4831 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4832 total length of the packed dbufs */
4833 retVal = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4834 &strtEndDBufNum, &ioLen);
4839 /* Incase of UDP/RAW messages call SCompressMsg. */
4840 if (sockFd->type != CM_INET_STREAM)
4842 /* Compress the message into a single dBuf */
4843 ret = SCompressMsg(mBuf);
4848 /* Rebuild the send vector */
4849 /* cm_inet_c_001.main_50 - Partial send handling. Added variable to hold
4850 total length of the packed dbuf */
4851 ret = buildSendIovec(mBuf, unSentLen, txArr, numDBufs, &i,
4852 &strtEndDBufNum, &ioLen);
4862 msg.msg_iov = txArr;
4869 if ( sockFd->fd >= 0xD001)
4870 ret = ntl_sendmsg(ntl_hLib, sockFd->fd, &msg, 0);
4872 ret = sendmsg(sockFd->fd, &msg, 0);
4875 ret = sendmsg(sockFd->fd, &msg, 0);
4877 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4878 if (ret == INET_ERR)
4880 if((INET_ERR_CODE == ERR_AGAIN) ||
4881 (INET_ERR_CODE == ERR_WOULDBLOCK))
4883 /* cm_inet_c_001.main_50 - Return without making length 0, if in case the partial
4884 message was sent earlier */
4885 return (RWOULDBLOCK);
4889 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4890 /* cm_inet_c_001.main_62:Warning fix */
4891 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4892 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
4893 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4895 /* cm_inet_c_001.main_62:Warning fix */
4896 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSendMsg() Failed : error(%d),"
4897 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
4898 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET024, 0, prntBuf);
4899 #endif /*ALIGN_64BIT*/
4900 #endif /* CMINETDBG */
4902 /* cm_inet_c_001.main_37 network unreacheble error is added */
4903 /* check if network is reacheble or not */
4904 if ((INET_ERR_CODE == ERR_NETUNREACH))
4906 return (RNETFAILED);
4909 /* Check if connection was closed by the peer */
4910 if ((INET_ERR_CODE == ERR_PIPE) ||
4911 (INET_ERR_CODE == ERR_CONNREFUSED) ||
4912 (INET_ERR_CODE == ERR_CONNABORTED))
4920 /* cm_inet_c_001.main_50 - Update the length only in successful cases */
4923 /* cm_inet_c_001.main_50 - if what is actually sent is less than what is attemped
4924 * to be sent, then return WOULDBLOCK
4927 return (RWOULDBLOCK);
4931 } while (*len < msgLen);
4932 #endif /* WIN32 | CMINETFLATBUF */
4936 } /* end of cmInetSendMsg */
4939 /* added new functions for IPv6 extension headers */
4940 #ifdef IPV6_OPTS_SUPPORTED
4944 * Fun: cmInet6BuildSendPktinfo
4946 * Desc: This function inserts src address (into ancillary data) which
4947 * will be used as the src addr in outgoing IP packet when sending
4948 * that packet using sendmsg()function.
4958 static S16 cmInet6BuildSendPktinfo
4960 CmInetIpAddr6 *srcAddr, /* src ip addr to set on outgoing packet */
4961 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
4962 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
4963 uint8_t protType /* whether IPv4/IPv6 socket */
4966 struct cmsghdr *tempHdr;
4967 struct in6_pktinfo *ipv6Pktinfo;
4968 struct in6_addr lpBkAddr;
4974 lpBkAddr = in6addr_loopback;
4976 /* cmsghdr struc will appear before data in the ancillary data object.
4977 * So put cmsghdr struc in flat buffer first. */
4979 /* cmsghdr struc points to flat buffer's starting address */
4980 tempHdr = (struct cmsghdr *)cmsgBuf;
4982 /* fill up level & type of cmsghdr structure */
4983 if (protType == AF_INET6)
4985 tempHdr->cmsg_level = IPPROTO_IPV6;
4986 tempHdr->cmsg_type = IPV6_PKTINFO;
4989 else if(protType == AF_INET)
4991 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
4992 /* cm_inet_c_001.main_62:Warning fix */
4993 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
4994 "protType(%d)\n", protType);
4995 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET025, 0, prntBuf);
4999 /* skip length of cmsghdr structure - 12 bytes */
5000 len += sizeof(struct cmsghdr);
5002 if(protType == AF_INET6)
5003 ipv6Pktinfo = (struct in6_pktinfo *)(cmsgBuf + len);
5007 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5008 /* cm_inet_c_001.main_62:Warning fix */
5009 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5010 "protType(%d)\n", protType);
5011 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET026, 0, prntBuf);
5015 /* insert the hoplimit. This will override the kernel's
5016 * default hoplimit value */
5017 if(protType == AF_INET6)
5019 /* store ipv6 src addr */
5020 memcpy(&(ipv6Pktinfo->ipi6_addr), srcAddr, 16);
5023 /* store interface index */
5024 /* 0 is invalid intf indx it tells kernel to chose any intf it likes to
5025 * send this pkt. if we use nozero intf indx then kernel will send this
5026 * pkt only through that intf */
5027 ipv6Pktinfo->ipi6_ifindex = 0;
5031 else if(protType == AF_INET)
5033 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5034 /* cm_inet_c_001.main_62:Warning fix */
5035 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid socket type in cmInet6BuildPktinfo(),"
5036 "protType(%d)\n", protType);
5037 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET027, 0, prntBuf);
5041 /* fill up the length of cmsghdr structure */
5042 tempHdr->cmsg_len = len;
5047 }/* end of cmInet6BuildSendPktinfo */
5048 #endif /* LOCAL_INTF */
5054 * Fun: cmInetBuildSendHoplimit
5056 * Desc: This function inserts hoplimit value to be sent out by ancillary
5057 * data by calling sendmsg()function.
5067 static S16 cmInetBuildSendHoplimit
5069 uint32_t hoplimit, /* the hoplimit value to be set on outgoing packet */
5070 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5071 uint32_t *curMsgIdx /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5074 struct cmsghdr *tempHdr;
5080 /* cmsghdr struc will appear before data in the ancillary data object.
5081 * So put cmsghdr struc in flat buffer first. */
5083 /* cmsghdr struc points to flat buffer's starting address */
5084 tempHdr = (struct cmsghdr *)cmsgBuf;
5086 /* fill up level & type of cmsghdr structure */
5087 tempHdr->cmsg_level = IPPROTO_IPV6;
5088 tempHdr->cmsg_type = IPV6_HOPLIMIT;
5090 /* skip cmsghdr struc (length of cmsghdr structure) */
5091 len += sizeof(struct cmsghdr);
5093 /* insert the hoplimit. This will override the kernel's
5094 * default hoplimit value */
5095 *(cmsgBuf + len) = hoplimit;
5096 len += sizeof(hoplimit);
5098 /* fill up the length of cmsghdr structure */
5099 tempHdr->cmsg_len = len;
5103 } /* end of cmInetBuildSendHoplimit */
5104 #endif /* SS_LINUX */
5109 * Fun: cmInet6BuildSendHBHOpts
5111 * Desc: This function builds the HopByHop option which will be put
5112 * in the data portion of the ancillary data object. To build
5113 * the HopByHop option this function takes an array of
5114 * individual HopByHop option and fill them in a flat buffer.
5115 * cmsghdr struc always appear before HopBYHop Options, Dest
5116 * Options and Route header option.
5118 * The address of the flat Buffer *cmsgBuf is passed to this
5119 * function from cmInetSendMsg. This buffer will have all extension
5120 * headers. This buffer is passed as ancillary data by sendmsg()
5124 * Notes: This function will also be used for Destination options
5130 static S16 cmInet6BuildSendHBHOpts
5132 CmInetIpv6HBHHdrArr *hbhOptsArr,/* IPv6 extensions headers HBH/Dest opts */
5133 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5134 uint32_t *curMsgIdx, /* idx in cmsgBuf where HBH/Dest ext hdr ends */
5135 uint8_t hdrId /* 0: HBH hdr, 1:Dest Hdr */
5138 struct cmsghdr *tempHdr;
5146 /* cmsghdr struc will appear before data in the ancillary data object.
5147 * So put cmsghdr struc in flat buffer first. */
5149 /* cmsghdr struc points to flat buffer's starting address */
5150 tempHdr = (struct cmsghdr *)cmsgBuf;
5152 /* fill up level & type of cmsghdr structure */
5155 tempHdr->cmsg_level = IPPROTO_IPV6;
5156 tempHdr->cmsg_type = IPV6_HOPOPTS;
5158 else if (hdrId == 1)
5160 tempHdr->cmsg_level = IPPROTO_IPV6;
5161 tempHdr->cmsg_type = IPV6_DSTOPTS;
5164 /* skip cmsghdr struc (length of cmsghdr structure) */
5165 len += (sizeof(tempHdr->cmsg_level) + sizeof(tempHdr->cmsg_len) +
5166 sizeof(tempHdr->cmsg_type));
5168 /* Next Hdr: will be fill up accordingly by Kernel */
5169 *(cmsgBuf + len) = 0x00;
5172 /* Header Ext Length: will be fill up by us. In units of 8-byte excluding
5173 * first 8 bytes starting from Next Header field. */
5174 *(cmsgBuf + len) = 0x00;
5177 /* fillup all HBH/dest options' TLV. Here, we assume that all the HBH/dest
5178 * options are packed inside 1 HBH option header. */
5179 for (optsIdx = 0; optsIdx < hbhOptsArr->numHBHOpts;
5182 /* Copy the TLV into cmsgBuf data portion */
5183 /* copy type field of every HBH/dest option */
5184 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].type;
5185 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].type);
5187 /* copy length field of every HBH/dest option */
5188 *(cmsgBuf + len) = hbhOptsArr->hbhOpts[optsIdx].length;
5189 len += sizeof(hbhOptsArr->hbhOpts[optsIdx].length);
5191 /* copy all value bytes of current HBH/dest option to the flat buffer */
5192 memcpy((cmsgBuf + len),
5193 (hbhOptsArr->hbhOpts[optsIdx].value),
5194 hbhOptsArr->hbhOpts[optsIdx].length);
5195 len += hbhOptsArr->hbhOpts[optsIdx].length;
5198 /* cuMsgIdx will have the total length of HBH options array */
5199 /* add this length to the length of cmsgHdr struc */
5201 /* Padding: Different header has different padding requirement(xn+y). For
5202 * HBH Router Alert we need 2 bytes of padding. As this same function is
5203 * used for Destination option also and there is no option for it is yet
5204 * proposed, we are passing padN options - 6 bytes to make the Dest Option
5205 * hdr a multiple of 8 bytes. */
5207 /* HBH: padN of 2 bytes needed for Router Alert */
5208 /* This logic is present currently to support router alert which is the
5209 * only supported HBH option today. For other, generic method needed */
5212 *(cmsgBuf + len) = 0x01;
5214 *(cmsgBuf + len) = 0x00;
5218 /* fill up the length of cmsghdr structure */
5219 tempHdr->cmsg_len = len;
5223 } /* end of cmInet6BuildSendHBHOpts */
5228 * Fun: cmInet6BuildSendRouteOpts
5230 * Desc: This function transfers bytes from the Route hdr array to the
5231 * flat buffer. First the top cmsghdr structure will be filled in
5232 * the flat buffer, then route hdr type 0 will be added after
5233 * cmsghdr struc in the flat buffer. Then all IPV6 addresses will
5244 static S16 cmInet6BuildSendRouteOpts
5246 CmInetIpv6RtHdr *rtOptsArr, /* IPv6 destination options array */
5247 uint8_t *cmsgBuf, /* flat buffer where to build ext hdrs */
5248 uint32_t *curMsgIdx /* idx in cmsgBuf where to start building RT hdr */
5251 struct cmsghdr *tempHdr;
5252 CmInetIpv6RtHdr0 *tempRtHdr;
5260 /* cmsghdr struc will appear before data in the ancillary data object.
5261 * So put cmsghdr struc in flat buffer first */
5263 /* cmsghdr struc points to flat buffer */
5264 tempHdr = (struct cmsghdr *)(cmsgBuf);
5266 tempHdr->cmsg_level = IPPROTO_IPV6;
5267 tempHdr->cmsg_type = IPV6_RTHDR;
5269 /* skip cmsghdr structure */
5270 len += sizeof(struct cmsghdr);
5272 /* we know the total size of Route hdr if we know the num of ipv6 addrs */
5273 tempHdr->cmsg_len = len + sizeof(CmInetIpv6RtHdr0)
5274 + rtOptsArr->numAddrs * sizeof(CmInetIpAddr6);
5276 /* attach route hdr type 0 after cmsghdr structure */
5277 tempRtHdr = (CmInetIpv6RtHdr0 *)(cmsgBuf + len);
5279 /* fill up fields of route hdr type 0 */
5281 /* will be filled up by Kernel */
5282 tempRtHdr->ip6r0_nextHdr = 0x00;
5284 tempRtHdr->ip6r0_hdrExtLen = (2 * rtOptsArr->numAddrs);
5286 /* only type supported today */
5287 tempRtHdr->ip6r0_type = 0x00;
5289 tempRtHdr->ip6r0_segLeft = rtOptsArr->numAddrs;
5291 /* Note: rfc 2292(1998) mentions 1 reserve byte & 3 strict/loose bytes
5292 * restricting total 23 ipv6 addresses can be added to the route header.
5293 * But rfc 2292(2002) mentions all 4 bytes are reserved which allows
5294 * as many ipv6 addresses as wishes to be added to the route header */
5296 tempRtHdr->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5298 /* move pointer in the flat buffer to the end of this structure */
5299 len += sizeof(CmInetIpv6RtHdr0);
5301 /* fill up all IPV6 addresses from rtOptsArr in the flat buffer */
5302 for (addrIdx = 0; addrIdx < rtOptsArr->numAddrs; addrIdx++)
5304 memcpy((cmsgBuf + len),
5305 (rtOptsArr->ipv6Addrs[addrIdx]), 16);
5311 } /* end of cmInet6BuildSendRouteOpts */
5316 * Fun: cmInet6BuildRecvHopOptsArr
5318 * Desc: This function fills up the HopByHop Array of ipHdrParam from
5319 * the ancillary data received through recvmsg() call. The memory
5320 * to hold the extension headers is allocated here. All received
5321 * ext hdr info will be passed to upper user as ipHdrParam.
5323 * Ret: ROK - successful
5332 static S16 cmInet6BuildRecvHopOptsArr
5334 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5335 uint32_t hbhDataLen, /* byte len of cmsghdr + hbh ancil data */
5336 CmInetIpv6HBHHdrArr *hbhOptsArr, /* IPv6 extensions headers */
5337 uint8_t hdrId, /* 0: HBH, 1: DEST */
5338 CmInetMemInfo *info /* Memory information */
5341 uint32_t curDataIdx; /* to keep track where we are in the hbh Data */
5342 uint8_t optsIdx; /* how many hbh opts present in data */
5343 uint8_t numOpts; /* number of hbh opts present in data */
5349 /* get length of actual hbh ancillary data */
5350 hbhDataLen -= sizeof(struct cmsghdr);
5356 /* skip Next Hdr byte & Hdr Ext Length byte */
5359 /* First find out how many hop-by-hop headers we need to allocate */
5362 /* break when all HBH data is copied to hbhOptsArr */
5363 if (curDataIdx >= hbhDataLen)
5369 tempType = *(uint8_t *)(cmsgData + curDataIdx);
5372 /* take care of pad1 option */
5375 /* not considering the pad1 as valid option */
5381 tempLen = *(uint8_t *)(cmsgData + curDataIdx);
5383 /* 1 is to skip length. tempLen to skip the value field */
5384 curDataIdx += (1 + tempLen);
5386 /* considering the padN as valid option for Dest Opt Hdr!!! As this is
5387 * the "only" valid option today. Ignore for HBH hdr */
5393 /* allocate mem needed to hold all HBH/Dest options */
5394 ret = SGetSBuf(info->region, info->pool,
5395 (Data **)&hbhOptsArr->hbhOpts,
5396 (Size)((sizeof(CmInetIpv6HBHHdr)) * numOpts));
5400 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5401 /* cm_inet_c_001.main_62:Warning fix */
5402 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvHopOptsArr\n");
5403 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET028, 0, prntBuf);
5404 #endif /* CMINETDBG */
5411 /* skip Next Hdr byte & Hdr Ext Length byte */
5414 hbhOptsArr->numHBHOpts = numOpts;
5416 /* fill up HBH/dest opt array from recvd ancillary data */
5419 /* break when all HBH data is copied to hbhOptsArr */
5420 if (curDataIdx >= hbhDataLen)
5423 /* only copy Router Alert HBH option part which has type 5. Otherwise,
5424 * skip it when it is a PAD1, PADN or Jumbogram option for HBH. But
5425 * consider padN as valid option for dest opt hdr. */
5427 /* get the type of current HBH/dest option */
5428 tempType = *(cmsgData + curDataIdx);
5431 /* ignore PAD1 for both HBH/dest by skipping to next option */
5435 /* calculate how much to skip for padN in case of HBH */
5440 /* get the length field of padN option */
5441 tempLen = *(cmsgData + curDataIdx);
5444 /* move pointer forward to skip value field */
5445 curDataIdx += tempLen;
5449 hbhOptsArr->hbhOpts[optsIdx].type = tempType;
5451 /* copy the length */
5452 hbhOptsArr->hbhOpts[optsIdx].length = *(cmsgData + curDataIdx);
5455 /* take care of PADN = 2 when value field empty. We also don't need
5456 * to allocate memory for empty value field */
5457 if (hbhOptsArr->hbhOpts[optsIdx].length == 0)
5458 hbhOptsArr->hbhOpts[optsIdx].value = NULLP;
5461 /* take care of all other options having valid value field
5462 * such as Router Alert, PADN >= 3 bytes and Jumbo */
5463 ret = SGetSBuf(info->region, info->pool,
5464 (Data **)&hbhOptsArr->hbhOpts[optsIdx].value,
5465 (Size)hbhOptsArr->hbhOpts[optsIdx].length);
5469 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5470 /* cm_inet_c_001.main_62:Warning fix */
5471 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 2 cmInet6BuildRecvHopOptsArr\n");
5472 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET029, 0, prntBuf);
5473 #endif /* CMINETDBG */
5474 /* now go inside every separate HBH option and free the memory
5475 * allocated for its value field */
5476 for (; optsIdx > 0; optsIdx --)
5478 if (hbhOptsArr->hbhOpts[optsIdx - 1].value != NULLP)
5481 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5482 /* cm_inet_c_001.main_62:Warning fix */
5483 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 1 in BuildRecvHopOptsArr\n");
5484 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET030, 0, prntBuf);
5485 #endif /* CMINETDBG */
5486 SPutSBuf(info->region, info->pool,
5487 (Data *)hbhOptsArr->hbhOpts[optsIdx - 1].value,
5488 (Size)hbhOptsArr->hbhOpts[optsIdx - 1].length);
5491 /* clean up all CmInetIpv6HBHHdr structures allocated for all
5492 * arrived HBH options OR numOpts CmInetIpv6HBHHdr structures
5493 * allocated after counting numOpts */
5495 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5496 /* cm_inet_c_001.main_62:Warning fix */
5497 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SPutSBuf call 2 in BuildRecvHopOptsArr\n");
5498 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET031, 0, prntBuf);
5499 #endif /* CMINETDBG */
5500 SPutSBuf(info->region, info->pool,
5501 (Data *)hbhOptsArr->hbhOpts, numOpts * sizeof(CmInetIpv6HBHHdr));
5502 hbhOptsArr->numHBHOpts = 0;
5503 hbhOptsArr->hbhOpts = NULLP;
5506 /* copy the value bytes */
5507 memcpy(hbhOptsArr->hbhOpts[optsIdx].value,
5508 (cmsgData + curDataIdx),
5509 hbhOptsArr->hbhOpts[optsIdx].length);
5510 curDataIdx += hbhOptsArr->hbhOpts[optsIdx].length;
5513 /* get next option */
5517 } /* end of cmInet6BuildRecvHopOptsArr() */
5522 * Fun: cmInet6BuildRecvRtHdr
5524 * Desc: This function fills up the Route Header in the cmInetIpv6HdrParm
5525 * from the recvd ancillary data from recvmsg system call.
5527 * Ret: ROK - successful
5536 static S16 cmInet6BuildRecvRtHdr
5538 uint8_t *cmsgData, /* flat buffer where to build Route hdr */
5539 uint32_t rtDataLen, /* byte len of cmsghdr struc+rtHdr ancil data */
5540 CmInetIpv6RtHdr0 *rtHdr0, /* rtHeader0 struct that precedes IPV6 addrss */
5541 CmInetIpv6RtHdr *rtOptsArr,/* IPv6 extensions headers */
5542 CmInetMemInfo *info /* Memory information */
5545 uint32_t curDataIdx; /* to keep track where we are in hbh Data */
5546 uint8_t i; /* loop counter */
5547 S16 ret; /* temporary return value */
5550 /* byte len of actual rtHdr ancil data */
5551 rtDataLen -= sizeof(struct cmsghdr);
5553 /* start from beginning */
5556 /* copy next header byte */
5557 rtHdr0->ip6r0_nextHdr = *(cmsgData + curDataIdx);
5560 /* copy header extension length byte */
5561 rtHdr0->ip6r0_hdrExtLen = *(cmsgData + curDataIdx);
5564 /* copy type byte (always 0) */
5565 rtHdr0->ip6r0_type = 0x00;
5568 /* copy segment left byte */
5569 rtHdr0->ip6r0_segLeft = *(cmsgData + curDataIdx);
5572 /* copy 1 reserve byte + 3 strict/loose bytes */
5573 memcpy((&rtOptsArr->slMap),
5574 (cmsgData + curDataIdx), 4);
5577 /* also save reserv byte + 3 sl bytes to rtHdro struc */
5578 rtHdr0->ip6r0_resrvAndSLmap = rtOptsArr->slMap;
5580 /* subtract 8 bytes for Next Hdr, Hdr Ext Len, .... + SL bit map */
5581 rtOptsArr->numAddrs = (rtDataLen - 8)/16;
5583 ret = SGetSBuf(info->region, info->pool,
5584 (Data **)&rtOptsArr->ipv6Addrs,
5585 (Size)rtOptsArr->numAddrs * 16);
5589 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
5590 /* cm_inet_c_001.main_62:Warning fix */
5591 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "SGetSBuf failure 1 in cmInet6BuildRecvRtHdr\n");
5592 CMINETLOGERROR(ERRCLS_ADD_RES, ECMINET032, 0, prntBuf);
5593 #endif /* CMINETDBG */
5597 /* copy all the ipv6 addresses */
5598 for(i=0; i < rtOptsArr->numAddrs; i++)
5600 memcpy((rtOptsArr->ipv6Addrs[i]),
5601 (cmsgData + curDataIdx), 16);
5606 } /* end of cmInet6BuildRecvRtHdr() */
5611 * Fun: cmInet6GetHopLimitValue
5613 * Desc: This function extracts the hop limit value(ttl) of from the
5614 * ancillary data received through recvmsg() call. Then this
5615 * hoplimit value will be passed to upper user as ipHdrParam.
5617 * Ret: ROK - successful
5625 static S16 cmInet6GetHopLimitValue
5627 uint8_t *cmsgData, /* flat buffer where to build ext hdrs */
5628 uint32_t hopLimitDataLen, /* byte len of cmsghdr + hbh ancil data */
5629 CmInetIpv6HdrParm *ipv6HdrParam /* ipv6 header parameters */
5632 uint16_t curDataIdx; /* to keep track where we are in the ancillary Data */
5633 uint32_t *hopLimitValue; /* ttl/hoplimit value */
5635 hopLimitValue = NULL;
5638 /* get length of actual hbh ancillary data */
5639 hopLimitDataLen -= sizeof(struct cmsghdr);
5641 /* go to the first byte of hop limit which present after cmsghdr struc */
5642 curDataIdx += sizeof(struct cmsghdr);
5644 /* mark that hoplimit(ttl) is present */
5645 ipv6HdrParam->ttl.pres = TRUE;
5647 /* the first byte will be the HopLimit value */
5648 hopLimitValue = (uint32_t *)(cmsgData);
5649 ipv6HdrParam->ttl.val = (uint8_t)(*hopLimitValue);
5653 #endif /* IPV6_OPTS_SUPPORTED */
5658 * Fun: cmInetRecvMsg
5660 * Desc: Reads data from a socket into a message.
5661 * The buffers for the message are allocated within the
5662 * cmInetRead() function from the pool and region Id set in the
5664 * If the number of octets given by the paramter len is not
5665 * available the function immediately returns with RKDNA.
5666 * If the len parameter is set to CM_INET_READ_ANY, the currently
5667 * available data is read.
5668 * Values for flag parameter:
5670 * CM_INET_NO_FLAG - no additional control flag
5671 * CM_INET_MSG_PEEK - do not destroy data on receive buffer
5673 * Ret: ROK - successful
5674 * ROKDNA - ok, data not available
5675 * RCLOSED - connection closed by peer
5676 * ROUTRES - failed, out of resources
5686 CmInetFd *sockFd, /* socket file descriptor */
5687 CmInetAddr *fromAddr, /* sender Internet address/port */
5688 CmInetMemInfo *info, /* buffer allocation info */
5689 Buffer **mPtr, /* received buffer structure */
5690 MsgLen *len, /* number of octets to read */
5691 /* added for IPv6 */
5692 #ifdef IPV6_OPTS_SUPPORTED
5693 CmInetIpHdrParm *ipHdrParams, /* IPv6 extensions headers */
5694 #endif /* IPV6_OPTS_SUPPORTED */
5696 CmInetLocalInf *localIf, /* local interface on which pkt was recvd */
5697 #endif /* LOCAL_INTF */
5698 S32 flags /* additional control flags */
5701 #if (defined(WIN32) || defined(CMINETFLATBUF))
5702 S32 ret = 0; /* temporary return value */
5703 uint32_t pendLen =0; /* pending data length */
5704 S32 recvLen =0; /* number of received octets by recvmsg() */
5705 MsgLen bufLen =0; /* entire number of received octets */
5706 MsgLen curLen =0; /* current number of octets in buffer */
5707 Data *recvBuf =NULLP; /* receive buffer */
5708 Data *bufPtr =NULLP; /* current buffer position */
5709 Buffer *mBuf = NULLP; /* received message */
5710 uint32_t remAddrLen =0; /* length of remote address */
5711 struct sockaddr_in *remAddr = {0}; /* remote Internet address */
5712 #ifdef IPV6_SUPPORTED
5713 struct sockaddr_in6 *remAddr6 = {0}; /* remote Internet address */
5714 struct sockaddr_in6 remSockAddr ={0}; /* to get packet's source IP address */
5716 CmInetSockAddr remSockAddr ={0}; /* to get packet's source IP address */
5717 #endif /* IPV6_SUPPORTED */
5719 S32 ret =0; /* temporary return value */
5720 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
5721 uint16_t i =0; /* index */
5722 uint32_t pendLen =0; /* pending data length */
5723 S32 numBuf =0; /* number of allocated dBufs */
5724 S32 recvLen =0; /* number of received octets by recvmsg() */
5725 MsgLen bufLen =0; /* entire number of received octets */
5726 struct msghdr msg = {0}; /* message header */
5727 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5728 Buffer *tempMsg = NULLP; /* temporary message */
5729 CmInetIovec rxArr[CM_INET_MAX_DBUF]= {{0}}; /* dynamic gather array */
5730 Buffer **dBufs = NULLP; /* dynamic array with allocated dBufs */
5731 S16 numDBufs =0; /* number of allocated dBufs */
5733 /* cm_inet_c_001.main_55: As remAddrLen is only being used when
5734 * WIN32 or CMINETFLATBUF is defined, then Removed variable
5736 struct sockaddr_in *remAddr = {0}; /* remote Internet address */
5737 #ifdef IPV6_SUPPORTED
5738 struct sockaddr_in6 *remAddr6 ={0}; /* remote Internet address */
5739 struct sockaddr_in6 remSockAddr ={0};/* to get packet's source IP address */
5740 /* added for IPv6 ext headers support */
5741 #ifdef IPV6_OPTS_SUPPORTED
5742 CmInetIpv6RtHdr0 rtHdr0 ={0}; /* type 0 route header */
5743 #endif /* IPV6_OPTS_SUPPORTED */
5746 struct in6_pktinfo *pkt6Info = {0}; /* IPv6 IP_PKTINFO */
5747 #endif /* LOCAL_INTF */
5749 #if (defined(SS_LINUX) || defined(_XPG4_2))
5750 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
5751 /* from stack for IPv6 ancill data */
5754 CmInetSockAddr remSockAddr ={0}; /* to get packet's src IP address */
5755 #if (defined(SS_LINUX) || defined(_XPG4_2))
5756 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
5757 /* from stack for IPv4 ancill data */
5759 #endif /* IPV6_SUPPORTED */
5760 /* added new definitions */
5761 Bool allocFlatBuf; /* allocate a flat buffer */
5762 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5763 Data *recvBuf = NULLP; /* receive buffer */
5766 struct in_pktinfo *pkt4Info; /* IPv4 IP_PKTINFO */
5768 #endif /* SS_LINUX */
5769 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
5770 struct cmsghdr *cmsgptr;/* pointer to struct cmsghdr */
5772 #endif /* WIN32 | CMINETFLATBUF */
5773 /* used by getsockopt */
5775 /* cm_inet_c_001.main_55:Removed unused variables errValue and optLen */
5778 #if (ERRCLASS & ERRCLS_INT_PAR)
5779 /* error check on parameters */
5780 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
5781 (info == NULLP) || (mPtr == NULLP) || (len == NULLP))
5785 #endif /* ERRCLASS & ERRCLS_INT_PAR */
5789 /*cm_inet_c_001.main_48 variables declaration */
5790 #if !((defined(WIN32) || defined(CMINETFLATBUF)))
5795 #if (defined(WIN32) || defined(CMINETFLATBUF))
5797 #ifdef IPV6_SUPPORTED
5799 #endif /* IPV6_SUPPORTED */
5801 #ifdef IPV6_SUPPORTED
5804 #endif /* IPV6_SUPPORTED */
5806 #if (defined(SS_LINUX) || defined(_XPG4_2))
5807 memset(ancillData, 0, sizeof(ancillData));
5808 #endif /* SS_LINUX || _XPG4_2 */
5810 #endif /* (WIN32 | CMINETFLATBUF) */
5812 /* clear the structure */
5813 memset(&remSockAddr, 0, sizeof(remSockAddr));
5815 /* get number of pending data */
5816 /* removed 3rd arg memInfo. MemInfo is no longer
5817 needed as we call ioctl for all sockets */
5819 /* cm_inet_c_001.main_48 : call ioctl only for STREAM
5820 * sockets now. For Non-Stream sockets(Raw & UDP), fix
5821 * pending length to CM_INET_MAX_UDPRAW_MSGSIZE
5823 if(sockFd->type == CM_INET_STREAM)
5825 ret = cmInetGetNumRead(sockFd, &pendLen);
5828 /* ret may be RFAILED or ROUTRES */
5834 /* cm_inet_c_001.main_48 : pendLen is set 1 greater
5835 * than the #defined value. If recvFrom/recvMsg
5836 * returns the len == pendLen, we would drop the
5837 * message as the msg len is larger than the largest
5838 * msg we are willing to accept.
5840 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE+1;
5844 /* check if connection got closed */
5847 if (sockFd->type == CM_INET_STREAM)
5849 /* cm_inet_c_001.main_50:
5850 * cm_inet_c_001.main_56: Removed comment for cm_inet_c_001.main_50 as
5851 * the current patch changes its functionality */
5852 uint8_t readBuf[1]; /* declaration of variable for Peek */
5855 * cm_inet_c_001.main_56:
5856 * We are peeking the socket buffer again with peek as on some machines
5857 * like solaris, there is a latency observed in ioctl. In such cases,
5858 * ioctl may return 0, even though there are bytes available to read.
5859 * We reconfirm through peek whether 0 means EOF or its ioctl latency
5862 ret = cmInetPeekNew(sockFd, NULLP, info, 0, 1, readBuf);
5867 /* cm_inet_c_001.main_56:
5868 * Returning ROKDNA even cmInetPeekNew returns ROK. Because currently
5869 * we are not sure about pending length. Anyway socket FD already set,
5870 * we do another iteration to get exact pendLen value. We cannot call
5871 * cmInetGetNumRead at this point because of latency between the ioctl
5872 * call and recvfrom call issues on some machines ioctl call may
5873 * return ZERO even their a data to read. */
5877 /* cm_inet_c_001.main_52: Support for partial reception */
5878 /* cm_inet_c_001.main_59: Fix for compilation warning */
5879 if ((sockFd->type == CM_INET_STREAM) && (*len > (MsgLen)pendLen))
5881 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5882 *len = (MsgLen)pendLen;
5885 /* check if there are enough pending data to read */
5886 if ((*len == CM_INET_READ_ANY) || ((uint32_t)*len <= pendLen))
5888 if (*len == CM_INET_READ_ANY)
5890 /* added check for TCP socket. Pending data length in
5891 the socket recv buffer is determined by ioctl call in
5893 For TCP it can't be > CM_INET_MAX_MSG_LEN. */
5894 if (sockFd->type == CM_INET_STREAM)
5896 /* max message length is limited to control the memory usage */
5897 if (pendLen > CM_INET_MAX_MSG_LEN)
5898 pendLen = CM_INET_MAX_MSG_LEN;
5900 /* cm_inet_c_001.main_48 : removed the check for
5901 * Non Stream sockets (pendLen < MAX_UDPRAW_MSGSIZE)
5902 * as we are hardcoding pendLen for Non-Stream sockets.
5905 /* read all pending data */
5906 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
5907 bufLen = (MsgLen)pendLen;
5908 *len = (MsgLen)pendLen;
5912 /* cm_inet_c_001.main_45- Returning CM_INET_MAX_MSG_LEN when input is larger than
5915 /* max message length is limited to control the memory usage */
5916 if ((*len) > CM_INET_MAX_MSG_LEN)
5918 (*len) = CM_INET_MAX_MSG_LEN;
5921 /* read data length given by user */
5925 #if (defined(WIN32) || defined(CMINETFLATBUF))
5927 /* set destination Internet address structure */
5928 if (fromAddr != NULLP)
5930 remAddrLen = sizeof(remSockAddr);
5937 /* allocate flat receive buffer */
5938 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
5947 * maybe needs more than one recvfrom() call to read an entire
5948 * message from a stream socket (TCP)
5952 /* added separate recvfrom calls different OS */
5954 /*cm_inet_c_001.main_42 1. In Vx-Works the 5th and 6th parameter of recvfrom
5955 system call are either NULL or should be valid pointer.*/
5956 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
5958 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5959 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
5961 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5962 NULLP, (int *)&remAddrLen);
5964 #if ( defined(SUNOS) || defined(SS_LINUX))
5966 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5967 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
5969 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5970 NULLP, (socklen_t *)&remAddrLen);
5973 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5974 &remSockAddr, (S32 *)&remAddrLen);
5976 recvLen = recvfrom(sockFd->fd, (S8 *)bufPtr, curLen, 0,
5977 NULLP, (S32 *)&remAddrLen);
5979 #endif /* defined(SUNOS) || defined(SS_LINUX) */
5980 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
5982 if (recvLen == INET_ERR)
5985 /* moved cleanup here */
5986 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
5988 /* added check ERR_WOULDBLOCK */
5989 if ((INET_ERR_CODE == ERR_AGAIN) ||
5990 (INET_ERR_CODE == ERR_WOULDBLOCK))
5997 /* In Windows the recvfrom function fails
5998 * with error code which maps to either WSAECONNABORTED. If
5999 * this happens then cmInetRecvMsg must return RCLOSED */
6000 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
6001 (INET_ERR_CODE == ERR_CONNRESET))
6009 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6010 /* cm_inet_c_001.main_62:Warning fix */
6011 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6012 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6013 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6015 /* cm_inet_c_001.main_62:Warning fix */
6016 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6017 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6018 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET034, 0, prntBuf);
6019 #endif /*ALIGN_64BIT*/
6020 #endif /* CMINETDBG */
6028 * a message is always read atomically on a datagram socket,
6029 * therefore it's ok to read less than pending data!
6032 if ((sockFd->type == CM_INET_RAW) ||
6033 (sockFd->type == CM_INET_DGRAM))
6038 #else /* CM_INET2 */
6039 if (sockFd->type == CM_INET_DGRAM)
6044 #endif /* CM_INET2 */
6045 } /* while (curLen > 0) (only for stream sockets) */
6047 /* For UDP, it is possible to receive
6048 * a 0 byte datagram, in this case just return ROKDNA.
6051 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6054 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6057 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6061 /* cm_inet_c_001.main_48 : If Received
6062 * len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6066 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6067 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6069 if ((sockFd->type == CM_INET_DGRAM)
6070 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6075 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6076 /* cm_inet_c_001.main_62:Warning fix */
6077 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6078 " > than allowed(%lu), sockFd->fd(%ld) \n",
6079 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6080 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6082 /* cm_inet_c_001.main_62:Warning fix */
6083 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg(),recevied a message"
6084 " > than allowed(%lu), sockFd->fd(%d) \n",
6085 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6086 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET068, 0, prntBuf);
6087 #endif /*ALIGN_64BIT*/
6089 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6093 /* cm_inet_c_001.main_48 : copy data to a message structure */
6094 ret = SGetMsg(info->region, info->pool, &mBuf);
6098 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6103 if ((sockFd->type == CM_INET_DGRAM) ||
6104 (sockFd->type == CM_INET_RAW))
6106 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6110 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6113 #else /* CM_INET2 */
6114 if (sockFd->type == CM_INET_DGRAM)
6116 ret = SAddPstMsgMult(recvBuf, *len, mBuf);
6120 ret = SAddPstMsgMult(recvBuf, bufLen, mBuf);
6122 #endif /* CM_INET2 */
6126 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6132 /* setup return destination Internet address */
6133 /* added the check of (remAddrLen > 0) */
6134 if ((fromAddr != NULLP) && (remAddrLen > 0))
6136 #ifdef IPV6_SUPPORTED
6137 if (remAddrLen == sizeof(struct sockaddr_in6))
6139 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6140 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6141 fromAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6142 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6143 &remAddr6->sin6_addr);
6147 remAddr = (struct sockaddr_in *)&remSockAddr;
6148 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6149 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6150 fromAddr->u.ipv4Addr.address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6153 remAddr = (struct sockaddr_in *)&remSockAddr;
6154 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6155 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6156 #endif /* IPV6_SUPPORTED */
6160 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6162 #else /* end of Win NT/flat buffer specific part */
6164 /* Initialise variable */
6165 allocFlatBuf = FALSE;
6168 * maybe needs more than one recvmsg() call to read entire message
6169 * on a stream socket
6173 /* allocate gather vector, it's a dynamic array */
6174 numDBufs = CM_INET_MAX_DBUF;
6176 ret = SGetSBuf(info->region, info->pool, (Data**)&dBufs,
6177 numDBufs*sizeof(Buffer*));
6183 /* Allocate dBufs for gather read */
6184 /* allocate dBufs for gathering read */
6185 if (sockFd->type == CM_INET_STREAM)
6186 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6189 ret = buildRecvBuf(info, bufLen, rxArr, dBufs, numDBufs, &msg,
6193 /* check if the function returned RNA */
6196 /* Incase of UDP/RAW messages allocate a flat buffer. Incase
6197 * of TCP ignore this error condition. The user will call
6198 * cmInetRecvMsg again */
6199 /* cm_inet_c_001.main_62:Warning fix */
6200 if (sockFd->type != (uint8_t)CM_INET_STREAM)/* G++ */
6203 #ifdef T2K_MEM_LEAK_DBG
6204 char * file = __FILE__;
6205 uint32_t line = __LINE__;
6208 /* cleanup the dBuf array */
6209 for (i = 0; i < msg.msg_iovlen; i++)
6210 SPutDBuf(info->region, info->pool, dBufs[i]);
6212 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6213 numDBufs * sizeof(Buffer*));
6215 /* allocate flat receive buffer */
6216 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
6220 allocFlatBuf = TRUE;
6222 /* update the message structure */
6224 rxArr[0].iov_base = (Void*)recvBuf;
6225 rxArr[0].iov_len = (uint32_t)bufLen;
6227 rxArr[0].iov_base = (S8*)recvBuf;
6228 rxArr[0].iov_len = bufLen;
6229 #endif /* SS_LINUX */
6230 msg.msg_iov = rxArr;
6236 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6237 numDBufs*sizeof(Buffer*));
6242 numBuf = msg.msg_iovlen;
6244 /* setup destination Internet address structure */
6245 if (fromAddr != NULLP)
6248 msg.msg_name = (Void*)&remSockAddr;
6251 msg.msg_name = (char *)&remSockAddr;
6253 msg.msg_name = (caddr_t)&remSockAddr;
6255 #endif /* SS_LINUX */
6256 msg.msg_namelen = sizeof(remSockAddr);
6260 msg.msg_name = NULLP;
6261 msg.msg_namelen = 0;
6264 /* added defined(_XPG4_2). Also changed the
6266 #if (defined(SS_LINUX) || defined(_XPG4_2))
6267 msg.msg_control = ancillData;
6268 msg.msg_controllen = sizeof(ancillData);
6270 msg.msg_accrights = NULLP;
6271 msg.msg_accrightslen = 0;
6272 #endif /* SS_LINUX */
6274 recvLen = recvmsg(sockFd->fd, &msg, flags);
6275 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
6277 /* Moved up the cleanup precedures here before returning */
6278 /* Cleanup flat buffer if allocated */
6280 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6284 for (i = 0; i < numBuf; i++)
6286 #ifdef T2K_MEM_LEAK_DBG
6287 char * file = __FILE__;
6288 uint32_t line = __LINE__;
6291 SPutDBuf(info->region, info->pool, dBufs[i]);
6293 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6294 numDBufs*sizeof(Buffer*));
6297 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6298 * it has partially received data
6300 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
6301 added check ERR_WOULDBLOCK */
6302 if ((INET_ERR_CODE == ERR_AGAIN) ||
6303 (INET_ERR_CODE == ERR_WOULDBLOCK))
6305 /* cm_inet_c_001.main_50 : If message is read partially then just return
6306 * OK without freeing the mPtr. This will gaurd us
6307 * against unexpected WOULDBLOCKS observed in solaris
6315 /* cm_inet_c_001.main_50 - Free the buffer only when valid, it might be that
6316 * it has partially received data
6324 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6325 /* cm_inet_c_001.main_62:Warning fix */
6326 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6327 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
6328 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6330 /* cm_inet_c_001.main_62:Warning fix */
6331 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() Failed : error(%d),"
6332 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
6333 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET035, 0, prntBuf);
6334 #endif /*ALIGN_64BIT*/
6335 #endif /* CMINETDBG */
6337 /* If this happens then cmInetRecvMsg must return RCLOSED.
6338 * Needed for getting icmp msgs */
6339 if (INET_ERR_CODE == ERR_CONNABORTED)
6349 /* added for IPv6 extn headers */
6350 #if (defined(IPV6_OPTS_SUPPORTED) || defined(LOCAL_INTF))
6352 /* check if ancillary data has been received.
6353 * Return the allocated memory when no ancillary data received */
6354 #if (defined(SS_LINUX) || defined(_XPG4_2))
6355 if (msg.msg_controllen)
6357 cmsgptr = CMSG_FIRSTHDR(&msg);
6363 #endif /* SS_LINUX || _XPG4_2 */
6365 if (cmsgptr != NULLP)
6367 #ifdef IPV6_OPTS_SUPPORTED
6368 if(ipHdrParams != NULLP)
6370 ipHdrParams->u.ipv6HdrParm.ttl.pres = FALSE;
6371 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt = FALSE;
6372 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt = FALSE;
6373 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt = FALSE;
6375 /* get all ancillary data objects recvd one by one */
6376 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6377 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6379 if (cmsgptr->cmsg_level == IPPROTO_IPV6)
6381 /* Initialise ipHdrParams properly */
6382 ipHdrParams->type = CM_INET_IPV6ADDR_TYPE;
6384 if (cmsgptr->cmsg_type == IPV6_HOPOPTS)
6386 /* build up HBH opt array from recvd ancillary data */
6387 ret = cmInet6BuildRecvHopOptsArr(
6388 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6389 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhOptsArr,
6393 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.hbhHdrPrsnt =
6397 else if(cmsgptr->cmsg_type == IPV6_DSTOPTS)
6399 else if ((cmsgptr->cmsg_type == IPV6_DSTOPTS) ||
6400 (cmsgptr->cmsg_type == IPV6_RTHDRDSTOPTS))
6401 #endif /* SS_LINUX */
6403 /* build up Dest opt array from recvd ancillary data */
6404 ret = cmInet6BuildRecvDstOptsArr(
6405 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len,
6406 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsArr,
6410 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.destOptsPrsnt =
6413 else if (cmsgptr->cmsg_type == IPV6_RTHDR)
6415 /* build up Route Hdr from recvd ancillary data */
6416 ret = cmInet6BuildRecvRtHdr(
6417 (uint8_t *)CMSG_DATA(cmsgptr), cmsgptr->cmsg_len, &rtHdr0,
6418 &ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsArr,
6422 ipHdrParams->u.ipv6HdrParm.ipv6ExtHdr.rtOptsPrsnt =
6425 else if(cmsgptr->cmsg_type == IPV6_HOPLIMIT)
6427 /* get the received hoplimit */
6428 ret = cmInet6GetHopLimitValue((uint8_t *)CMSG_DATA(cmsgptr),
6429 cmsgptr->cmsg_len, &ipHdrParams->u.ipv6HdrParm);
6436 #endif /* IPV6_OPTS_SUPPORTED */
6438 #ifdef IPV6_SUPPORTED
6440 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULLP;
6441 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6443 if(cmsgptr->cmsg_type == IPV6_PKTINFO)
6445 pkt6Info = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
6446 localIf->intfPrsnt = TRUE;
6447 localIf->localIf = pkt6Info->ipi6_ifindex;
6448 localIf->localIfAddr.type = CM_INET_IPV6ADDR_TYPE;
6449 memcpy(&localIf->localIfAddr.u.ipv6NetAddr,
6450 &pkt6Info->ipi6_addr, 16);
6453 #endif /* LOCAL_INTF */
6456 #if (defined(SS_LINUX) && defined(LOCAL_INTF))
6457 #ifdef IPV6_SUPPORTED
6458 if(sockFd->protType == AF_INET)
6461 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
6462 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
6464 if (cmsgptr->cmsg_level == IPPROTO_IP &&
6465 cmsgptr->cmsg_type == IP_PKTINFO)
6467 pkt4Info = (struct in_pktinfo *)CMSG_DATA(cmsgptr);
6468 localIf->intfPrsnt = TRUE;
6469 localIf->localIf = pkt4Info->ipi_ifindex;
6470 localIf->localIfAddr.type = CM_INET_IPV4ADDR_TYPE;
6471 localIf->localIfAddr.u.ipv4NetAddr =
6472 ntohl(*(int *)&pkt4Info->ipi_addr);
6475 #ifdef IPV6_SUPPORTED
6478 #endif /* SS_LINUX */
6480 #endif /* IPV6_OPTS_SUPPORTED || LOCAL_INTF */
6482 /* setup return destination Internet address */
6483 if (fromAddr != NULLP)
6485 #ifdef IPV6_SUPPORTED
6486 if (msg.msg_namelen == sizeof(struct sockaddr_in6))
6488 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6489 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6490 fromAddr->u.ipv6Addr.port =
6491 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6492 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6493 &remAddr6->sin6_addr);
6497 remAddr = (struct sockaddr_in *)&remSockAddr;
6498 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6499 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6500 fromAddr->u.ipv4Addr.address =
6501 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6504 remAddr = (struct sockaddr_in *)&remSockAddr;
6505 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6506 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6507 #endif /* IPV6_SUPPORTED */
6510 /* Incase a flat buffer was allocated get
6511 * a message to pass up */
6517 ret = SGetMsg(info->region, info->pool, &tempMsg);
6521 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6525 /* cm_inet_c_001.main_48 : A 0 len UDP packet could be received */
6528 ret = SAddPstMsgMult(recvBuf, recvLen, tempMsg);
6531 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6539 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
6540 /* cm_inet_c_001.main_48 :flat buffers are allocated
6541 * for non -TCP sockets. On these sockets we can receive
6542 * only one message at a time
6544 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6545 *len = (MsgLen)recvLen;
6550 /* build message out of dBufs */
6551 ret = buildRecvMsg(info, rxArr, numBuf, recvLen, dBufs, &tempMsg);
6554 /* Deallocate previously allocated
6558 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6559 numDBufs*sizeof(Buffer*));
6566 /* it's first recvmsg() call */
6571 /* concatenate messages */
6572 ret = SCatMsg(*mPtr, tempMsg, M1M2);
6578 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6579 numDBufs*sizeof(Buffer*));
6585 SPutSBuf(info->region, info->pool, (Data*)dBufs,
6586 numDBufs*sizeof(Buffer*));
6589 * a message is always read atomically on a datagram socket,
6590 * therefore it's ok to read less than pending data!
6593 if ((sockFd->type == CM_INET_DGRAM) ||
6594 (sockFd->type == CM_INET_RAW))
6596 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6597 *len = (MsgLen)recvLen;
6600 #else /* CM_INET2 */
6601 if (sockFd->type == CM_INET_DGRAM)
6603 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6604 *len = (MsgLen)recvLen;
6607 #endif /* CM_INET2 */
6608 } /* while(bufLen > 0) (only for stream sockets) */
6610 /* cm_inet_c_001.main_48 : For UDP, it is possible to receive
6611 * a 0 byte datagram, in this case just return ROKDNA
6615 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6618 if ((sockFd->type == CM_INET_DGRAM) && (*len == 0))
6630 /* Received len == CM_INET_MAX_UDPRAW_MSGSIZE+1
6635 if ((sockFd->type == CM_INET_DGRAM || sockFd->type == CM_INET_RAW)
6636 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6638 if ((sockFd->type == CM_INET_DGRAM)
6639 && (*len == (CM_INET_MAX_UDPRAW_MSGSIZE+1)))
6650 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6651 /* cm_inet_c_001.main_62:Warning fix */
6652 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6653 " allowed(%d),sockFd->fd(%ld)\n",
6654 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6655 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6657 /* cm_inet_c_001.main_62:Warning fix */
6658 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetRecvMsg() recevied a message > than"
6659 " allowed(%d),sockFd->fd(%d)\n",
6660 CM_INET_MAX_UDPRAW_MSGSIZE, sockFd->fd);
6661 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET069, 0, prntBuf);
6668 #endif /* WIN32 | CMINETFLATBUF */
6672 /* not enough data pending yet */
6677 } /* end of cmInetRecvMsg */
6680 /* cm_inet_c_001.main_56: Added new function cmInetPeekNew() */
6684 * Fun: cmInetPeekNew
6686 * Desc: Reads some data from the socket without destroying the socket
6688 * The data is specified by the byte positon (first byte is at
6689 * position 0) and the length.
6691 * Ret: ROK - successful
6692 * ROKDNA - ok, data not available
6693 * RCLOSED - connection closed by peer
6696 * Notes: Following are the differences from the cmInetPeek to cmInetPeekNew.
6697 * This primitive does not call the select function as this is already
6698 * taken care by the called primitive. This primitive will not use any
6699 * ioctl calls, because on some machines due to latency in ioctl call
6700 * length may return as ZERO, even there is some data to be read from
6701 * the socket and this primitive only peek buffer using recvfrom.
6703 * Caller of this function need to allocate the sufficient memory to hold
6704 * the data peeked from the socket i.e. dataPos + dataLen. Socket data
6705 * will be copied in the "data" starting from dataPos offset.
6707 * For example, caller passed the following values to this function.
6708 * dataPos = 2 and dataLen = 10,then size of data buffer received should
6709 * be minimum of (dataPos + dataLen)12 bytes and socket data will be
6710 * copied in the data buffer from offset 2 (dataPos) onwards.
6718 CmInetFd *sockFd, /* socket file descriptor */
6719 CmInetAddr *fromAddr, /* sender Internet address/port */
6720 CmInetMemInfo *info, /* buffer allocation info */
6721 MsgLen dataPos, /* position of data */
6722 MsgLen dataLen, /* length of read data */
6723 Data *data /* read data */
6726 /* cm_inet_c_001.main_57 - Fix for validation and compilation warning */
6727 S32 recvLen; /* number of received octets */
6728 S32 remAddrLen; /* length of remote address length */
6729 struct sockaddr_in *remAddr; /* remote Internet address */
6730 #ifdef IPV6_SUPPORTED
6731 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6732 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6734 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6735 #endif /* IPV6_SUPPORTED */
6738 #if (ERRCLASS & ERRCLS_INT_PAR)
6739 /* error check on parameters */
6740 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6741 (info == NULLP) || (data == NULLP) ||
6742 (dataPos < 0) || (dataLen < 0))
6746 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6748 /* check if fromAddr is present or not */
6749 if (fromAddr != NULLP)
6751 remAddrLen = sizeof(remSockAddr);
6758 /* added different recvfrom calls with different 6th arg for
6759 * different OS If remAddrLen is 0, pass NULLP */
6760 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
6762 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6763 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
6765 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6766 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
6768 #if ( defined(SUNOS) || defined(SS_LINUX))
6770 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6771 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
6772 (socklen_t *)&remAddrLen);
6774 recvLen = recvfrom(sockFd->fd, (S8*)(data + dataPos),(dataLen),
6775 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
6778 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6779 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
6781 recvLen = recvfrom(sockFd->fd,(S8*)(data + dataPos), (dataLen),
6782 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
6783 #endif /* defined(SUNOS) || defined(SS_LINUX) */
6784 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
6786 /* removed the check of returned remAddrLen */
6787 if (recvLen == INET_ERR)
6789 /* added check ERR_WOULDBLOCK */
6790 if ((INET_ERR_CODE == ERR_AGAIN) ||
6791 (INET_ERR_CODE == ERR_WOULDBLOCK))
6796 /* cm_inet_c_001.main_61: added host unreachable check */
6797 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
6798 (INET_ERR_CODE == ERR_CONNRESET) ||
6799 (INET_ERR_CODE == ERR_HOSTUNREACH) ||
6800 (INET_ERR_CODE == ERR_CONNREFUSED))
6807 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
6808 /* cm_inet_c_001.main_62:Warning fix */
6809 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%ld)\n",
6810 INET_ERR_CODE, sockFd->fd);
6811 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6813 /* cm_inet_c_001.main_62:Warning fix */
6814 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeekNew() Failed : error(%d), sockFd->fd(%d)\n",
6815 INET_ERR_CODE, sockFd->fd);
6816 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET070, 0, prntBuf);
6818 #endif /* CMINETDBG */
6822 else if (recvLen == 0)
6827 /* cm_inet_c_001.main_57 - Fix for validation */
6828 if (recvLen < (S32)dataLen) /* maybe happen */
6833 /* setup return destination Internet address */
6834 /* added the check of (remAddLen > 0) */
6835 if ((fromAddr != NULLP) && (remAddrLen > 0))
6837 #ifdef IPV6_SUPPORTED
6838 memset(fromAddr, 0, sizeof(fromAddr));
6839 if (remAddrLen == sizeof(struct sockaddr_in6))
6841 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
6842 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
6843 fromAddr->u.ipv6Addr.port =
6844 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
6845 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
6846 &remAddr6->sin6_addr);
6850 remAddr = (struct sockaddr_in *)&remSockAddr;
6851 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
6852 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6853 fromAddr->u.ipv4Addr.address =
6854 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6857 remAddr = (struct sockaddr_in *)&remSockAddr;
6858 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
6859 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
6860 #endif /* IPV6_SUPPORTED */
6864 } /* end of cmInetPeeknew */
6871 * Desc: Reads some data from the socket without destroying the socket
6873 * The data is specified by the byte positon (first byte is at
6874 * position 0) and the length.
6876 * Ret: ROK - successful
6877 * ROKDNA - ok, data not available
6878 * RCLOSED - connection closed by peer
6889 CmInetFd *sockFd, /* socket file descriptor */
6890 CmInetAddr *fromAddr, /* sender Internet address/port */
6891 CmInetMemInfo *info, /* buffer allocation info */
6892 MsgLen dataPos, /* position of data */
6893 MsgLen dataLen, /* length of read data */
6894 Data *data /* read data */
6897 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
6898 Data *recvBuf = NULLP; /* plain receive buffer */
6899 /* cm_inet_c_001.main_47: 102069 Changed from S32 to MsgLen for bufLen*/
6900 MsgLen bufLen; /* buffer length */
6901 MsgLen i; /* index */
6902 MsgLen j; /* index */
6903 S32 ret; /* temporary return value */
6904 uint32_t timeout; /* timeout for cmInetSelect() */
6905 uint32_t *timeoutPtr; /* pointer to timeout */
6906 S16 numFdS; /* number of ready descriptors */
6907 /* cm_inet_c_001.main_45 - fixing the UMR issue in 64bit linux */
6908 uint32_t pendLen = 0; /* pending data length */
6909 S32 recvLen; /* number of received octets */
6910 S32 remAddrLen; /* length of remote address length */
6911 CmInetFdSet readFdS; /* socket file descriptor set */
6912 struct sockaddr_in *remAddr; /* remote Internet address */
6913 #ifdef IPV6_SUPPORTED
6914 struct sockaddr_in6 *remAddr6; /* remote Internet IPV6 address */
6915 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
6917 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
6918 #endif /* IPV6_SUPPORTED */
6921 #if (ERRCLASS & ERRCLS_INT_PAR)
6922 /* error check on parameters */
6923 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
6924 (info == NULLP) || (data == NULLP) ||
6925 (dataPos < 0) || (dataLen < 0))
6929 #endif /* ERRCLASS & ERRCLS_INT_PAR */
6931 /* check if there are some datas */
6932 if (sockFd->blocking)
6939 /* poll (non-blocking) */
6941 timeoutPtr = &timeout;
6943 CM_INET_FD_ZERO(&readFdS);
6944 CM_INET_FD_SET(sockFd, &readFdS);
6946 ret = cmInetSelect(&readFdS, NULLP, timeoutPtr, &numFdS);
6947 if (CM_INET_FD_ISSET(sockFd, &readFdS))
6949 /* get number of pending data */
6950 /* removed 3rd arg memInfo. MemInfo is no longer needed as we
6951 call ioctl for all sockets */
6952 ret = cmInetGetNumRead(sockFd, &pendLen);
6955 /* cm_inet_c_001.main_50
6956 * Return RCLOSED if cmInetGetNumRead returns RCLOSED. For other
6957 * errors just return RFAILED.
6965 /* check if connection got closed */
6969 /* cm_inet_c_001.main_50
6970 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
6971 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
6972 * socket that select says is ready to read. This should not be
6973 * considered as connection closed. So return ROKDNA instead of
6974 * RCLOSED even for TCP sockets
6978 /* added check for TCP/UDP socket. Pending data len in the socket
6979 recv buffer is determined by ioctl call in cmInetGetNumRead.
6980 For TCP it can't be > CM_INET_MAX_MSG_LEN.
6981 For UDP it can't be > CM_INET_MAX_UDPRAW_MSGSIZE. */
6982 if (sockFd->type == CM_INET_STREAM)
6984 /* max message length is limited to control the memory usage */
6985 if (pendLen > CM_INET_MAX_MSG_LEN)
6986 pendLen = CM_INET_MAX_MSG_LEN;
6987 /* In STREAM remote address is not required */
6992 if (pendLen > CM_INET_MAX_UDPRAW_MSGSIZE)
6993 pendLen = CM_INET_MAX_UDPRAW_MSGSIZE;
6995 remAddrLen = sizeof(CmInetSockAddr);
6998 /* check if there are enough pending data to read */
6999 bufLen = dataPos + dataLen;
7001 /* check if fromAddr is present or not */
7002 if (fromAddr != NULLP)
7004 remAddrLen = sizeof(remSockAddr);
7011 /* cm_inet_c_001.main_58: Fix for g++ compilation warning */
7012 if ((MsgLen)pendLen >= bufLen)
7014 /* allocate receive buffer (flat structure) */
7015 ret = SGetSBuf(info->region, info->pool, &recvBuf, bufLen);
7021 /* added different recvfrom calls with
7022 * different 6th arg for different OS */
7024 /* If remAddrLen is 0, pass NULLP */
7025 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
7027 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7028 CM_INET_MSG_PEEK, &remSockAddr, (int*)&remAddrLen);
7030 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7031 CM_INET_MSG_PEEK, NULLP, (int*)&remAddrLen);
7033 #if ( defined(SUNOS) || defined(SS_LINUX))
7035 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7036 CM_INET_MSG_PEEK, (struct sockaddr *)&remSockAddr,
7037 (socklen_t *)&remAddrLen);
7039 recvLen = recvfrom(sockFd->fd, (S8*)recvBuf,bufLen,
7040 CM_INET_MSG_PEEK, NULLP, (socklen_t *)&remAddrLen);
7043 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7044 CM_INET_MSG_PEEK, &remSockAddr, (S32*)&remAddrLen);
7046 recvLen = recvfrom(sockFd->fd,(S8*)recvBuf, bufLen,
7047 CM_INET_MSG_PEEK, NULLP, (S32*)&remAddrLen);
7048 #endif /* defined(SUNOS) || defined(SS_LINUX) */
7049 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
7051 /* removed the check of returned remAddrLen */
7052 if (recvLen == INET_ERR)
7055 /* moved cleanup here */
7056 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7058 /* added check ERR_WOULDBLOCK */
7059 if ((INET_ERR_CODE == ERR_AGAIN) ||
7060 (INET_ERR_CODE == ERR_WOULDBLOCK))
7066 /* moved up the cleanup */
7070 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7071 /* cm_inet_c_001.main_62:Warning fix */
7072 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%ld)\n",
7073 INET_ERR_CODE, sockFd->fd);
7074 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7076 /* cm_inet_c_001.main_62:Warning fix */
7077 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetPeek() Failed : error(%d), sockFd->fd(%d)\n",
7078 INET_ERR_CODE, sockFd->fd);
7079 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET036, 0, prntBuf);
7081 #endif /* CMINETDBG */
7083 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
7084 (INET_ERR_CODE == ERR_CONNRESET))
7092 if (recvLen < (S32)bufLen) /* maybe happen */
7095 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7100 for (j = 0, i = dataPos; i < bufLen; j++, i++)
7101 data[j] = recvBuf[i];
7103 /* setup return destination Internet address */
7104 /* added the check of (remAddLen > 0) */
7105 if ((fromAddr != NULLP) && (remAddrLen > 0))
7107 #ifdef IPV6_SUPPORTED
7108 memset(fromAddr, 0, sizeof(fromAddr));
7109 if (remAddrLen == sizeof(struct sockaddr_in6))
7111 remAddr6 = (struct sockaddr_in6 *)&remSockAddr;
7112 fromAddr->type = CM_INET_IPV6ADDR_TYPE;
7113 fromAddr->u.ipv6Addr.port =
7114 CM_INET_NTOH_UINT16(remAddr6->sin6_port);
7115 CM_INET_COPY_IPV6ADDR(&fromAddr->u.ipv6Addr.ipv6NetAddr,
7116 &remAddr6->sin6_addr);
7120 remAddr = (struct sockaddr_in *)&remSockAddr;
7121 fromAddr->type = CM_INET_IPV4ADDR_TYPE;
7122 fromAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7123 fromAddr->u.ipv4Addr.address =
7124 CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7127 remAddr = (struct sockaddr_in *)&remSockAddr;
7128 fromAddr->port = CM_INET_NTOH_UINT16(remAddr->sin_port);
7129 fromAddr->address = CM_INET_NTOH_UINT32(remAddr->sin_addr.s_addr);
7130 #endif /* IPV6_SUPPORTED */
7134 SPutSBuf(info->region, info->pool, recvBuf, bufLen);
7138 /* not enough data pending yet */
7144 /* no data pending */
7149 } /* end of cmInetPeek */
7156 * Desc: Close a socket gracefully.
7158 * Ret: ROK - successful
7169 CmInetFd *sockFd /* socket file descriptor */
7172 S32 ret; /* temporary return value */
7175 #if (ERRCLASS & ERRCLS_INT_PAR)
7176 /* error check on parameters */
7177 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7181 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7184 ret = closesocket(sockFd->fd);
7186 ret = close(sockFd->fd);
7188 if (ret == INET_ERR)
7192 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7193 /* cm_inet_c_001.main_62:Warning fix */
7194 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%ld)\n",
7195 INET_ERR_CODE, sockFd->fd);
7196 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7198 /* cm_inet_c_001.main_62:Warning fix */
7199 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetClose() Failed : error(%d), sockFd->fd(%d)\n",
7200 INET_ERR_CODE, sockFd->fd);
7201 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET037, 0, prntBuf);
7202 #endif /*ALIGN_64BIT*/
7203 #endif /* CMINETDBG */
7208 } /* end of cmInetClose */
7213 * Fun: cmInetShutdown
7215 * Desc: Close an Internet connection with more control over the data of
7216 * the full-duplex connection.
7217 * Values for the howTo parameter:
7219 * CM_INET_SHTDWN_RECV - discard data in receive buffer
7220 * CM_INET_SHTDWN_SEND - discard data in transmit buffer
7221 * CM_INET_SHTDWN_BOTH - discard data in receive and transmit buffer
7223 * Ret: ROK - successful
7226 * Notes: This function does not free the socket descriptor but only closes the
7227 * connection (cmInetClose() has to be called afterwards).
7228 * No error is returned if the socket is not connected while calling
7237 CmInetFd *sockFd, /* socket file descriptor */
7238 S32 howTo /* operation flag */
7241 S32 ret; /* temporary return value */
7244 #if (ERRCLASS & ERRCLS_INT_PAR)
7245 /* error check on parameters */
7246 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7250 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7252 ret = shutdown(sockFd->fd, howTo);
7253 if (ret == INET_ERR)
7255 if (INET_ERR_CODE == ERR_NOTCONN)
7257 /* socket is not connected */
7265 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7266 /* cm_inet_c_001.main_62:Warning fix */
7267 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7268 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
7269 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7271 /* cm_inet_c_001.main_62:Warning fix */
7272 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetShutdown() Failed : error(%d),"
7273 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
7274 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET038, 0, prntBuf);
7275 #endif /*ALIGN_64BIT*/
7276 #endif /* CMINETDBG */
7282 } /* end of cmInetShutdown */
7289 * Desc: Allows multiplex i/o requests among multiple sockets.
7290 * If the parameter mSecTimeout points to a value of zero the
7291 * call immediatley returns (poll), if it is a null pointer, the
7292 * timeout is set to infinit.
7293 * numFdS returns the number of ready file descriptors contained
7294 * in the file descriptor sets
7296 * Ret: ROK - successful
7297 * RTIMEOUT - timout expired
7308 CmInetFdSet *readFdS, /* read socket descriptor file set */
7309 CmInetFdSet *writeFdS, /* write socket descriptor file set */
7310 uint32_t *mSecTimeout, /* timeout in msecs */
7311 S16 *numFdS /* number of ready descriptors */
7314 S32 ret; /* temporary return value */
7315 struct timeval timeout; /* timeout structure */
7316 struct timeval *timeoutPtr;
7319 #if (ERRCLASS & ERRCLS_INT_PAR)
7320 /* error check on parameters */
7321 if (numFdS == NULLP)
7325 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7329 if (mSecTimeout != NULLP)
7331 timeout.tv_sec = *mSecTimeout / 1000;
7332 timeout.tv_usec = (*mSecTimeout % 1000) * 1000;
7333 timeoutPtr = &timeout;
7337 /* infinite timeout */
7343 timeout.tv_usec = 1;
7346 /* cm_inet_c_001.main_53 - Removed do-while loop */
7347 ret = select(FD_SETSIZE, readFdS, writeFdS, (fd_set*)0, timeoutPtr);
7349 /* cm_inet_c_001.main_53 - Return ROKDNA in case select was interrupted */
7350 if ((ret == INET_ERR) && (INET_ERR_CODE == ERR_EINTR))
7355 /* timeout occured */
7361 if (ret == INET_ERR)
7363 /* asa: Added a check for ERR_INVAL to return ROK
7364 * readFdS and writeFdS may be passed as NULL to
7365 * cmInetSelect() call
7367 switch(errCode = INET_ERR_CODE)
7374 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
7375 /* cm_inet_c_001.main_62:Warning fix */
7376 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSelect() Failed : error(%d)\n",
7378 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET039, 0, prntBuf);
7379 #endif /* CMINETDBG */
7382 } /* end of switch */
7385 /* return number of ready file descriptors */
7386 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
7390 } /* end of cmInetSelect */
7397 * Desc: Sets a socket option.
7398 * The function supports following options:
7400 * CM_INET_OPT_BLOCK:
7401 * value: CM_INET_OPT_DISABLE non-blocking
7402 * value: CM_INET_OPT_ENABLE blocking
7404 * CM_INET_OPT_REUSEADDR:
7405 * value: CM_INET_OPT_ENABLE reuse address
7407 * CM_INET_OPT_BROADCAST:
7408 * value: CM_INET_OPT_DISABLE
7409 * value: CM_INET_OPT_ENABLE
7411 * CM_INET_OPT_KEEPALIVE:
7412 * value: CM_INET_OPT_DISABLE
7413 * value: CM_INET_OPT_ENABLE
7415 * CM_INET_OPT_RX_BUF_SIZE:
7416 * value: receive buffer size in bytes
7418 * CM_INET_OPT_TX_BUF_SIZE:
7419 * value: transmitter buffer size in bytes
7421 * CM_INET_OPT_ADD_MCAST_MBR:
7422 * value: address of CmInetMCastInf structure
7424 * CM_INET_OPT_DRP_MCAST_MBR:
7425 * value: address of CmInetMCastInf structure
7427 * CM_INET_OPT_TCP_NODELAY:
7428 * value: CM_INET_OPT_DISABLE
7429 * value: CM_INET_OPT_ENABLE
7431 * CM_INET_OPT_BSD_COMPAT: For Linux only
7432 * value: CM_INET_OPT_ENABLE
7433 * value: CM_INET_OPT_DISABLE
7435 * CM_INET_OPT_HDR_INCLD:
7436 * value: CM_INET_ENABLE
7437 * value: CM_INET_DISABLE
7439 * CM_INET_OPT_DONT_FRAGMENT:
7440 * value: CM_INET_OPT_ENABLE
7441 * value: CM_INET_DISABLE
7444 * value: Type of Service.
7447 * value: Time To Live.
7449 * CM_INET_OPT_IP_OPTIONS:
7450 * value: IPv4 header option value
7453 * CM_INET_OPT_IP_ROUTER_ALERT:
7454 * value: CM_INET_OPT_DISABLE
7455 * value: CM_INET_OPT_ENABLE
7457 * CM_INET_OPT_IPV4_PKTINFO
7458 * value: CM_INET_OPT_ENABLE
7459 * value: CM_INET_OPT_DISABLE
7461 * CM_INET_OPT_MCAST_LOOP:
7462 * value: CM_INET_OPT_DISABLE
7463 * value: CM_INET_OPT_ENABLE
7465 * CM_INET_OPT_MCAST_IF:
7466 * value: Address of interface.
7468 * CM_INET_OPT_MCAST_TTL:
7469 * value: TTL of the outgoing multicast packet.
7471 * The next options are defined only if IPV6 is
7474 * CM_INET_OPT_ADD_MCAST6_MBR:
7475 * value: address of CmInetMCastInf6 structure
7477 * CM_INET_OPT_DRP_MCAST6_MBR:
7478 * value: address of CmInetMCastInf6 structure
7480 * CM_INET_OPT_MCAST6_LOOP:
7481 * value: CM_INET_OPT_DISABLE
7482 * value: CM_INET_OPT_ENABLE
7484 * CM_INET_OPT_MCAST6_IF:
7485 * value: Interface index
7487 * CM_INET_OPT_MCAST6_HOPS:
7488 * value: multicast hop limit
7490 * CM_INET_OPT_RECVIPV6_HOPLIM:
7491 * value: CM_INET_OPT_ENABLE hop limit will be returned
7493 * value: CM_INET_OPT_DISABLE hop limit wont be returned
7496 * CM_INET_OPT_RECVIPV6_HBHOPTS:
7497 * value: CM_INET_OPT_ENABLE HBH Options will be returned
7499 * value: CM_INET_OPT_DISABLE HBH Options wont be returned
7502 * CM_INET_OPT_RECVIPV6_DSTOPTS:
7503 * value: CM_INET_OPT_ENABLE Dest Options will be returned
7505 * value: CM_INET_OPT_DISABLE Dest Options wont be returned
7508 * CM_INET_OPT_RECVIPV6_RTHDR:
7509 * value: CM_INET_OPT_ENABLE Route Hdr Opt will be turned
7511 * value: CM_INET_OPT_DISABLE Route Hdr Opt will be turned
7512 * OFF on the socket.
7514 * CM_INET_OPT_IP_ROUTER_ALERT6
7515 * value: CM_INET_OPT_ENABLE
7516 * value: CM_INET_OPT_DISABLE
7518 * CM_INET_OPT_IPV6_PKTINFO
7519 * value: CM_INET_OPT_ENABLE Enable sending and receiving
7521 * value: CM_INET_OPT_DISABLE Disable sending and receiving
7524 * CM_INET_OPT_LINGER
7525 * value: address of CmInetSockLinger structure
7527 * CM_INET_OPT_SCTP_EVENTS
7528 * value: address of CmInetSctpSockEvent structure
7530 * CM_INET_OPT_SCTP_PRIM_ADDR
7531 * value: address of CmInetSctpPrimAddr structure
7533 * CM_INET_OPT_SCTP_PEERADDR_PARAMS
7534 * value: address of CmInetSctpPeerAddrParams structure
7537 * Ret: ROK - successful
7539 * RNA - failed, option not available
7540 * (Only when CM_INET2 is defined)
7542 * Notes: The send and receive buffer size may be system
7543 * specific. The cmInetSetOpt() call may return
7544 * successfuly although not the entire buffer size
7552 CmInetFd *sockFd, /* socket file descriptor */
7553 uint32_t level, /* option level */
7554 uint32_t type, /* option type */
7555 Ptr value /* option value */
7558 S32 ret = ROK; /* temporary return value */
7559 uint32_t disable = 0; /* disable option */
7560 uint32_t enable = 1; /* enable option */
7562 /* added for IPv4 options */
7563 #ifdef IPV4_OPTS_SUPPORTED
7564 #if((!defined (SS_VW)) && (!defined(SS_LINUX)))
7565 TknStr64 *tempTknStr64; /* points TknStr64 structure */
7566 /* which has value for IPv4 hdr options.*/
7567 #endif /* SS_VW && SS_LINUX */
7571 #endif /* IPV4_OPTS_SUPPORTED */
7573 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST)\
7575 uint8_t lpEnable = 1; /* multicast loop enable */
7576 uint8_t lpDisable = 0; /* multicast loop disable */
7577 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7580 BOOL boolEnable = TRUE; /* enable option */
7581 BOOL boolDisable = FALSE; /* disable option */
7584 #if (defined(SUNOS) || defined(WIN32) || defined(SS_PS) || \
7585 defined(SS_VW_MCAST) || defined(HPOS))
7586 struct ip_mreq stMreq;
7587 CmInetMCastInf *mCast;
7588 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7590 #ifdef IPV6_SUPPORTED
7591 uint32_t loopEna = 1; /* IPv6 multicast loop enable */
7592 uint32_t loopDis = 0; /* IPv6 multicast loop disable */
7593 struct ipv6_mreq *stMreq6Ptr;
7594 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
7595 this flag is gaurded under ICMPV6_FILTER_SUPPORTED. so if user want this
7596 support he has to enable the above flag.*/
7597 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
7598 * to support filteration of ICMP messages */
7599 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
7600 struct icmp6_filter *icmp6Filter;
7601 #endif /* ICMPV6_FILTER_SUPPORTED */
7602 #endif /* IPV6_SUPPORTED */
7604 /* cm_inet_c_001.main_58 : Added new local variables to support filteration
7605 * of ICMP messages */
7607 #ifdef CM_ICMP_FILTER_SUPPORT
7608 struct icmp_filter icmpFilter;
7612 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
7615 struct sctp_event_subscribe event;
7616 struct sctp_paddrparams addrParams;
7617 struct sctp_setprim setPrim;
7618 struct sockaddr_in *pAddr;
7619 struct sctp_assocparams assocParams;
7620 struct sctp_initmsg initmsg;
7621 struct sctp_rtoinfo rtoinfo;
7622 #ifdef IPV6_SUPPORTED
7623 struct sockaddr_in6 *pAddr6;
7624 #endif /* IPV6_SUPPORTED */
7626 CmInetSockLinger *pSockLinger;
7627 CmInetSctpSockEvent *pSctpEvent;
7628 CmInetSctpPrimAddr *pSctpPrimAddr;
7629 CmInetSctpPeerAddrParams *pSctpPAddrParams;
7630 CmInetSctpRtoInfo *pSctpRtoInfo;
7631 CmInetSctpInitMsg *pSctpInitMsg;
7632 CmInetSctpAssocParams *pSctpAssocParams;
7638 /* cm_inet_c_001.main_58 : Added NULL check for value field */
7644 #if (ERRCLASS & ERRCLS_INT_PAR)
7645 /* error check on parameters */
7646 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
7650 #endif /* ERRCLASS & ERRCLS_INT_PAR */
7654 case CM_INET_OPT_BLOCK:
7655 optVal = (uint32_t*)value;
7658 case CM_INET_OPT_ENABLE:
7661 /* cm_inet_c_001.main_59: Fix for compilation warning */
7662 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&disable);
7665 ret = ioctl(sockFd->fd, FIONBIO, (char*)&disable);
7668 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&disable);
7670 ret = ioctl(sockFd->fd, (S32)FIONBIO, &disable);
7675 sockFd->blocking = 1;
7678 case CM_INET_OPT_DISABLE:
7680 /* cm_inet_c_001.main_59: Fix for compilation warning */
7681 ret = ioctlsocket(sockFd->fd, FIONBIO, (uint32_t *)&enable);
7684 ret = ioctl(sockFd->fd, FIONBIO, (char*)&enable);
7687 ret = ioctl(sockFd->fd, (S32)FIONBIO, (S32)&enable);
7689 ret = ioctl(sockFd->fd, (S32)FIONBIO, &enable);
7693 sockFd->blocking = 0;
7703 case CM_INET_OPT_REUSEADDR:
7704 optVal = (uint32_t*)value;
7705 if (*optVal == CM_INET_OPT_ENABLE)
7708 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7709 (char*)&boolEnable, sizeof(boolEnable));
7711 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7712 (char*)&enable, sizeof(enable));
7714 setsockopt(sockFd->fd, level, SO_REUSEPORT,
7715 (char*)&enable, sizeof(enable));
7719 else if (*optVal == CM_INET_OPT_DISABLE)
7722 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7723 (char*)&boolDisable, sizeof(boolDisable));
7725 ret = setsockopt(sockFd->fd, level, SO_REUSEADDR,
7726 (char*)&disable, sizeof(disable));
7728 ret = setsockopt(sockFd->fd, level, SO_REUSEPORT,
7729 (char*)&disable, sizeof(disable));
7735 case CM_INET_OPT_BROADCAST:
7736 optVal = (uint32_t*)value;
7737 if (*optVal == CM_INET_OPT_ENABLE)
7740 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7741 (char*)&boolEnable, sizeof(boolEnable));
7743 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7744 (char*)&enable, sizeof(enable));
7747 else if (*optVal == CM_INET_OPT_DISABLE)
7750 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7751 (char*)&boolDisable, sizeof(boolDisable));
7753 ret = setsockopt(sockFd->fd, level, SO_BROADCAST,
7754 (char*)&disable, sizeof(disable));
7759 case CM_INET_OPT_KEEPALIVE:
7760 optVal = (uint32_t*)value;
7761 if (*optVal == CM_INET_OPT_ENABLE)
7764 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7765 (char*)&boolEnable, sizeof(boolEnable));
7767 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7768 (char*)&enable, sizeof(enable));
7771 else if (*optVal == CM_INET_OPT_DISABLE)
7774 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7775 (char*)&boolDisable, sizeof(boolDisable));
7777 ret = setsockopt(sockFd->fd, level, SO_KEEPALIVE,
7778 (char*)&disable, sizeof(disable));
7783 case CM_INET_OPT_RX_BUF_SIZE:
7784 optVal = (uint32_t*)value;
7785 ret = setsockopt(sockFd->fd, level, SO_RCVBUF,
7786 (char*)optVal, sizeof(*optVal));
7789 case CM_INET_OPT_TX_BUF_SIZE:
7790 optVal = (uint32_t*)value;
7791 ret = setsockopt(sockFd->fd, level, SO_SNDBUF,
7792 (char*)optVal, sizeof(*optVal));
7795 case CM_INET_OPT_TCP_NODELAY:
7796 optVal = (uint32_t*)value;
7797 if (*optVal == CM_INET_OPT_ENABLE)
7801 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7802 (char*)&boolEnable, sizeof(boolEnable));
7803 #endif /* SS_WINCE */
7805 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7806 (char*)&enable, sizeof(enable));
7809 else if (*optVal == CM_INET_OPT_DISABLE)
7813 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7814 (char*)&boolDisable, sizeof(boolDisable));
7815 #endif /* SS_WINCE */
7817 ret = setsockopt(sockFd->fd, level, TCP_NODELAY,
7818 (char*)&disable, sizeof(disable));
7823 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || \
7824 defined(SS_VW_MCAST) || defined(HPOS))
7826 case CM_INET_OPT_ADD_MCAST_MBR:
7827 mCast = (CmInetMCastInf*)value;
7829 /* Copy the addresses to stMreq structure */
7831 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7833 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7835 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7837 ret = setsockopt(sockFd->fd, level, IP_ADD_MEMBERSHIP,
7838 (char*)&stMreq, sizeof(stMreq));
7841 case CM_INET_OPT_DRP_MCAST_MBR:
7842 mCast = (CmInetMCastInf*)value;
7844 /* Copy the addresses to stMreq structure */
7846 stMreq.imr_mcastaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7848 stMreq.imr_multiaddr.s_addr = CM_INET_HTON_UINT32(mCast->mCastAddr);
7850 stMreq.imr_interface.s_addr = CM_INET_HTON_UINT32(mCast->localAddr);
7852 ret = setsockopt(sockFd->fd, level, IP_DROP_MEMBERSHIP,
7853 (char*)&stMreq, sizeof(stMreq));
7856 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
7859 /* cm_inet_c_001.main_37 - Enable CMINET_BSDCOMPAT flag if system doesnt
7860 support CM_INET_OPT_BSD_COMPAT */
7861 #ifndef CMINET_BSDCOMPAT
7862 case CM_INET_OPT_BSD_COMPAT:
7863 optVal = (uint32_t*)value;
7864 if (*optVal == CM_INET_OPT_ENABLE)
7866 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7867 &enable, sizeof(enable));
7869 else if (*optVal == CM_INET_OPT_DISABLE)
7871 ret = setsockopt(sockFd->fd, level, SO_BSDCOMPAT,
7872 &disable, sizeof(disable));
7875 #endif /* CMINET_BSDCOMPAT */
7876 #endif /* SS_LINUX */
7879 /* Added for support of Raw socket modify according to the
7880 * option available on different platform */
7881 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW) \
7883 case CM_INET_OPT_HDR_INCLD:
7884 optVal = (uint32_t*)value;
7885 if (*optVal == CM_INET_OPT_ENABLE)
7890 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7891 (char*)&enable, sizeof(enable));
7894 else if (*optVal == CM_INET_OPT_DISABLE)
7899 ret = setsockopt(sockFd->fd, level, IP_HDRINCL,
7900 (char*)&disable, sizeof(disable));
7905 /* added new options */
7906 #ifdef IPV4_OPTS_SUPPORTED
7908 /* Linux: set Router Alert socket option to Intercept RAW RSVP
7909 packets at the Intermediate node(Router) with Router Alert SET.
7910 This socket option is MUST be set (when this server is opened)
7911 if the RSVP server wants to intercept raw RSVP packets. */
7912 case CM_INET_OPT_IP_ROUTER_ALERT:
7913 optVal = (uint32_t*)value;
7914 if (*optVal == CM_INET_OPT_ENABLE)
7916 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7917 (char*)&enable, sizeof(enable));
7921 else if (*optVal == CM_INET_OPT_DISABLE)
7923 ret = setsockopt(sockFd->fd, level, IP_ROUTER_ALERT,
7924 (char*)&disable, sizeof(disable));
7929 #endif /* SS_LINUX */
7931 /* set Router Alert socket option */
7932 case CM_INET_OPT_IP_OPTIONS:
7933 #if (defined (SS_VW) || defined(SS_LINUX))
7936 tempTknStr64=(TknStr64 *)value;
7937 if (tempTknStr64->pres == TRUE)
7939 if (tempTknStr64->len == 0)
7941 /* disable the IP_OPTIONS for Router Alert. */
7943 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7944 (const char *)&disableOpt, sizeof(int));
7946 ret = setsockopt(sockFd->fd, level, IP_OPTIONS, NULL, 0);
7950 /* enable the IP_OPTIONS for Router Alert */
7951 ret = setsockopt(sockFd->fd, level, IP_OPTIONS,
7952 (char *)tempTknStr64->val, tempTknStr64->len);
7955 return RFAILED; /* Trying to set IPv4 Hdr option
7956 * without giving option values*/
7957 #endif /* SS_VW || SS_LINUX */
7959 #endif /* IPV4_OPTS_SUPPORTED */
7961 /* added new options */
7962 #if (defined(SS_LINUX) && (!defined(SS_VW) && !defined(WIN32)))
7964 case CM_INET_OPT_IPV4_PKTINFO:
7965 optVal = (uint32_t*)value;
7966 if (*optVal == CM_INET_OPT_ENABLE)
7968 /* set IP_PKTINFO option when IP_ROUTER_ALERT is set in linux */
7969 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7970 (char*)&enable, sizeof(enable));
7975 else if (*optVal == CM_INET_OPT_DISABLE)
7977 /* disable IP_PKTINFO when IP_ROUTER_ALERT is set in linux */
7978 ret = setsockopt(sockFd->fd, level, IP_PKTINFO,
7979 (char*)&disable, sizeof(disable));
7985 #endif /* LOCAL_INTF */
7986 #endif /* SS_LINUX */
7988 #endif /* SUNOS || WIN32 || SS_PS || SS_VW || HPOS */
7990 case CM_INET_OPT_DONTFRAGMENT:
7991 optVal = (uint32_t*)value;
7992 if (*optVal == CM_INET_OPT_ENABLE)
7995 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
7996 (char*)&boolEnable, sizeof(boolEnable));
7999 else if (*optVal == CM_INET_OPT_DISABLE)
8002 ret = setsockopt(sockFd->fd, level, IP_DONTFRAGMENT,
8003 (char*)&boolDisable, sizeof(boolDisable));
8008 /* also add these 2 options for VxWorks */
8009 #if (defined(SUNOS)|| defined(WIN32) || defined(HPOS) || defined(SS_VW))
8010 case CM_INET_OPT_TOS:
8011 optVal = (uint32_t*)value;
8012 ret = setsockopt(sockFd->fd, level, IP_TOS,
8013 (char*)optVal, sizeof(*optVal));
8016 case CM_INET_OPT_TTL:
8017 optVal = (uint32_t*)value;
8018 ret = setsockopt(sockFd->fd, level, IP_TTL,
8019 (char*)optVal, sizeof(*optVal));
8021 #endif /* SUNOS || WIN32 || HPOS || SS_VW */
8022 #endif /* CM_INET2 */
8024 #if (defined(SUNOS)|| defined(WIN32) || defined(SS_PS) || defined(SS_VW_MCAST) \
8026 case CM_INET_OPT_MCAST_LOOP:
8027 optVal = (uint32_t*)value;
8028 if (*optVal == CM_INET_OPT_ENABLE)
8031 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8032 (char *)&lpEnable, sizeof(lpEnable));
8034 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8035 (const char *)&lpEnable, sizeof(lpEnable));
8041 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8042 (char *)&lpDisable, sizeof(lpDisable));
8044 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_LOOP,
8045 (const char *)&lpDisable, sizeof(lpDisable));
8050 case CM_INET_OPT_MCAST_IF:
8051 optVal = (uint32_t*)value;
8052 *optVal = CM_INET_HTON_UINT32((uint32_t)*optVal);
8053 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_IF,
8054 (char *)optVal, sizeof(struct in_addr));
8057 case CM_INET_OPT_MCAST_TTL:
8058 optVal = (uint32_t*)value;
8059 /* remove const in setsockopt for VW */
8061 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8062 (char *)optVal, sizeof(uint8_t));
8064 ret = setsockopt(sockFd->fd, level, IP_MULTICAST_TTL,
8065 (const char *)optVal, sizeof(uint8_t));
8068 #endif /* SUNOS || WIN32 || SS_PS || SS_VW_MCAST || HPOS */
8070 #ifdef IPV6_SUPPORTED
8071 case CM_INET_OPT_IPV6_TTL:
8072 optVal = (uint32_t*)value;
8073 ret = setsockopt(sockFd->fd, level, IPV6_UNICAST_HOPS,
8074 (char*)optVal, sizeof(*optVal));
8077 case CM_INET_OPT_ADD_MCAST6_MBR:
8078 stMreq6Ptr = (struct ipv6_mreq *)value;
8079 ret = setsockopt(sockFd->fd, level, IPV6_JOIN_GROUP,
8080 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8083 case CM_INET_OPT_DRP_MCAST6_MBR:
8084 stMreq6Ptr = (struct ipv6_mreq *)value;
8085 ret = setsockopt(sockFd->fd, level, IPV6_LEAVE_GROUP,
8086 (char*)stMreq6Ptr, sizeof(struct ipv6_mreq));
8089 case CM_INET_OPT_MCAST6_LOOP:
8090 optVal = (uint32_t*)value;
8091 if (*optVal == CM_INET_OPT_ENABLE)
8093 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8094 &loopEna, sizeof(loopEna));
8098 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_LOOP,
8099 &loopDis, sizeof(loopDis));
8103 case CM_INET_OPT_MCAST6_IF:
8104 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_IF,
8105 (uint32_t *)value, sizeof(uint32_t));
8108 case CM_INET_OPT_MCAST6_HOPS:
8109 optVal = (uint32_t*)value;
8110 ret = setsockopt(sockFd->fd, level, IPV6_MULTICAST_HOPS,
8111 (char *)optVal, sizeof(uint32_t));
8114 /* cm_inet_c_001.main_44 : some operating system doesnt have icmp6_filter. so
8115 this flag is gaurded under ICMPV6_SUPPORTED. so if user want this
8116 support he has to enable the above flag.*/
8117 /* cm_inet_c_001.main_58 : Protaected under flag CM_ICMP_FILTER_SUPPORT
8118 * to support filteration of ICMP messages */
8119 #if (defined(ICMPV6_FILTER_SUPPORTED) || defined(CM_ICMP_FILTER_SUPPORT))
8120 case CM_INET_OPT_ICMP6_FILTER:
8121 icmp6Filter = (struct icmp6_filter *)value;
8122 ret = setsockopt(sockFd->fd, level, ICMP6_FILTER,
8123 (char *)icmp6Filter, sizeof(struct icmp6_filter));
8125 #endif /* ICMPV6_FILTER_SUPPORTED */
8127 /* added new options */
8128 #ifdef IPV6_OPTS_SUPPORTED
8129 case CM_INET_OPT_RECVIPV6_HOPLIM:
8130 optVal = (uint32_t*)value;
8132 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8133 (char *)optVal, sizeof(uint32_t));
8135 ret = setsockopt(sockFd->fd, level, IPV6_HOPLIMIT,
8136 (char *)optVal, sizeof(uint32_t));
8137 /* enable the reception of IPv6 HopLimit value as ancillary data */
8138 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPLIMIT,
8139 (char*)&enable, sizeof(enable));
8140 #endif /* SS_LINUX */
8144 case CM_INET_OPT_RECVIPV6_HBHOPTS:
8145 optVal = (uint32_t*)value;
8147 ret = setsockopt(sockFd->fd, level, IPV6_HOPOPTS,
8148 (char *)optVal, sizeof(uint32_t));
8150 ret = setsockopt(sockFd->fd, level, IPV6_RECVHOPOPTS,
8151 (char *)optVal, sizeof(uint32_t));
8152 #endif /* SS_LINUX */
8155 case CM_INET_OPT_RECVIPV6_DSTOPTS:
8156 optVal = (uint32_t*)value;
8158 ret = setsockopt(sockFd->fd, level, IPV6_DSTOPTS,
8159 (char *)optVal, sizeof(uint32_t));
8161 ret = setsockopt(sockFd->fd, level, IPV6_RECVDSTOPTS,
8162 (char *)optVal, sizeof(uint32_t));
8163 #endif /* SS_LINUX */
8166 case CM_INET_OPT_RECVIPV6_RTHDR:
8167 optVal = (uint32_t*)value;
8169 ret = setsockopt(sockFd->fd, level, IPV6_RTHDR,
8170 (char *)optVal, sizeof(uint32_t));
8172 ret = setsockopt(sockFd->fd, level, IPV6_RECVRTHDR,
8173 (char *)optVal, sizeof(uint32_t));
8174 #endif /* SS_LINUX */
8177 /* works ONLY for IPPROTO_RAW type socket. so if it this socket
8178 * option is tried to set for IPPROTO_RSVP, then it is supposed
8179 * to fail with EINVAL according to net/ipv6/ipv6_sockglue.c
8181 * if HI_SRVC_RAW_RAW is not used during ServOpenReq as the server
8182 * type, then it will fail here due to above reason */
8184 case CM_INET_OPT_IP_ROUTER_ALERT6:
8185 optVal = (uint32_t*)value;
8186 if(*optVal == CM_INET_OPT_ENABLE)
8187 ret = setsockopt(sockFd->fd, IPPROTO_IPV6, IPV6_ROUTER_ALERT,
8188 (char *)&enable, sizeof(enable));
8190 ret = setsockopt(sockFd->fd, level, IPV6_ROUTER_ALERT,
8191 (char *)&disable, sizeof(disable));
8194 #endif /* SS_LINUX */
8195 #endif /* IPV6_OPTS_SUPPORTED */
8198 case CM_INET_OPT_IPV6_PKTINFO:
8199 optVal = (uint32_t*)value;
8201 ret = setsockopt(sockFd->fd, level, IPV6_PKTINFO,
8202 (char *)optVal, sizeof(uint32_t));
8204 ret = setsockopt(sockFd->fd, level, IPV6_RECVPKTINFO,
8205 (char *)&enable, sizeof(enable));
8206 #endif /* SS_LINUX */
8208 #endif /* LOCAL_INTF */
8210 #endif /* IPV6_SUPPORTED */
8212 /*cm_inet_c_001.main_38 Updated for TUCL 2.1 Release (Kernel SCTP Support) */
8214 case CM_INET_OPT_LINGER:
8215 pSockLinger = (CmInetSockLinger *)value;
8217 memset(&lngr, 0, sizeof(struct linger));
8219 if (pSockLinger->enable == TRUE)
8224 lngr.l_linger = pSockLinger->lingerTime;
8225 ret = setsockopt(sockFd->fd, level, SO_LINGER, &lngr, sizeof(lngr));
8228 case CM_INET_OPT_SCTP_EVENTS:
8229 pSctpEvent = (CmInetSctpSockEvent *)value;
8231 memset(&event, 0, sizeof(struct sctp_event_subscribe));
8233 if (pSctpEvent->dataIoEvent == TRUE)
8234 event.sctp_data_io_event = 1;
8236 if (pSctpEvent->associationEvent == TRUE)
8237 event.sctp_association_event = 1;
8239 if (pSctpEvent->addressEvent == TRUE)
8240 event.sctp_address_event = 1;
8242 if (pSctpEvent->sendFailureEvent == TRUE)
8243 event.sctp_send_failure_event = 1;
8245 if (pSctpEvent->peerErrorEvent == TRUE)
8246 event.sctp_peer_error_event = 1;
8248 if (pSctpEvent->shutdownEvent == TRUE)
8249 event.sctp_shutdown_event = 1;
8251 if (pSctpEvent->partialDeliveryEvent == TRUE)
8252 event.sctp_partial_delivery_event = 1;
8254 if (pSctpEvent->adaptationLayerEvent == TRUE)
8256 event.sctp_adaption_layer_event = 1;
8258 event.sctp_adaptation_layer_event = 1;
8261 ret = setsockopt(sockFd->fd, level, SCTP_EVENTS, &event, sizeof(event));
8264 case CM_INET_OPT_SCTP_PRIM_ADDR:
8265 pSctpPrimAddr = (CmInetSctpPrimAddr *)value;
8267 memset(&setPrim, 0, sizeof(struct sctp_setprim));
8269 #ifdef IPV6_SUPPORTED
8270 if (pSctpPrimAddr->addr.type == CM_INET_IPV6ADDR_TYPE)
8272 if (sockFd->protType == AF_INET)
8276 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8277 /* cm_inet_c_001.main_62:Warning fix */
8278 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8279 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8280 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8282 /* cm_inet_c_001.main_62:Warning fix */
8283 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8284 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8285 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET040, 0, prntBuf);
8286 #endif /*ALIGN_64BIT*/
8287 #endif /* CMINETDBG */
8291 pAddr6 = (struct sockaddr_in6*)&(setPrim.ssp_addr);
8292 pAddr6->sin6_family = AF_INET6;
8293 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8294 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPrimAddr->addr.u.ipv6NetAddr);
8298 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8299 pAddr->sin_family = AF_INET;
8300 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8301 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8304 pAddr = (struct sockaddr_in*)&(setPrim.ssp_addr);
8305 pAddr->sin_family = AF_INET;
8306 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPrimAddr->port);
8307 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPrimAddr->addr.u.ipv4NetAddr);
8308 #endif /* IPV6_SUPPORTED */
8310 setPrim.ssp_assoc_id = pSctpPrimAddr->assocId;
8312 ret = setsockopt(sockFd->fd, level, SCTP_PRIMARY_ADDR, &setPrim, sizeof(setPrim));
8315 case CM_INET_OPT_SCTP_PEERADDR_PARAMS:
8316 pSctpPAddrParams = (CmInetSctpPeerAddrParams *)value;
8318 memset(&addrParams, 0, sizeof(struct sctp_paddrparams));
8321 if (pSctpPAddrParams->s.addrPres == TRUE)
8323 #ifdef IPV6_SUPPORTED
8324 if (pSctpPAddrParams->s.addr.type == CM_INET_IPV6ADDR_TYPE)
8326 if (sockFd->protType == AF_INET)
8330 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8331 /* cm_inet_c_001.main_62:Warning fix */
8332 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8333 " sockFd->fd(%ld)\n", sockFd->protType, sockFd->fd);
8334 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8336 /* cm_inet_c_001.main_62:Warning fix */
8337 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "Invalid address: sockFd->protType(%d),"
8338 " sockFd->fd(%d)\n", sockFd->protType, sockFd->fd);
8339 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET041, 0, prntBuf);
8340 #endif /*ALIGN_64BIT*/
8341 #endif /* CMINETDBG */
8346 pAddr6 = (struct sockaddr_in6*)&(addrParams.spp_address);
8347 pAddr6->sin6_family = AF_INET6;
8348 pAddr6->sin6_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8349 CM_INET_COPY_IPV6ADDR(&pAddr6->sin6_addr.s6_addr, &pSctpPAddrParams->s.addr.u.ipv6NetAddr);
8353 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8354 pAddr->sin_family = AF_INET;
8355 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8356 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8359 pAddr = (struct sockaddr_in*)&(addrParams.spp_address);
8360 pAddr->sin_family = AF_INET;
8361 pAddr->sin_port = CM_INET_HTON_UINT16(pSctpPAddrParams->s.port);
8362 pAddr->sin_addr.s_addr = CM_INET_HTON_UINT32(pSctpPAddrParams->s.addr.u.ipv4NetAddr);
8363 #endif /* IPV6_SUPPORTED */
8367 #ifdef IPV6_SUPPORTED
8368 if (sockFd->protType == AF_INET6)
8369 addrParams.spp_address.ss_family = AF_INET6;
8371 addrParams.spp_address.ss_family = AF_INET;
8373 addrParams.spp_address.ss_family = AF_INET;
8377 /* Not validating the address, whether addr is a valid address or not */
8379 addrParams.spp_assoc_id = pSctpPAddrParams->assocId;
8380 /*cm_inet_c_001.main_58 : fix for klockwork issue */
8381 addrParams.spp_pathmaxrxt = (uint16_t)pSctpPAddrParams->pathMaxRxt;
8383 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8384 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8386 addrParams.spp_hbinterval = 0;
8389 addrParams.spp_flags = 0;
8391 if (pSctpPAddrParams->pmtudFlag == CM_INET_OPT_ENABLE)
8393 addrParams.spp_flags |= SPP_PMTUD_ENABLE;
8394 addrParams.spp_pathmtu = pSctpPAddrParams->pathMtu;
8396 else if(pSctpPAddrParams->pmtudFlag == CM_INET_OPT_DISABLE)
8397 addrParams.spp_flags |= SPP_PMTUD_DISABLE;
8399 if (pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_ENABLE)
8401 addrParams.spp_flags |= SPP_SACKDELAY_ENABLE;
8402 addrParams.spp_sackdelay = pSctpPAddrParams->sackDelay;
8404 else if(pSctpPAddrParams->sackDelayFlag == CM_INET_OPT_DISABLE)
8405 addrParams.spp_flags |= SPP_SACKDELAY_DISABLE;
8407 if (pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_ENABLE)
8409 addrParams.spp_flags |= SPP_HB_ENABLE;
8410 addrParams.spp_hbinterval = pSctpPAddrParams->hbInterval;
8412 else if(pSctpPAddrParams->hbEnblFlag == CM_INET_OPT_DISABLE)
8413 addrParams.spp_flags |= SPP_HB_DISABLE;
8415 ret = setsockopt(sockFd->fd, level, SCTP_PEER_ADDR_PARAMS, &addrParams, sizeof(addrParams));
8418 case CM_INET_OPT_SCTP_ASSOC_PARAMS:
8419 pSctpAssocParams = (CmInetSctpAssocParams *)value;
8421 memset(&assocParams, 0, sizeof(struct sctp_assocparams));
8423 assocParams.sasoc_cookie_life = pSctpAssocParams->cookieLife;
8424 assocParams.sasoc_asocmaxrxt = pSctpAssocParams->assocMaxReTx;
8425 assocParams.sasoc_assoc_id = pSctpAssocParams->assocId;
8426 assocParams.sasoc_number_peer_destinations = pSctpAssocParams->numberOfPeerDest;
8427 assocParams.sasoc_peer_rwnd = pSctpAssocParams->peerRwnd;
8428 assocParams.sasoc_local_rwnd = pSctpAssocParams->localRwnd;
8430 ret = setsockopt(sockFd->fd, level, SCTP_ASSOCINFO, &assocParams, sizeof(assocParams));
8433 case CM_INET_OPT_SCTP_RTO_INFO:
8434 pSctpRtoInfo = (CmInetSctpRtoInfo *)value;
8436 memset(&rtoinfo, 0, sizeof(struct sctp_rtoinfo));
8438 rtoinfo.srto_assoc_id = pSctpRtoInfo->assocId;
8439 rtoinfo.srto_initial = pSctpRtoInfo->rtoInitial;
8440 rtoinfo.srto_max = pSctpRtoInfo->rtoMax;
8441 rtoinfo.srto_min = pSctpRtoInfo->rtoMin;
8443 ret = setsockopt(sockFd->fd, level, SCTP_RTOINFO, &rtoinfo, sizeof(rtoinfo));
8446 case CM_INET_OPT_SCTP_INIT_MSG:
8447 pSctpInitMsg = (CmInetSctpInitMsg *)value;
8449 memset(&initmsg, 0, sizeof(struct sctp_initmsg));
8451 initmsg.sinit_max_attempts = pSctpInitMsg->maxInitReTx;
8452 initmsg.sinit_max_init_timeo = pSctpInitMsg->maxInitTimeout;
8453 initmsg.sinit_num_ostreams = pSctpInitMsg->numOstreams;
8454 initmsg.sinit_max_instreams = pSctpInitMsg->maxInstreams;
8456 ret = setsockopt(sockFd->fd, level, SCTP_INITMSG, &initmsg, sizeof(initmsg));
8459 #endif /*CM_LKSCTP*/
8461 /* cm_inet_c_001.main_58 : Added to support filteration of ICMP
8462 * messages and protected under CM_ICMP_FILTER_SUPPORT flag. Its a
8463 * partial implementaion for icmp filter done for TUCL */
8465 #ifdef CM_ICMP_FILTER_SUPPORT
8466 case CM_INET_OPT_ICMP_FILTER:
8467 optVal = (uint32_t*)value;
8468 ret = setsockopt(sockFd->fd, level, ICMP_FILTER,
8469 optVal, sizeof(icmpFilter));
8475 /* wrong socket option type */
8480 if (ret == INET_ERR)
8484 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8485 /* cm_inet_c_001.main_62:Warning fix */
8486 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%ld)\n",
8487 INET_ERR_CODE, sockFd->fd);
8488 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8490 /* cm_inet_c_001.main_62:Warning fix */
8491 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetSetOpt() Failed : error(%d), sockFd->fd(%d)\n",
8492 INET_ERR_CODE, sockFd->fd);
8493 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET042, 0, prntBuf);
8494 #endif /*ALIGN_64BIT*/
8495 #endif /* CMINETDBG */
8499 } /* end of cmInetSetOpt */
8505 * Fun: cmInetGetNumRead
8507 * Desc: Gives the number of pending octets in the socket receive buffer.
8509 * Ret: ROK - successful
8518 S16 cmInetGetNumRead
8520 CmInetFd *sockFd, /* socket file descriptor */
8521 uint32_t *dataLen /* number of pending octets */
8522 /* removed 3rd argument memInfo */
8525 S32 ret; /* temporary return value */
8527 /* removed local variables added for recvfrom call */
8530 #if (ERRCLASS & ERRCLS_INT_PAR)
8531 /* error check on parameters */
8532 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
8539 /* use ioctl call for all types of socket to get length of
8540 pending data in the socket recv buffer */
8542 /* cm_inet_c_001.main_59: Fix for compilation warning */
8543 ret = ioctlsocket(sockFd->fd, FIONREAD, (uint32_t *)dataLen);
8546 ret = ioctl(sockFd->fd, FIOREAD, (char*)dataLen);
8549 ret = ioctl(sockFd->fd, FIONREAD, (S32)dataLen);
8551 ret = ioctl(sockFd->fd, FIONREAD, dataLen);
8556 /* For UDP socket assign the length of pending data in the
8557 socket recv buffer to largest datagram size.
8558 Removed recvfrom call & necessary processing for it. */
8560 if (ret == INET_ERR)
8562 /* removed error check CONABORTED added for recvfrom call.
8563 Also return value changed from RCLOSED to ROK */
8564 /* Check for reset connection */
8565 /* cm_inet_c_001.main_45: Close the TCP connection only when err is one of these*/
8566 if ((INET_ERR_CODE == ERR_CONNREFUSED) ||
8567 (INET_ERR_CODE == ERR_CONNABORTED) ||
8568 (INET_ERR_CODE == ERR_TIMEDOUT))
8572 /* cm_inet_c_001.main_50
8573 * Return RCLOSED instead of ROK to initiate connection closure.
8574 * ROK will be returned only if the ioctl call above returns ROK.
8575 * The routines calling this function have been modified to not
8576 * return RCLOSED when this function returns ROK with pending data
8577 * length value of 0. This modification is needed because:
8578 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
8579 * returns successfully with pend length as 0 on a TCP socket that
8580 * select says is ready to read. This should not be considered as
8581 * connection closed.
8586 /* removed error check ERR_WOULDBLOCK */
8587 /* cm_inet_c_001.main_45: Dont close the connection in case of ERR_CONNRESET */
8588 if ((INET_ERR_CODE == ERR_AGAIN) ||
8589 (INET_ERR_CODE == ERR_CONNRESET))
8596 /* cm_inet_c_001.main_45: Change 2048 to CM_INET_MAX_UDPRAW_MSGSIZE */
8597 *dataLen = CM_INET_MAX_UDPRAW_MSGSIZE;
8599 #endif /* SS_LINUX */
8601 /* removed error debug printing added for recvfrom call. */
8605 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8606 /* cm_inet_c_001.main_62:Warning fix */
8607 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8608 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
8609 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8611 /* cm_inet_c_001.main_62:Warning fix */
8612 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetNumRead() Failed : error(%d),"
8613 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
8614 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET043, 0, prntBuf);
8615 #endif /*ALIGN_64BIT*/
8616 #endif /* CMINETDBG */
8621 } /* end of cmInetGetNumRead */
8627 * Fun: cmInetGetHostByName
8629 * Desc: Resolves a host name into the appropriate 4 byte Internet
8632 * Ret: ROK - successful
8641 S16 cmInetGetHostByName
8643 S8 *hostName, /* host name */
8644 CmInetIpAddrTbl *addrTbl /* Address Table of IPV4 Addresses */
8648 uint8_t numAddrs; /* Number of Addresses */
8651 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8652 struct hostent *hostid; /* pointer to host information */
8655 struct hostent hostid; /* host information */
8656 S8 infoBuf[CM_INET_MAX_INFO]; /* info buffer */
8657 S32 err; /* error code */
8659 #endif /* WIN32 || SS_LINUX || HPOS */
8662 #if (ERRCLASS & ERRCLS_INT_PAR)
8663 /* error check on parameters */
8664 if ((hostName == NULLP) || (addrTbl == NULLP))
8668 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8677 #if (defined(WIN32) || defined(SS_LINUX) || defined(HPOS))
8678 hostid = gethostbyname(hostName);
8682 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8683 /* cm_inet_c_001.main_62:Warning fix */
8684 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8685 " hostName(%p)\n", INET_ERR_CODE, hostName);
8686 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET044, 0, prntBuf);
8687 #endif /* CMINETDBG */
8690 if (hostid->h_addrtype != AF_INET)
8693 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8694 /* cm_inet_c_001.main_62:Warning fix */
8695 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetHostByName() Failed : error(%d),"
8696 " hostName(%p), hostid->h_addrtype(%d)\n",
8697 INET_ERR_CODE, hostName, hostid->h_addrtype);
8698 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET045, 0, prntBuf);
8699 #endif /* CMINETDBG */
8704 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8705 (hostid->h_addr_list[numAddrs] != NULLP))
8707 addrTbl->netAddr[addrTbl->count++] =
8708 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8718 vwIpAddr = hostGetByName(hostName);
8719 if (vwIpAddr == INET_ERR)
8722 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8723 /* cm_inet_c_001.main_62:Warning fix */
8724 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
8725 " hostName(%p)\n", INET_ERR_CODE, hostName);
8726 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET046, 0, prntBuf);
8727 #endif /* CMINETDBG */
8730 CM_COPY_VWIPADDR(vwIpAddr, &(addrTbl->netAddr[addrTbl->count]));
8735 err = 0; /* err is not reset by gethostnyname_r()! */
8737 gethostbyname_r(hostName, &hostid, infoBuf, CM_INET_MAX_INFO, (int*)&err);
8738 if ((hostid.h_addrtype != AF_INET) || (err < 0))
8741 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8742 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d), hostName(%p),"
8743 " hostid.h_addrtype(%d)\n",
8744 INET_ERR_CODE, hostName, hostid.h_addrtype);
8745 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET047, 0, prntBuf);
8746 #endif /* CMINETDBG */
8751 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8752 (hostid.h_addr_list[numAddrs] != NULLP))
8754 addrTbl->netAddr[addrTbl->count++] =
8755 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid.h_addr_list[numAddrs]));
8761 #endif /* WIN32 || SS_LINUX || HPOS */
8765 } /* end of cmInetGetHostByName */
8768 /* The getipnodebyname is not supported on all the Solaris Operating system
8769 * versions. This has to be supported on operating systems that support IPV6
8770 * as per the RFC on the IPV6 socket interface. Hence this function is moved
8771 * under the IPV6_SUPPORTED flag */
8773 /* This function now can be called for both IPv4 and IPv6. However, we will
8774 * call cmInetGetHostByName inside for IPv4. Move all flag dependencies
8775 * inside this function. */
8778 * Fun: cmInetGetIpNodeByName
8780 * Desc: Resolves a host name into the appropriate 4 byte Internet
8781 * address or into the appropriate 16 byte IPV6 address.
8782 * This function is expected to be thread safe and should be used
8783 * instead of the cmInetGetHostByName function.
8785 * Ret: ROK - successful
8793 S16 cmInetGetIpNodeByName
8795 S8 *hostName, /* host name */
8796 CmInetIpAddrArr *addrArr /* Array of addressed filled in */
8799 /* for return value from cmInetGetHostByName */
8800 #ifndef IPV6_SUPPORTED
8805 uint8_t numAddrs=0; /* Number of addresses */
8806 int err=0; /* error code */
8807 struct hostent *hostid; /* host information */
8808 #endif /* SS_LINUX */
8810 #endif /* IPV6_SUPPORTED */
8814 #if (ERRCLASS & ERRCLS_INT_PAR)
8815 /* error check on parameters */
8816 if ((hostName == NULLP) || (addrArr == NULLP))
8820 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8822 #ifdef IPV6_SUPPORTED
8826 #ifdef IPV6_SUPPORTED
8827 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8828 hostid = getipnodebyname(hostName, AF_INET6, 0, &err);
8830 #endif /* IPV6_SUPPORTED */
8831 hostid = getipnodebyname(hostName, AF_INET, 0, &err);
8835 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8836 /* cm_inet_c_001.main_62:Warning fix */
8837 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetIpNodeByName() Failed : error(%d),"
8838 " hostName(%p), addrArr->type(%d)n",
8839 err, hostName, addrArr->type);
8840 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET048, 0, prntBuf);
8841 #endif /* CMINETDBG */
8845 #ifdef IPV6_SUPPORTED
8846 if (addrArr->type == CM_INET_IPV6ADDR_TYPE)
8848 if (hostid->h_addrtype == AF_INET6)
8850 while ((numAddrs < CM_INET_IPV6_NUM_ADDR) &&
8851 (hostid->h_addr_list[numAddrs] != NULLP))
8853 /* Use the cminet fill macro here */
8854 CM_INET_COPY_IPV6ADDR(&addrArr->u.ipv6AddrArr.netAddr[numAddrs],
8855 hostid->h_addr_list[numAddrs]);
8856 addrArr->u.ipv6AddrArr.count++;
8863 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8864 /* cm_inet_c_001.main_62:Warning fix */
8865 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8866 " hostName(%p), addrArr->type(%d),hostid->h_addrtype(%d) \n",
8867 err, hostName, addrArr->type, hostid->h_addrtype);
8868 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET049, 0, prntBuf);
8869 #endif /* CMINETDBG */
8874 #endif /* IPV6_SUPPORTED */
8876 if (hostid->h_addrtype == AF_INET)
8878 while ((numAddrs < CM_INET_IPV4_NUM_ADDR) &&
8879 (hostid->h_addr_list[numAddrs] != NULLP))
8881 addrArr->u.ipv4AddrArr.count ++;
8882 addrArr->u.ipv4AddrArr.netAddr[numAddrs] =
8883 CM_INET_NTOH_UINT32 (*((uint32_t *) hostid->h_addr_list[numAddrs]));
8890 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
8891 /* cm_inet_c_001.main_62:Warning fix */
8892 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetIpNodeByName() Failed : error(%d),"
8893 " hostName(%p), hostid->h_addrtype(%d), addrArr->type(%d)\n",
8894 err, hostName, hostid->h_addrtype, addrArr->type);
8895 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET050, 0, prntBuf);
8896 #endif /* CMINETDBG */
8900 #endif /* SS_LINUX */
8905 ret = cmInetGetHostByName(hostName, &addrArr->u.ipv4AddrArr);
8907 #endif /* IPV6_SUPPORTED */
8909 } /* end of cmInetGetIpNodeByName */
8916 * Desc: Converts an ASCII string containig an internet address
8917 * ("xxx.xxx.xxx.xxx") into a CmInetIpAddr (uint32_t) format.
8918 * This function is a wrapper for the inet_addr() call.
8920 * Ret: ROK - successful
8930 S8 *asciiAddr, /* ascii address representation */
8931 CmInetIpAddr *address /* 4 byte interent address */
8935 #if (ERRCLASS & ERRCLS_INT_PAR)
8936 /* error check on parameters */
8937 if (asciiAddr == NULLP)
8941 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8943 *address = inet_addr(asciiAddr);
8944 if (*address == (uint32_t)ERR_INADDRNONE)
8946 /* asciiAddr does not contain a valid internet address */
8958 * Desc: Converts an CmInetIPAddr based IP address into a string
8959 * of the format "xxx.xxx.xxx.xxx".
8960 * This function is a wrapper for the inet_ntoa() call.
8962 * Ret: ROK - successful
8965 * Notes: This function delivers a pointer to a static buffer
8966 * within the system. Therefore the string has to be copied
8967 * by the caller before another call is made!
8974 CmInetIpAddr address, /* 4 byte interent address */
8975 S8 **asciiAddr /* ascii address representation */
8978 struct in_addr inetAddr; /* internet address structure */
8981 #if (ERRCLASS & ERRCLS_INT_PAR)
8982 /* error check on parameters */
8983 if (asciiAddr == NULLP)
8987 #endif /* ERRCLASS & ERRCLS_INT_PAR */
8989 inetAddr.s_addr = address;
8991 *asciiAddr = inet_ntoa(inetAddr);
8992 if (*asciiAddr == NULL)
9003 * Desc: Converts an network address into a string.
9004 * This function is a wrapper for the inet_ntop() call.
9006 * Ret: ROK - successful
9009 * Notes: This function copies the resulting string to the buffer pointed to
9010 * by asciiaddr,which must be a non NULL pointer.The caller specifies
9011 * the number of bytes available in this buffer in the argument len.
9018 uint8_t type, /* ip address type */
9019 Void *address, /* 4/16 byte interent address */
9020 S8 *asciiAddr, /* ascii adress representation */
9027 #if (ERRCLASS & ERRCLS_INT_PAR)
9028 /* error check on parameters */
9029 if (asciiAddr == NULLP || address == NULLP || len == 0 )
9034 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9037 case CM_INET_IPV4ADDR_TYPE :
9040 case CM_INET_IPV6ADDR_TYPE :
9044 if(inet_ntop(domain,address,asciiAddr,len) == NULL)
9053 /* The inet_pton is not supported on all the Solaris Operating system
9054 * versions. This has to be supported on operating systems that support
9055 * IPV6 as per the RFC on the IPV6 socket interface. Hence this function
9056 *is moved under the IPV6_SUPPORTED flag */
9057 #ifdef IPV6_SUPPORTED
9064 * Desc: Converts a IP address string to address.
9066 * Ret: ROK - successful
9076 CmInetIpAddr *address, /* 4 byte interent address */
9077 S8 *asciiAddr /* ascii address representation */
9083 #if (ERRCLASS & ERRCLS_INT_PAR)
9084 /* error check on parameters */
9085 if ((asciiAddr == NULLP) || (address == NULLP))
9089 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9091 ret = inet_pton(AF_INET, asciiAddr, (void *)address);
9098 } /* end of cmInetPton */
9100 #endif /* IPV6_SUPPORTED */
9102 #ifdef IPV6_SUPPORTED
9108 * Desc: Converts a IP address string to IPV6 address suitable
9109 * to be used in bind.
9111 * Ret: ROK - successful
9120 CmInetIpAddr6 *address6, /* 16 byte interent address */
9121 S8 *asciiAddr /* ascii address representation */
9127 struct sockaddr_storage ss;
9128 uint32_t sslen = sizeof(ss);
9131 #if (ERRCLASS & ERRCLS_INT_PAR)
9132 /* error check on parameters */
9133 if ((asciiAddr == NULLP) || (address6 == NULLP))
9137 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9140 ret = inet_pton(AF_INET6, asciiAddr, (void *)address6);
9146 /* cm_inet_c_001.main_44 : In windows inet_pton is not implemented. so we are using the below function
9147 * to convert the ipv6 address string to appropriate form */
9148 WSAStringToAddressA((LPTSTR)asciiAddr, AF_INET6, NULL, (struct sockaddr*)&ss, &sslen);
9149 memcpy(address6, &(((struct sockaddr_in6 *)&ss)->sin6_addr), sizeof(CmInetIpAddr6));
9153 } /* end of cmInetPton6 */
9154 #endif /* IPV6_SUPPORTED */
9160 * Fun: cmInetGetMemSize
9162 * Desc: This function gives the max number of static buffer space that
9163 * the internet library will allocate.
9165 * Ret: ROK - successful
9173 S16 cmInetGetMemSize(
9174 S32 *size /* max used memory size */
9178 /* max static memory size depends on max flat buffer size */
9179 *size = CM_INET_MAX_MSG_LEN;
9181 /* max static memory size depends on max flat buffer or iovect size */
9182 *size = CM_INET_MAX_MSG_LEN;
9194 * Desc: This function initializes the socket library.
9196 * Ret: ROK - successful
9198 * Notes: Required only for Winsock and not for 4.3BSD
9204 S16 cmInetInit(Void)
9211 version = MAKEWORD(CM_INET_HIGH_VER, CM_INET_LOW_VER);
9212 err = WSAStartup(version, &data);
9227 * Desc: This function de initializes the socket library. The
9228 * WINSOCK implementation de registers the application and
9229 * releases any resources allocated on behalf of the
9232 * Ret: ROK - successful
9234 * Notes: Required only for Winsock and not for 4.3BSD
9240 S16 cmInetDeInit(Void)
9253 }/* end of cmInetDeInit() */
9258 * Fun: cmInetGetSockName
9260 * Desc: This function is used to retireve the current name
9261 * for the specified socket descriptor. It returns the
9262 * local association(address and port) for the socket.
9264 * Ret: ROK - successful
9267 * Notes: Please note if the socket was bound to CM_INET_INADDR_ANY
9268 * cmInetGetSockName() will not necessarily return the local
9269 * address information unless the socket has been connected.
9275 S16 cmInetGetSockName
9277 CmInetFd *sockFd, /* socket file descriptor */
9281 struct sockaddr_in *sockAddr;
9282 #ifdef IPV6_SUPPORTED
9283 struct sockaddr_in6 *sockAddr6;
9284 struct sockaddr_in6 lclSockAddr;
9286 CmInetSockAddr lclSockAddr;
9287 #endif /* IPV6_SUPPORTED */
9292 #endif /* SS_LINUX */
9294 /*cm_inet_c_001.main_58 : fix for klockwork issue */
9298 #if (ERRCLASS & ERRCLS_INT_PAR)
9299 /* error check on parameters */
9300 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd) ||
9305 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9307 memset(&lclSockAddr, 0, sizeof(lclSockAddr));
9308 size = sizeof(lclSockAddr);
9311 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr,
9312 (socklen_t *)&size);
9314 ret = getsockname(sockFd->fd, (CmInetSockAddr*)&lclSockAddr, (int*)&size);
9315 #endif /* SS_LINUX */
9319 switch(errCode = INET_ERR_CODE)
9322 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9323 #ifdef IPV6_SUPPORTED
9324 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9325 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9327 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9328 #endif /* IPV6_SUPPORTED */
9334 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9335 /* cm_inet_c_001.main_62:Warning fix */
9336 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9337 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
9338 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9340 /* cm_inet_c_001.main_62:Warning fix */
9341 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetGetHostByName() Failed : error(%d),"
9342 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
9343 CMINETLOGERROR(ERRCLS_INT_PAR, ECMINET051, 0, prntBuf);
9344 #endif /* ALIGN_64BIT */
9345 #endif /* CMINETDBG */
9347 }/* end of switch */
9351 /* Fill the returned address in to locAddr */
9352 #ifdef IPV6_SUPPORTED
9353 memset(locAddr, 0, sizeof(CmInetAddr));
9354 if (size == sizeof(struct sockaddr_in6))
9356 sockAddr6 = (struct sockaddr_in6 *)&lclSockAddr;
9357 locAddr->type = CM_INET_IPV6ADDR_TYPE;
9358 locAddr->u.ipv6Addr.port = CM_INET_NTOH_UINT16(sockAddr6->sin6_port);
9359 CM_INET_COPY_IPV6ADDR(&locAddr->u.ipv6Addr.ipv6NetAddr,
9360 &sockAddr6->sin6_addr);
9364 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9365 locAddr->type = CM_INET_IPV4ADDR_TYPE;
9366 locAddr->u.ipv4Addr.port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9367 locAddr->u.ipv4Addr.address =
9368 CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9371 sockAddr = (struct sockaddr_in *)&lclSockAddr;
9372 locAddr->port = CM_INET_NTOH_UINT16(sockAddr->sin_port);
9373 locAddr->address = CM_INET_NTOH_UINT32(sockAddr->sin_addr.s_addr);
9374 #endif /* IPV6_SUPPORTED */
9376 }/* end of cmInetGetSockName() */
9378 /* New functions to peek into the file descriptor
9380 #if (defined(SUNOS) || defined(WIN32) || defined(SS_LINUX) || defined(SS_VW) \
9385 * Fun: cmInetFdSetInfoInit
9387 * Desc: This function is used to initialise operating system specific
9388 * data that will be used to peek into the file descriptor lists
9389 * to get the sockets that are set
9391 * Ret: ROK - successful
9400 S16 cmInetFdSetInfoInit
9402 CmInetFdSetInfo *fdSetInfo
9405 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW) || defined(HPOS))
9410 #endif /* SUNOS || SS_LINUX || SS_VW */
9412 #if (ERRCLASS & ERRCLS_INT_PAR)
9413 if (fdSetInfo == NULLP)
9415 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9417 if (fdSetInfo->initDone == TRUE)
9421 fdSetInfo->numFds = 0;
9424 #if (defined(SUNOS) || defined(SS_LINUX) || defined(SS_VW)|| defined(HPOS))
9425 /* Check if we are on a big endian machine */
9427 if (*(uint8_t *)&arIdx)
9428 fdSetInfo->bigEndian = FALSE;
9430 fdSetInfo->bigEndian = TRUE;
9432 fdSetInfo->arIdx = 0;
9433 fdSetInfo->ar[0] = 0xff;
9435 /* Initialise the array */
9436 /* The array contains bit positions for the first bit
9437 * for each integer from 1 to 2^8.
9439 for (arIdx = 1; arIdx < 256; arIdx++)
9441 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9442 curByte = (uint8_t)arIdx;
9449 fdSetInfo->ar[arIdx] = bitPos;
9453 curByte = curByte >> 1;
9456 /* Calculate the number of array elements in this fd_set */
9457 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9458 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->__fds_bits[0]);
9460 fdSetInfo->numArElems = sizeof(CmInetFdSet)/sizeof(fdSet->fds_bits[0]);
9461 #endif /* SS_LINUX */
9462 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9464 fdSetInfo->initDone = TRUE;
9466 }/* end of cmInetFdSetInfoInit() */
9473 * Desc: This function is used to get the file descriptor from the
9474 * file descriptor set.
9476 * Ret: ROK - successful
9477 * ROKDNA - socket not found
9479 * RNA - failed, initialisation not done
9481 * Notes: If the application modifies fdSet between calls to this
9482 * function then the results are undefined. This function should
9483 * be called in a loop till either it returns - not ROK, or if
9484 * all sockets in the file descriptor set are processed.
9492 CmInetFdSetInfo *fdSetInfo,
9494 CmInetFdType *sockFd
9497 /*cm_inet_c_001.main_58 : Fix for klockwork issue */
9498 #if (!defined (WIN32))
9499 uint32_t sizOfFdSetArElem;
9500 uint8_t bytesScanned;
9505 #endif /* !defined (WIN32) */
9507 #if (ERRCLASS & ERRCLS_INT_PAR)
9508 if ((fdSetInfo == NULLP) || (fdSet == NULLP) || (sockFd == NULLP))
9511 if (fdSetInfo->initDone != TRUE)
9513 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9516 #if (ERRCLASS & ERRCLS_DEBUG)
9517 if (fdSetInfo->numFds > FD_SETSIZE)
9519 #endif /* ERRCLASS & ERRCLS_DEBUG */
9520 /* cm_inet_c_001.main_32 : Corrected check for number of fd set in
9522 if (fdSetInfo->numFds >= fdSet->fd_count)
9525 *sockFd = fdSet->fd_array[fdSetInfo->numFds];
9526 fdSetInfo->numFds += 1;
9530 /* cm_inet_c_001.main_59: Protected under if not defined WIN32 */
9531 #if (!defined (WIN32))
9532 /* Start with arIdx and continue upto number of array elements. */
9533 curIdx = fdSetInfo->arIdx;
9536 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9537 sizOfFdSetArElem = sizeof(fdSet->__fds_bits[0]);
9539 sizOfFdSetArElem = sizeof(fdSet->fds_bits[0]);
9540 #endif /* SS_LINUX */
9542 for (curIdx = fdSetInfo->arIdx; curIdx < fdSetInfo->numArElems;
9545 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9546 if (fdSet->__fds_bits[curIdx])
9548 if (fdSet->fds_bits[curIdx])
9549 #endif /* SS_LINUX */
9551 /* Walk through the bytes in this element */
9552 #if (defined(SS_LINUX) && !defined(_GNU_SOURCE))
9553 tempByte = (uint8_t *)&fdSet->__fds_bits[curIdx];
9555 tempByte = (uint8_t *)&fdSet->fds_bits[curIdx];
9556 #endif /* SS_LINUX */
9558 /* Set the starting byte offset */
9559 if (fdSetInfo->bigEndian)
9560 tempByte += sizOfFdSetArElem - 1;
9562 for (bytesScanned = 0; bytesScanned < sizOfFdSetArElem;
9567 bitPos = fdSetInfo->ar[*tempByte];
9568 /* cm_inet_c_001.main_54: Fix for Klockworks issue */
9569 fdSetInfo->arIdx = (uint16_t)curIdx;
9570 /* Calculate fd depending on where we are */
9571 *sockFd = ((bytesScanned << 3) + bitPos);
9572 *sockFd += (curIdx * (sizOfFdSetArElem << 3));
9573 /* Clear the file descriptor */
9574 *tempByte &= ~(1 << bitPos);
9577 if (fdSetInfo->bigEndian)
9590 #endif /* SUNOS || SS_LINUX || SS_VW || HPOS */
9591 } /* end of cmInetGetFd */
9593 #endif /* SUNOS || WIN32 || SS_LINUX || SS_VW || HPOS */
9596 /* add cmInetConvertStrToIpAddr and
9597 * cmInetAsciiToIpv4 functions */
9600 * Fun: cmInetConvertStrToIpAddr
9602 * Desc: This function parses the input string for an IPV4/IPV6 address.
9604 * 1) IPV4 in dot number format:
9606 * 2) IPV6, in uncompressed, compressed, and IPV4 embedded format
9607 * 10:20:30:40:502:610:70C:80ad
9609 * 45::AB:34:123.34.5.667
9611 * Ret: ROK - SUCCESS
9620 S16 cmInetConvertStrToIpAddr
9622 uint16_t len, /* Length of IP address */
9623 uint8_t *val, /* Domain Name String */
9624 CmInetNetAddr *address /* IP Address */
9627 uint8_t idx; /* Index for string*/
9628 uint8_t ipv4[CM_INET_IPV4ADDR_SIZE]; /* IPV4 Address bytes */
9629 #ifdef IPV6_SUPPORTED
9630 uint16_t *ipv6; /* IPV6 Address bytes */
9631 uint16_t ipv6Reg[8]; /* regular IPV6 Address bytes */
9632 uint16_t ipv6Cmp[8]; /* compressed IPV6 Address bytes */
9633 uint8_t numBlk; /* number of blocks in IPV6 addr */
9634 Bool compressed; /* IPV6 in compressed format */
9635 uint8_t ipv6Idx; /* counter for IPV6 */
9636 uint8_t blkBeginIdx; /* IPV6, char index for the
9637 beginning of the block */
9638 uint8_t i; /* counter for IPV6 */
9639 S16 retVal; /* return value */
9640 Bool embedIPV4 = FALSE; /* IPV4 embedded in IPV6 ? */
9641 #endif /* IPV6_SUPPORTED*/
9645 #ifdef IPV6_SUPPORTED
9650 ipv6 = ipv6Reg; /* assign pointer to IPV6 regular, uncompressed */
9651 memset(ipv6Reg, 0, CM_INET_IPV6ADDR_SIZE);
9652 memset(ipv6Cmp, 0, CM_INET_IPV6ADDR_SIZE);
9653 #endif /* IPV6_SUPPORTED*/
9655 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9657 /* Check for IP Address */
9658 while ((val[idx] != '.') && (val[idx] != ':') &&
9661 #if (ERRCLASS & ERRCLS_DEBUG)
9662 if (((val[idx] < '0') || (val[idx] > '9')) &&
9663 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9664 ((val[idx] < 'A') || (val[idx] > 'F')))
9669 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9671 /* Convert Ascii to integer */
9672 CM_INET_ATOI(ipv4[0], val[idx]);
9674 #ifdef IPV6_SUPPORTED
9675 /* convert Ascii to hex */
9676 CM_INET_ATOH(ipv6[0], val[idx]);
9677 #endif /* IPV6_SUPPORTED */
9679 idx++; /* move to the next character */
9680 } /* while, try to determine IPV4 or IPV6 */
9682 #if (ERRCLASS & ERRCLS_DEBUG)
9683 if ((val[idx] != '.') && (val[idx] != ':'))
9687 } /* if, couldn't determine IPV4 or IPV6 */
9688 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9691 if (val[idx] == '.')
9694 cmInetAsciiToIpv4(3, &(ipv4[1]), (uint16_t)(len - idx), &(val[idx]));
9696 address->type = CM_INET_IPV4ADDR_TYPE;
9697 CM_INET_GET_IPV4_ADDR_FRM_STRING(address->u.ipv4NetAddr, ipv4);
9699 #ifdef IPV6_SUPPORTED
9702 numBlk = 1; /* already converted the 1st block */
9704 while ((val[idx] != '\0') && (idx < len) && (numBlk <= 8))
9706 idx++; /* go to the next char, either a number or the 2nd : */
9707 if (val[idx] == ':')
9709 #if (ERRCLASS & ERRCLS_DEBUG)
9710 if (compressed == TRUE)
9712 /* can't have 2 :: */
9715 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9718 idx++; /* skip the : */
9721 } /* if, IPV6 in compressed format :: */
9725 } /* else, uncompressed, convert next block */
9727 numBlk++; /* increase number of blocks */
9729 /* assign the index the beginning of the block */
9732 while(val[idx] != ':' && val[idx] != '\0' && idx < len)
9734 if (val[idx] == '.')
9736 /* convert number to IPV4 */
9737 ipv6[ipv6Idx] = 0; /* clear out whatever we did */
9738 memset(ipv4, 0, CM_INET_IPV4ADDR_SIZE);
9739 retVal = cmInetAsciiToIpv4(4, ipv4, len - blkBeginIdx,
9740 &(val[blkBeginIdx]));
9741 /* stop the loop, embedded IPV4 is the last part of
9749 } /* if, '.' means IPV4 address embedded in IPV6 */
9751 #if (ERRCLASS & ERRCLS_DEBUG)
9752 if (((val[idx] < '0') || (val[idx] > '9')) &&
9753 ((val[idx] < 'a') || (val[idx] > 'f')) &&
9754 ((val[idx] < 'A') || (val[idx] > 'F')))
9759 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9761 /* Convert Ascii to integer */
9762 CM_INET_ATOH(ipv6[ipv6Idx], val[idx]);
9764 /* move to the next index */
9766 } /* while, convert a block of 16 bits Hex number */
9767 if (embedIPV4 == TRUE)
9769 ipv6Idx--; /* deccrease in case of compressed IPV6 */
9770 break; /* stop the while look */
9771 } /* if, IPV4 embedded in IPV6 */
9772 } /* while, IPV6 parsing */
9773 if (compressed == TRUE)
9775 if (embedIPV4 == TRUE)
9777 numBlk = 5; /* the last 2 blocks are IPV4 */
9778 } /* if, IPV4 embedded */
9781 numBlk = 7; /* copy from the last block */
9782 } /* else, no embedded IPV4 */
9784 /* type cast uint8_t over -1 becasue we want to copy the last block,
9787 for (i = ipv6Idx; i != (uint8_t) (-1); i --)
9789 ipv6Reg[numBlk] = ipv6Cmp[i];
9791 } /* for, copying compress IPV6 to regular IPV6 */
9792 } /* if, compressed format */
9794 if (embedIPV4 == TRUE)
9796 ipv6Reg[6] = PutHiByte(ipv6Reg[6], ipv4[0]);
9797 ipv6Reg[6] = PutLoByte(ipv6Reg[6], ipv4[1]);
9798 ipv6Reg[7] = PutHiByte(ipv6Reg[7], ipv4[2]);
9799 ipv6Reg[7] = PutLoByte(ipv6Reg[7], ipv4[3]);
9800 } /* if, IPV4 embedded */
9802 /* convert IPV6 to cmInetIpv6 */
9803 address->type = CM_INET_IPV6ADDR_TYPE;
9804 memcpy(address->u.ipv6NetAddr,
9805 ipv6Reg, CM_INET_IPV6ADDR_SIZE);
9807 #endif /* IPV6_SUPPORTED */
9810 } /* cmInetConvertStrToIpAddr */
9815 * Fun: cmInetAsciiToIpv4
9817 * Desc: This function parses the input string to an IPV4 address.
9818 * The input string can be
9819 * - the whole IPV4 address, '123.43.45.56', or
9820 * - a part of it. '34.56.454'
9821 * numBytes: number of bytes needs to be converted, IPV4 has
9822 * 4 bytes. If we are only converting the end of an
9823 * address, this number needs to be adjusted. For
9824 * example, when converting '34.56.454]', the number
9827 * Ret: ROK - SUCCESS
9835 S16 cmInetAsciiToIpv4
9837 uint8_t numBytes, /* number of Byte to convert */
9838 uint8_t *ipv4Addr, /* IPV4 Address */
9839 uint16_t len, /* Length of IP address */
9840 uint8_t *val /* Domain Name String */
9843 uint8_t byteCount; /* Byte Count */
9844 uint8_t idx; /* Index for string*/
9848 for (byteCount = 0; byteCount < numBytes; byteCount++)
9850 while((val[idx] != '.') && (idx < len))
9852 #if (ERRCLASS & ERRCLS_DEBUG)
9853 if (val[idx] < '0' || val[idx] > '9')
9858 #endif /* (ERRCLASS & ERRCLS_DEBUG) */
9860 /* Convert Ascii to integer */
9861 CM_INET_ATOI(ipv4Addr[byteCount], val[idx]);
9863 /* move to the next index */
9870 } /* cmInetAsciiToIpv4 */
9872 /* cm_inet_c_001.main_34:Added wrapper function for getaddrinfo and freeaddrinfo */
9873 #if (!defined(SS_VW) && !defined(SS_PS) && !defined(WIN32))
9877 * Fun: cmInetGetAddrInfo
9879 * Desc: a socket file descriptor to a local Internet
9882 * Ret: Value returned by getaddrinfo
9890 S32 cmInetGetAddrInfo
9892 const S8 *node, /* Network addr which has to be resolved */
9893 const S8 *service, /* Sets the port number in network addr */
9894 const CmInetAddrInfo *hints, /* Specifies preferred socket type or protocol */
9895 CmInetAddrInfo **res /* Link list of addrInfo structure */
9901 #if (ERRCLASS & ERRCLS_INT_PAR)
9902 /* error check on parameters */
9903 if ((node == NULLP) || (hints == NULLP))
9907 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9909 ret = getaddrinfo(node,service,hints,res);
9914 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9915 /* cm_inet_c_001.main_62:Warning fix */
9916 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%ld), node(%p),"
9917 " service(%p)\n", ret, node, service);
9918 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET052, 0, prntBuf);
9920 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
9921 /* cm_inet_c_001.main_62:Warning fix */
9922 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE, "cmInetGetAddrInfo() Failed : error(%d), node(%p),"
9923 " service(%p)\n ", ret, node, service);
9924 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET053, 0, prntBuf);
9925 #endif /* ALIGN_64BIT */
9926 #endif /* CMINETDBG */
9929 } /* end of cmInetGetAddrInfo */
9934 * Fun: cmInetFreeAddrInfo
9936 * Desc: Free the dynamically allocated addrinfo structure
9946 Void cmInetFreeAddrInfo
9948 CmInetAddrInfo *res /* Link list of addrInfo structure */
9952 #if (ERRCLASS & ERRCLS_INT_PAR)
9953 /* error check on parameters */
9956 #endif /* ERRCLASS & ERRCLS_INT_PAR */
9959 } /* end of cmInetFreeAddrInfo */
9961 #endif /* SS_VW | SS_PS | WIN32*/
9963 /* cm_inet_c_001.main_36 : 1. Added new interface - cmInetFlushRecvBuf()
9964 to flush the data from socket receive buffer. */
9965 #ifdef CM_INET_FLUSH_RECV_BUF
9969 * Fun: cmInetFlushRcvBuf
9971 * Desc: Reads all the data from a socket and throw it!!
9972 * The buffers for the receive buffer for recvfrom() are allocated from the stack.
9974 * Ret: ROK - successful
9975 * ROKDNA - ok, data not available
9976 * RCLOSED - connection closed by peer
9977 * ROUTRES - failed, out of resources
9985 S16 cmInetFlushRecvBuf
9987 CmInetFd *sockFd, /* socket file descriptor */
9988 MsgLen *len, /* number of octects to be flushed */
9989 S32 flags /* additional control flags */
9993 Data recvTempBuf[CM_INET_MAX_BYTES_READ];
9995 #if (defined(WIN32) || defined(CMINETFLATBUF))
9996 S32 ret; /* temporary return value */
9997 uint32_t pendLen; /* pending data length */
9998 S32 recvLen; /* number of received octets by recvmsg() */
9999 MsgLen curLen; /* current number of octets in buffer */
10000 uint32_t remAddrLen; /* length of remote address */
10001 struct sockaddr_in *remAddr; /* remote Internet address */
10002 #ifdef IPV6_SUPPORTED
10003 struct sockaddr_in6 remSockAddr; /* to get packet's source IP address */
10005 CmInetSockAddr remSockAddr; /* to get packet's source IP address */
10006 #endif /* IPV6_SUPPORTED */
10008 S32 ret; /* temporary return value */
10009 MsgLen curLen; /* current number of octets in buffer */
10010 uint32_t pendLen; /* pending data length */
10011 S32 recvLen; /* number of received octets by recvmsg() */
10012 struct msghdr msg; /* message header */
10013 CmInetIovec rxArr[CM_INET_MAX_DBUF]; /* dynamic gather array */
10014 uint32_t remAddrLen; /* length of remote address */
10015 #ifdef IPV6_SUPPORTED
10016 struct sockaddr_in6 remSockAddr;/* to get packet's source IP address */
10018 #if (defined(SS_LINUX) || defined(_XPG4_2))
10019 uint8_t ancillData[CM_INET_IPV6_ANCIL_DATA];
10020 /* from stack for IPv6 ancill data */
10023 CmInetSockAddr remSockAddr; /* to get packet's src IP address */
10024 #if (defined(SS_LINUX) || defined(_XPG4_2))
10025 uint8_t ancillData[CM_INET_IPV4_ANCIL_DATA];
10026 /* from stack for IPv4 ancill data */
10028 #endif /* IPV6_SUPPORTED */
10029 #endif /* WIN32 | CMINETFLATBUF */
10031 /* used by getsockopt */
10032 uint32_t errValue; /* error value */
10033 uint32_t optLen; /* option length */
10036 #if (ERRCLASS & ERRCLS_INT_PAR)
10037 /* error check on parameters */
10038 if ((sockFd == NULLP) || CM_INET_INV_SOCK_FD(sockFd))
10042 #endif /* ERRCLASS & ERRCLS_INT_PAR */
10045 #if (defined(WIN32) || defined(CMINETFLATBUF))
10047 #endif /* (WIN32 | CMINETFLATBUF) */
10049 /* clear the structure */
10050 memset(&remSockAddr, 0, sizeof(remSockAddr));
10052 /* get number of pending data */
10053 ret = cmInetGetNumRead(sockFd, &pendLen);
10056 /* ret may be RFAILED or ROUTRES */
10060 /* check if connection got closed */
10063 if (sockFd->type == CM_INET_STREAM)
10066 /* cm_inet_c_001.main_50
10067 * Due to latency (mostly in solaris) sometimes ioctl(FIONREAD)
10068 * (inside cmInetGetNumRead) returns pend length as 0 on a TCP
10069 * socket that select says is ready to read. This should not be
10070 * considered as connection closed. So return ROKDNA instead of
10076 /* clear error if there is any, because if there is internal error
10077 * here it will cause infinite loop in TUCL */
10080 optLen = sizeof(int);
10082 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10083 (char*)&errValue, (socklen_t *)&optLen);
10085 #if (defined(SS_VW) || defined(SS_PS))
10086 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10087 (char*)&errValue, (int *)&optLen);
10090 ret = getsockopt(sockFd->fd, SOL_SOCKET, SO_ERROR,
10091 (char*)&errValue, (int *)&optLen);
10092 #endif /* SS_WINCE */
10094 #endif /* SS_LINUX */
10095 if (ret == INET_ERR)
10098 #ifndef ALIGN_64BIT
10099 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10100 /* cm_inet_c_001.main_62:Warning fix */
10101 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10102 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10103 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10105 /* cm_inet_c_001.main_62:Warning fix */
10106 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10107 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10108 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET054, 0, prntBuf);
10109 #endif /*ALIGN_64BIT*/
10110 #endif /* CMINETDBG */
10116 /* added separate recvfrom calls different OS */
10117 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10118 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10119 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10121 #if ( defined(SUNOS) || defined(SS_LINUX))
10122 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10123 NULLP, (socklen_t *)&remAddrLen);
10125 recvLen = recvfrom(sockFd->fd, (S8 *)&tempBuf, pendLen, 0,
10126 NULLP, (S32 *)&remAddrLen);
10128 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10129 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10134 }/* if (pendLen == 0)*/
10137 if((*len == CM_INET_READ_THROW) || (*len >= CM_INET_MAX_BYTES_READ))
10139 curLen = CM_INET_MAX_BYTES_READ;
10143 curLen = *len; /*set to given number of messasges to be flushed */
10146 if((*len != CM_INET_READ_THROW) && (*len < pendLen))
10151 #if (defined(WIN32) || defined(CMINETFLATBUF))
10155 * maybe needs more than one recvfrom() call to read an entire
10160 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10161 /* added separate recvfrom calls different OS */
10163 #if( defined(SS_VW) || defined(HPOS) || defined(SS_PS))
10164 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10165 (struct sockaddr *)&remSockAddr, (int *)&remAddrLen);
10167 #if ( defined(SUNOS) || defined(SS_LINUX))
10168 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempBuf, curLen, 0,
10169 (struct sockaddr *)&remSockAddr, (socklen_t *)&remAddrLen);
10171 recvLen = recvfrom(sockFd->fd, (S8 *)recvTempbuf, curLen, 0,
10172 &remSockAddr, (S32 *)&remAddrLen);
10174 #endif /* defined(SUNOS) || defined(SS_LINUX) */
10175 #endif /* defined(SS_VW) || defined(HPOS) || defined(SS_PS) */
10177 if (recvLen == INET_ERR)
10180 /* added check ERR_WOULDBLOCK */
10181 if ((INET_ERR_CODE == ERR_AGAIN) ||
10182 (INET_ERR_CODE == ERR_WOULDBLOCK))
10189 /* In Windows the recvfrom function fails
10190 * with error code which maps to either WSAECONNABORTED. If
10191 * this happens then cmInetFlushRecvBuf must return RCLOSED */
10192 if ((INET_ERR_CODE == ERR_CONNABORTED) ||
10193 (INET_ERR_CODE == ERR_CONNRESET))
10200 #ifndef ALIGN_64BIT
10201 /* cm_inet_c_001.main_54 : CMINETLOGERROR added insted of SDisp */
10202 /* cm_inet_c_001.main_62:Warning fix */
10203 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10204 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10205 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10207 /* cm_inet_c_001.main_62:Warning fix */
10208 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10209 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10210 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET055, 0, prntBuf);
10211 #endif /*ALIGN_64BIT*/
10212 #endif /* CMINETDBG */
10217 if(recvLen < curLen)
10220 pendLen -= recvLen;
10222 if(pendLen < curLen)
10225 } /* while (curLen > 0) */
10227 #else /* end of Win NT/flat buffer specific part */
10230 * maybe needs more than one recvmsg() call to read entire message
10231 * on a stream socket
10235 memset(recvTempBuf, 0, CM_INET_MAX_BYTES_READ);
10236 /* update the message structure */
10238 rxArr[0].iov_base = (Void*)recvTempBuf;
10239 rxArr[0].iov_len = (uint32_t)curLen;
10241 rxArr[0].iov_base = (S8*)recvTempBuf;
10242 rxArr[0].iov_len = curLen;
10243 #endif /* SS_LINUX */
10244 msg.msg_iov = rxArr;
10245 msg.msg_iovlen = 1;
10247 msg.msg_name = NULLP;
10248 msg.msg_namelen = 0;
10250 /* added defined(_XPG4_2). Also changed the
10252 #if (defined(SS_LINUX) || defined(_XPG4_2))
10253 msg.msg_control = ancillData;
10254 msg.msg_controllen = sizeof(ancillData);
10257 msg.msg_accrights = NULLP;
10258 msg.msg_accrightslen = 0;
10259 #endif /* SS_LINUX */
10261 recvLen = recvmsg(sockFd->fd, &msg, flags);
10262 if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))
10264 /* added check ERR_AGAIN when CMINETFLATBUF is not defined.
10265 added check ERR_WOULDBLOCK */
10266 if ((INET_ERR_CODE == ERR_AGAIN) ||
10267 (INET_ERR_CODE == ERR_WOULDBLOCK))
10274 #ifndef ALIGN_64BIT
10275 /* cm_inet_c_001.main_54: CMINETLOGERROR added insted of SDisp */
10276 /* cm_inet_c_001.main_62:Warning fix */
10277 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10278 " sockFd->fd(%ld)\n", INET_ERR_CODE, sockFd->fd);
10279 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10281 /* cm_inet_c_001.main_62:Warning fix */
10282 snprintf(prntBuf, CMINET_PRNT_BUF_SIZE,"cmInetFlushRecvBuf() Failed : error(%d),"
10283 " sockFd->fd(%d)\n", INET_ERR_CODE, sockFd->fd);
10284 CMINETLOGERROR(ERRCLS_DEBUG, ECMINET056, 0, prntBuf);
10285 #endif /*ALIGN_64BIT*/
10286 #endif /* CMINETDBG */
10288 /* If this happens then cmInetFlushRecvBuf must return RCLOSED.
10289 * Needed for getting icmp msgs */
10290 if (INET_ERR_CODE == ERR_CONNABORTED)
10296 }/* if ((recvLen == INET_ERR) || (recvLen > CM_INET_MAX_MSG_LEN))*/
10298 if(recvLen < curLen)
10301 pendLen -= recvLen;
10303 if(pendLen < curLen)
10306 } /* while(curLen > 0) */
10308 #endif /* WIN32 | CMINETFLATBUF */
10312 } /* end of cmInetFlushRecvBuf */
10314 #endif /* CM_INET_FLUSH_RECV_BUF*/
10316 /**********************************************************************
10318 **********************************************************************/