Go to the documentation of this file.00001
00025 #include "stdint.h"
00026
00027 #if defined(_USE_WIN_API)
00028 #include <winsock2.h>
00029 #pragma comment(lib, "ws2_32.lib")
00030 #elif defined(_USE_LINUX_API)
00031 #include <arpa/inet.h>
00032 #include <errno.h>
00033 #include <ifaddrs.h>
00034 #include <sys/socket.h>
00035 #include <unistd.h>
00036 #else
00037 #include "dn_additional.h"
00038 #endif
00039
00040 #include "dn_common.h"
00041 #include "dn_device.h"
00042 #include "dn_socket.h"
00043
00044 int socket_counter;
00045
00046 #if defined(_USE_WIN_API)
00047 static int _socket_close(int sock)
00048 {
00049 shutdown(sock, SD_BOTH);
00050 return closesocket(sock);
00051 }
00052
00053 static HRESULT _socket_bind(const struct CONN_PARAM_ETH *param, int *sock)
00054 {
00055 int i, ret;
00056 HRESULT hr;
00057 DWORD d;
00058 char buffer[1024];
00059 SOCKET_ADDRESS_LIST *addressList = (SOCKET_ADDRESS_LIST *)buffer;
00060
00061
00062 if(WSAIoctl(*sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, buffer, 1024, &d, NULL, NULL) != 0) {
00063 ret = DNGetLastError();
00064 return OSERR2HRESULT(ret);
00065 }
00066
00067
00068 if(param->src_addr == htonl(INADDR_LOOPBACK)) {
00069 hr = S_OK;
00070 } else {
00071 hr = E_FAIL;
00072 for(i = 0; i < addressList->iAddressCount; i++) {
00073 if(param->src_addr == ((SOCKADDR_IN *)addressList->Address[i].lpSockaddr)->sin_addr.s_addr) {
00074 hr = S_OK;
00075 break;
00076 }
00077 }
00078 }
00079
00080 return hr;
00081 }
00082 #elif defined(_USE_LINUX_API)
00083 static int _socket_close(int sock)
00084 {
00085 shutdown(sock, SHUT_RDWR);
00086 return close(sock);
00087 }
00088
00089 static HRESULT _socket_bind(const struct CONN_PARAM_ETH *param, int *sock)
00090 {
00091 int ret;
00092 HRESULT hr;
00093 struct ifaddrs *ifaddr, *ifa;
00094
00095
00096 if(getifaddrs(&ifaddr) == -1) {
00097 ret = DNGetLastError();
00098 return OSERR2HRESULT(ret);
00099 }
00100
00101
00102 hr = E_FAIL;
00103 for(ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
00104 if((ifa->ifa_addr == NULL) || (ifa->ifa_addr->sa_family != AF_INET)) {
00105 continue;
00106 }
00107
00108 if(param->src_addr == (((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr)) {
00109 hr = S_OK;
00110 break;
00111 }
00112 }
00113
00114 freeifaddrs(ifaddr);
00115
00116 return hr;
00117 }
00118 #endif
00119
00128 HRESULT
00129 socket_open(int type, int *sock)
00130 {
00131 int ret;
00132
00133 if ((type != SOCK_STREAM) && (type != SOCK_DGRAM))
00134 return E_INVALIDARG;
00135
00136 if (sock == NULL)
00137 return E_INVALIDARG;
00138
00139 #if defined(_USE_WIN_API)
00140 if(socket_counter == 0) {
00141 WSADATA wsaData;
00142
00143 ret = WSAStartup(MAKEWORD(2, 0), &wsaData);
00144 if(ret != 0) {
00145 ret = DNGetLastError();
00146 return OSERR2HRESULT(ret);
00147 }
00148
00149 if(MAKEWORD(2, 0) != wsaData.wVersion) {
00150 WSACleanup();
00151 return E_UNEXPECTED;
00152 }
00153 }
00154 #endif
00155
00156 *sock = socket(AF_INET, type, 0);
00157 if (*sock < 0) {
00158 *sock = 0;
00159 ret = DNGetLastError();
00160 return OSERR2HRESULT(ret);
00161 }
00162
00163 socket_counter++;
00164
00165 return S_OK;
00166 }
00167
00175 HRESULT
00176 socket_close(int *sock)
00177 {
00178 int ret;
00179
00180 if (sock == NULL || *sock <= 0)
00181 return E_HANDLE;
00182
00183 ret = _socket_close(*sock);
00184 if (ret != 0) {
00185 ret = DNGetLastError();
00186 return OSERR2HRESULT(ret);
00187 }
00188
00189 #if defined(_USE_WIN_API)
00190 if(socket_counter == 1) {
00191 WSACleanup();
00192 }
00193 #endif
00194
00195 *sock = 0;
00196
00197 if (socket_counter > 0) {
00198 socket_counter--;
00199 }
00200
00201 return S_OK;
00202 }
00203
00210 HRESULT
00211 socket_bind(const struct CONN_PARAM_ETH *param, int *sock)
00212 {
00213 int ret;
00214 struct sockaddr_in sockaddr =
00215 { AF_INET, };
00216 HRESULT hr = S_OK;
00217
00218 if ((param == NULL) || (sock == NULL))
00219 return E_INVALIDARG;
00220
00221 sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
00222 sockaddr.sin_port = param->src_port;
00223
00224 if ((param->src_addr != htonl(INADDR_ANY))
00225 && (param->src_addr != htonl(INADDR_NONE)))
00226 {
00227 hr = _socket_bind(param, sock);
00228 if (FAILED(hr)) {
00229 return hr;
00230 }
00231
00232 sockaddr.sin_addr.s_addr = param->src_addr;
00233 }
00234
00235 if ((sockaddr.sin_addr.s_addr != htonl(INADDR_ANY))
00236 || (sockaddr.sin_port != 0))
00237 {
00238 ret = bind(*sock, (struct sockaddr *) &sockaddr, sizeof(sockaddr));
00239 if (ret < 0) {
00240 ret = DNGetLastError();
00241 return OSERR2HRESULT(ret);
00242 }
00243 }
00244
00245 return hr;
00246 }
00247
00254 HRESULT
00255 socket_set_timeout(int sock, uint32_t timeout)
00256 {
00257 int ret;
00258 struct timeval tv;
00259
00260 if (sock <= 0)
00261 return E_HANDLE;
00262
00263 tv.tv_sec = timeout / 1000;
00264 tv.tv_usec = (timeout % 1000) * 1000;
00265
00266 ret = setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, sizeof(tv));
00267 if (ret < 0) {
00268 ret = DNGetLastError();
00269 return OSERR2HRESULT(ret);
00270 }
00271
00272 ret = setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(tv));
00273 if (ret < 0) {
00274 ret = DNGetLastError();
00275 return OSERR2HRESULT(ret);
00276 }
00277
00278 return S_OK;
00279 }