int name_by_ip (int conn_index, char * buf) { struct addrinfo hints, *res; hints.ai_family = AF_INET6; hints.ai_socktype = 0; hints.ai_protocol = 0; hints.ai_flags = AI_CANONNAME| AI_V4MAPPED; static char out_buf[OUT_BUF_SIZE]; if(getaddrinfo(&buf[sizeof(int)], "0", &hints, &res)){ //failed sprintf(out_buf, "%s 0\n", &buf[sizeof(int)]); DBG(("name_by_ip: malformed address request.")); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); return 0; } char tmpbuf[80], tmpp[80]; int ret; if(ret = getnameinfo(res->ai_addr, res->ai_addrlen, tmpbuf, 79, tmpp, 79, NI_NAMEREQD|NI_NUMERICSERV)){ sprintf(out_buf, "%s 0\n", &buf[sizeof(int)]); DBG(("%s", out_buf)); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); DBG(("name_by_ip: unable to resolve address.")); freeaddrinfo(res); return 0; } sprintf(out_buf, "%s %s\n", &buf[sizeof(int)], tmpbuf); DBG(("%s", out_buf)); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); freeaddrinfo(res); return 1; }
int name_by_ip(int conn_index, char * buf) { long addr; struct hostent *hp; static char out_buf[OUT_BUF_SIZE]; if ((addr = inet_addr(&buf[sizeof(int)])) == -1) { sprintf(out_buf, "%s 0\n", &buf[sizeof(int)]); DBG(("name_by_ip: malformed address request.")); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); return 0; } if ((hp = gethostbyaddr((char *) &addr, sizeof(addr), AF_INET))) { sprintf(out_buf, "%s %s\n", &buf[sizeof(int)], hp->h_name); DBG(("%s", out_buf)); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); return 1; } else { sprintf(out_buf, "%s 0\n", &buf[sizeof(int)]); DBG(("%s", out_buf)); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); DBG(("name_by_ip: unable to resolve address.")); return 0; } }
/* * This is the new connection handler. This function is called by the * event handler when data is pending on the listening socket (conn_fd). * If space is available, an interactive data structure is initialized and * the connected is established. */ void new_conn_handler() { #ifdef IPV6 struct sockaddr_in6 client; #else struct sockaddr_in client; #endif socklen_t client_len; struct hostent *c_hostent; int new_fd; int conn_index; client_len = sizeof(client); new_fd = accept(conn_fd, (struct sockaddr *) & client, &client_len); if (new_fd == -1) { socket_perror("new_conn_handler: accept", 0); return; } if (set_socket_nonblocking(new_fd, 1) == -1) { socket_perror("new_conn_handler: set_socket_nonblocking 1", 0); OS_socket_close(new_fd); return; } if (total_conns >= MAX_CONNS) { char *message = "no available slots -- closing connection.\n"; fprintf(stderr, "new_conn_handler: no available connection slots.\n"); OS_socket_write(new_fd, message, strlen(message)); if (OS_socket_close(new_fd) == -1) socket_perror("new_conn_handler: close", 0); return; } /* get some information about new connection */ for (conn_index = 0; conn_index < MAX_CONNS; conn_index++) { if (all_conns[conn_index].state == CONN_CLOSED) { DBG(("new_conn_handler: opening conn index %d", conn_index)); /* update global data for new fd */ all_conns[conn_index].fd = new_fd; all_conns[conn_index].state = CONN_OPEN; all_conns[conn_index].addr = client; char portname[256]; if(getnameinfo(&client, sizeof(client), all_conns[conn_index].sname, SNAME_LEN, portname, 255, NI_NAMEREQD|NI_NUMERICHOST)) strcpy(all_conns[conn_index].sname, "<unknown>"); total_conns++; return; } } fprintf(stderr, "new_conn_handler: sanity check failed!\n"); }
int ip_by_name (int conn_index, char * buf) { struct hostent *hp; struct in_addr my_in_addr; static char out_buf[OUT_BUF_SIZE]; hp = gethostbyname(&buf[sizeof(int)]); if (hp == NULL) { /* Failed :( */ sprintf(out_buf, "%s 0\n", &buf[sizeof(int)]); DBG(("%s", out_buf)); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); return 0; } else { /* Success! */ memcpy(&my_in_addr, hp->h_addr, sizeof(struct in_addr)); sprintf(out_buf, "%s %s\n", &buf[sizeof(int)], inet_ntoa(my_in_addr)); DBG(("%s", out_buf)); OS_socket_write(all_conns[conn_index].fd, out_buf, strlen(out_buf)); return 1; } } /* ip_by_name() */
/* * This is the new connection handler. This function is called by the * event handler when data is pending on the listening socket (conn_fd). * If space is available, an interactive data structure is initialized and * the connected is established. */ void new_conn_handler() { struct sockaddr_in client; int client_len; struct hostent *c_hostent; int new_fd; int conn_index; client_len = sizeof(client); new_fd = accept(conn_fd, (struct sockaddr *) & client, (int *) &client_len); if (new_fd == -1) { socket_perror("new_conn_handler: accept", 0); return; } if (set_socket_nonblocking(new_fd, 1) == -1) { socket_perror("new_conn_handler: set_socket_nonblocking 1", 0); OS_socket_close(new_fd); return; } if (total_conns >= MAX_CONNS) { char *message = "no available slots -- closing connection.\n"; fprintf(stderr, "new_conn_handler: no available connection slots.\n"); OS_socket_write(new_fd, message, strlen(message)); if (OS_socket_close(new_fd) == -1) socket_perror("new_conn_handler: close", 0); return; } /* get some information about new connection */ c_hostent = gethostbyaddr((char *) &client.sin_addr.s_addr, sizeof(client.sin_addr.s_addr), AF_INET); for (conn_index = 0; conn_index < MAX_CONNS; conn_index++) { if (all_conns[conn_index].state == CONN_CLOSED) { DBG(("new_conn_handler: opening conn index %d", conn_index)); /* update global data for new fd */ all_conns[conn_index].fd = new_fd; all_conns[conn_index].state = CONN_OPEN; all_conns[conn_index].addr = client; if (c_hostent) strcpy(all_conns[conn_index].sname, c_hostent->h_name); else strcpy(all_conns[conn_index].sname, "<unknown>"); total_conns++; return; } } fprintf(stderr, "new_conn_handler: sanity check failed!\n"); }
void f_thread() { int sv[2]; fd = find_new_socket(); if (fd < 0) return fd; if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1) return EESOCKET; ret = fork(); if (ret == -1) { error("fork() in debug() failed: %s\n", strerror(errno)); } if(ret){ close(sv[1]); lpc_socks[fd].fd = sv[0]; lpc_socks[fd].flags = S_EXTERNAL; set_read_callback(fd, sp-3); set_write_callback(fd, sp-2); set_close_callback(fd, sp-1); lpc_socks[fd].owner_ob = current_object; lpc_socks[fd].mode = MUD; lpc_socks[fd].state = STATE_DATA_XFER; memset((char *) &lpc_socks[fd].l_addr, 0, sizeof(lpc_socks[fd].l_addr)); memset((char *) &lpc_socks[fd].r_addr, 0, sizeof(lpc_socks[fd].r_addr)); lpc_socks[fd].owner_ob = current_object; lpc_socks[fd].release_ob = NULL; lpc_socks[fd].r_buf = NULL; lpc_socks[fd].r_off = 0; lpc_socks[fd].r_len = 0; lpc_socks[fd].w_buf = NULL; lpc_socks[fd].w_off = 0; lpc_socks[fd].w_len = 0; current_object->flags |= O_EFUN_SOCKET; return fd; } close(sv[0]); function_to_call_t cb; memset(&cb, 0, sizeof(function_to_call_t)); process_efun_callback(0, &cb, F_THREAD); for(i=0; i<5; i++) if(external_port[i].port) close(external_port[i].fd); //close external ports for(i=0;i<sizeof(lpc_socks)/sizeof(lpc_socks[0]);i++) close(lpc_sock[i].fd); svalue_t *res = call_efun_callback(&cb, 1); switch (res->type) { case T_OBJECT: break; default: save_svalue_depth = 0; int len = svalue_save_size(message); if (save_svalue_depth > MAX_SAVE_SVALUE_DEPTH) { OS_socket_write(sv[1], "\x00\x00\x00\x11\"result too big\"", 21); break; } char *buf = (char *) DMALLOC(len + 5, TAG_TEMPORARY, "socket_write: default"); if (buf == NULL) break; *(INT_32 *) buf = htonl((long) len); len += 4; buf[4] = '\0'; p = buf + 4; save_svalue(message, &p); int ret,written = 0; while(written < len){ ret = OS_socket_write(sv[1], buf+written, len-written); if(ret < 0) break; written += ret; } break; } fflush(0); exit(0); }