00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "transport.h"
00024 #include "comm.h"
00025
00026 #ifndef WIN32
00027 #ifdef HAVE_SOCKADDR_DL_STRUCT
00028 # include <net/if_dl.h>
00029 #endif
00030 #ifdef AF_UNIX
00031 #include <sys/un.h>
00032 #endif
00033 #endif
00034
00035 #ifdef HAVE_LIBSCTP
00036 #include <netinet/sctp.h>
00037 #endif
00038
00045 int sockaddr_get_nms_addr(const struct sockaddr *sockaddr, nms_addr * retaddr)
00046 {
00047 if (!sockaddr || !retaddr)
00048 return 1;
00049
00050 retaddr->family = sockaddr->sa_family;
00051 switch (sockaddr->sa_family) {
00052 case AF_INET:
00053 memcpy(&retaddr->addr.in,
00054 &((struct sockaddr_in *) sockaddr)->sin_addr,
00055 sizeof(struct in_addr));
00056 return 0;
00057 break;
00058 #ifdef IPV6
00059 case AF_INET6:
00060 memcpy(&retaddr->addr.in6,
00061 &((struct sockaddr_in6 *) sockaddr)->sin6_addr,
00062 sizeof(struct in6_addr));
00063 return 0;
00064 break;
00065 #endif
00066 default:
00067 retaddr->family = AF_UNSPEC;
00068 break;
00069 }
00070
00071 return 1;
00072 }
00073
00074 static int sock_cmp_addr(const struct sockaddr *sa1, const struct sockaddr *sa2)
00075 {
00076 if (sa1->sa_family != sa2->sa_family)
00077 return -1;
00078
00079 switch (sa1->sa_family) {
00080 case AF_INET:
00081 return (memcmp
00082 (&((struct sockaddr_in *) sa1)->sin_addr,
00083 &((struct sockaddr_in *) sa2)->sin_addr,
00084 sizeof(struct in_addr)));
00085 break;
00086
00087 #ifdef IPV6
00088 case AF_INET6:
00089 return (memcmp
00090 (&((struct sockaddr_in6 *) sa1)->sin6_addr,
00091 &((struct sockaddr_in6 *) sa2)->sin6_addr,
00092 sizeof(struct in6_addr)));
00093 break;
00094 #endif
00095
00096 #if !defined(WIN32) && defined(AF_UNIX)
00097 case AF_UNIX:
00098 return (strcmp
00099 (((struct sockaddr_un *) sa1)->sun_path,
00100 ((struct sockaddr_un *) sa2)->sun_path));
00101 break;
00102 #endif
00103
00104 #ifdef HAVE_SOCKADDR_DL_STRUCT
00105 case AF_LINK:
00106 return -1;
00107 break;
00108 #endif
00109 default:
00110 return -1;
00111 break;
00112 }
00113
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 static int sock_cmp_port(const struct sockaddr *sa1, const struct sockaddr *sa2)
00123 {
00124 if (sa1->sa_family != sa2->sa_family)
00125 return -1;
00126
00127 switch (sa1->sa_family) {
00128 case AF_INET:
00129 return !(((struct sockaddr_in *) sa1)->sin_port ==
00130 ((struct sockaddr_in *) sa2)->sin_port);
00131 break;
00132
00133 #ifdef IPV6
00134 case AF_INET6:
00135 return !(((struct sockaddr_in6 *) sa1)->sin6_port ==
00136 ((struct sockaddr_in6 *) sa2)->sin6_port);
00137 break;
00138 #endif
00139 default:
00140 return -1;
00141 break;
00142
00143 }
00144
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 int sockaddr_cmp(struct sockaddr *addr1, socklen_t addr1_len, struct sockaddr *addr2, socklen_t addr2_len)
00157 {
00158 if (addr1_len != addr2_len)
00159 return WSOCK_ERRSIZE;
00160 if (addr1->sa_family != addr1->sa_family)
00161 return WSOCK_ERRFAMILY;
00162 if (sock_cmp_addr(addr1, addr2 ))
00163 return WSOCK_ERRADDR;
00164 if (sock_cmp_port(addr1, addr2 ))
00165 return WSOCK_ERRPORT;
00166
00167 return 0;
00168 }
00169
00173 char *nms_addr_ntop(const nms_addr * addr, char *str, size_t len)
00174 {
00175 switch (addr->family) {
00176 case AF_INET:
00177 if (inet_ntop(AF_INET, &addr->addr.in, str, len) == NULL)
00178 return (NULL);
00179 return (str);
00180 break;
00181 #ifdef IPV6
00182 case AF_INET6:
00183 if (inet_ntop(AF_INET6, &addr->addr.in6, str, len) == NULL)
00184 return (NULL);
00185 return (str);
00186 break;
00187 #endif
00188
00189 #if 0 // not yet supported by nms_addr
00190 #ifdef AF_UNIX
00191 case AF_UNIX:
00192
00193
00194 if (addr->addr.un_path[0] == 0)
00195 strcpy(str, "(no pathname bound)");
00196 else
00197 snprintf(str, len, "%s", addr->addr.un_path);
00198 return (str);
00199 #endif
00200
00201 #ifdef HAVE_SOCKADDR_DL_STRUCT
00202 case AF_LINK:
00203 if (addr->addr.dl_nlen > 0)
00204 snprintf(str, len, "%*s", addr->addr.dl_nlen,
00205 &addr->addr.dl_data[0]);
00206 else
00207 snprintf(str, len, "AF_LINK, index=%d",
00208 addr->addr.dl_index);
00209 return (str);
00210 #endif
00211 #endif
00212 default:
00213 snprintf(str, len, "addr_ntop: unknown AF_xxx: %d",
00214 addr->family);
00215 return (str);
00216 }
00217 return (NULL);
00218 }
00219
00223 int nms_sockaddr_dup(nms_sockaddr * dst, nms_sockaddr * src)
00224 {
00225
00226 if (!(dst->addr = malloc(src->addr_len)))
00227 return -nms_printf(NMSML_FATAL, "Cannot allocate memory\n");
00228 memcpy(dst->addr, src->addr, src->addr_len);
00229 dst->addr_len = src->addr_len;
00230
00231 return 0;
00232 }
00233
00237 int nms_addr_cmp(const nms_addr * addr1, const nms_addr * addr2)
00238 {
00239 if (addr1->family != addr2->family)
00240 return WSOCK_ERRFAMILY;
00241 switch (addr1->family) {
00242 case AF_INET:
00243 if (!memcmp
00244 (&addr1->addr.in, &addr2->addr.in, sizeof(struct in_addr)))
00245 return 0;
00246 else
00247 return WSOCK_ERRADDR;
00248 break;
00249 case AF_INET6:
00250 if (!memcmp
00251 (&addr1->addr.in6, &addr2->addr.in6,
00252 sizeof(struct in6_addr)))
00253 return 0;
00254 else
00255 return WSOCK_ERRADDR;
00256 break;
00257 default:
00258 return WSOCK_ERRFAMILYUNKNOWN;
00259 }
00260
00261 return 0;
00262 }
00263
00264
00265
00266 int nmst_read(nms_transport * transport, void *buffer, size_t nbytes, void *protodata)
00267 {
00268 switch (transport->sock.socktype) {
00269 case TCP:
00270 return recv(transport->sock.fd, buffer, nbytes, 0);
00271 break;
00272 #ifdef HAVE_LIBSCTP
00273 case SCTP:
00274 if (!protodata) {
00275 return -1;
00276 }
00277 return sctp_recvmsg(transport->sock.fd, buffer, nbytes, NULL, 0,
00278 (struct sctp_sndrcvinfo *) protodata, NULL);
00279 break;
00280 #endif
00281 default:
00282 break;
00283 }
00284 return -1;
00285 }
00286
00287 int nmst_write(nms_transport * transport, void *buffer, size_t nbytes, void *protodata)
00288 {
00289 #ifdef HAVE_LIBSCTP
00290 struct sctp_sndrcvinfo sinfo;
00291 #endif
00292 switch (transport->sock.socktype) {
00293 case TCP:
00294 return send(transport->sock.fd, buffer, nbytes, 0);
00295 break;
00296 #ifdef HAVE_LIBSCTP
00297 case SCTP:
00298 if (!protodata) {
00299 protodata = &sinfo;
00300 memset(protodata, 0, sizeof(struct sctp_sndrcvinfo));
00301 }
00302 return sctp_send(transport->sock.fd, buffer, nbytes,
00303 (struct sctp_sndrcvinfo *) protodata, MSG_EOR);
00304 break;
00305 #endif
00306 default:
00307 break;
00308 }
00309
00310 return -1;
00311 }
00312
00313 inline int nmst_is_active(nms_transport * transport)
00314 {
00315 return ((transport->sock.socktype != SOCK_NONE) && (transport->sock.fd >= 0));
00316 }
00317
00318 void nmst_init(nms_transport * transport)
00319 {
00320 memset(transport, 0, sizeof(nms_transport));
00321
00322
00323 transport->sock.socktype = TCP;
00324
00325 transport->sock.fd = -1;
00326 }
00327
00328 int nmst_close(nms_transport * transport)
00329 {
00330 if (transport->sock.remote_host)
00331 free(transport->sock.remote_host);
00332
00333
00334 return close(transport->sock.fd);
00335 }
00336
00337