| 주소유형 | 프리픽스 |
| 미지정 | ::/128 |
| 루프백 | ::1/128 |
| 멀티캐스트 | ff00::/8 |
| 로컬 유니캐스트(링크) | fe80::/10 |
| 로컬 유니캐스트(사이트) | fec0::/10 |
| 전역 유니캐스트(Global) | 위의 유형을 제외한 나머지 모든 비트 |
| 10bits | 54bits | 64bits |
| 1111 1110 10 | 0 | Interface ID |
| 10bits | 38bits | 16bits | 64bits |
| 1111 1110 11 | 0 | Subnet ID | Interface ID |
| 8bits | 4bits | 4bits | 112bits |
| 1111 1111 | flags | scope | Group ID |
| 0 | 0 | 0 | I |
| 값 | 설명 |
| 0 | 예약 |
| 1 | 로컬 범위의 인터페이스 |
| 2 | 로컬 범위의 링크 |
| 3 | 로컬 범위의 서트넷 |
| 4 | 로컬 범위의 관리 |
| 5 | 로컬 범위의 사이트 |
| 6 | 할당되지 않음 |
| 7 | 할당되지 않음 |
| 8 | 로컬 범위의 조직 |
| 9 | 할당되지 않음 |
| 10 | 할당되지 않음 |
| 11 | 할당되지 않음 |
| 12 | 할당되지 않음 |
| 13 | 할당되지 않음 |
| 14 | 글로벌 범위 |
| 15 | 예약 |
struct addrinfo s_hints;
struct addrinfo *s_result;
struct addrinfo *s_this;
int s_check;
(void)memset((void *)(&s_hints), 0, sizeof(s_hints));
s_hints.ai_family = AF_UNSPEC; /* IPv4 or IPv6 */
s_hints.ai_socktype = SOCK_STREAM; /* UDP or TCP */
s_hints.ai_flags = AI_PASSIVE; /* wildcard IP address */
s_hints.ai_flags = 0; /* wildcard IP address */
s_hints.ai_protocol = IPPROTO_TCP; /* any protocol */
s_hints.ai_canonname = NULL;
s_hints.ai_addr = NULL;
s_hints.ai_next = NULL;
s_check = getaddrinfo((s_argc >= 2) ? s_argv[1] : "ipv6.minzkn.com", "http", (const struct addrinfo *)(&s_hints), (struct addrinfo **)(&s_result));
if(s_check == 0) {
s_this = s_result;
while(s_this != ((struct addrinfo *)0)) {
/* ai_flags */
if(s_this->ai_flags & AI_PASSIVE) {
(void)fprintf(stdout, "flags: AI_PASSIVE\n");
}
if(s_this->ai_flags & AI_CANONNAME) {
(void)fprintf(stdout, "flags: AI_CANONNAME\n");
}
if(s_this->ai_flags & AI_NUMERICHOST) {
(void)fprintf(stdout, "flags: AI_NUMERICHOST\n");
}
if(s_this->ai_flags & AI_V4MAPPED) {
(void)fprintf(stdout, "flags: AI_V4MAPPED\n");
}
if(s_this->ai_flags & AI_ALL) {
(void)fprintf(stdout, "flags: AI_ALL\n");
}
if(s_this->ai_flags & AI_ADDRCONFIG) {
(void)fprintf(stdout, "flags: AI_ADDRCONFIG\n");
}
#if defined(AI_IDN)
if(s_this->ai_flags & AI_IDN) {
(void)fprintf(stdout, "flags: AI_IDN\n");
}
#endif
#if defined(AI_CANONIDN)
if(s_this->ai_flags & AI_CANONIDN) {
(void)fprintf(stdout, "flags: AI_CANONIDN\n");
}
#endif
#if defined(AI_IDN_ALLOW_UNASSIGNED)
if(s_this->ai_flags & AI_IDN_ALLOW_UNASSIGNED) {
(void)fprintf(stdout, "flags: AI_IDN_ALLOW_UNASSIGNED\n");
}
#endif
#if defined(AI_IDN_USE_STD3_ASCII_RULES)
if(s_this->ai_flags & AI_IDN_USE_STD3_ASCII_RULES) {
(void)fprintf(stdout, "flags: AI_IDN_USE_STD3_ASCII_RULES\n");
}
#endif
#if defined(AI_NUMERICSERV)
if(s_this->ai_flags & AI_NUMERICSERV) {
(void)fprintf(stdout, "flags: NUMERICSERV\n");
}
#endif
/* ai_family */
if(s_this->ai_family == AF_UNSPEC) {
(void)fprintf(stdout, "family=%s\n", "UNSPEC");
}
else if(s_this->ai_family == AF_LOCAL) {
(void)fprintf(stdout, "family=%s\n", "LOCAL");
}
else if(s_this->ai_family == AF_INET) {
(void)fprintf(stdout, "family=%s\n", "AF_INET");
}
else if(s_this->ai_family == AF_INET6) {
(void)fprintf(stdout, "family=%s\n", "AF_INET6");
}
else {
(void)fprintf(stdout, "family=%d\n", s_this->ai_family);
}
/* ai_socktype */
if(s_this->ai_socktype == SOCK_DGRAM) {
(void)fprintf(stdout, "socktype=%s\n", "SOCK_DGRAM");
}
else if(s_this->ai_socktype == SOCK_STREAM) {
(void)fprintf(stdout, "socktype=%s\n", "SOCK_STREAM");
}
else {
(void)fprintf(stdout, "socktype=%d\n", s_this->ai_socktype);
}
/* ai_protocol */
if(s_this->ai_protocol == IPPROTO_IP) {
(void)fprintf(stdout, "protocol=%s\n", "IPPROTO_IP");
}
else if(s_this->ai_protocol == IPPROTO_IPV6) {
(void)fprintf(stdout, "protocol=%s\n", "IPPROTO_IPV6");
}
else if(s_this->ai_protocol == IPPROTO_TCP) {
(void)fprintf(stdout, "protocol=%s\n", "IPPROTO_TCP");
}
else if(s_this->ai_protocol == IPPROTO_UDP) {
(void)fprintf(stdout, "protocol=%s\n", "IPPROTO_UDP");
}
else if(s_this->ai_protocol == IPPROTO_IGMP) {
(void)fprintf(stdout, "protocol=%s\n", "IPPROTO_IGMP");
}
else if(s_this->ai_protocol == IPPROTO_ICMP) {
(void)fprintf(stdout, "protocol=%s\n", "IPPROTO_ICMP");
}
else if(s_this->ai_protocol == IPPROTO_ICMPV6) {
(void)fprintf(stdout, "protocol=%s\n", "IPPROTO_ICMPV6");
}
else {
(void)fprintf(stdout, "protocol=%d\n", s_this->ai_protocol);
}
/* ai_addrlen */
(void)fprintf(stdout, "addrlen=%lu\n", (unsigned long)s_this->ai_addrlen);
/* ai_addr */
if(s_this->ai_addr != ((struct sockaddr *)0)) {
char s_address_local[ 128 ];
const char *s_address;
struct sockaddr_in *s_sockaddr_in;
struct sockaddr_in6 *s_sockaddr_in6;
int s_unspec = (-1);
if(s_this->ai_family == AF_INET) {
s_sockaddr_in = (struct sockaddr_in *)s_this->ai_addr;
s_address = inet_ntop(s_this->ai_family, (const void *)(&s_sockaddr_in->sin_addr.s_addr), (char *)(&s_address_local[0]), (socklen_t)sizeof(s_address_local));
}
else if(s_this->ai_family == AF_INET6) {
s_sockaddr_in6 = (struct sockaddr_in6 *)s_this->ai_addr;
s_address = inet_ntop(s_this->ai_family, (const void *)(&s_sockaddr_in6->sin6_addr), (char *)(&s_address_local[0]), (socklen_t)sizeof(s_address_local));
s_unspec = IN6_IS_ADDR_UNSPECIFIED((const struct in6_addr *)(&s_sockaddr_in6->sin6_addr));
}
else {
s_address = (const char *)0;
}
if(s_address != ((const char *)0)) {
(void)fprintf(stdout, "addr=\"%s\" (unspec?=%d)\n", s_address, s_unspec);
}
else {
(void)fprintf(stdout, "addr=%s (unspec?=%d)\n", "UNKNOWN", s_unspec);
}
}
else {
(void)fprintf(stdout, "addr=%s\n", "NULL");
}
/* ai_canonname */
(void)fprintf(stdout, "canonname=%s\n", (s_this->ai_canonname != ((char *)0)) ? s_this->ai_canonname : "NULL");
(void)fprintf(stdout, "\n");
s_this = s_this->ai_next;
}
freeaddrinfo(s_result);
}
else {
(void)fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(s_check));
}
iec_sockaddr_t s_remote, s_bind;
iec_socket_t s_socket;
iec_const_string_t s_remote_address;
iec_socket_t s_socket;
s_remote_address = "http://test.minzkn.com:80/index.php";
/* 먼저 remote 주소의 sockaddr을 설정한다. (node는 uri를 허용한다) */
if(iec_xapi_resolve_sockaddr(AF_UNSPEC, (iec_sockaddr_t *)(&s_remote), s_remote_address, iec_xapi_int_const(80), def_iec_true) == def_iec_true) {
/* 설정된 s_remote의 family를 bind address family 로 결정한다. (node는 uri를 허용하지 않는다) */
if(iec_xapi_resolve_sockaddr(s_remote.ss.ss_family, (iec_sockaddr_t *)(&s_bind), def_iec_null_string, iec_xapi_int_const(0), def_iec_false) != def_iec_error) {
/* 결정된 bind address family에 맞는 소켓을 연다. */
s_socket = iec_xapi_socket(s_bind.ss.ss_family, SOCK_STREAM, IPPROTO_TCP);
if(s_socket != def_iec_invalid_socket) {
if(iec_xapi_bind(s_socket, (iec_sockaddr_t *)(&s_bind)) == def_iec_true) {
if(iec_xapi_connect(s_socket, (iec_sockaddr_t *)(&s_remote), s_timeout) == def_iec_true) {
/* connected */
}
}
s_socket = iec_xapi_closesocket(s_socket);
}
}
}
iec_const_string_t s_bind_address;
iec_int_t s_bind_port;
iec_sockaddr_t s_sockaddr_bind, s_sockaddr_accept;
iec_socket_t s_listen_socket, s_accept_socket;
iec_socklen_t s_socklen;
if(iec_xapi_resolve_sockaddr(AF_UNSPEC, (iec_sockaddr_t *)(&s_sockaddr_bind), s_bind_address, s_bind_port, def_iec_false) == def_iec_true) {
s_listen_socket = iec_xapi_socket(s_sockaddr_bind.ss_family, SOCK_STREAM, IPPROTO_TCP);
if(s_listen_socket != def_iec_invalid_socket) {
if(iec_xapi_bind(s_listen_socket, (iec_sockaddr_t *)(&s_sockaddr_bind), (iec_socklen_t)sizeof(s_sockaddr_bind)) == def_iec_true) {
if(iec_xapi_listen(s_listen_socket, def_iec_max_backlog) == def_iec_true) {
for(; /* exit condition */ ;) {
s_socklen = (iec_socklen_t)sizeof(s_sockaddr_accept);
s_accept_socket = iec_xapi_accept(s_listen_socket, (iec_sockaddr_t *)(&s_sockaddr_accept), (iec_socklen_t *)(&s_socklen), 0/* timeout */);
if(s_accept_socket != def_iec_invalid_socket) {
if(s_sockaddr_accept.ss_family == AF_INET) {
/* IPv4 accept process */
}
else if(s_sockaddr_accept.ss_family == AF_INET6) {
/* IPv6 accept process */
}
else {
/* Unspec accept process */
}
iec_xapi_closesocket(s_accept_socket);
}
else {
iec_xapi_load_balance();
}
}
}
}
iec_xapi_closesocket(s_listen_socket);
}
}
struct ip_mreq
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (struct ip_mreq *)(&r), sizeof(struct ip_mreq));
struct ipv6_mreq {
/* IPv6 multicast address of group */
struct in6_addr ipv6mr_multiaddr;
/* local IPv6 address of interface */
int ipv6mr_ifindex;
};
setsockopt(socket, IPPROTO_IPV6, IPV6_JOIN_GROUP, (struct ipv6_mreq *)(&r), sizeof(struct ipv6_mreq));
int s_ttl; /* unicast ttl */ setsockopt(socket, IPPROTO_IP, IP_TTL, &s_ttl, sizeof(s_ttl)); /* multicast ttl */ setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, &s_ttl, sizeof(s_ttl));
int s_hops; /* unicast ttl */ setsockopt(socket, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s_hops, sizeof(s_hops)); /* multicast ttl */ setsockopt(socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &s_hops, sizeof(s_hops));
EPRT<space><d><net-prt><d><net-addr><d><tcp-port><d> 여기서 <d>는 구분자로써 '|'을 사용하는것으로 되어 있습니다. <net-prt>는 '1'은 IPv4를 의미하고 '2'는 IPv6를 의미합니다. EPSV<space><net-prt> 229 Entering Extended Passive Mode (|||<tcp-port>|) EPSV에 대한 응답형식은 EPRT와 유사합니다. EPSV의 <net-prt>에는 '1', '2', 'ALL'이 사용될수 있다고 합니다. 하지만 실험결과 'ALL'은 제대로 동작하지 않는 경우가 많았습니다.