static int32_t __camd35_send(struct s_client *cl, uchar *buf, int32_t buflen, int answer_awaited) { int32_t l; unsigned char rbuf[REQ_SIZE + 15 + 4], *sbuf = rbuf + 4; if(!cl->udp_fd || !cl->crypted) { return (-1); } //exit if no fd or aes key not set! //Fix ECM len > 255 if(buflen <= 0) { buflen = ((buf[0] == 0) ? (((buf[21] & 0x0f) << 8) | buf[22]) + 3 : buf[1]); } l = 20 + (((buf[0] == 3) || (buf[0] == 4)) ? 0x34 : 0) + buflen; memcpy(rbuf, cl->ucrc, 4); memcpy(sbuf, buf, l); memset(sbuf + l, 0xff, 15); // set unused space to 0xff for newer camd3's i2b_buf(4, crc32(0L, sbuf + 20, buflen), sbuf + 4); l = boundary(4, l); cs_log_dump_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, sbuf, l, "send %d bytes to %s", l, username(cl)); aes_encrypt_idx(cl->aes_keys, sbuf, l); int32_t status; if(cl->is_udp) { status = sendto(cl->udp_fd, rbuf, l + 4, 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len); if(status == -1) { set_null_ip(&SIN_GET_ADDR(cl->udp_sa)); } } else { status = send(cl->udp_fd, rbuf, l + 4, 0); if(cl->typ == 'p' && cl->reader) { if(status == -1) { network_tcp_connection_close(cl->reader, "can't send"); } } else if(cl->typ == 'c') { if(status == -1) { cs_disconnect_client(cl); } } } if(status != -1) { if(cl->reader && answer_awaited) { cl->reader->last_s = time(NULL); } if(cl->reader && !answer_awaited) { cl->reader->last_s = cl->reader->last_g = time(NULL); } cl->last = time(NULL); } return status; }
static void serverip_fn(const char *token, char *value, void *setting, FILE *f) { IN_ADDR_T srvip = *(IN_ADDR_T *)setting; if (value) { if (strlen(value) == 0) { set_null_ip((IN_ADDR_T *)setting); } else { cs_inet_addr(value, (IN_ADDR_T *)setting); } return; } if (IP_ISSET(srvip) || cfg.http_full_cfg) fprintf_conf(f, token, "%s\n", cs_inet_ntoa(srvip)); }
/* Resolves the ip of the hostname of the specified account and saves it in account->dynip. If the hostname is not configured, the ip is set to 0. */ static void cs_user_resolve(struct s_auth *account) { if (account->dyndns) { IN_ADDR_T lastip; IP_ASSIGN(lastip, account->dynip); cs_resolve(account->dyndns, &account->dynip, NULL, NULL); if (!IP_EQUAL(lastip, account->dynip)) { cs_log("%s: resolved ip=%s", account->dyndns, cs_inet_ntoa(account->dynip)); } } else { set_null_ip(&account->dynip); } }
/************************************************************************************************************************ * client functions *************************************************************************************************************************/ int pandora_client_init(struct s_client *cl) { static struct sockaddr_in loc_sa; int16_t p_proto; char ptxt[16]; struct s_reader *rdr = cl->reader; uchar md5tmp[MD5_DIGEST_LENGTH]; cl->pfd = 0; if (rdr->r_port <= 0) { cs_log("invalid port %d for server %s", rdr->r_port, rdr->device); return (1); } p_proto = IPPROTO_UDP; set_null_ip(&cl->ip); memset((char *) &loc_sa, 0, sizeof(loc_sa)); loc_sa.sin_family = AF_INET; if (IP_ISSET(cfg.srvip)) IP_ASSIGN(SIN_GET_ADDR(loc_sa), cfg.srvip); else loc_sa.sin_addr.s_addr = INADDR_ANY; loc_sa.sin_port = htons(rdr->l_port); if ((cl->udp_fd = socket(PF_INET, SOCK_DGRAM, p_proto)) < 0) { cs_log("Socket creation failed (errno=%d)", errno); return 1; } int32_t opt = 1; setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)); #ifdef SO_REUSEPORT setsockopt(cl->udp_fd, SOL_SOCKET, SO_REUSEPORT, (void *)&opt, sizeof(opt)); #endif set_socket_priority(cl->udp_fd, cfg.netprio); if (rdr->l_port > 0) { if (bind(cl->udp_fd, (struct sockaddr *) &loc_sa, sizeof(loc_sa)) < 0) { cs_log("bind failed (errno=%d)", errno); close(cl->udp_fd); return (1); } snprintf(ptxt, sizeof(ptxt), ", port=%d", rdr->l_port); } else ptxt[0] = '\0'; memcpy(cl->pand_md5_key, MD5((uchar*)rdr->r_pwd, strlen(rdr->r_pwd), md5tmp), 16); cl->crypted = 1; //cl->grp = 0xFFFFFFFF; //rdr->caid[0] = rdr->ctab.caid[0]; cl->pand_send_ecm = rdr->pand_send_ecm; memset((char *) &cl->udp_sa, 0, sizeof(cl->udp_sa)); #ifdef IPV6SUPPORT ((struct sockaddr_in *)(&cl->udp_sa))->sin_family = AF_INET; ((struct sockaddr_in *)(&cl->udp_sa))->sin_port = htons((u_short) rdr->r_port); #else cl->udp_sa.sin_family = AF_INET; cl->udp_sa.sin_port = htons((u_short) rdr->r_port); #endif cs_log("proxy %s:%d pandora %s (%s)", rdr->device, rdr->r_port, rdr->pand_send_ecm?"with ECM support":"", ptxt ); cl->pfd = cl->udp_fd; //fcntl(cl->udp_fd, F_SETFL, fcntl(cl->udp_fd, F_GETFL, 0) | O_NONBLOCK); //!!!!! return (0); }