breakdeps/usocket.cpp
changeset 20 37dc158a4522
child 21 4a02a61ca23a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/breakdeps/usocket.cpp	Mon Oct 11 15:37:45 2010 +0100
@@ -0,0 +1,2248 @@
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include <sys/types.h>
+#include <string.h>		// for memcpy
+#include <fcntl.h>		// for struct stat
+#include <sys/errno.h>		// for ENOTSOCK
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <netinet/in.h>		// for htons
+#include <sys/sockio.h>
+#include <bt_sock.h>     // Symbian BT constantss needed for cooperation with Symbian sockets
+#include <arpa/inet.h>   
+#include <es_sock.h>
+#include <in_sock.h>
+#include <net/if.h>
+#include <commdb.h>
+#include <cdbcols.h>
+#include <commdbconnpref.h>
+#include <e32base.h>
+#include <e32err.h>
+#include <utf.h>
+#include <e32std.h>
+#include <net/route.h>
+#include <in_iface.h>
+#include "fdesc.h"
+#include "lposix.h"
+#include "sysif.h"
+
+// Support for struct sockaddr conversion
+TUSockAddr::TUSockAddr (TAny* aBuf) 
+: TSockAddr(), iError(0)
+		{
+		Prepare(aBuf);
+		}
+
+void TUSockAddr::Prepare (TAny* aBuf) 
+//
+// Prepare a TUSockAddr to receive an address (used in RecvFrom)
+// Setting the length to 0 indicates that we don't really want this address anyway.
+//
+	{
+	if (aBuf==0)
+		{
+		SetLength(0);
+		iError = EFAULT;
+		return;
+		}
+	}
+
+EXPORT_C TUSockAddr::TUSockAddr (const TAny* aBuf, TUint aLen) 
+: TSockAddr(), iError(0)
+		{
+		Set(aBuf,aLen);
+		}
+
+void TUSockAddr::Set (const TAny* aBuf, TUint aLen) 
+//
+// Construct an ESOCK TSockAddr from a struct sockaddr.
+// We have to deal with the network byte ordering of AF_INET addresses
+//
+	{
+	if (!aBuf)
+		{
+		iError = EFAULT;
+		SetLength(0);
+		return;
+		}
+	
+	const TUint dataOffset = (TUint)&((struct sockaddr *)0)->sa_data[0];
+	// aLen should be atleast have minimum size.
+	if (aLen < dataOffset)
+		{
+		iError = EINVAL;
+		SetLength(0);
+		return;
+		}
+
+	const struct sockaddr* sp= (const struct sockaddr *)(aBuf);
+	TUint8 *from=(TUint8*)aBuf;	
+
+	if (sp->sa_family==AF_INET)
+		{		
+		// byte-swap sockaddr_in back into host ordering
+		TUint port=(from[2]<<8)+from[3];
+		from+=4;
+		TUint32 addr=(from[0]<<24)+(from[1]<<16)+(from[2]<<8)+from[3];
+		from+=4;
+		SetFamily(AF_INET);
+		SetPort(port);
+		*(TUint32*)UserPtr()=addr;
+		SetUserLen(4);
+		return;
+		}
+	else if (sp->sa_family == AF_INET6)
+		{
+		SetFamily(sp->sa_family);
+		SetPort(ByteOrder::Swap16(sp->sa_port));
+		from+=4;
+		// copy the rest of the data as given
+		TUint8 *to=UserPtr();
+		if (aLen<4)
+			aLen=4;
+		aLen-=4;	// skip fmaily and port
+		if (aLen>24)
+			aLen=24;
+		memcpy(to,from,aLen);
+		SetUserLen(aLen);    	
+		return;
+		}	
+	else if (sp->sa_family == KBTAddrFamily)
+		{
+		// Make a TBTSockAddr from a sockaddr_bt...
+		TBTSockAddr tmpAddr;
+
+		// Family is always Bluetooth:
+		tmpAddr.SetFamily(KBTAddrFamily);
+
+		// The port number has the correct byte order already, as the
+		// POSIX Bluetooth APIs assume litle-endian format:
+		tmpAddr.SetPort(sp->sa_port);
+
+		// For the address we need to reverse the byte ordering, as
+		// Symbian appears to index Bluetooth addresses in a
+		// big-endian manner:
+
+		const TInt KBTAddrLength = 6;  // Bytes in a Bluetooth address
+		const TInt KBTAddrOffset = 4;  // Offset of address in sockaddr_bt
+
+		TBTDevAddr devAddr;
+		const TInt KMinLength = KBTAddrLength + KBTAddrOffset;
+
+		if (aLen >= KMinLength)
+			{
+			for (TInt i=0; i<KBTAddrLength; ++i)
+				{
+				devAddr[i] = from[KMinLength - 1 - i];
+				}
+			}
+
+		tmpAddr.SetBTAddr(devAddr);
+
+		// Security settings:
+		TBTServiceSecurity sec;
+		sec.SetUid(TUid::Uid(0));
+		sec.SetAuthentication(EFalse);
+		sec.SetEncryption(EFalse);
+		sec.SetAuthorisation(EFalse);
+		sec.SetDenied(EFalse);
+		tmpAddr.SetSecurity(sec);
+
+		// Now we must copy the contents of the "tmpAddr" TBTSockAddr,
+		// but unfortunately there isn't an assignment operator for us
+		// to use. Still, we know it is a self-contained T class for
+		// which a direct shallow copy using memcopy() will be ok:
+		//
+		memcpy(this, &tmpAddr, sizeof(TBTSockAddr));
+
+		return;
+		}
+	else
+		{
+		// Not AF_INET or KBTAddrFamily:
+
+		// expand the family and port
+		SetFamily(sp->sa_family);
+		SetPort(sp->sa_port);
+		from+=4;
+		// copy the rest of the data as given
+		TUint8 *to=UserPtr();
+		if (aLen<4)
+			aLen=4;
+		aLen-=4;	// skip fmaily and port
+		if (aLen>24)
+			aLen=24;
+		memcpy(to,from,aLen);
+		SetUserLen(aLen);
+		}
+	}
+
+/*
+ * Extract a struct sockaddr from a TSockAddr
+ */
+EXPORT_C void TUSockAddr::Get(TAny* addr, unsigned long* len)
+	{
+	if (addr==0)
+		{
+		iError = EFAULT;
+		SetLength(0);
+		return;
+		}
+	const TUint dataOffset = (TUint)&((struct sockaddr *)0)->sa_data[0];
+	// aLen should be atleast have minimum size.
+	if (*len < dataOffset)
+		{
+		iError = EINVAL;
+		SetLength(0);
+		return;
+		};
+
+	struct sockaddr* sp=(struct sockaddr*)addr;
+	TUint16 port=(TUint16)Port();
+
+	//The ipv4 address could be obtained either as
+	//plain 32 bit address or as ipv4 mapped ipv6 address
+	TInetAddr inetAddr(*this);
+	TBool isV4Mapped = (Family()==AF_INET6) && (inetAddr.IsV4Mapped() || inetAddr.IsV4Compat());
+	if (Family()==AF_INET || isV4Mapped)
+		{
+		sp->sa_family=AF_INET;
+		sp->sa_port= ByteOrder::Swap16(port);
+		TUint8* from=UserPtr();
+		TUint32 fromaddr;
+		//If the address is v4 mapped, we take the last 4 bytes from the 16 bytes long v6 structure. 
+		if(isV4Mapped)
+			fromaddr = (from[15]<<24)+(from[14]<<16)+(from[13]<<8)+from[12];
+		else
+			fromaddr = (from[0]<<24)+(from[1]<<16)+(from[2]<<8)+ from[3];
+		*(TUint32*)sp->sa_data=fromaddr;
+		*len=8;
+		return;
+		}
+	else if (Family()==AF_INET6)
+		{
+
+		sp->sa_family=(TUint16)Family();
+		sp->sa_port=ByteOrder::Swap16(port);
+		TUint ulen=GetUserLen();
+		if (ulen+4>(*len))
+			ulen=(*len)-4;
+		*len=ulen+4;
+		memcpy(sp->sa_data,UserPtr(),ulen);
+		sp->sa_len = ulen;
+		return;
+		}		
+	else if (Family()==KBTAddrFamily)
+		{
+		sp->sa_family=KBTAddrFamily;
+		sp->sa_port=port;
+
+		const TInt KBTAddrLength = 6;
+		if (GetUserLen() == KBTAddrLength)
+			{
+			for (TInt i=0; i<KBTAddrLength; ++i)
+				{
+				sp->sa_data[KBTAddrLength - 1 - i] = UserPtr()[i];
+				}
+			}
+		return;
+		}
+	else
+		{
+		// Not AF_INET or KBTAddrFamily:
+		sp->sa_family=(TUint16)Family();
+		sp->sa_port=port;
+		TUint ulen=GetUserLen();
+		if (ulen+4>(*len))
+			ulen=(*len)-4;
+		*len=ulen+4;
+		memcpy(sp->sa_data,UserPtr(),ulen);
+		}
+	}
+
+// The Socket descriptor class
+CSocketDesc::CSocketDesc()
+:iIoctlBuf(0,0),
+iSocketPtr(NULL),
+iConnPref(),
+iConnectionPtr(NULL),
+iSubConnectionPtr(NULL),
+iRConnectionIndex(-1),		
+iSockServPtr(NULL)
+		{
+
+		};
+
+
+TInt CSocketDesc::Socket(RSocketServ& aSs, int family, int style, int protocol)
+	{
+	if (protocol == 0)
+		{
+		if (family == AF_INET)
+			{
+			switch (style)
+				{
+				case SOCK_STREAM:
+					protocol = IPPROTO_TCP;
+					break;
+
+				case SOCK_DGRAM:
+					protocol = IPPROTO_UDP;
+					break;
+				}
+			}
+		else
+			{
+			protocol = KUndefinedProtocol;
+			}
+		}
+
+	iFcntlFlag = 0;
+	TInt err = CreateLock();
+	if (err)
+		{
+		return err;
+		}
+
+	if (family == AF_INET6)
+		{
+		err = iSocket.Open(aSs, KAfInet, style, protocol);
+		}
+	else
+		{
+		err = iSocket.Open(aSs, family, style, protocol);
+		}
+
+	if (err == KErrNone)
+		{
+		iStyle = style;
+		iSocket.Close(); // We will close now, to open later using connection preferences
+		iAddrFamily = family;
+		iProtocol = protocol; 
+		iSockServPtr = &aSs; // Saving the const session pointer for later use
+		}
+	return err;
+	}
+
+TInt CSocketDesc::FinalClose()
+	{
+	CLocalSystemInterface* backend = Backend();
+	backend->DefConnLock().Wait();
+	RHeap* oheap = User::SwitchHeap(backend->Heap());	
+	if (iSocketPtr != NULL)
+		{
+		iSocketPtr = NULL;	
+		StopInterface(NULL); // Checks for RConnection as well as RSubConnection
+	    backend->RemoveSocket(this);
+		}
+
+	CSockDescBase::FinalClose();
+	User::SwitchHeap(oheap);
+	backend->DefConnLock().Signal();
+	return KErrNone;
+	}
+
+
+void CSocketDesc::Read (TDes8& aBuf, TRequestStatus& aStatus)
+	{
+	//Acquire the Lock before read and release it later
+	iReadLock.Wait();
+	if (iSocketPtr == NULL)
+		{
+		TInt ret = OpenUsingPreference();
+		if (ret != KErrNone)	// Error in open
+			{
+			Complete(aStatus,ret);
+			iReadLock.Signal();
+			return;
+			}
+		}
+	CSockDescBase::Read (aBuf,aStatus);
+	iReadLock.Signal();
+	}
+
+TInt CSocketDesc::ReadCompletion(TDes8& aBuf, TInt aStatus)
+	{
+	return CSockDescBase::ReadCompletion(aBuf, aStatus);
+	}
+
+void CSocketDesc::ReadCancel()
+	{
+	if (iSocketPtr != NULL)
+		{
+		CSockDescBase::ReadCancel();
+		}
+	}
+
+void CSocketDesc::Write (TDes8& aBuf, TRequestStatus& aStatus)
+	{
+
+    TInt err = maybe_reopen_socket();
+    if (err != KErrNone)
+        {
+        Complete(aStatus, err);
+        return;
+        }
+	
+	iWriteLock.Wait();
+	CSockDescBase::Write(aBuf, aStatus);
+	iWriteLock.Signal();	
+	}
+
+void CSocketDesc::WriteCancel()
+	{
+	if (iSocketPtr != NULL)
+		{
+		CSockDescBase::WriteCancel();
+		}
+	}
+
+
+TInt CSocketDesc::Bind(const struct sockaddr* aAddr, unsigned long aSize)
+	{
+	TInt ret;
+	TUSockAddr addr(aAddr,aSize);
+
+	if (addr.iError != 0)
+		{
+		return addr.iError;
+		}
+	
+	ret = maybe_reopen_socket();
+	if (ret != KErrNone)
+	    return ret;
+	ATOMICSOCKETOP(ret = iSocket.Bind(addr),return KErrBadHandle)
+	return ret;
+	}
+
+TInt CSocketDesc::Listen(TUint qSize)
+	{
+
+    TInt ret;
+	if (iStyle == SOCK_DGRAM) // Listen on UDP socket, crashing at RSocket::Listen().
+		{
+		return EOPNOTSUPP;
+		}
+	
+	ret = maybe_reopen_socket();
+	if (ret != KErrNone)
+	    return ret;
+
+	return CSockDescBase::Listen(qSize);
+	}
+
+TInt CSocketDesc::SockName(int anEnd, struct sockaddr* anAddr,unsigned long* aSize)
+	{
+
+
+	if (!anAddr)
+        {
+        return EFAULT;
+        }
+
+	TInt ret = maybe_reopen_socket();
+	if (ret != KErrNone)
+	    return ret;
+	
+   
+    struct sockaddr temp;
+    unsigned long len = sizeof( temp );
+    
+	TUSockAddr nSockAddr(&temp, len );
+
+	ret = CSockDescBase::SockName(anEnd,nSockAddr);
+	if(ret == KErrNone )
+	    {
+            nSockAddr.Get(&temp,&len );
+            if( *aSize > len )
+                *aSize = len;
+            memcpy( anAddr,&temp,*aSize);
+            
+            }
+	
+	return ret;
+	}
+
+TInt CSocketDesc::GetSockOpt(TInt anOptionName, TInt anOptionLevel, TDes8& anOption)
+	{
+	TInt ret;
+	if (anOption.Ptr() == NULL)
+		{
+		return EFAULT;
+		}
+	if (anOption.Length() == 0)
+		{
+		return EINVAL;
+		}
+	
+	ret = maybe_reopen_socket();
+	if (ret != KErrNone)
+	    return ret;
+
+	if (SO_TYPE == anOptionName && SOL_SOCKET == anOptionLevel)
+		{
+		TProtocolDesc protocolInfo;
+		ATOMICSOCKETOP(ret = iSocket.Info(protocolInfo), ret = KErrBadHandle)
+		if (KErrNone == ret )
+			{
+			// Copy the Socket Type to the buffer
+			TInt size = (anOption.Length() < sizeof(protocolInfo.iSockType))? anOption.Length(): sizeof(protocolInfo.iSockType);
+			Mem::Copy((unsigned char*)anOption.Ptr(), &protocolInfo.iSockType, size);
+			anOption.SetLength(size);
+			}
+		return ret;
+		}
+
+	if(IPPROTO_IP == anOptionLevel && IP_MULTICAST_IF == anOptionName)
+		{
+		TUSockAddr addr;
+		struct sockaddr_in sockAddress;
+		sockAddress.sin_family = AF_INET;
+		ATOMICSOCKETOP(sockAddress.sin_port = iSocket.LocalPort(),return KErrBadHandle)			
+		ATOMICSOCKETOP(iSocket.LocalName(addr);,return KErrBadHandle)		
+		TInt a = sizeof(sockAddress);
+		addr.Get(&sockAddress,(unsigned long*)&a);  
+		TInt size = (anOption.Length() < sizeof(sockAddress.sin_addr))? anOption.Length(): sizeof(sockAddress.sin_addr);
+		Mem::Copy((unsigned char*)anOption.Ptr(), &(sockAddress.sin_addr), size); 
+		anOption.SetLength(size);
+		return KErrNone;
+		}
+
+	switch(anOptionLevel)
+		{
+		case IPPROTO_TCP:
+			anOptionLevel=SOL_TCP;
+			break;
+		case IPPROTO_IP:
+			anOptionLevel=SOL_IP;
+			break;
+		case SOL_SOCKET:
+			{
+			switch(anOptionName)
+				{
+				case SO_REUSEADDR: 
+					anOptionLevel=SOL_IP;
+					break;
+				case SO_OOBINLINE:
+				case SO_KEEPALIVE:
+					anOptionLevel=SOL_TCP;
+					break; 
+				case SO_BROADCAST:
+					*((TInt*)anOption.Ptr()) = 1;
+					return KErrNone;
+				}
+			}
+		} 
+
+	switch(anOptionName)
+		{
+		case IP_MULTICAST_TTL:
+			anOptionLevel=KSolInetIp;
+			anOptionName=KSoIp6MulticastHops;
+			break;
+		case IP_MULTICAST_LOOP:
+			anOptionLevel=KSolInetIp;
+			anOptionName=KSoIp6MulticastLoop;
+			break;
+		}
+	ATOMICSOCKETOP(ret = iSocket.GetOpt(anOptionName,anOptionLevel,anOption), return KErrBadHandle)
+	return ret;
+	}
+
+TInt CSocketDesc::GetInterfaceIndex(TUint32 anAddr)
+	{
+	TPckgBuf<TSoInetIfQuery> ifq;
+	TInt aIndex = -1;
+	if (KInetAddrAny == anAddr)
+		{
+		aIndex = 0;
+		return aIndex;
+		}
+	else 
+		{
+		TInt ret = KErrNone;
+		ATOMICSOCKETOP(ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle)
+		if (ret != KErrNone)
+			return KErrGeneral;
+
+		TPckgBuf<TSoInetInterfaceInfo>iface;
+		ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle )
+		while(ret == KErrNone)
+			{
+			TSoInetInterfaceInfo &info = iface();
+			TInt result;
+			if(info.iState == EIfUp)
+				{
+				if (anAddr == info.iAddress.Address()) 
+					{      	
+					ifq().iName = info.iName;
+					ATOMICSOCKETOP( result = iSocket.GetOpt(KSoInetIfQueryByName, KSolInetIfQuery, ifq), result = KErrBadHandle )
+					if (result == KErrNone)
+						aIndex = ifq().iIndex;
+
+					}
+				}
+			ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle )
+			}   	
+		}
+	return aIndex;
+	}
+
+TInt CSocketDesc::SetSockOpt(TInt anOptionName, TInt anOptionLevel, TDesC8& anOption)
+	{
+	TInt ret;
+	if (anOption.Ptr() == NULL)
+		{
+		return EFAULT;
+		}
+	if (anOption.Length() == 0)
+		{
+		return EINVAL;
+		}
+	
+	ret = maybe_reopen_socket();
+	if (ret != KErrNone)
+	    return ret;
+
+	switch(anOptionLevel)
+		{
+		case IPPROTO_TCP:
+			anOptionLevel=SOL_TCP;
+			break;
+		case IPPROTO_IP:
+			anOptionLevel=SOL_IP;
+			break;
+		case SOL_SOCKET:
+			{
+			switch(anOptionName)
+				{
+				case SO_REUSEADDR: 
+					anOptionLevel=SOL_IP;
+					break;
+				case SO_OOBINLINE:
+				case SO_KEEPALIVE:
+					anOptionLevel=SOL_TCP;
+					break; 
+				}
+			}
+
+		}
+	TPckgBuf<TIp6Mreq> req;
+	struct ip_mreq *mreq;
+	TInt aIndex = -1;
+	TUint8 *from;
+	TUint32 srcAddr;
+	TUint32 maddr;
+	TInetAddr multiAddr;
+	TInt *Option = NULL;
+	TInt ttlValue = 0;
+	switch(anOptionName) 
+		{
+		case IP_ADD_MEMBERSHIP:  //KSoIp6JoinGroup
+		case IP_DROP_MEMBERSHIP: //KSoIp6LeaveGroup
+
+			mreq = (struct ip_mreq *)anOption.Ptr();
+			from = (TUint8 *)anOption.Ptr(); 
+			from+=4;
+			// swaping the byte order
+			srcAddr = ByteOrder::Swap32( mreq->imr_interface.s_addr); 
+			//fetch the interface index
+			aIndex = GetInterfaceIndex(srcAddr);
+
+			// Set the multicast addr
+			from = (TUint8 *)anOption.Ptr();
+			maddr=(from[0]<<24)+(from[1]<<16)+(from[2]<<8)+from[3];
+			multiAddr.SetAddress( maddr);
+			multiAddr.ConvertToV4Mapped();
+			if (multiAddr.IsMulticast())
+			    {
+                req().iAddr = multiAddr.Ip6Address();
+                req().iInterface = aIndex;  
+			    }
+			ATOMICSOCKETOP( ret = iSocket.SetOpt(anOptionName, anOptionLevel, req), return KErrBadHandle )
+			return ret;
+
+		case IP_MULTICAST_TTL:
+			anOptionLevel=KSolInetIp;
+			anOptionName=KSoIp6MulticastHops;
+			Option = (TInt*)anOption.Ptr();
+			ttlValue = *Option;
+			ATOMICSOCKETOP( ret = iSocket.SetOpt(anOptionName,anOptionLevel,ttlValue), return KErrBadHandle )
+			return ret;
+			
+		case SO_BROADCAST: 
+			//check if user is trying to disable broadcast
+			Option = (TInt*)anOption.Ptr();
+			return (*Option == 0 ? KErrNotSupported : KErrNone);
+
+		case IP_MULTICAST_IF:
+			{
+			//No support for equivalent flag KsoIp6MulticastIf presently
+			//call bind instead	    
+			struct in_addr *inAddress = (struct in_addr*)anOption.Ptr();	    
+			struct sockaddr_in sockAddress; 	 		    
+			sockAddress.sin_family = AF_INET;
+			ATOMICSOCKETOP(sockAddress.sin_port = iSocket.LocalPort();,return KErrBadHandle)         
+			sockAddress.sin_addr.s_addr = inAddress->s_addr;
+			TUSockAddr ifAddress(&sockAddress, sizeof(sockAddress));
+			ATOMICSOCKETOP( ret = iSocket.Bind(ifAddress), return KErrBadHandle )
+			return ret;
+			}
+
+		case IP_MULTICAST_LOOP:
+			anOptionLevel=KSolInetIp;
+			anOptionName=KSoIp6MulticastLoop;
+			break;	    	
+
+
+
+		}
+	ATOMICSOCKETOP( ret = iSocket.SetOpt(anOptionName,anOptionLevel,anOption), return KErrBadHandle )
+	return ret;
+	}
+
+void CSocketDesc::Sync (TRequestStatus& aStatus)
+	{
+	// Judging from the Solaris man pages, this does nothing.
+	Complete(aStatus,KErrNone);
+	}
+
+void CSocketDesc::RecvFrom(TDes8& aDesc, TSockAddr& from, int flags, TRequestStatus& aStatus)
+	{
+    TInt err = maybe_reopen_socket();
+    if (err != KErrNone)
+        {
+        Complete(aStatus, err);
+        return;
+        }
+
+	iReadLock.Wait();
+	CSockDescBase::RecvFrom(aDesc, from, flags, aStatus);
+	iReadLock.Signal();
+	}
+
+void CSocketDesc::RecvFromCancel()
+	{
+	if (iSocketPtr != NULL)
+		{
+		CSockDescBase::RecvFromCancel();
+		}
+	}
+
+
+void CSocketDesc::SendTo(TDes8& aDesc, const struct sockaddr* anAddr, unsigned long aAddrLen, int flags, TRequestStatus& aStatus)
+	{
+    TInt err = maybe_reopen_socket();
+    if (err != KErrNone)
+        {
+        Complete(aStatus, err);
+        return;
+        }
+    
+	TUSockAddr toAddr(anAddr, aAddrLen);
+	
+	iWriteLock.Wait();  
+	CSockDescBase::SendTo(aDesc, toAddr, flags, aStatus);
+	iWriteLock.Signal();
+	}
+
+void CSocketDesc::SendToCancel()
+	{
+// Should we use atomic loads here?
+	if (iSocketPtr != NULL)
+		{
+		CSockDescBase::SendToCancel();
+		}
+	}
+
+void CSocketDesc::Shutdown(TUint aHow,TRequestStatus& aStatus)
+	{
+
+    if (__e32_atomic_load_acq32(&iSocketPtr) == NULL) // Not opened at all. Nothing to do.
+		{
+		Complete(aStatus,KErrNone);
+		return;
+		}
+
+	CSockDescBase::Shutdown(aHow,aStatus);
+	return;
+	}
+
+void CSocketDesc::Accept(CFileDescBase*& aNewSocket, TRequestStatus& aStatus, RSocketServ& aSs, TSockAddr * /*aAddr*/)
+	{
+    aNewSocket = NULL;
+	TInt err = maybe_reopen_socket();
+	if (err != KErrNone)
+	    {
+        Complete(aStatus, err);
+        return;
+	    }
+	
+	iReadLock.Wait();
+	// what are the below coverity thingummichs?
+	//coverity[alloc_fn]
+	//coverity[assign]
+	CSocketDesc *newSocket = new CSocketDesc;
+	if (!newSocket)
+	    {
+        Complete(aStatus, KErrNoMemory);
+        iReadLock.Signal();
+        return;
+	    }
+	
+	err = newSocket->CreateLock();
+	if (err)
+		{
+        Complete(aStatus, KErrNoMemory);
+        delete newSocket;
+        iReadLock.Signal();
+        //coverity[memory_leak]
+        return;
+		}
+
+	err = newSocket->iSocket.Open(aSs);
+	if (err)
+		{
+		Complete(aStatus, err);
+		newSocket->FinalClose();  // this will Close locks
+		delete newSocket;
+
+		iReadLock.Signal();
+		//coverity[memory_leak]
+		return;
+		}
+	newSocket->iSocketPtr = &newSocket->iSocket;
+	newSocket->iStyle = iStyle;
+	err = KErrNone;
+	ATOMICSOCKETOP( iSocket.Accept(newSocket->iSocket,aStatus), err = KErrBadHandle )
+	if( err )
+	    {
+	    Complete(aStatus, err);
+	    newSocket->FinalClose();  // this will Close locks
+	    delete newSocket;
+	    }
+	else
+	    {
+	    aNewSocket = newSocket;
+	    }
+	iReadLock.Signal();
+	}
+
+void CSocketDesc::AcceptCancel()
+	{
+	if (iSocketPtr != NULL)
+		{
+		ATOMICSOCKETOP( iSocket.CancelAccept(), NOP )
+		}
+	}
+
+void CSocketDesc::Connect(const struct sockaddr* aAddr,unsigned long size,TRequestStatus& aStatus)
+	{
+	TUSockAddr addr(aAddr,size);
+
+	if (addr.iError != 0)
+		{
+		aStatus = addr.iError;
+		return;
+		}
+	
+	TInt err = maybe_reopen_socket();
+	if (err != KErrNone)
+	    {
+        aStatus = err;
+        return;
+	    }
+	
+	iWriteLock.Wait();
+	if( GetConnectionProgress() == EFalse )
+	    {
+		ATOMICSOCKETOP(iSocket.Connect(addr, aStatus), Complete(aStatus,KErrBadHandle))
+	    User::WaitForRequest(aStatus);
+	    if( aStatus.Int() == KErrWouldBlock )
+	        SetConnectionProgress(ETrue);
+	    }
+	else
+	    {
+	    aStatus = EALREADY;
+	    }
+	iWriteLock.Signal();
+	}
+
+void CSocketDesc::ConnectCancel()
+	{
+	if (iSocketPtr != NULL)
+		{
+		ATOMICSOCKETOP(iSocket.CancelConnect(),NOP)
+		}
+	}
+
+void CSocketDesc::Ioctl(int aCmd, void* aParam, TRequestStatus& aStatus)
+	{
+	TInt ret = KErrNone;
+	int* param = reinterpret_cast<int*>(aParam);
+
+	ret = maybe_reopen_socket();
+	if (ret != KErrNone)
+	    {
+        Complete(aStatus, ret);
+        return;
+	    }
+
+	switch ((unsigned)aCmd)
+		{
+		case FIONREAD:
+		case E32IONREAD:
+		    {
+			ATOMICSOCKETOP( ret=iSocket.GetOpt(KSOReadBytesPending,KSOLSocket,*param), ret = KErrBadHandle )
+		    }
+			break;
+		case E32IOSELECT:
+			{
+			iIoctlBuf.Set((TText8*)aParam,4,4);
+			iIoctlLock.Wait();
+			iIoctlFlag = ETrue;		
+			ATOMICSOCKETOP(iSocket.Ioctl(KIOctlSelect,aStatus,&iIoctlBuf,KSOLSocket), Complete(aStatus,KErrBadHandle))
+			}
+			return;
+		case SIOCGIFCONF:
+			ret = GetInterfaceList(aParam);
+			break;
+		case SIOCGIFINDEX:
+			ret = GetInterfaceIndexByName(aParam);
+			break;
+		case SIOCGIFACTIVECONF:
+			ret = GetActiveInterfaceList(aParam);
+			break;
+		case SIOCSIFNAME:
+			ret = SetInterfaceByName(aParam);
+			break;
+		case SIOCIFSTART:
+			ret = StartInterface(aParam);
+			if(KErrNone == ret)
+				{
+				iSocket.Close();
+				iSocketPtr = NULL;
+				}
+			break;
+		case SIOCIFACTIVESTART:
+			ret = StartActiveInterface(aParam);
+			if(KErrNone == ret)
+				{
+				iSocket.Close();
+				iSocketPtr = NULL;
+				}
+			break;
+		case SIOCIFSTOP:
+			ret = StopInterface(aParam);
+			break;	
+		case SIOCATMARK:
+			ATOMICSOCKETOP(ret=iSocket.GetOpt(KSoTcpRcvAtMark,KSolInetTcp,*param), ret = KErrBadHandle)
+			break;	
+		case SIOCGIFADDR:
+			ret = GetIpAddress(aParam);
+			break;	
+		case SIOCGIFNUM:
+			ret = GetInterafceNumber(aParam);
+			break;	
+		case SIOCADDRT:
+			ret = RouteRequest(KSoInetAddRoute, aParam);
+			break;	
+		case SIOCDELRT:		
+			ret = RouteRequest(KSoInetDeleteRoute, aParam);
+			break;	
+		case SIOCGIFHWADDR:
+			ret = GetInterfaceHWAddress(aParam);
+		    break;
+		case SIOCGIFACTIVEIAP:
+		    ret = GetActiveInterface( aParam);
+		    break;
+		
+		default:
+			ret=KErrNotSupported;
+			break;
+		}
+	Complete(aStatus,ret);
+	}
+
+TInt CSocketDesc::IoctlCompletion(int /*aCmd*/, void* /*aParam*/, TInt aStatus)
+	{
+	if(iIoctlFlag)
+		{
+		iIoctlLock.Signal();
+		iIoctlFlag = EFalse;
+		}
+	return aStatus;
+	}
+
+void CSocketDesc::IoctlCancel()
+	{
+	if (iSocketPtr && iIoctlFlag)
+		{
+		ATOMICSOCKETOP(iSocket.CancelIoctl(), NOP)
+		iIoctlLock.Signal();
+		iIoctlFlag = EFalse;
+		}
+	}
+// -----------------------------------------------------------------------------
+// CSocketDesc::Fcntl
+// Symbian Socket Specific Implementation for fcntl
+// Implementation of fcntl for Socket will make use of  
+// RSocket::SetOpt(KSONonBlockingIO/KSOBlockingIO, KSOLSocket)
+// As of now fcntl supports F_SETFL and F_GETFL
+// -----------------------------------------------------------------------------
+//
+TInt CSocketDesc::Fcntl(TUint anArg, TUint aCmd)
+	{
+
+    TInt err = maybe_reopen_socket();
+    if (err != KErrNone)
+        return err;
+
+    return CSockDescBase::Fcntl(anArg, aCmd);
+	}
+
+TInt CSocketDesc :: GetIpAddress( void *aParam )
+	{
+	TInetAddr myAddr;
+	ATOMICSOCKETOP( iSocket.LocalName(myAddr), return KErrBadHandle )
+	TUint32 myIP = myAddr.Address();			
+	if (myIP == 0)
+		{
+		return KErrGeneral;
+		}
+
+	ifreq *ifr = (ifreq *)aParam;
+	((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr.s_addr = myIP;
+	return KErrNone;
+	}
+
+TInt CSocketDesc :: GetRemoteIpAddress( void *aParam )
+	{
+	TInetAddr remoteAddr;
+	ATOMICSOCKETOP( iSocket.RemoteName(remoteAddr), return KErrBadHandle )
+	TUint32 remoteIP = remoteAddr.Address();			
+
+	if (remoteIP == 0)
+		{
+		return KErrGeneral;
+		}
+	ifreq *ifr = (ifreq *)aParam;
+	((struct sockaddr_in *)&ifr->ifr_dstaddr)->sin_addr.s_addr = remoteIP;
+	return KErrNone;
+	}
+
+TInt CSocketDesc :: GetInterafceNumber( void *aParam )
+	{
+	TInt count = 0;	
+	TInt ret = KErrNone;
+	TRAP(ret, AccessPointCountL(count));
+	*(TInt *)aParam = count;
+	return ret;	
+	}
+
+#ifdef __SYMBIAN_COMPILE_UNUSED__
+TInt CSocketDesc :: GetInterafceParamInfo( void *aParam,TInt aType)
+	{
+	TInt ret = KErrNone;	
+	TAccessPointRecord tempRecord;
+	ifreq *ifr = (ifreq *)aParam;
+	TRAP(ret,FindConnectionInfoL(tempRecord,ifr->ifr_name));
+	if(ret != KErrNone)
+		return ret;
+	wchar_t *str = (wchar_t *)( tempRecord.iServiceType.PtrZ());	 
+	TInt servFlag = 0;
+	if(WcsCmp(str,L"LANService") == 0)
+		{
+		servFlag = 0;
+		}
+	else if(WcsCmp(str,L"OutgoingGPRS") == 0)
+		{
+		servFlag  = 1;	
+		}
+	if(aType == EACCESS_GETMETRIC)
+		{
+		ret = GetInterfaceDetails(aParam,servFlag,EACCESS_GETMETRIC);					
+		}	
+	else if(aType == EACCESS_GETMTU)
+		{
+		ret = GetInterfaceDetails(aParam,servFlag,EACCESS_GETMTU);					
+		}
+	else if(aType == EACCESS_GETNETMASK)
+		{
+		ret = GetInterfaceDetails(aParam,servFlag,EACCESS_GETNETMASK);					
+		}
+	else if(aType == EACCESS_GETBROADCAST)
+		{
+		ret = GetInterfaceDetails(aParam,servFlag,EACCESS_GETBROADCAST);					
+		}
+	else if(aType == EACCESS_GETPHYSADDR)
+		{
+		ret = GetInterfaceDetails(aParam,servFlag,EACCESS_GETPHYSADDR);					
+		}
+	else if(aType == EACCESS_GETFLAGS)
+		{
+		ret = GetInterfaceDetails(aParam,servFlag,EACCESS_GETFLAGS);					
+		}
+	return ret;	
+	}
+
+TInt CSocketDesc :: SetInterafceParamInfo( void *aParam,TInt aType)
+	{
+	TInt ret = KErrNone;	
+	TAccessPointRecord tempRecord;
+	ifreq *ifr = (ifreq *)aParam;
+	TRAP(ret,FindConnectionInfoL(tempRecord,ifr->ifr_name));
+	if(ret != KErrNone)
+		return ret;
+	wchar_t *str = (wchar_t *)(tempRecord.iServiceType.PtrZ());	 
+	TInt servFlag = 0;
+	if(WcsCmp(str,L"LANService") == 0)
+		{
+		servFlag = 0;
+		}
+	else if(WcsCmp(str,L"OutgoingGPRS") == 0)
+		{
+		servFlag  = 1;	
+		}
+	if(aType == EACCESS_SETMETRIC)
+		{
+		ret = SetInterfaceDetails(aParam,servFlag,EACCESS_SETMETRIC);					
+		}	
+	else if(aType == EACCESS_SETMTU)
+		{
+		ret = SetInterfaceDetails(aParam,servFlag,EACCESS_SETMTU);					
+		}		
+	else if(aType == EACCESS_SETFLAGS)
+		{
+		ret = SetInterfaceDetails(aParam,servFlag,EACCESS_SETFLAGS);					
+		}
+	else if(aType == EACCESS_SETPHYSADDR)
+		{
+		ret = SetInterfaceDetails(aParam,servFlag,EACCESS_SETPHYSADDR);					
+		}	
+	else if(aType == EACCESS_SETNETMASK)
+		{
+		ret = SetInterfaceDetails(aParam,servFlag,EACCESS_SETNETMASK);					
+		}	
+	else if(aType == EACCESS_SETBROADCAST)
+		{
+		ret = SetInterfaceDetails(aParam,servFlag,EACCESS_SETBROADCAST);					
+		}		
+	return ret;	
+
+	}
+
+void CSocketDesc::FindConnectionInfoL(TAccessPointRecord &aRecord,char *ptr)
+	{
+	//TAccessPointRecord tempRecord;
+	CCommsDatabase* iapDatabase;
+	CCommsDbTableView* view;
+	TInt res;	
+	TPtrC8 tptr((TText8*)ptr);
+	TBuf<KCommsDbSvrMaxColumnNameLength> temp;
+	res = CnvUtfConverter::ConvertToUnicodeFromUtf8(temp, tptr);
+	if(res < KErrNone)
+		{
+		User::Leave(res);
+		}
+	else if(res > KErrNone)
+		{
+		User::Leave(KErrOverflow);
+		}
+	// This function can leave on insufficient memory
+	OpenIapTableLC(&iapDatabase, &view);	
+	res = view->GotoFirstRecord();
+	while (res == KErrNone)
+		{    	
+		// On error continue with the next record	
+		TRAP( res,ReadRecordFromIapTableL(view, aRecord));
+		if (res == KErrNone)
+			{   
+			if(WcsCmp ((wchar_t*)aRecord.iName.PtrZ(),(wchar_t*)temp.PtrZ()) == 0)
+				break; 	
+			}    	
+		res = view->GotoNextRecord();
+		}
+	CleanupStack::PopAndDestroy();// view
+	CleanupStack::PopAndDestroy(iapDatabase);	
+	return;
+	}
+
+TInt CSocketDesc :: SetInterfaceDetails( void *aParam ,TInt aFlag, TInt aType )
+	{
+	ifreq *ifr = (ifreq *)aParam;
+	TPckgBuf<TSoInetIfQuery> ifq;
+	TBuf8 <25> ipBuf8;
+	TName aBuf;			
+	TInt ret = KErrNone;
+	ATOMICSOCKETOP( ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle )
+	if (ret != KErrNone)
+		{
+		return KErrGeneral;
+		}    	
+	TPckgBuf<TSoInet6InterfaceInfo> info;
+	TSoInet6InterfaceInfo &in = info();	
+	ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle )
+	while(ret == KErrNone)
+		{			
+		if(info().iName != _L("") && info().iName != _L("loop6") && info().iName != _L("loop4"))
+			{   			
+			TDes16& aName = info().iName;							
+			if( ((aFlag == 0 ) && ( aName.FindC(_L("WLAN")) != KErrNotFound )) ||
+					((aFlag == 1) && (aName.FindC(_L("Generic")) != KErrNotFound )) )
+				{
+				switch(aType)
+					{				
+					case  EACCESS_SETMETRIC:
+						if(info().iState == EIfUp)										 
+							{
+							info().iSpeedMetric =  ifr->ifr_metric;
+							}
+						goto setout;
+
+					case  EACCESS_SETMTU:										 
+						if(info().iState == EIfUp)
+							{
+							info().iMtu = ifr->ifr_mtu ;		
+							}		
+						goto setout;
+
+					case  EACCESS_SETNETMASK :																																																					
+						// Presently netmask address is NULL											
+						if((info().iState == EIfUp) && (ifr->ifr_addr.sa_data !=NULL))
+							{																																																		
+							/*
+							CharToTBuf8(ifr->ifr_addr.sa_data,ipBuf8);											
+											if (CnvUtfConverter::ConvertToUnicodeFromUtf8( aBuf,ipBuf8 ) == KErrNone)
+											{													
+												ret = info().iNetMask.Input(aBuf);												
+											}																							
+							info().iNetMask.SetAddress(INET_ADDR(255,255,255,0));	
+							*/
+							return KErrNotSupported;
+							}
+						break;	
+					case  EACCESS_SETBROADCAST :										
+						if((info().iState == EIfUp) && (ifr->ifr_broadaddr.sa_data !=NULL))
+							{																																																		
+							/*CharToTBuf8(ifr->ifr_broadaddr.sa_data,ipBuf8);											
+											if (CnvUtfConverter::ConvertToUnicodeFromUtf8( aBuf,ipBuf8 ) == KErrNone)
+											{													
+												ret = info().iBrdAddr.Input(aBuf);												
+											} 
+							*/												
+							return KErrNotSupported;
+							}
+
+						break;
+					case  EACCESS_SETPHYSADDR :										
+						// Currently no imeplentation is given as KIfHasHardwareAddr is always 
+						// set to 0 for wlan and GPRS
+						if(info().iFeatures&KIfHasHardwareAddr)
+							{
+							return KErrNotSupported;
+							}
+						break;									
+					case  EACCESS_SETFLAGS :										
+						info().iFeatures = 0;
+						// Interface UP
+						if((ifr->ifr_flags & IFF_UP) && (ifr->ifr_flags & IFF_DRV_RUNNING)) 
+							{
+							info().iState = EIfUp;																						
+							}																						
+						else
+							{
+							info().iState = EIfDown;																																	
+							}																																	
+
+						// Loopback										
+						if(ifr->ifr_flags & IFF_LOOPBACK)
+							{
+							info().iFeatures |= KIfIsLoopback;																				            													           
+							}																				            													           
+
+						// point to point support
+						if(ifr->ifr_flags &  IFF_POINTOPOINT)
+							{
+							info().iFeatures |= KIfIsPointToPoint; 							                
+							} 							                
+
+						// Broadcast
+						if(ifr->ifr_flags & IFF_BROADCAST)
+							{
+							info().iFeatures |=KIfCanBroadcast; 
+							} 
+
+
+						// Multicast
+						if(ifr->ifr_flagshigh & IFF_MULTICAST)
+							{
+							info().iFeatures = KIfCanMulticast;							            	      
+							}
+						//these flags details are available in symbian but not used by lib layer.
+						/* if(info().iFeatures&KIfCanSetMTU)			            	
+							               if(info().iFeatures&KIfHasHardwareAddr)    
+							               if(info().iFeatures&KIfCanSetHardwareAddr) */
+						goto setout;							            	
+
+					default:
+						break;					 
+					}
+				}
+
+			}
+		ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle )
+		}
+	setout:	
+	TPckgBuf<TSoInet6InterfaceInfo> changeToNew(info());
+	ATOMICSOCKETOP(ret = iSocket.SetOpt(KSoInetConfigInterface, KSolInetIfCtrl,changeToNew), return KErrBadHandle )
+	return ret;
+	}
+#endif // __SYMBIAN_COMPILE_UNUSED__
+
+TInt CSocketDesc::GetInterfaceDetails( void *aParam ,TInt aFlag, TInt aType )
+	{
+	TPckgBuf<TSoInetIfQuery> ifq;
+
+	TInt ret = KErrNone; 
+	ATOMICSOCKETOP( ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle )
+	if (ret != KErrNone)
+		{
+		return KErrGeneral;
+		}
+	
+	ifreq *ifr = (ifreq *)aParam;
+    *(ifr->ifr_addr.sa_data) = '\0';
+
+	TPckgBuf<TSoInetInterfaceInfo> info;
+	ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle )
+	while( ret == KErrNone)
+		{
+
+		if(info().iName != _L("") && info().iName != _L("loop6") && info().iName != _L("loop4"))
+			{   
+			TDes16& aName = info().iName;
+			TName aBuf;
+			TBuf8<KMaxName> ipAddr;
+			if( ((aFlag == 0 ) && ( aName.FindC(_L("WLAN")) != KErrNotFound )) ||
+					((aFlag == 1) && (aName.FindC(_L("Generic")) != KErrNotFound )) )
+				{
+				switch(aType)
+					{
+
+					case  EACTIVE_GETIP :
+						if((info().iState == EIfUp) && (info().iAddress.Address() != NULL))
+							{
+							if(!((info().iAddress.IsLinkLocal()) || (info().iAddress.IsSiteLocal())))
+								{
+								info().iAddress.Output(aBuf);  
+								if (CnvUtfConverter::ConvertFromUnicodeToUtf8( ipAddr, aBuf ) == KErrNone)
+									{			
+									StrlCopy(ifr->ifr_addr.sa_data,(const char *) ipAddr.PtrZ(),ipAddr.Length()+1);														
+									}  
+								}
+							}
+						break;
+					case  EACCESS_GETMETRIC:
+						ifr->ifr_metric = 0;
+						if (info().iState == EIfUp)
+							{
+							ifr->ifr_metric = info().iSpeedMetric;
+							}
+						break;
+					case  EACCESS_GETMTU:
+						ifr->ifr_mtu = 0;
+						if (info().iState == EIfUp)
+							{
+							ifr->ifr_mtu = info().iMtu;
+							}
+						break;	
+					case  EACCESS_GETNETMASK :
+						*(ifr->ifr_addr.sa_data) = '\0';
+						// Presently netmask address is NULL
+						if((info().iState == EIfUp) && (info().iNetMask.Address() != NULL))
+							{
+							//anAddr = info().iNetMask.Address();	
+							info().iNetMask.Output(aBuf);  
+							if (CnvUtfConverter::ConvertFromUnicodeToUtf8( ipAddr, aBuf ) == KErrNone)
+								{			
+								StrlCopy(ifr->ifr_addr.sa_data,(const char *) ipAddr.PtrZ(),ipAddr.Length()+1);												
+								}  											
+							}
+						break;	
+					case  EACCESS_GETBROADCAST :
+						*(ifr->ifr_broadaddr.sa_data) = '\0';
+						// Presently Breaodcast address is NULL
+						if((info().iState == EIfUp) && (info().iBrdAddr.Address() != NULL))
+							{
+
+							//anAddr = info().iBrdAddr.Address();	
+							info().iBrdAddr.Output(aBuf);  
+							if (CnvUtfConverter::ConvertFromUnicodeToUtf8( ipAddr, aBuf ) == KErrNone)
+								{			
+								StrlCopy(ifr->ifr_broadaddr.sa_data,(const char *) ipAddr.PtrZ(),ipAddr.Length()+1);												
+								}											
+							}
+						break;
+					case  EACCESS_GETPHYSADDR :
+						ifr->ifr_phys = 0;
+						// Currently no imeplentation is given as KIfHasHardwareAddr is always 
+						// set to 0 for wlan and GPRS
+						if(info().iFeatures&KIfHasHardwareAddr)
+							{
+							//nada.
+							}
+						break;									
+					case  EACCESS_GETFLAGS :
+						ifr->ifr_flags = 0;
+						ifr->ifr_flagshigh=0;
+						// Interface UP
+						if(info().iState == EIfUp)
+							{
+							ifr->ifr_flags |= IFF_UP; 
+							ifr->ifr_flags |= IFF_DRV_RUNNING;
+							}
+						// Loopback
+						if(info().iFeatures&KIfIsLoopback)
+							{
+							ifr->ifr_flags |= IFF_LOOPBACK;
+							}										            													           
+
+						// point to point support
+						if(info().iFeatures&KIfIsPointToPoint) 
+							{
+							ifr->ifr_flags |= IFF_POINTOPOINT;	
+							}
+						
+						// Broadcast
+						if(info().iFeatures&KIfCanBroadcast)
+							{
+							ifr->ifr_flags |= IFF_BROADCAST;
+							}      
+
+						// Multicast
+						if(info().iFeatures&KIfCanMulticast)
+							{
+							ifr->ifr_flagshigh |= ((IFF_MULTICAST & 0xff00) >> 8);
+							}
+						//these flags details are available in symbian but not used by lib layer.
+						/* if(info().iFeatures&KIfCanSetMTU)			            	
+							               if(info().iFeatures&KIfHasHardwareAddr)    
+							               if(info().iFeatures&KIfCanSetHardwareAddr) */
+
+						break;																 				 
+				 
+					}
+				}
+
+			}
+		ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, info), ret = KErrBadHandle )
+		}
+
+	return KErrNone;	
+	}
+
+TInt CSocketDesc::Poll(TPollMode aMode,TBool& aReadyStatus,TInt& aErrno)
+	{
+	TInt ret = maybe_reopen_socket();
+    if (ret != KErrNone)
+        {
+        return ret;
+        }
+
+    TInt status;
+    ATOMICSOCKETOP(ret = iSocket.GetOpt(KSOSelectPoll, KSOLSocket, status), ret = KErrBadHandle)
+    if (ret == KErrNone)
+		{
+    	aReadyStatus = status & aMode;	
+		}
+    
+    return MapError(ret, aErrno);
+	}
+
+/* The synchronous - non-blocking Poll */
+TInt CSocketDesc::Poll(TUint aEvents)
+	{
+
+    TInt err = maybe_reopen_socket();
+	if (err != KErrNone)
+	    return err;
+		
+	return CSockDescBase::Poll(aEvents);
+	}
+
+
+/* Cancel an outstanding notification request */
+void CSocketDesc::CancelNotify()
+	{
+	CSockDescBase::CancelNotify();
+	}
+
+TAccessPointRecord::TAccessPointRecord()
+:iId(0), 
+iName(0),
+iDialogPref(ECommDbDialogPrefDoNotPrompt),
+iDirection(ECommDbConnectionDirectionUnknown), 
+iService(0),
+iServiceType(0), // Text value
+iBearer(0),
+iBearerType(0),	// Text value
+iNetwork(0),
+iNetworkWeighting(0),
+iLocation(0)
+		{
+		}
+
+inline TInt CSocketDesc::GetInterfaceList(void *aParam)
+	{
+	return GetInterface(aParam, EACCESS_POINT);
+	}
+
+TInt CSocketDesc::GetInterfaceIndexByName(void *aParam)
+	{
+	ifreq *ifrQuery = (ifreq*)aParam;	
+	ifconf ifc;
+
+	// Know how many interfaces
+	ifc.ifc_len = 0;
+	ifc.ifc_buf = NULL;
+	TInt ret = GetInterface(&ifc, EACCESS_POINT);
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+
+	// Allocate the memory to get the detail interface information
+	ifc.ifc_buf = (caddr_t)Backend()->Alloc( ifc.ifc_len);
+	if (ifc.ifc_buf == NULL)
+		{
+		return KErrNoMemory;
+		}
+	ret = GetInterface(&ifc, EACCESS_POINT);
+	if (ret != KErrNone)
+		{
+		Backend()->Free(ifc.ifc_buf);
+		return ret;
+		}
+	ifreq *ifr = ifc.ifc_req;
+	TInt ifCount = ifc.ifc_len / sizeof(ifreq);
+	TInt i = 0;
+
+	// We wouldn't need this if we were using a StrNcmp below
+	ifrQuery->ifr_name[IFNAMSIZ-1] = 0; // don't assume NULL terminated input
+	// Search for the interface name
+	for (; i < ifCount; i++, ifr++)
+		{
+		if ( StrCmp(ifrQuery->ifr_name, ifr->ifr_name) == 0)
+			{
+			ifrQuery->ifr_index = ifr->ifr_index;
+			break;
+			}
+		}
+
+	if (i == ifCount)
+		{
+		ret = KErrNotFound;
+		}
+	Backend()->Free(ifc.ifc_buf);
+	return ret;
+	}
+
+inline TInt CSocketDesc::GetActiveInterfaceList(void *aParam)
+	{
+	return GetInterface(aParam, EACTIVE_CONNECTION);
+	}
+
+TInt CSocketDesc::GetInterface(void *aParam, TInt aType)
+	{
+	TInt ret = KErrNone;
+	ifconf *ifc = (ifconf*)aParam;	
+	TInt length = (ifc->ifc_len) / sizeof(ifreq);
+	TInt count = 0;
+	// If the length is zero, fill the number of interface information
+	if ( length <= 0 || ifc->ifc_buf == NULL )
+		{
+		if (aType == EACCESS_POINT)
+			{
+			TRAP(ret, AccessPointCountL(count));
+			}
+		else if (aType == EACTIVE_CONNECTION)
+			{
+			ret = ActiveConnectionCount(count);
+			}
+		else
+			{
+			ret = KErrArgument;
+			}
+
+		if (ret == KErrNone)
+		    {
+            ifc->ifc_len = sizeof(ifreq) * count;
+		    }
+		return ret;
+		}
+
+	// length is not 0, read 'length' number of records
+	CArrayFixFlat<TAccessPointRecord> *apArray;
+	wchar_t *str;
+	TInt apIndex;
+	TInt result = KErrNone;
+	ifreq *ifr = ifc->ifc_req;
+	TInt ActiveSet = 0;
+
+	// Fixed array of 'length'
+	apArray = new CArrayFixFlat<TAccessPointRecord>(length);
+	if (apArray == NULL)
+		{
+		return KErrNoMemory;
+		}
+	if (aType == EACCESS_POINT)
+		{
+		// On return length would contain the number of access points.
+		TRAP(result, AccessPointListL(apArray, length));
+		}
+	else if (aType == EACTIVE_CONNECTION)
+		{
+		TRAP(ret, ret=ActiveConnectionListL(apArray, length));
+		if( ret == KErrNone )
+			{
+			TRAP(ret,FindConnectionDetailsL(apArray, length));
+			ActiveSet = 1;  	
+			}
+		}
+	if (ret != KErrNone)
+		{
+		delete apArray;
+		return ret;
+		}
+	for (apIndex = 0; apIndex < length; apIndex++,ifr++)
+		{
+		TAccessPointRecord& ref = (*apArray)[apIndex];
+		ifr->ifr_name[IFNAMSIZ-1] = 0; // don't assume NULL terminated input
+		TPtr8 ptr((TText8*)ifr->ifr_name, IFNAMSIZ);
+
+		ret = CnvUtfConverter::ConvertFromUnicodeToUtf8(ptr, ref.iName);
+		if(ret == KErrNone)
+			{
+			if(ptr.Length() < ptr.MaxLength())
+				{
+				ptr.ZeroTerminate();
+				} 
+			else
+				{
+				return KErrOverflow;
+				} 
+			}
+		else if (ret > KErrNone)
+			{
+			return KErrOverflow;
+			} 
+		else
+			{
+			return ret;
+			}
+
+		// Copy theinterface index
+		ifr->ifr_index = ref.iId;
+		if(ActiveSet == 1)
+			{
+			str = (wchar_t *)(ref.iServiceType.PtrZ() ); 
+			TInt servFlag = 0;
+			if(WcsCmp(str,L"LANService") == 0)
+				{
+				servFlag = 0;
+				}
+			else if(WcsCmp(str,L"OutgoingGPRS") == 0)
+				{
+				servFlag  = 1;	
+				}
+			GetInterfaceDetails(ifr,servFlag,EACTIVE_GETIP);
+			}
+		}
+	ifc->ifc_len = sizeof(ifreq) * apIndex;
+	delete apArray;	
+	return KErrNone;
+	}
+
+TInt CSocketDesc::SetInterfaceByName(void *aParam)
+	{
+	ifreq *ifr = (ifreq *)aParam;
+	if (!ifr)
+		{
+		return KErrArgument;
+		}
+
+	ifr->ifr_name[IFNAMSIZ-1] = 0; // don't assume NULL terminated input
+	TPtrC8 ptr((TText8*)ifr->ifr_name);
+	TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(iConnPref.iName,ptr);
+	if(ret > KErrNone )
+		{
+		return KErrOverflow;
+		}
+	return ret; 
+	}
+
+inline TInt CSocketDesc::StartInterface(void *aParam)
+	{
+	return StartConnection(aParam);	
+	}
+
+inline TInt CSocketDesc::StartActiveInterface(void *aParam)
+	{
+	return StartSubConnection(aParam);	
+	}
+
+TInt CSocketDesc::StopInterface(void *)
+	{
+	if (iConnectionPtr != NULL)
+		{
+		StopConnection();
+		return KErrNone;
+		}
+	else if (iSubConnectionPtr != NULL)
+		{
+		StopSubConnection();
+		return KErrNone;
+		}	
+	return KErrNotFound;
+	}
+
+TInt CSocketDesc::OpenUsingPreference()
+	{
+	TInt ret = 0;	
+    // Update when supporting INET6
+    TInt addrfamily = (iAddrFamily == AF_INET6 ? KAfInet : iAddrFamily);	
+	if (iConnectionPtr != NULL) // iConnection initialized
+		{
+		ret = iSocket.Open(*iSockServPtr,addrfamily,iStyle,iProtocol,iConnection);
+		}
+	else if (iSubConnectionPtr != NULL) // iSubConnection initialized
+		{
+		ret = iSocket.Open(*iSockServPtr,addrfamily,iStyle,iProtocol,iSubConnection);
+		}
+	else
+	    {
+	    RConnection& defConnection = Backend()->GetDefaultConnection();
+	    //Now check if the default connection is intialized. This is given lesser 
+	     //priority than the socket specific preferences checked above.
+	     if(defConnection.SubSessionHandle() != 0)
+	         {
+	         ret = iSocket.Open(*iSockServPtr,addrfamily,iStyle,iProtocol,defConnection);	         
+	         if (!ret)
+	             {
+	             Backend()->AddSocket(this);
+	             }
+	         }
+	     else // No connection preference is set
+	         {
+	         ret = ECONNABORTED;
+            }
+        }
+    
+    if (ret == KErrNone)
+        {
+        __e32_atomic_store_rel32(&iSocketPtr, (unsigned long)&iSocket);
+        }
+    
+    iConnectInProgress = EFalse;
+
+    return ret;
+    }
+
+void CSocketDesc::TempClose()
+    {
+    TUint32 ret = __e32_atomic_ior_ord32((void *)&iCount,0x8000);
+    if( ret >= 0x8000 )
+        {
+        // This indicates a TempClose has already been done from one of the threads
+        return;
+        }
+    // loop and yeild till no more references are held to the iSocket
+    while( iCount != 0x8000 )
+        {
+        // Yeild for 1 ms
+        User::After(1000);
+        }
+    if (iSocket.SubSessionHandle() != 0)
+        {
+	    iSocketPtr = NULL;
+        iSocket.CancelAll();    
+        TRequestStatus status;
+        iSocket.Shutdown(RSocket::EImmediate, status);
+        User::WaitForRequest(status);
+        iSocket.Close();
+        }
+    }
+
+void CSocketDesc::AccessPointListL(CArrayFixFlat<TAccessPointRecord> *&aRecordPtr,
+		TInt &aCount)
+	{
+	TAccessPointRecord tempRecord;
+	CCommsDatabase* iapDatabase;
+	CCommsDbTableView* view;
+
+	// This function can leave on insufficient memory
+	OpenIapTableLC(&iapDatabase, &view);
+	TInt count = 0;
+	TInt ret = view->GotoFirstRecord();
+    while (ret == KErrNone && count < aCount)
+		{
+    	TRAP(ret, ReadRecordFromIapTableL(view, tempRecord));
+    	if (ret == KErrNone)
+			{
+			aRecordPtr->AppendL(tempRecord);
+			count++;
+			}	
+    	ret = view->GotoNextRecord();
+		}
+    
+	CleanupStack::PopAndDestroy();// view
+	CleanupStack::PopAndDestroy(iapDatabase);
+	aCount = aRecordPtr->Count();
+	}
+
+void CSocketDesc::FindConnectionDetailsL(CArrayFixFlat<TAccessPointRecord> *&aRecordPtr,
+		TInt &aCount)
+	{
+	TAccessPointRecord tempRecord;
+	CCommsDatabase* iapDatabase;
+	CCommsDbTableView* view;
+
+	// This function can leave on insufficient memory
+	OpenIapTableLC(&iapDatabase, &view);
+	TInt count = 0;
+	TInt ret = view->GotoFirstRecord();
+    while (ret == KErrNone && count < aCount)
+		{
+    	TRAP(ret, ReadRecordFromIapTableL(view, tempRecord));
+    	if (ret == KErrNone)
+			{    		
+			if((*aRecordPtr)[count].iId == tempRecord.iId )    			
+				{    			    		
+				(*aRecordPtr)[count].iServiceType = tempRecord.iServiceType;
+				ret = view->GotoFirstRecord();
+				count++;    		
+				continue;
+				}    		
+    		ret = view->GotoNextRecord();
+			}
+		}
+    
+	CleanupStack::PopAndDestroy();// view
+	CleanupStack::PopAndDestroy(iapDatabase);
+	aCount = aRecordPtr->Count();
+		}
+
+void CSocketDesc::AccessPointCountL(TInt &aCount)
+	{
+	CCommsDatabase* iapDatabase;
+	CCommsDbTableView* view;
+
+	OpenIapTableLC(&iapDatabase, &view);
+	aCount = 0;
+	TInt ret = view->GotoFirstRecord();
+	while(ret == KErrNone)
+		{
+		aCount++;
+		ret = view->GotoNextRecord();
+		}
+	CleanupStack::PopAndDestroy();// view
+	CleanupStack::PopAndDestroy(iapDatabase);
+	}
+
+void CSocketDesc::ReadRecordFromIapTableL(CCommsDbTableView* aView, TAccessPointRecord &aRecord)
+	{
+	aView->ReadUintL(TPtrC(COMMDB_ID), aRecord.iId);
+	aView->ReadTextL(TPtrC(COMMDB_NAME), aRecord.iName); 
+	aRecord.iDialogPref = ECommDbDialogPrefDoNotPrompt;
+	aView->ReadUintL(TPtrC(IAP_SERVICE), aRecord.iService);
+	aView->ReadTextL(TPtrC(IAP_SERVICE_TYPE), aRecord.iServiceType);
+	aView->ReadUintL(TPtrC(IAP_BEARER), aRecord.iBearer);
+	/*
+	 * IAP_BEARER_TYPE is not a column of IAP table even though its 
+	 * listed in header. So not trying to read it.
+	 */
+	aView->ReadUintL(TPtrC(IAP_NETWORK), aRecord.iNetwork);
+	aView->ReadUintL(TPtrC(IAP_NETWORK_WEIGHTING), aRecord.iNetworkWeighting);
+	aView->ReadUintL(TPtrC(IAP_LOCATION), aRecord.iLocation);
+	}
+
+void CSocketDesc::OpenIapTableLC(CCommsDatabase **aIapDatabase, CCommsDbTableView **aView)
+	{
+	// Get IAP names and ids from the database
+	*aIapDatabase = CCommsDatabase::NewL(EDatabaseTypeIAP);
+	CleanupStack::PushL(*aIapDatabase);
+
+	(*aIapDatabase)->ShowHiddenRecords();
+
+	// This is LC code, that means code has pushed, but not popped
+	(*aView) = (*aIapDatabase)->OpenTableLC(TPtrC(IAP));
+	}
+
+inline TInt CSocketDesc::ActiveConnectionCount(TInt &aCount)
+	{
+	aCount = ((CFileTable*)iFids)->RConnectionCount();
+	return KErrNone;
+	}
+
+TInt CSocketDesc::ActiveConnectionListL(CArrayFixFlat<TAccessPointRecord> *aRecordPtr, TInt &aLength)
+	{
+	TInt rcIndex;
+	RConnection *rc;
+	TAccessPointRecord tempRecord;
+
+	for (rcIndex = 0;rcIndex < aLength; rcIndex++)
+		{
+		if  ( ((CFileTable*)iFids)->RConnectionAt(rcIndex, rc) != KErrNone )
+			{
+			break;
+			}
+		// Read index and name of the connection
+		if  ( GetRConnectionDetails(rc, tempRecord) != KErrNone )
+			{
+			break;
+			}
+		aRecordPtr->AppendL(tempRecord);
+		}
+	aLength = aRecordPtr->Count();
+	return KErrNone;
+	}
+
+TInt CSocketDesc::GetRConnectionDetails(RConnection *aRc, TAccessPointRecord &aApr)
+	{
+	_LIT(KName, "IAP\\Name");
+	_LIT(KId, "IAP\\Id");
+
+	TInt ret = aRc->GetDesSetting(KName, aApr.iName);
+	if (ret == KErrNone)
+		{
+		ret = aRc->GetIntSetting(KId, aApr.iId);
+		}
+	
+		return ret;
+		}
+
+TInt CSocketDesc::StartConnection(void * /* ptr */)
+	{
+	if (iConnectionPtr != NULL)
+		{
+		return KErrAlreadyExists;
+		}
+	TCommDbConnPref connPref;
+	TInt ret = GetConnectionPreference(connPref);
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+	ret = iConnection.Open(*iSockServPtr);
+	if (ret != KErrNone)
+		{
+		return ret;
+		}	
+	ret = iConnection.Start(connPref);
+	if (ret != KErrNone)
+		{
+		iConnection.Close();
+		return ret;
+		}
+	iConnectionPtr = &iConnection;
+	ret = ((CFileTable*)iFids)->AddRConnectionPtr(iConnectionPtr, iRConnectionIndex);
+	if (ret != KErrNone)
+		{
+		iConnection.Close();
+		iConnectionPtr = NULL;
+		}
+	return ret;
+	}
+
+TInt CSocketDesc::GetConnectionPreference(TCommDbConnPref &aCommPref)
+	{
+	if (iConnPref.iName.Length() == 0)
+		{
+		return KErrArgument;
+		}
+	
+	TAccessPointRecord apr;	
+	TInt ret;
+
+	// Connection preference is set
+		TRAP(ret, GetIapDetailsByNameL(iConnPref.iName, apr));
+
+	if (ret == KErrNone)
+		{
+		aCommPref.SetIapId(apr.iId);
+		aCommPref.SetNetId(apr.iNetwork);
+		aCommPref.SetBearerSet(apr.iBearer);		
+		aCommPref.SetDialogPreference((TCommDbDialogPref)apr.iDialogPref);
+		aCommPref.SetDirection((TCommDbConnectionDirection)apr.iDirection);
+		}
+	return ret;	
+	}
+
+void CSocketDesc::GetIapDetailsByNameL(
+		TBuf<KCommsDbSvrMaxColumnNameLength> aIapName, 
+		TAccessPointRecord &aRecord)
+	{
+	TAccessPointRecord tempRecord;
+	CCommsDatabase* iapDatabase;
+	CCommsDbTableView* view;
+	TInt ret = KErrNotFound;
+
+	OpenIapTableLC(&iapDatabase, &view);
+	ret = view->GotoFirstRecord();
+	while (ret == KErrNone)
+		{
+		TRAP(ret, ReadRecordFromIapTableL(view, tempRecord));
+		if (ret == KErrNone)
+			{
+			if (aIapName == tempRecord.iName)
+				{
+				aRecord = tempRecord;
+				ret = KErrNone;
+				break;
+				}
+			}    	
+		ret = view->GotoNextRecord();
+		}
+	CleanupStack::PopAndDestroy();// view
+	CleanupStack::PopAndDestroy(iapDatabase);
+
+	if (ret != KErrNone)
+		{
+		User::Leave(KErrNotFound);
+		}
+	}
+
+void CSocketDesc::StopConnection()
+	{
+	iConnection.Close();
+	iConnectionPtr = NULL;
+	((CFileTable*)iFids)->RemoveRConnectionPtrAt(iRConnectionIndex);
+	iRConnectionIndex = -1;
+	}
+
+void CSocketDesc::StopSubConnection()
+	{
+	iSubConnection.Close();
+	iSubConnectionPtr = NULL;
+	}
+
+TInt CSocketDesc::StartSubConnection(void *)
+	{
+	if (iSubConnectionPtr != NULL)
+		{
+		return KErrAlreadyExists;
+		}
+
+	TInt ret = KErrArgument;
+	TInt rcIndex = 0;
+	RConnection *rc;
+	TAccessPointRecord record;	
+	do
+		{
+		if (((CFileTable*)iFids)->RConnectionAt(rcIndex, rc) != KErrNone)
+			{
+			break;
+			}
+
+		// Read index and name of the connection
+		GetRConnectionDetails(rc, record);
+		if (record.iName == iConnPref.iName)
+			{
+			ret = KErrNone; // RConnection found
+			break;
+			}
+		rcIndex++;	
+		}
+	while (ETrue); //Loop over all active connections
+
+	if (ret == KErrNone)
+		{
+		ret = iSubConnection.Open(*iSockServPtr, RSubConnection::EAttachToDefault, *rc);
+		if (ret == KErrNone)
+			{
+			iSubConnectionPtr = &iSubConnection;
+			}
+		}
+
+	return ret;
+	}
+
+inline void CSocketDesc::SetFids(void *aFids)
+	{
+	iFids = aFids;
+	}
+
+//Add an entry in the interface routing table	
+TInt CSocketDesc::RouteRequest(TInt aReq, void *aParam)
+	{
+	struct rtentry* rt=reinterpret_cast<struct rtentry*>(aParam);
+
+	if (!rt)
+		{
+		return KErrArgument;	
+		}
+
+	TInt ret;
+	TPckgBuf<TSoInetRouteInfo>iroute;	
+	iroute().iType=ERtNormal;
+	iroute().iState=ERtReady; 
+	iroute().iMetric=rt->rt_metric;
+	if (rt->rt_dev)
+		{
+		TPckgBuf<TSoInetInterfaceInfo> iface;		
+		TFileName name;
+		name.Copy(TPtrC8((TText8*)rt->rt_dev));
+
+		if((ret=GetInterfaceByName(name, iface)) != KErrNone)
+			return ret;
+
+		Copy(iroute().iIfAddr, iface().iAddress);
+		ConvertRtEntry(iroute(), rt);
+
+		//add the entry
+		ATOMICSOCKETOP( ret = iSocket.SetOpt(aReq, KSolInetRtCtrl, iroute),return KErrBadHandle )
+		return ret;
+		}
+
+	return KErrUnknown;				
+	}
+
+
+TInt CSocketDesc::Copy(TInetAddr& aDest, TInetAddr& aSrc)
+	{
+	if (aSrc.IsV4Mapped() || aSrc.IsV4Compat())
+		{
+		aSrc.ConvertToV4();
+		}
+
+	aDest.SetAddress(aSrc.Address());
+	aDest.SetFamily(aSrc.Family());
+	aDest.SetPort(aSrc.Port());
+
+	return KErrNone;
+	}
+
+TInt CSocketDesc::ConvertSockAddr(TInetAddr& aInetAddr, struct sockaddr_in *aSockAddr)
+	{
+	if (aSockAddr == NULL)
+		{
+		return KErrArgument;
+		}
+
+		//convert the address and port from network to host byte order...
+		aInetAddr.SetAddress(ByteOrder::Swap32(aSockAddr->sin_addr.s_addr));
+		aInetAddr.SetFamily(aSockAddr->sin_family);
+		aInetAddr.SetPort(ByteOrder::Swap16(aSockAddr->sin_port));
+	return KErrNone;	
+	}
+
+TInt CSocketDesc::ConvertRtEntry(TSoInetRouteInfo& aRouteInfo, struct rtentry *aRouteEntry)
+	{
+	if(aRouteEntry == NULL)	
+		{
+		return KErrArgument;
+		}
+
+		ConvertSockAddr(aRouteInfo.iDstAddr, (struct sockaddr_in *)&aRouteEntry->rt_dst);
+		ConvertSockAddr(aRouteInfo.iNetMask, (struct sockaddr_in *)&aRouteEntry->rt_genmask);
+		ConvertSockAddr(aRouteInfo.iGateway, (struct sockaddr_in *)&aRouteEntry->rt_gateway);			
+	return KErrNone;	
+	}
+
+TInt CSocketDesc::GetInterfaceByName(const TDesC& aIfName, TPckgBuf<TSoInetInterfaceInfo>& aIface)
+	{
+	TInt ret = KErrNone;
+	ATOMICSOCKETOP(ret = iSocket.SetOpt(KSoInetEnumInterfaces, KSolInetIfCtrl), ret = KErrBadHandle)
+	if (ret != KErrNone)
+		{
+		return ret;
+		}
+	TPckgBuf<TSoInetInterfaceInfo> iface;
+	ATOMICSOCKETOP(ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle)
+	while(ret == KErrNone)
+		{
+		if (!iface().iAddress.IsUnspecified() && iface().iName.CompareF(aIfName) == 0)
+			{
+			aIface = iface;
+			return ret;    	        
+			}
+		ATOMICSOCKETOP( ret = iSocket.GetOpt(KSoInetNextInterface, KSolInetIfCtrl, iface), ret = KErrBadHandle )
+		}   	
+	return KErrUnknown;	
+	}
+
+TInt CSocketDesc::GetInterfaceHWAddress(void *aParam)
+	{
+	ifreq *ifr = reinterpret_cast<ifreq *>(aParam);
+
+	if (!ifr)
+		{
+		return KErrArgument;	
+		}
+
+	if (ifr->ifr_name[0] != '\0')
+		{
+        TPckgBuf<TSoInetInterfaceInfo> iface;
+        TFileName name;
+        ifr->ifr_name[IFNAMSIZ-1] = 0; // don't assume NULL terminated input
+        name.Copy(TPtrC8((TText8*)ifr->ifr_name));
+    
+        TInt ret = GetInterfaceByName(name, iface); 		
+        if (ret != KErrNone)
+            return ret;
+    
+        if (iface().iHwAddr.Length() > sizeof(SSockAddr))		
+            {
+            Mem::Copy(&(ifr->ifr_hwaddr.sa_data[0]),&(iface().iHwAddr[sizeof(SSockAddr)]), 6);
+            ifr->ifr_hwaddr.sa_family = (TUint16)iface().iHwAddr.Family();
+            ifr->ifr_hwaddr.sa_port = ByteOrder::Swap16(iface().iHwAddr.Port());				
+            return ret;
+            }
+		}
+
+	return KErrUnknown;
+	}
+
+//This function retrieves the Currently active IAP ID using the RSocket Query.
+//First get the interface index of the active connection using KSoInterfaceIndex
+//Then with the help of the interface index, fetch the TSoInetIfQuery, under which iZone
+//will contain the snap id. User is supposed to call if_indextoname() api to get the IAP name
+//from the ID retured with this Ioctl implementation.
+TInt CSocketDesc::GetActiveInterface( void *aParam)
+    {
+    TInt ifindex = -1;
+    TInt ret = KErrNone;
+    ATOMICSOCKETOP(ret = iSocket.GetOpt(KSoInterfaceIndex, KSolInetIp , ifindex), ret = KErrBadHandle)
+    if(ret!=KErrNone)
+        {
+        return ret;
+        }   
+    TPckgBuf<TSoInetIfQuery> opt;
+    opt().iIndex = ifindex;
+    ATOMICSOCKETOP(ret = iSocket.GetOpt(KSoInetIfQueryByIndex, KSolInetIfQuery, opt), ret = KErrBadHandle)
+    if(ret!=KErrNone)
+        {
+        return ret;
+        }
+    ifreq *ifr = (ifreq * )aParam;
+    ifr->ifr_index  = opt().iZone[1]; //IAP_ID
+    return KErrNone;
+    }