int procket_open_socket(PROCKET_STATE *ps) { switch (ps->protocol) { case IPPROTO_ICMP: /* getaddrinfo(3): node for SOCK_RAW must not be NULL */ if (ps->address == NULL) { char *ipaddr = ps->family == AF_INET6 ? "::" : "0.0.0.0"; ps->address = strdup(ipaddr); if (ps->address == NULL) return -1; } /* getaddrinfo(3): port for SOCK_RAW must NULL */ free(ps->port); ps->port = NULL; /* fall through */ case IPPROTO_TCP: case IPPROTO_UDP: if (procket_lookup_socket(ps) < 0) return -1; break; default: if (procket_create_socket(ps) < 0) return -1; break; } return 0; }
int procket_open_socket(PROCKET_STATE *ps) { switch (ps->protocol) { case IPPROTO_TCP: case IPPROTO_UDP: if (procket_lookup_socket(ps) < 0) return -1; break; default: if (procket_create_socket(ps) < 0) return -1; break; } return 0; }
int procket_lookup_socket(PROCKET_STATE *ps) { struct addrinfo hints = {0}; struct addrinfo *res = NULL; struct addrinfo *rp = NULL; int err = 0; hints.ai_family = ps->family; hints.ai_socktype = ps->type; hints.ai_protocol = ps->protocol; hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE; err = getaddrinfo(ps->address, ps->port, &hints, &res); switch (err) { case 0: break; case EAI_SYSTEM: return -1; /* fake errno values */ #ifdef EAI_ADDRFAMILY case EAI_ADDRFAMILY: errno = EAFNOSUPPORT; return -1; #endif case EAI_AGAIN: errno = EAGAIN; return -1; case EAI_FAMILY: errno = EPFNOSUPPORT; return -1; case EAI_MEMORY: errno = EAI_MEMORY; return -1; case EAI_SERVICE: case EAI_SOCKTYPE: errno = ESOCKTNOSUPPORT; return -1; default: errno = EINVAL; return -1; } for (rp = res; rp != NULL; rp = rp->ai_next) { ps->family = rp->ai_family; ps->type = rp->ai_socktype; ps->protocol = rp->ai_protocol; if (procket_create_socket(ps) == 0) { if (bind(ps->s, rp->ai_addr, rp->ai_addrlen) < 0) return -1; break; } } freeaddrinfo(res); if (ps->s < 0) return -1; return 0; }