Esempio n. 1
0
// 打开分组捕获设备
void open_pcap(void)
{
    uint32_t localnet, netmask;
    char cmd[MAXLINE], errbuf[PCAP_ERRBUF_SIZE];
    char str1[INET_ADDRSTRLEN], str2[INET_ADDRSTRLEN];
    struct bpf_program fcode;

    // 选择分组设备:如果分组设备未曾指定(通过 -i 选项),那就调用
    // pcap_lookupdev函数选择一个设备
    if (device == NULL) {
        if ((device = pcap_lookupdev(errbuf)) == NULL) {
            err_quit("pcap_lookup: %s", errbuf);
        }
    }
    printf("device = %s\n", device);

    // 打开设备
    // hardcode: promisc = 0, to_ms = 500
    if ((pd = pcap_open_live(device, snaplen, 0, 500, errbuf)) == NULL) {
        err_quit("pcap_open_live: %s", errbuf);
    }

    // 获取网络地址与子网掩码
    if (pcap_lookupnet(device, &localnet, &netmask, errbuf) < 0) {
        err_quit("pcap_lookupnet: % s", errbuf);
    }
    if (verbose) {
        printf("localnet = %s, netmask = %s\n",
               inet_ntop(AF_INET, &localnet, str1, sizeof(str1)),
               inet_ntop(AF_INET, &netmask, str2, sizeof(str2)));
    }

    // 编译分组过滤器
    snprintf(cmd, sizeof(cmd), CMD, sock_ntop_host(dest, destlen), ntohs(sock_get_port(dest, destlen)));
    if (verbose) {
        printf("cmd = %s\n", cmd);
    }
    if (pcap_compile(pd, &fcode, cmd, 0, netmask) < 0) {
        err_quit("pcap_compile: %s", pcap_geterr(pd));
    }

    // 装载过滤程序
    if (pcap_setfilter(pd, &fcode) < 0) {
        err_quit("pcap_setfilter: %s", pcap_geterr(pd));
    }

    // 确定数据链路类型
    if ((datalink = pcap_datalink(pd)) < 0) {
        err_quit("pcap_datalink: %s", pcap_geterr(pd));
    }
    if (verbose) {
        printf("datalink = %d\n", datalink);
    }
}
Esempio n. 2
0
int
readable_conn(int i)
{
	int				unixfd, recvfd;
	char			c;
	ssize_t			n;
	socklen_t		len;
	struct sockaddr_storage	ss;

	unixfd = client[i].connfd;
	recvfd = -1;
	if ( (n = Read_fd(unixfd, &c, 1, &recvfd)) == 0) {
		err_msg("client %d terminated, recvfd = %d", i, recvfd);
		goto clientdone;	/* client probably terminated */
	}

		/* 4data from client; should be descriptor */
	if (recvfd < 0) {
		err_msg("read_fd did not return descriptor");
		goto clienterr;
	}
/* end readable_conn1 */

/* include readable_conn2 */
	len = sizeof(ss);
	if (getsockname(recvfd, (SA *) &ss, &len) < 0) {
		err_ret("getsockname error");
		goto clienterr;
	}

	client[i].family = ss.ss_family;
	if ( (client[i].lport = sock_get_port((SA *)&ss, len)) == 0) {
		client[i].lport = sock_bind_wild(recvfd, client[i].family);
		if (client[i].lport <= 0) {
			err_ret("error binding ephemeral port");
			goto clienterr;
		}
	}
	Write(unixfd, "1", 1);	/* tell client all OK */
	Close(recvfd);			/* all done with client's UDP socket */
	return(--nready);

clienterr:
	Write(unixfd, "0", 1);	/* tell client error occurred */
clientdone:
	Close(unixfd);
	if (recvfd >= 0)
		Close(recvfd);
	FD_CLR(unixfd, &allset);
	client[i].connfd = -1;
	return(--nready);
}
Esempio n. 3
0
int main(int argc, char** argv)
{
    int sockfd, family, port;
    const int on = 1;
    pid_t pid;
    socklen_t salen;
    struct sockaddr *sa, *wild;
    struct ifi_info *ifi, *ifihead;

    if (argc == 2)
        sockfd = Udp_client(NULL, argv[1], (void**)&sa, &salen);
    else if (argc == 3)
        sockfd = Udp_client(argv[1], argv[2], (void**)&sa, &salen);
    else
        err_quit("usage: udpserv04 [ <host> ] <service or port>");
    family = sa->sa_family;
    port = sock_get_port(sa, salen);
    Close(sockfd); /* we just want family, port, salen */

    for (ifihead = ifi = Get_ifi_info(family, 1); ifi != NULL;
         ifi = ifi->ifi_next) {
        /*4bind unicast address */
        sockfd = Socket(family, SOCK_DGRAM, 0);
        Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

        sock_set_port(ifi->ifi_addr, salen, port);
        Bind(sockfd, ifi->ifi_addr, salen);
        printf("bound %s\n", Sock_ntop(ifi->ifi_addr, salen));

        if ((pid = Fork()) == 0) { /* child */
            mydg_echo(sockfd, ifi->ifi_addr, salen);
            exit(0); /* never executed */
        }

        if (ifi->ifi_flags & IFF_BROADCAST) {
            /* 4try to bind broadcast address */
            sockfd = Socket(family, SOCK_DGRAM, 0);
            Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

            sock_set_port(ifi->ifi_brdaddr, salen, port);
            if (bind(sockfd, ifi->ifi_brdaddr, salen) < 0) {
                if (errno == EADDRINUSE) {
                    printf("EADDRINUSE: %s\n",
                           Sock_ntop(ifi->ifi_brdaddr, salen));
                    Close(sockfd);
                    continue;
                } else
                    err_sys("bind error for %s",
                            Sock_ntop(ifi->ifi_brdaddr, salen));
            }
            printf("bound %s\n", Sock_ntop(ifi->ifi_brdaddr, salen));

            if ((pid = Fork()) == 0) { /* child */
                mydg_echo(sockfd, ifi->ifi_brdaddr, salen);
                exit(0); /* never executed */
            }
        }
    }

    /* 4bind wildcard address */
    sockfd = Socket(family, SOCK_DGRAM, 0);
    Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));

    wild = Malloc(salen);
    memcpy(wild, sa, salen); /* copy family and port */
    sock_set_wild(wild, salen);

    Bind(sockfd, wild, salen);
    printf("bound %s\n", Sock_ntop(wild, salen));

    if ((pid = Fork()) == 0) { /* child */
        mydg_echo(sockfd, wild, salen);
        exit(0); /* never executed */
    }
    exit(0);
}
Sock * Sock_connect(char *host, char *port, Sock *binded, sock_type socktype, sock_flags ssl_flag)
{
    Sock *s;
    char remote_host[128]; /*Unix Domain is largest*/
    char local_host[128]; /*Unix Domain is largest*/
    int sockfd = -1;
    struct sockaddr *sa_p = NULL;
    socklen_t sa_len = 0;
    int32_t local_port;
    int32_t remote_port;
#if HAVE_SSL
    SSL *ssl_con;
#endif

    if(binded) {
        sockfd = binded->fd;
    }

    if (sock_connect(host, port, &sockfd, socktype)) {
            net_log(NET_LOG_ERR, "Sock_connect() failure.\n");
            return NULL;
    }

#if HAVE_SSL
    if(ssl_flag & IS_SSL) {
        if (sock_SSL_connect(&ssl_con))
            net_log (NET_LOG_ERR, "Sock_connect() failure in SSL init.\n");
            sock_close(sockfd);
            return NULL;
    }
    else
#endif


    if (binded) {
        s = binded;
        free(s->local_host);
        s->local_host = NULL;
        free(s->remote_host);
        s->remote_host = NULL;
    } else if (!(s = calloc(1, sizeof(Sock)))) {
        net_log(NET_LOG_FATAL, "Unable to allocate a Sock struct in Sock_connect().\n");
#if HAVE_SSL
        if(ssl_flag & IS_SSL) 
            sock_SSL_close(ssl_con);
#endif
        sock_close (sockfd);
        return NULL;
    }

    s->fd = sockfd;
    s->socktype = socktype;
#if HAVE_SSL
    if(ssl_flag & IS_SSL) 
        s->ssl = ssl_con;
#endif
    s->flags = ssl_flag;

    sa_p = (struct sockaddr *) &(s->local_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getsockname(s->fd, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, local_host, sizeof(local_host)))
        memset(local_host, 0, sizeof(local_host));

    if (!(s->local_host = strdup(local_host))) {
        net_log(NET_LOG_FATAL, "Unable to allocate local host in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    local_port = sock_get_port(sa_p);

    if(local_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get local port in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    } else
        s->local_port = ntohs(local_port);

    sa_p = (struct sockaddr *) &(s->remote_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getpeername(s->fd, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR, "Unable to get remote address in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, remote_host, sizeof(remote_host)))
        memset(remote_host, 0, sizeof(remote_host));
    
    if (!(s->remote_host = strdup(remote_host))) {
        net_log(NET_LOG_FATAL, "Unable to allocate remote host in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    }

    remote_port = sock_get_port(sa_p);
    if(remote_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_connect().\n");
        Sock_close(s);
        return NULL;
    } else
        s->remote_port = ntohs(remote_port);

    net_log(NET_LOG_DEBUG, "Socket connected between local=\"%s\":%u and "
        "remote=\"%s\":%u.\n", s->local_host, s->local_port, s->remote_host,
        s->remote_port);

    if(is_multicast_address(sa_p, s->remote_stg.ss_family)) {
        //fprintf(stderr,"IS MULTICAST\n");
        if(mcast_join(s->fd, sa_p, NULL, 0, &(s->addr))!=0) {
            Sock_close(s);
            return NULL;
        }
        s->flags |= IS_MULTICAST;
    }

    return s;
}
Esempio n. 5
0
/**
 * Create a new socket accepting a new connection from a listening socket.
 * @param main Listening socket.
 * @param octx optional ssl global context
 * @return the newly allocated Sock
 */
Sock * Sock_accept(Sock *s, void * octx)
{
    int res = -1;
    char remote_host[128]; /*Unix Domain is largest*/
    char local_host[128]; /*Unix Domain is largest*/
    int remote_port = -1;
    int local_port = -1;
    Sock *new_s = NULL;
    struct sockaddr *sa_p = NULL;
    socklen_t sa_len = 0;

#if ENABLE_SSL
    SSL_CTX * ctx = octx;
    SSL *ssl_con = NULL;
#endif

    if (!s)
        return NULL;

    if ((res = sock_accept(s->fd)) < 0) {
        net_log(NET_LOG_ERR, "System error in sock_accept().\n");
        return NULL;
    }

#if ENABLE_SSL
    if(ctx) {
        if( !(ssl_con = SSL_sock_accept(res, ctx)) ) {
            net_log(NET_LOG_ERR, "Unable to accept SSL connection.\n");
            sock_close(res);
            return NULL;
        }
    }
#endif

    if (!(new_s = calloc(1, sizeof(Sock)))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate a Sock struct in Sock_accept().\n");
#if ENABLE_SSL
        if(ctx)
            SSL_close_connection(ssl_con, res);
#endif
        sock_close(res);
        return NULL;
    }

    new_s->fd = res;
    new_s->socktype = s->socktype;
    new_s->flags = s->flags;

#if ENABLE_SSL
    if(ctx)
        new_s->ssl = ssl_con;
#endif

    sa_p = (struct sockaddr *) &(new_s->remote_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getpeername(res, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR,
                "Unable to get remote address in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, remote_host, sizeof(remote_host)))
        memset(remote_host, 0, sizeof(remote_host));

    if (!(new_s->remote_host = strdup(remote_host))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate remote host in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    remote_port = sock_get_port(sa_p);
    if(remote_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }
    else
        new_s->remote_port = ntohs(remote_port);

    sa_p = (struct sockaddr *) &(new_s->remote_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getsockname(res, sa_p, &sa_len))
    {
        net_log(NET_LOG_ERR, "Unable to get remote port in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, local_host, sizeof(local_host)))
        memset(local_host, 0, sizeof(local_host));

    if (!(new_s->local_host = strdup(local_host))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate local host in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }

    local_port = sock_get_port(sa_p);
    if(local_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get local port in Sock_accept().\n");
        Sock_close(new_s);
        return NULL;
    }
    else
        new_s->local_port = ntohs(local_port);

    net_log(NET_LOG_DEBUG, "Socket accepted between local=\"%s\":%u and "
        "remote=\"%s\":%u.\n", new_s->local_host, new_s->local_port,
        new_s->remote_host, new_s->remote_port);

    return new_s;
}
Esempio n. 6
0
Sock * Sock_bind(char const *host, char const *port, Sock *sock,
                 sock_type socktype, void * octx)
{

    Sock *s = NULL;
    int sockfd = -1;
    struct sockaddr *sa_p;
    socklen_t sa_len;
    char local_host[128];
    int local_port;

#if ENABLE_SSL
    if ((octx)) {
        if(socktype != TCP) {
            net_log(NET_LOG_ERR, "SSL can't work on this protocol.\n");
            return NULL;
        }
    }
#endif

    if(sock) {
        sockfd = sock->fd;
    }

    if (sock_bind(host, port, &sockfd, socktype)) {
        net_log(NET_LOG_ERR, "Error in low level sock_bind().\n");
        return NULL;
    }

    if (!(s = calloc(1, sizeof(Sock)))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate a Sock struct in Sock_bind().\n");
        sock_close(sockfd);
        return NULL;
    }

    s->fd = sockfd;
    s->socktype = socktype;
    s->flags = 0;

    sa_p = (struct sockaddr *)&(s->local_stg);
    sa_len = sizeof(struct sockaddr_storage);

    if(getsockname(s->fd, sa_p, &sa_len) < 0) {
        Sock_close(s);
        return NULL;
    }

    if(!sock_ntop_host(sa_p, local_host, sizeof(local_host)))
        memset(local_host, 0, sizeof(local_host));

    if (!(s->local_host = strdup(local_host))) {
        net_log(NET_LOG_FATAL,
                "Unable to allocate local host in Sock_bind().\n");
        Sock_close(s);
        return NULL;
    }

    local_port = sock_get_port(sa_p);

    if(local_port < 0) {
        net_log(NET_LOG_ERR, "Unable to get local port in Sock_bind().\n");
        Sock_close(s);
        return NULL;
    } else
        s->local_port = ntohs(local_port);

    net_log(NET_LOG_DEBUG,
            "Socket bound with addr=\"%s\" and port=\"%u\".\n",
            s->local_host, s->local_port);

    if(is_multicast_address(sa_p, s->local_stg.ss_family)) {
        if(mcast_join(s->fd, sa_p)) {
            Sock_close(s);
            return NULL;
        }
        s->flags |= IS_MULTICAST;
    }

    return s;
}