#include "net.h" #include "log.h" #include typedef struct { struct sockaddr_in addr; int socket; socklen_t addr_len; } net_info; static net_info broadcast_info; static net_info listen_info; static net_info peer_info; static int PORT; static int init = 0; int net_init(unsigned int port) { PORT = port; // broadcast socket init broadcast_info.socket = socket(AF_INET, SOCK_DGRAM, 0); if (broadcast_info.socket < 0) { log_message(LOG_ERROR, "Error creating broadcast socket"); close(broadcast_info.socket); return 0; } int broadcast_enable = 1; if (setsockopt(broadcast_info.socket, SOL_SOCKET, SO_BROADCAST, &broadcast_enable, sizeof(broadcast_enable)) < 0) return 0; memset(&broadcast_info.addr, 0, sizeof(broadcast_info.addr)); broadcast_info.addr.sin_family = AF_INET; broadcast_info.addr.sin_addr.s_addr = inet_addr("255.255.255.255"); broadcast_info.addr.sin_port = htons(port); broadcast_info.addr_len = sizeof(broadcast_info.addr); // listen socket init listen_info.socket = socket(AF_INET, SOCK_DGRAM, 0); if (listen_info.socket < 0) { log_message(LOG_ERROR, "Error creating listen socket", strerror(errno)); close(listen_info.socket); return 0; } int reuse_enable = 1; if (setsockopt(listen_info.socket, SOL_SOCKET, SO_REUSEADDR, &reuse_enable, sizeof(reuse_enable)) < 0) return 0; memset(&listen_info.addr, 0, sizeof(listen_info.addr)); listen_info.addr.sin_family = AF_INET; listen_info.addr.sin_addr.s_addr = INADDR_BROADCAST; listen_info.addr.sin_port = htons(port); listen_info.addr_len =sizeof(listen_info.addr); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 100000; setsockopt(listen_info.socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); if (bind(listen_info.socket, (const struct sockaddr*)&listen_info.addr, sizeof(listen_info.addr)) < 0) { log_message(LOG_ERROR, "Socket bind failed: %s", strerror(errno)); close(listen_info.socket); return 0; } peer_info.socket = -1; init = 1; return 1; } int net_broadcast() { if (!init) return 0;; const char* message = "broadcast message"; int retv = sendto(broadcast_info.socket, message, strlen(message), 0, (struct sockaddr*)&broadcast_info.addr, broadcast_info.addr_len); if (retv < 0) { log_message(LOG_ERROR, "Failed to send broadcast message: %s", strerror(errno)); log_message(LOG_ERROR, "retv: %i", retv); return 0; } log_message(LOG_INFO, "Broadcast message sent"); return 1; } int net_listen_clients() { if (!init) return 0; if (peer_info.socket >= 0) { log_message(LOG_WARNING, "Peer socket already created"); log_message(LOG_INFO, "Peer socket address:\n%s:%d", inet_ntoa(peer_info.addr.sin_addr), ntohs(peer_info.addr.sin_port)); return 1; } peer_info.socket = socket(AF_INET, SOCK_DGRAM, 0); if (peer_info.socket < 0) { log_message(LOG_ERROR, "Error creating listen socket", strerror(errno)); close(peer_info.socket); return 0; } char buffer[64]; memset(&peer_info.addr, 0, sizeof(peer_info.addr)); peer_info.addr.sin_family = AF_INET; peer_info.addr.sin_addr.s_addr = INADDR_ANY; peer_info.addr.sin_port = htons(PORT); peer_info.addr_len = sizeof(peer_info.addr); int retv = recvfrom(listen_info.socket, buffer, sizeof(buffer), 0, (struct sockaddr*)&peer_info.addr, &peer_info.addr_len); if (retv < 0) { log_message(LOG_ERROR, "Failed to receive broadcast message: %s", strerror(errno)); close(peer_info.socket); peer_info.socket = -1; return 0; } buffer[retv] = '\0'; log_message(LOG_INFO, "Broadcast message received from:\n%s:%d", inet_ntoa(peer_info.addr.sin_addr), ntohs(peer_info.addr.sin_port)); log_message(LOG_INFO, "%s", buffer); return 1; } int net_send() { if (!init) return 0; return 1; } int net_receive() { if (!init) return 0; return 1; }