static gboolean package_write (xmms_vis_client_t *c, int32_t id, struct timeval *time, int channels, int size, short *buf) { if (c->type == VIS_UNIXSHM) { return write_shm (&c->transport.shm, c, id, time, channels, size, buf); } else if (c->type == VIS_UDP) { return write_udp (&c->transport.udp, c, id, time, channels, size, buf, vis->socket); } return FALSE; }
int check_dhcp(const struct arguments *args, const struct udp_session *u, const uint8_t *data, const size_t datalen) { // This is untested // Android routing of DHCP is erroneous log_android(ANDROID_LOG_WARN, "DHCP check"); if (datalen < sizeof(struct dhcp_packet)) { log_android(ANDROID_LOG_WARN, "DHCP packet size %d", datalen); return -1; } const struct dhcp_packet *request = (struct dhcp_packet *) data; if (ntohl(request->option_format) != DHCP_OPTION_MAGIC_NUMBER) { log_android(ANDROID_LOG_WARN, "DHCP invalid magic %x", request->option_format); return -1; } if (request->htype != 1 || request->hlen != 6) { log_android(ANDROID_LOG_WARN, "DHCP unknown hardware htype %d hlen %d", request->htype, request->hlen); return -1; } log_android(ANDROID_LOG_WARN, "DHCP opcode", request->opcode); // Discover: source 0.0.0.0:68 destination 255.255.255.255:67 // Offer: source 10.1.10.1:67 destination 255.255.255.255:68 // Request: source 0.0.0.0:68 destination 255.255.255.255:67 // Ack: source: 10.1.10.1 destination: 255.255.255.255 if (request->opcode == 1) { // Discover/request struct dhcp_packet *response = calloc(500, 1); // Hack inet_pton(AF_INET, "10.1.10.1", &u->saddr); /* Discover: DHCP option 53: DHCP Discover DHCP option 50: 192.168.1.100 requested DHCP option 55: Parameter Request List: Request Subnet Mask (1), Router (3), Domain Name (15), Domain Name Server (6) Request DHCP option 53: DHCP Request DHCP option 50: 192.168.1.100 requested DHCP option 54: 192.168.1.1 DHCP server. */ memcpy(response, request, sizeof(struct dhcp_packet)); response->opcode = (uint8_t) (request->siaddr == 0 ? 2 /* Offer */ : /* Ack */ 4); response->secs = 0; response->flags = 0; memset(&response->ciaddr, 0, sizeof(response->ciaddr)); inet_pton(AF_INET, "10.1.10.2", &response->yiaddr); inet_pton(AF_INET, "10.1.10.1", &response->siaddr); memset(&response->giaddr, 0, sizeof(response->giaddr)); // https://tools.ietf.org/html/rfc2132 uint8_t *options = (uint8_t *) (response + sizeof(struct dhcp_packet)); int idx = 0; *(options + idx++) = 53; // Message type *(options + idx++) = 1; *(options + idx++) = (uint8_t) (request->siaddr == 0 ? 2 : 5); /* 1 DHCPDISCOVER 2 DHCPOFFER 3 DHCPREQUEST 4 DHCPDECLINE 5 DHCPACK 6 DHCPNAK 7 DHCPRELEASE 8 DHCPINFORM */ *(options + idx++) = 1; // subnet mask *(options + idx++) = 4; // IP4 length inet_pton(AF_INET, "255.255.255.0", options + idx); idx += 4; *(options + idx++) = 3; // gateway *(options + idx++) = 4; // IP4 length inet_pton(AF_INET, "10.1.10.1", options + idx); idx += 4; *(options + idx++) = 51; // lease time *(options + idx++) = 4; // quad *((uint32_t *) (options + idx)) = 3600; idx += 4; *(options + idx++) = 54; // DHCP *(options + idx++) = 4; // IP4 length inet_pton(AF_INET, "10.1.10.1", options + idx); idx += 4; *(options + idx++) = 6; // DNS *(options + idx++) = 4; // IP4 length inet_pton(AF_INET, "8.8.8.8", options + idx); idx += 4; *(options + idx++) = 255; // End /* DHCP option 53: DHCP Offer DHCP option 1: 255.255.255.0 subnet mask DHCP option 3: 192.168.1.1 router DHCP option 51: 86400s (1 day) IP address lease time DHCP option 54: 192.168.1.1 DHCP server DHCP option 6: DNS servers 9.7.10.15 */ write_udp(args, u, (uint8_t *) response, 500); free(response); } return 0; }
void sendto_udp(int senderid,int sockfd,int datalen,u_char *data,int flags, struct sockaddr *addr,socklen_t addrlen) { uint16_t hostport; uint16_t dstport; uint32_t host_IP; uint32_t dst_IP; int len=datalen; int index; /** check if the original call is either (sendto) or (send) or (write)*/ if ( (addr == NULL) && (addrlen == 0) && (flags != -1000) ) { /** In case of (send) */ PRINT_DEBUG(); return ( send_udp(senderid,sockfd,datalen,data,flags) ) ; } if ( (addr == NULL) && (addrlen == 0) && (flags == -1000)) { PRINT_DEBUG(); /** In case of (write) */ return ( write_udp (senderid,sockfd,datalen,data) ) ; } PRINT_DEBUG(); /** TODO handle flags cases */ switch (flags) { case MSG_CONFIRM: case MSG_DONTROUTE: case MSG_DONTWAIT : case MSG_EOR: case MSG_MORE : case MSG_NOSIGNAL: case MSG_OOB: /** case of recieving a (write call)*/ default: break; } PRINT_DEBUG(""); struct sockaddr_in *address; address = (struct sockaddr_in *) addr; /** TODO lock access to the jinnisockets */ index = findjinniSocket(senderid,sockfd); PRINT_DEBUG(""); /** TODO unlock access to the jinnisockets */ if (index == -1) { PRINT_DEBUG("CRASH !! socket descriptor not found into jinni sockets"); exit(1); } if (address->sin_family != AF_INET ) { PRINT_DEBUG("Wrong address family"); PRINT_DEBUG(""); sem_wait(jinniSockets[index].s); PRINT_DEBUG(""); nack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); PRINT_DEBUG(""); } /** copying the data passed to be able to free the old memory location * the new created location is the one to be included into the newly created finsFrame*/ PRINT_DEBUG(""); /** Keep all ports and addresses in host order until later action taken */ dstport =ntohs( address->sin_port); /** reverse it since it is in network order after application used htons */ if (dst_IP != INADDR_LOOPBACK) dst_IP = ntohl(address-> sin_addr.s_addr);/** it is in network format since application used htonl */ else dst_IP = ntohl(address-> sin_addr.s_addr); //hostport = jinniSockets[index].hostport; hostport = 3000; host_IP = jinniSockets[index].host_IP; PRINT_DEBUG(""); PRINT_DEBUG("%d,%d,%d,%d", dst_IP, dstport, host_IP,hostport); //free(data); //free(addr); PRINT_DEBUG(""); /** the meta-data paraters are all passes by copy starting from this point * */ if (jinni_UDP_to_fins(data,len,dstport,dst_IP,hostport,host_IP)== 1) { PRINT_DEBUG(""); /** TODO prevent the socket interceptor from holding this semaphore before we reach this point */ sem_wait(jinniSockets[index].s); PRINT_DEBUG(""); ack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); PRINT_DEBUG(""); } else { PRINT_DEBUG("socketjinni failed to accomplish sendto"); sem_wait(jinniSockets[index].s); nack_write(jinniSockets[index].jinniside_pipe_ds,senderid,sockfd); sem_post(jinniSockets[index].as); sem_post(jinniSockets[index].s); } return; } //end of sendto_udp
void send_udp(unsigned long long uniqueSockID, int socketCallType, int datalen, u_char *data, int flags) { uint16_t hostport; uint16_t dstport; uint32_t host_IP; uint32_t dst_IP; int len = datalen; int index; if (flags == -1000) { return (write_udp(uniqueSockID, socketCallType, datalen, data)); } /** TODO handle flags cases */ switch (flags) { case MSG_CONFIRM: case MSG_DONTROUTE: case MSG_DONTWAIT: case MSG_EOR: case MSG_MORE: case MSG_NOSIGNAL: case MSG_OOB: /** case of recieving a (write call)*/ default: break; } // end of the switch clause PRINT_DEBUG(""); index = findjinniSocket(uniqueSockID); if (index == -1) { PRINT_DEBUG("CRASH !! socket descriptor not found into jinni sockets"); return; } /** copying the data passed to be able to free the old memory location * the new created location is the one to be included into the newly created finsFrame*/ PRINT_DEBUG(""); /** check if this socket already connected to a destined address or not */ if (jinniSockets[index].connection_status == 0) { /** socket is not connected to an address. Send call will fail */ PRINT_DEBUG("socketjinni failed to accomplish send"); nack_send(uniqueSockID, socketCallType); return; } /** Keep all ports and addresses in host order until later action taken */ dstport = jinniSockets[index].dstport; dst_IP = jinniSockets[index].dst_IP; //hostport = jinniSockets[index].hostport; //hostport = 3000; /** addresses are in host format given that there are by default already filled * host IP and host port. Otherwise, a port and IP has to be assigned explicitly below */ /** * the current value of host_IP is zero but to be filled later with * the current IP using the IPv4 modules unless a binding has occured earlier */ host_IP = jinniSockets[index].host_IP; /** * Default current host port to be assigned is 58088 * It is supposed to be randomly selected from the range found in * /proc/sys/net/ipv4/ip_local_port_range * default range in Ubuntu is 32768 - 61000 * The value has been chosen randomly when the socket firstly inserted into the jinnisockets * check insertjinniSocket(processid, sockfd, fakeID, type, protocol); */ hostport = jinniSockets[index].hostport; if (hostport == (uint16_t)(-1)) { while (1) { hostport = randoming(MIN_port, MAX_port); if (checkjinniports(hostport, host_IP)) { break; } } jinniSockets[index].hostport = hostport; } PRINT_DEBUG(""); PRINT_DEBUG("addr %d,%d,%d,%d", dst_IP, dstport, host_IP, hostport); //free(data); //free(addr); PRINT_DEBUG(""); /** the meta-data paraters are all passes by copy starting from this point * */ if (jinni_UDP_to_fins(data, len, dstport, dst_IP, hostport, host_IP) == 1) { PRINT_DEBUG(""); /** TODO prevent the socket interceptor from holding this semaphore before we reach this point */ PRINT_DEBUG(""); ack_send(uniqueSockID, socketCallType); PRINT_DEBUG(""); } else { PRINT_DEBUG("socketjinni failed to accomplish send"); nack_send(uniqueSockID, socketCallType); } }// end of send_udp