// 打开分组捕获设备 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); } }
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); }
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; }
/** * 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; }
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; }