void *process_request(void *sock_id){ char *host; char *serv_port; void *buf = malloc(BUF_START_SIZE+1); size_t bufsize = BUF_START_SIZE; int new_s_client = (int) (intptr_t) sock_id; int s_server, proxy_port; int length=0, i, recieved, recieved_s, sent; struct addrinfo hints, *servinfo, *p; /*declare for getpeername*/ struct sockaddr_in sin; socklen_t sockLen = sizeof(struct sockaddr); int src_port; char ipstr[INET6_ADDRSTRLEN]; static char dstbuf[INET6_ADDRSTRLEN]; char eth0_IP[INET6_ADDRSTRLEN]; /*declare for bind*/ char SNAT[100]; struct sockaddr_in serv_add; socklen_t serv_len = sizeof( struct sockaddr); bzero((char *)&serv_add, sizeof(serv_add)); serv_add.sin_family = AF_INET; serv_add.sin_port = htons(0); /*declare for log*/ int bytes_recv=0; int bytes_sent=0; pthread_detach(pthread_self()); bzero(buf, bufsize); /* update number of threads currently operating */ pthread_mutex_lock(&count_lock); num_threads++; printf("Increasing:%d\n",num_threads); pthread_mutex_unlock(&count_lock); /* recieve from client*/ recieved = read(new_s_client, buf, bufsize); if(recieved < 0){ printf("recieved error\n"); free(host); free(buf); kill_thread(); pthread_cancel(pthread_self()); return NULL; }else if(recieved == 0){ close(new_s_client); close(s_server); return NULL; } printf("recv from client:%s\n",buf); /*getpeername -- client IP*/ getpeername(new_s_client, (struct sockaddr*)&sin, &sockLen); struct sockaddr_in *s = (struct sockaddr_in *)&sin; src_port = ntohs(s->sin_port); inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); /*Get the server ip*/ struct sockaddr_in dstaddr; socklen_t len = sizeof(dstaddr); if (getsockopt(new_s_client, SOL_IP, SO_ORIGINAL_DST, (struct sockaddr *) &dstaddr, &len) == -1) { perror("getsockopt"); close(new_s_client); } inet_ntop(dstaddr.sin_family, &dstaddr.sin_addr, dstbuf, sizeof(dstbuf)); printf("original destination %s:%u\n", dstbuf, ntohs(dstaddr.sin_port)); host = malloc(strlen(dstbuf)); sprintf(host, "%s", dstbuf); serv_port = malloc(sizeof (ntohs(dstaddr.sin_port))); sprintf(serv_port, "%u", ntohs(dstaddr.sin_port)); getInterfaceIP("eth0", eth0_IP); /* printf("client address: %s\n", ipstr); // printf("proxy port of server side: %d\n", proxy_port); printf("port of client: %d\n", src_port); printf("serverside_ip: %s\n", eth0_IP); printf("dst port:%s\n",serv_port); //addto_iptables (proxy_port, ipstr, dstbuf, eth0_IP, src_port, serv_port); */ /* send request to the specified host */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ( (getaddrinfo(host, serv_port, &hints, &servinfo)) != 0) { send_err(new_s_client, HTTP_ERR_502); free(host); free(buf); kill_thread(); pthread_cancel(pthread_self()); return NULL; } for(p = servinfo; p != NULL; p = p->ai_next) { if ((s_server = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0){ kill_thread(); pthread_cancel(pthread_self()); return NULL; } if ( (bind(s_server, (struct sockaddr *)&serv_add, sizeof(serv_add))) < 0){ perror("cannot bind to socket"); exit(1); } /*getsockname -- source port*/ getsockname(s_server, (struct sockaddr*)&serv_add, &serv_len); proxy_port = ntohs(serv_add.sin_port); sprintf(SNAT, "iptables -t nat -A POSTROUTING --protocol tcp -d %s -j SNAT --sport %d --to-source %s", dstbuf, proxy_port, ipstr); system(SNAT); if (connect(s_server, p->ai_addr, p->ai_addrlen) < 0) { close(s_server); continue; } break; } freeaddrinfo(servinfo); if (p == NULL){ send_err(new_s_client, HTTP_ERR_500); free(host); free(buf); kill_thread(); pthread_cancel(pthread_self()); return NULL; } /*Send req to server*/ if( ( sent = write(s_server, buf, recieved)) == -1 ){ printf("Send error\n"); free(host); free(buf); kill_thread(); pthread_cancel(pthread_self()); return NULL; } //printf("sent:%d\n", sent); bytes_sent += recieved; bzero(buf, bufsize); pthread_mutex_lock(&cache_write_lock); for (i = 0; i < MAX_NUM_THREADS; i++) sem_wait(&cache_read_sem); //echo bytes_recv = echo(s_server, new_s_client, buf, bufsize); //printf("bytes recieved:%d\n",bytes_recv); for (i = 0; i < MAX_NUM_THREADS; i++) sem_post(&cache_read_sem); pthread_mutex_unlock(&cache_write_lock); /*logging*/ logEvent("%s %d %s %s %d %d\n", ipstr, src_port, host, serv_port, bytes_sent, bytes_recv ); sprintf(SNAT, "iptables -t nat -D POSTROUTING --protocol tcp -d %s -j SNAT --sport %d --to-source %s", dstbuf, proxy_port, ipstr); system(SNAT); pthread_mutex_lock(&count_lock); num_threads--; printf("Decreasing:%d\n",num_threads); pthread_mutex_unlock(&count_lock); free(host); pthread_cancel(pthread_self()); return NULL; }
int main(int argc, char * argv[]){ int MULTITHREADED = TRUE; void (*ret)(int); int s_client; int new_s_client; struct sockaddr_in sin; socklen_t sockLen = sizeof(struct sockaddr); uint16_t portnum; /*DNAT system call*/ char DNAT[100]; char eth1_IP[INET6_ADDRSTRLEN]; char ip[INET6_ADDRSTRLEN]; pthread_t thread; pthread_attr_t thread_attr; pthread_attr_init(&thread_attr); pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); if(geteuid() != 0){ printf("This program must be run as root\n"); exit(1); } ret = signal(SIGPIPE, SIG_IGN); if (ret == SIG_ERR){ perror(argv[0]); exit(1); } if (argc == 2) portnum = (uint16_t)atoi(argv[1]); else{ fprintf(stderr, "usage: proxy [-t] <portnum>\n"); exit(1); } bzero((char *)&sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(portnum); /* open a socket and attempt to bind to the given port */ if ( (s_client = socket(PF_INET, SOCK_STREAM, 0)) < 0){ perror("error requesting socket"); exit (1); } setsockopt(s_client, SOL_SOCKET, SO_REUSEADDR, NULL, 0); if ( (bind(s_client, (struct sockaddr *)&sin, sizeof(sin))) < 0){ perror("cannot bind to socket"); exit(1); } /*DNAT - System call*/ getInterfaceIP("eth1", eth1_IP); //printf("proxy ip:%s\nproxy port num:%d\n", eth1_IP, sin.sin_port); sprintf(DNAT, "iptables -t nat -A PREROUTING --protocol tcp -i eth1 -j DNAT --to %s:%d", eth1_IP, portnum); system(DNAT); listen(s_client, MAX_QUEUE); pthread_mutex_init(&count_lock, NULL); pthread_mutex_init(&cache_write_lock, NULL); sem_init(&cache_read_sem, PTHREAD_PROCESS_PRIVATE, MAX_NUM_THREADS); while (1){ if (num_threads < MAX_NUM_THREADS){ if ( (new_s_client = accept(s_client, (struct sockaddr *)&sin, &sockLen)) < 0) continue; inet_ntop(sin.sin_family, &sin.sin_addr, ip, sizeof(ip)); printf("connection from %s:%u\n", ip, ntohs(sin.sin_port)); /*Implement multi-thread*/ if (MULTITHREADED) { if (pthread_create(&thread, &thread_attr, process_request, (void *) (long) new_s_client) != 0) { send_err(new_s_client, HTTP_ERR_500); close(new_s_client); } }else{ process_request((void *) (long) new_s_client); } }else{ sleep(1); } } return 1; }
void dhcp_server( void ) { char *iface_pref, *euid_pref, *dbhost_pref, *force_chroot; char *dhcp_high_load_c; int dhcp_high_load; dhcp_message message; u_int32_t server_ip; struct passwd *pass_struct; int retval = 0, cc = 0, sentreply; iface_pref = my_GetDHCPint(); server_ip = getInterfaceIP( iface_pref ); init_DHCP_Socket( server_ip ); // euid_pref = GetConfigVar( "effective-userid" ); // pass_struct = getpwnam( euid_pref ); // if (pass_struct) { // seteuid( pass_struct->pw_uid ); // setegid( pass_struct->pw_gid ); // } dbhost_pref = GetConfigVar( "mysql-host" ); force_chroot = GetConfigVar( "force-localhost-chroot" ); // if (strcmp(dbhost_pref,"localhost") || !strcmp(force_chroot, "yes")) { // // We cannot chroot if connect to the DB via // // a unix socket vs tcp // chroot( CHROOT_PATH ); // } dhcp_high_load_c = GetConfigVar( "dhcp-high-load" ); if (*dhcp_high_load_c == ' ') { dhcp_high_load_c = "16"; } dhcp_high_load = strtoul( dhcp_high_load_c, NULL, 10 ); if (dhcp_high_load <= 4) { dhcp_high_load = 4; } if (dhcp_high_load >= 128) { dhcp_high_load = 128; } my_Check_Load( dhcp_high_load ); InitSQLconnection(); my_syslog( MLOG_DHCP, "docsis_server DHCP version %s activated", VERSION); Clear_Remote_Commands(); while (dhcpd_exit_flag) { /* loop until universe collapses */ /* update the PID file */ update_pid_file(); /* Clear Message Struct */ memset( &message, 0, sizeof( dhcp_message ) ); retval = getPacket( &message ); if (retval == -2) Check_Remote_Commands(); if (retval < 0) { // ping the MySQL server my_SQL_Ping(); continue; } message.server_ip = server_ip; if (Check_Canary) { fprintf(stderr,"canary A died %llu %llu %llu " " %llu %llu %llu %llu %llu %llu\n",Canaries); continue; } DecodeOptions( &message ); if (message.in_opts.message_type == 0) { message.in_opts.message_type = DHCP_REQUEST; } if (Check_Canary) { fprintf(stderr,"canary B died %llu %llu %llu " " %llu %llu %llu %llu %llu %llu\n",Canaries); continue; } sentreply = 0; switch( message.in_opts.message_type ) { case DHCP_DISCOVER: sentreply = send_Offer( &message ); break; case DHCP_REQUEST: sentreply = send_ACK( &message ); break; case DHCP_RELEASE: /* checkRelease( &message ); */ break; case DHCP_INFORM: sentreply = send_ACK( &message ); break; case DHCP_DECLINE: /* ignore */ break; case DHCP_LEASE_QUERY: /* wierd ubR thingy 0x0d */ sentreply = leaseQuery( &message ); break; default: { my_syslog(LOG_WARNING, "unsupported DHCP message (%02x) %s -- ignoring", message.in_opts.message_type, message.s_macaddr ); } } if (Check_Canary) { fprintf(stderr,"canary C died %llu %llu %llu " " %llu %llu %llu %llu %llu %llu\n",Canaries); continue; } if (sentreply) my_Check_Load( dhcp_high_load ); Check_Remote_Commands(); } my_syslog(LOG_INFO, "exit"); Flush_ALL_SQL_Updates(); closelog(); exit(0); }
/* bootAgentNotice is used to notice the PM service that the boot Agent starts up. Also, the hostname and IP address is deliver to the PM service. */ static int bootAgentNotice(int dbg) { int sock; char bsip[30]; char myIP[30]; char hostname[100]; char sendbuf[1024]; char recvbuf[1024]; int socklen=0; fd_set rfds; int ret = 0; int retry = 0; struct timeval tv; struct sockaddr_in sendAddr; struct sockaddr_in recvaddr; if(dbg == 1) sprintf(bsip, "127.0.0.1\0"); else bsDiscovery(bsip); getInterfaceIP("eth1", myIP, sizeof(myIP)); if(getHostname(hostname, sizeof(hostname))==-1) return -1; printf("Hostname-->%s\n",hostname); sock=createUdpClient(); if(sock==-1) return -1; memset(&sendAddr,0,sizeof(sendAddr)); sendAddr.sin_family=AF_INET; sendAddr.sin_port=htons(POALPORT); sendAddr.sin_addr.s_addr=inet_addr(bsip); sprintf(sendbuf, "%s,%s\0", hostname, myIP); while(1) { if(sendto(sock, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&sendAddr, sizeof(sendAddr)) ==-1) { goto errexit; } socklen=1024; memset(recvbuf, 0, sizeof(recvbuf)); memset(&tv, 0, sizeof(tv)); FD_ZERO(&rfds); FD_SET(sock, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; ret = select(sock+1, &rfds, NULL, NULL, &tv); if(ret == -1) { printf("Select Error\n"); goto errexit; }else if(ret) { if (recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&recvaddr, &socklen) > 0) { printf("%s\n", recvbuf); if(!strncmp(recvbuf, "OK", 2)) break; } }else { printf("No Ack retry\n"); if(retry > 5) break; retry++; } } close(sock); return 1; errexit: close(sock); return -1; }
int getRemoteARP(struct pm_cfg cfg, unsigned int targetIP, const char *device, char *mac) { unsigned int localIP; char errbuf[PCAP_ERRBUF_SIZE] = {0}; ARPPACKET arp; struct bpf_program fp; struct pcap_pkthdr *header; const u_char *pkt_data; int sent = 0; int found = 1; char filter[100] = {0}; struct in_addr addr; pcap_t *pHandle = pcap_open_live(device, SNAP_LEN, 0, ARP_WAIT_TIME, errbuf); if (pHandle == NULL) { syslog(LOG_ERR, "unable to open capture device %s: %s", device, errbuf); return -1; } if (getInterfaceIP(device, &localIP) < 0) { syslog(LOG_ERR, "unable to get IP address for %s", device); pcap_close(pHandle); return -1; } //send arp request to an IP. memset(&arp, 0, sizeof(arp)); memset(arp.ethhdr.h_dest, 0xFF, ETH_ALEN); arp.ethhdr.h_proto = htons(ETH_P_ARP); arp.arphdr.ar_hrd = htons(ETH_P_802_3); arp.arphdr.ar_pro = htons(ETH_P_IP); arp.arphdr.ar_hln = ETH_ALEN; // Hardware size: 6(0x06) arp.arphdr.ar_pln = 4; // Protocol size; 4 arp.arphdr.ar_op = htons(ARPOP_REQUEST); // Opcode: request (0x0001) memset(arp.arphdr.ar_tha, 0, ETH_ALEN); arp.arphdr.ar_tip = targetIP; memcpy(arp.ethhdr.h_source, cfg.src_mac, ETH_ALEN); memcpy(arp.arphdr.ar_sha, cfg.src_mac, ETH_ALEN); arp.arphdr.ar_sip = localIP; addr.s_addr = targetIP; sprintf(filter, "arp host %s", inet_ntoa(addr)); pcap_compile(pHandle, &fp, filter, 0, 0); pcap_setfilter(pHandle, &fp); pcap_sendpacket(pHandle, (unsigned char *)&arp, sizeof(arp)); while (1) { int res = pcap_next_ex(pHandle, &header, &pkt_data); if (res == 1) { if (*(unsigned short *)(pkt_data + 12) == htons(0x0806) && header->len >= sizeof(ARPPACKET)) { ARPPACKET* p = (ARPPACKET *)pkt_data; if (p->arphdr.ar_op == htons(ARPOP_REPLY) && p->arphdr.ar_sip == targetIP) { memcpy(mac, (const char *)p->ethhdr.h_source, ETH_ALEN); found = 0; if (cfg.flags & PM_DEBUG) { syslog(LOG_INFO, "ARP reply on '%s'['%s'] filter '%s'", device, printMACStr(mac), filter); } break; } } } if (res == 0) { if (sent++ < 2) { pcap_sendpacket(pHandle, (unsigned char *)&arp, sizeof(arp)); } else { break; } } if (res == -1) { syslog(LOG_ERR, "error reading packet: %s", pcap_geterr(pHandle)); break; } } pcap_close(pHandle); return found; }