int main(int argc, char *argv[]) { option_data options = {0}; fd_set rfds; struct timeval tv; int dmac_set = 0; int len; struct ifreq ifr; int i; int res; u8 buffer[BUFSIZE]; time_t time_now; struct arpreq arpr; odata = &options; options.spi_wait_time = 10; options.packet_print_intervall = 1000; options.ap_overhead = 44; options.rsv_bit = 1; read_arguments(argc, argv, &options); for (i = 0; i < 6; i++) { if (options.dmac[i] != 0x00) dmac_set = 1; } if (!dmac_set) { printf("Error! Destination mac must be set\n"); exit(0); } printf("Listening traffic between "); ipv4_print_address(htonl(options.src_address)); printf(" and "); ipv4_print_address(htonl(options.dst_address)); printf(" using fake IP src address "); ipv4_print_address(htonl(options.fake_src_address)); printf("\n"); printf(" using fake IP dst address "); ipv4_print_address(htonl(options.fake_dst_address)); printf("\n"); printf("Reserved bit check is %s\n",(options.rsv_bit ? "ON":"OFF")); printf("Verbose mode %i\n",options.verbose); printf("SPI change detection is %s\n",(options.spi_change_detection ? "ON":"OFF")); printf("Block to crack is "); for (i = 0; i < 6; i++) printf("%02x%s",options.block_to_crack[i],(i == 5 ? "\n" : ":")); printf("Initial guess is "); for (i = 0; i < 6; i++) printf("%02x%s",options.guess[i],(i == 5 ? "\n" : ":")); printf("Original IV is "); for (i = 0; i < 6; i++) printf("%02x%s",options.original_iv[i],(i == 5 ? "\n" : ":")); if (options.spi == 0x00000000) printf("SPI not set -> taking SPI from first ESP packet\n"); else printf("SPI 0x%08x\n",options.spi); /* Open socket for sending and listening */ listen_s = socket(AF_INET, SOCK_PACKET, htons (ETH_P_ALL)); if (listen_s < 0) { perror ("socket"); exit(1); } /* get local ethernet address. */ len = sizeof(listen_sockaddr); bzero(&listen_sockaddr, len); listen_sockaddr.sa_family = AF_INET; strcpy(listen_sockaddr.sa_data, options.listen_if); bzero (&ifr, sizeof(ifr)); strcpy (ifr.ifr_name, options.listen_if); if (ioctl (listen_s, SIOCGIFHWADDR, &ifr) < 0) { perror ("ioctl(SIOCGIFHWADDR)"); exit(1); } printf ("local address in listen socket: %s is ", options.listen_if); for (i = 0; i < 6; i++) { printf ("%02x%s", (ifr.ifr_hwaddr.sa_data [i]) & 0xff, (i == 5) ? "" : ":"); } printf (", address family 0x%x%s\n", ifr.ifr_hwaddr.sa_family, (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER) ? " (ethernet)" : ""); /* Now the send if */ send_s = socket(AF_INET, SOCK_PACKET, htons (ETH_P_ALL)); if (send_s < 0) { perror ("socket"); exit(1); } /* get local ethernet address. */ len = sizeof(send_sockaddr); bzero(&send_sockaddr, len); send_sockaddr.sa_family = AF_INET; strcpy(send_sockaddr.sa_data, options.send_if); bzero (&ifr, sizeof(ifr)); strcpy (ifr.ifr_name, options.send_if); if (ioctl (send_s, SIOCGIFHWADDR, &ifr) < 0) { perror ("ioctl(SIOCGIFHWADDR)"); exit(1); } /* bzero (&arpr, sizeof(arpr)); arpr.arp_pa.sa_family = AF_INET; memcpy(arpr.arp_pa.sa_data, (u8 *)&options.gw, 4); strcpy(arpr.arp_dev, options.send_if); if (ioctl (send_s, SIOCGARP, &arpr) < 0) { perror ("ioctl(SIOCGARP)"); exit(1); } */ for (i = 0; i < 6; i++) options.smac[i] = ifr.ifr_hwaddr.sa_data[i]; printf ("local address in send socket: %s is ", options.send_if); for (i = 0; i < 6; i++) { printf ("%02x%s", (options.smac[i]) & 0xff, (i == 5) ? "" : ":"); } printf (", address family 0x%x%s\n", ifr.ifr_hwaddr.sa_family, (ifr.ifr_hwaddr.sa_family == ARPHRD_ETHER) ? " (ethernet)" : ""); if (signal(SIGINT, user_signal_handler) == SIG_ERR || signal(SIGTERM, user_signal_handler) == SIG_ERR) { fprintf(stderr, "Error in setting a signal handler!\n"); return -1; } /* */ options.state = init; FD_ZERO(&rfds); FD_SET(listen_s,&rfds); options.start_time = time(NULL); options.spi_last_seen = time(NULL); while(1) { FD_ZERO(&rfds); FD_SET(listen_s,&rfds); tv.tv_sec = 0; tv.tv_usec = 500000; len = sizeof(listen_sockaddr); res = 0; res = select((listen_s + 1), &rfds, NULL, NULL, &tv); if (res) { res = recvfrom(listen_s, buffer, BUFSIZE, 0, &listen_sockaddr, &len); if (res < 0) { perror ("recvfrom"); exit(1); } user_ipv4_handler(buffer, &options); if (options.spi_change_detection) { time_now = time(NULL); if ((time_now - options.spi_last_seen) > options.spi_wait_time && options.spi_last_seen != 0) { printf("SPI not seen for %i seconds\n", options.spi_wait_time); exit(0); } } } else { if (options.state == send_done) { printf("senddoneK\n"); } if (options.verbose) printf("Sending a keepalive packet\n"); send_keepalive_packet(&options); } } return 1; }
/** Read incoming MMST media, header or command packet. */ static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst) { int read_result; MMSSCPacketType packet_type = -1; MMSContext *mms = &mmst->mms; for(;;) { read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer, 8); if (read_result != 8) { if(read_result < 0) { av_log(NULL, AV_LOG_ERROR, "Error reading packet header: %d (%s)\n", read_result, strerror(read_result)); packet_type = SC_PKT_CANCEL; } else { av_log(NULL, AV_LOG_ERROR, "The server closed the connection\n"); packet_type = SC_PKT_NO_DATA; } return packet_type; } // handle command packet. if(AV_RL32(mms->in_buffer + 4) == 0xb00bface) { int length_remaining, hr; mmst->incoming_flags = mms->in_buffer[3]; read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer + 8, 4); if(read_result != 4) { av_log(NULL, AV_LOG_ERROR, "Reading command packet length failed: %d (%s)\n", read_result, read_result < 0 ? strerror(read_result) : "The server closed the connection"); return read_result < 0 ? read_result : AVERROR(EIO); } length_remaining = AV_RL32(mms->in_buffer + 8) + 4; av_dlog(NULL, "Length remaining is %d\n", length_remaining); // read the rest of the packet. if (length_remaining < 0 || length_remaining > sizeof(mms->in_buffer) - 12) { av_log(NULL, AV_LOG_ERROR, "Incoming packet length %d exceeds bufsize %zu\n", length_remaining, sizeof(mms->in_buffer) - 12); return AVERROR_INVALIDDATA; } read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer + 12, length_remaining) ; if (read_result != length_remaining) { av_log(NULL, AV_LOG_ERROR, "Reading pkt data (length=%d) failed: %d (%s)\n", length_remaining, read_result, read_result < 0 ? strerror(read_result) : "The server closed the connection"); return read_result < 0 ? read_result : AVERROR(EIO); } packet_type = AV_RL16(mms->in_buffer + 36); if (read_result >= 44 && (hr = AV_RL32(mms->in_buffer + 40))) { av_log(NULL, AV_LOG_ERROR, "Server sent a message with packet type 0x%x and error status code 0x%08x\n", packet_type, hr); return AVERROR(EINVAL); } } else { int length_remaining; int packet_id_type; int tmp; // note we cache the first 8 bytes, // then fill up the buffer with the others tmp = AV_RL16(mms->in_buffer + 6); length_remaining = (tmp - 8) & 0xffff; mmst->incoming_packet_seq = AV_RL32(mms->in_buffer); packet_id_type = mms->in_buffer[4]; mmst->incoming_flags = mms->in_buffer[5]; if (length_remaining < 0 || length_remaining > sizeof(mms->in_buffer) - 8) { av_log(NULL, AV_LOG_ERROR, "Data length %d is invalid or too large (max=%zu)\n", length_remaining, sizeof(mms->in_buffer)); return AVERROR_INVALIDDATA; } mms->remaining_in_len = length_remaining; mms->read_in_ptr = mms->in_buffer; read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer, length_remaining); if(read_result != length_remaining) { av_log(NULL, AV_LOG_ERROR, "Failed to read packet data of size %d: %d (%s)\n", length_remaining, read_result, read_result < 0 ? strerror(read_result) : "The server closed the connection"); return read_result < 0 ? read_result : AVERROR(EIO); } // if we successfully read everything. if(packet_id_type == mmst->header_packet_id) { packet_type = SC_PKT_ASF_HEADER; // Store the asf header if(!mms->header_parsed) { void *p = av_realloc(mms->asf_header, mms->asf_header_size + mms->remaining_in_len); if (!p) { av_freep(&mms->asf_header); return AVERROR(ENOMEM); } mms->asf_header = p; memcpy(mms->asf_header + mms->asf_header_size, mms->read_in_ptr, mms->remaining_in_len); mms->asf_header_size += mms->remaining_in_len; } // 0x04 means asf header is sent in multiple packets. if (mmst->incoming_flags == 0x04) continue; } else if(packet_id_type == mmst->packet_id) { packet_type = SC_PKT_ASF_MEDIA; } else { av_dlog(NULL, "packet id type %d is old.", packet_id_type); continue; } } // preprocess some packet type if(packet_type == SC_PKT_KEEPALIVE) { send_keepalive_packet(mmst); continue; } else if(packet_type == SC_PKT_STREAM_CHANGING) { handle_packet_stream_changing_type(mmst); } else if(packet_type == SC_PKT_ASF_MEDIA) { pad_media_packet(mms); } return packet_type; } }
/** Read incoming MMST media, header or command packet. */ static MMSSCPacketType get_tcp_server_response(MMSContext *mms) { int read_result; MMSSCPacketType packet_type= -1; for(;;) { if((read_result= url_read_complete(mms->mms_hd, mms->in_buffer, 8))==8) { // handle command packet. if(AV_RL32(mms->in_buffer + 4)==0xb00bface) { mms->incoming_flags= mms->in_buffer[3]; read_result= url_read_complete(mms->mms_hd, mms->in_buffer+8, 4); if(read_result == 4) { int length_remaining= AV_RL32(mms->in_buffer+8) + 4; int hr; dprintf(NULL, "Length remaining is %d\n", length_remaining); // read the rest of the packet. if (length_remaining < 0 || length_remaining > sizeof(mms->in_buffer) - 12) { dprintf(NULL, "Incoming message len %d exceeds buffer len %d\n", length_remaining, sizeof(mms->in_buffer) - 12); return -1; } read_result = url_read_complete(mms->mms_hd, mms->in_buffer + 12, length_remaining) ; if (read_result == length_remaining) { packet_type= AV_RL16(mms->in_buffer+36); } else { dprintf(NULL, "read for packet type failed%d!\n", read_result); return -1; } hr = AV_RL32(mms->in_buffer + 40); if (hr) { dprintf(NULL, "The server side send back error code:0x%x\n", hr); return -1; } } else { dprintf(NULL, "read for length remaining failed%d!\n", read_result); return -1; } } else { int length_remaining; int packet_id_type; int tmp; // note we cache the first 8 bytes, // then fill up the buffer with the others tmp = AV_RL16(mms->in_buffer + 6); length_remaining = (tmp - 8) & 0xffff; mms->incoming_packet_seq = AV_RL32(mms->in_buffer); packet_id_type = mms->in_buffer[4]; mms->incoming_flags = mms->in_buffer[5]; if (length_remaining < 0 || length_remaining > sizeof(mms->in_buffer) - 8) { dprintf(NULL, "Incoming data len %d exceeds buffer len %d\n", length_remaining, sizeof(mms->in_buffer)); return -1; } mms->remaining_in_len = length_remaining; mms->read_in_ptr = mms->in_buffer; read_result= url_read_complete(mms->mms_hd, mms->in_buffer, length_remaining); if(read_result != length_remaining) { dprintf(NULL, "read_bytes result: %d asking for %d\n", read_result, length_remaining); return -1; } else { // if we successfully read everything. if(packet_id_type == mms->header_packet_id) { packet_type = SC_PKT_ASF_HEADER; // Store the asf header if(!mms->header_parsed) { void *p = av_realloc(mms->asf_header, mms->asf_header_size + mms->remaining_in_len); if (!p) { av_freep(&mms->asf_header); return AVERROR(ENOMEM); } mms->asf_header = p; memcpy(mms->asf_header + mms->asf_header_size, mms->read_in_ptr, mms->remaining_in_len); mms->asf_header_size += mms->remaining_in_len; } // 0x04 means asf header is sent in multiple packets. if (mms->incoming_flags == 0x04) continue; } else if(packet_id_type == mms->packet_id) { packet_type = SC_PKT_ASF_MEDIA; } else { dprintf(NULL, "packet id type %d is old.", packet_id_type); continue; } } } // preprocess some packet type if(packet_type == SC_PKT_KEEPALIVE) { send_keepalive_packet(mms); continue; } else if(packet_type == SC_PKT_STREAM_CHANGING) { handle_packet_stream_changing_type(mms); } else if(packet_type == SC_PKT_ASF_MEDIA) { pad_media_packet(mms); } return packet_type; } else { if(read_result<0) { dprintf(NULL, "Read error (or cancelled) returned %d!\n", read_result); packet_type = SC_PKT_CANCEL; } else { dprintf(NULL, "Read result of zero?!\n"); packet_type = SC_PKT_NO_DATA; } return packet_type; } } }