static void sso_socket(struct socket_triplet *triplet, struct sockopt *so, int fd) { int ret; unsigned int tries = 0; /* skip over bluetooth due to weird linger bug */ if (triplet->family == PF_BLUETOOTH) return; so->optval = 0; retry: if (so->optval != 0) free((void *) so->optval); do_setsockopt(so); ret = setsockopt(fd, so->level, so->optname, (void *)so->optval, so->optlen); if (ret == 0) { output(2, "setsockopt(%lx %lx %lx %lx) on fd %d [%d:%d:%d]\n", so->level, so->optname, so->optval, so->optlen, fd, triplet->family, triplet->type, triplet->protocol); } else { tries++; if (tries != 100) goto retry; } if (so->optval != 0) free((void *) so->optval); }
static int set_int_sockopt (Socket_Type *s, int level, int optname) { int val; if (-1 == SLang_pop_int (&val)) return -1; return do_setsockopt (s->fd, level, optname, (void *)&val, sizeof(int)); }
static int set_struct_sockopt (Socket_Type *s, int level, int optname, SLang_CStruct_Field_Type *cs, VOID_STAR v, socklen_t len) { int ret; if (-1 == SLang_pop_cstruct (v, cs)) return -1; ret = do_setsockopt (s->fd, level, optname, v, len); SLang_free_cstruct (v, cs); return ret; }
static int set_str_sockopt (Socket_Type *s, int level, int optname) { char *val; socklen_t len; int ret; if (-1 == SLang_pop_slstring (&val)) return -1; len = strlen (val); len++; ret = do_setsockopt (s->fd, level, optname, (void *)val, len); SLang_free_slstring (val); return ret; }
/* {SO_PEERCRED, NULL, get_peercred_sockopt}, */ # endif # ifdef SO_RCVTIMEO {SO_RCVTIMEO, set_timeval_sockopt, get_timeval_sockopt}, # endif # ifdef SO_SNDTIMEO {SO_SNDTIMEO, set_timeval_sockopt, get_timeval_sockopt}, # endif # ifdef SO_LINGER {SO_LINGER, set_linger_sockopt, get_linger_sockopt}, # endif {-1, NULL, NULL} }; #endif /* SOL_SOCKET */ #if defined(IP_ADD_MEMBERSHIP) /* either add or drop same args */ static int set_multicast_sockopt (Socket_Type *s, int level, int option) { struct ip_mreq group; char *multi; char *local = NULL; Host_Addr_Info_Type *multi_info = NULL; Host_Addr_Info_Type *local_info = NULL; int ret = -1; if (-1 == SLang_pop_slstring(&multi)) return -1; if (5 == SLang_Num_Function_Args) { if (-1 == SLang_pop_slstring(&local)) { SLang_free_slstring (multi); return -1; } } if (NULL == (multi_info = get_host_addr_info (multi))) goto free_and_return; if (local != NULL) { if (NULL == (local_info = get_host_addr_info (local))) goto free_and_return; memcpy ((char *) &group.imr_interface.s_addr, local_info->h_addr_list[0], local_info->h_length); } else { group.imr_interface.s_addr = INADDR_ANY; } memcpy ((char *) &group.imr_multiaddr.s_addr, multi_info->h_addr_list[0], multi_info->h_length); ret = do_setsockopt (s->fd, level, option, (void *)&group, sizeof(group)); free_and_return: SLang_free_slstring(multi); if (NULL != local) SLang_free_slstring(local); free_host_addr_info (multi_info); if (NULL != local_info) free_host_addr_info (local_info); return ret; }
static void do_sso_sockets(void) { struct sockopt so = { 0, 0, 0, 0 }; unsigned int i; int fd, ret; for (i = 0; i < nr_sockets; i++) { fd = shm->sockets[i].fd; do_setsockopt(&so); ret = setsockopt(fd, so.level, so.optname, (void *)so.optval, so.optlen); if (ret == 0) output(1, "Setsockopt(%lx %lx %lx %lx) on fd %d\n", so.level, so.optname, so.optval, so.optlen, fd); // else // output(1, "sso failed %s\n", strerror(errno)); } }
static int set_multicast_if_sockopt (Socket_Type *s, int level, int option) { struct in_addr iface; char *local; Host_Addr_Info_Type *local_info; if (-1 == SLang_pop_slstring(&local)) return -1; if (NULL == (local_info = get_host_addr_info (local))) { SLang_free_slstring (local); return -1; } memcpy ((char *) &iface.s_addr, local_info->h_addr_list[0], local_info->h_length); SLang_free_slstring(local); free_host_addr_info (local_info); return do_setsockopt (s->fd, level, option, (void *)&iface, sizeof(iface)); }
int masqmod_main(int argc, const char *argv[]) { int c; int command = IP_MASQ_CMD_NONE; struct ip_masq_ctl mctl; #define ums mctl.u.user struct sockaddr_in m_sin, s_sin, d_sin; int tmp; int nonames = 0; memset (&m_sin, 0, sizeof (m_sin)); memset (&d_sin, 0, sizeof (d_sin)); memset (&s_sin, 0, sizeof (s_sin)); memset (&ums, 0, sizeof (ums)); ums.protocol = IPPROTO_NONE; modname = argv[0]; while ((c = getopt(argc, (char**) argv, "adsgnP:M:D:S:t:h")) != -1) switch (c) { case 'a': if (command != IP_MASQ_CMD_NONE) exit_error(2, "multiple commands specified"); command = IP_MASQ_CMD_ADD; break; case 'd': if (command != IP_MASQ_CMD_NONE) exit_error(2, "multiple commands specified"); command = IP_MASQ_CMD_DEL; break; case 's': if (command != IP_MASQ_CMD_NONE) exit_error(2, "multiple commands specified"); command = IP_MASQ_CMD_SET; break; case 'g': if (command != IP_MASQ_CMD_NONE) exit_error(2, "multiple commands specified"); command = IP_MASQ_CMD_GET; break; case 'n': nonames++; break; case 'P': if (ums.protocol != IPPROTO_NONE) exit_error(2, "multiple protocols specified"); switch (*optarg) { case 't': ums.protocol = IPPROTO_TCP; break; case 'u': ums.protocol = IPPROTO_UDP; break; default: exit_error(2, "invalid protocol specified"); } break; case 'M': if (m_sin.sin_addr.s_addr||m_sin.sin_port) exit_error(2, "multiple [M]asq specified"); tmp = optind-1; tmp = parse_addressport(argv+tmp, argc-tmp, &m_sin, nonames); if (tmp!=2) exit_error(2, "illegal [M]asq address/port specified"); optind += tmp -1; break; case 'S': if (s_sin.sin_addr.s_addr||s_sin.sin_port) exit_error(2, "multiple [S]ource specified"); tmp = optind-1; tmp = parse_addressport(argv+tmp, argc-tmp, &s_sin, nonames); if (tmp != 2) exit_error(2, "illegal destination specified"); optind += tmp -1; break; case 'D': if (d_sin.sin_addr.s_addr||d_sin.sin_port) exit_error(2, "multiple [D]estinations specified"); tmp = optind-1; tmp = parse_addressport(argv+tmp, argc-tmp, &d_sin, nonames); if (tmp != 2) exit_error(2, "illegal destination specified"); optind += tmp -1; break; case 't': ums.timeout = atoi(optarg) * HZ; if (ums.timeout <= 0) exit_error(2, "illegal timeout value specified"); break; case 'h': case '?': default: exit_display_help(); } if (optind < argc) { printf("optind=%d (%s) argc=%d\n", optind, argv[optind-1], argc); exit_error(2, "unknown arguments found on commandline"); } if (command == IP_MASQ_CMD_NONE) exit_display_help(); if (ums.protocol == IPPROTO_NONE) { exit_error(2,"no protocol specified"); } ums.mport = m_sin.sin_port; ums.maddr = m_sin.sin_addr.s_addr; ums.dport = d_sin.sin_port; ums.daddr = d_sin.sin_addr.s_addr; ums.sport = s_sin.sin_port; ums.saddr = s_sin.sin_addr.s_addr; switch (command) { case IP_MASQ_CMD_ADD: if (0) exit_error(2, "insufficient options specified"); break; case IP_MASQ_CMD_DEL: if ((ums.mport == 0)||(ums.maddr == 0)) exit_error(2, "insufficient options specified"); break; } return(do_setsockopt(command, &mctl, sizeof(mctl))); }