int main( void ) { // Stop the watchdog timer. WDTCTL = WDTPW + WDTHOLD; // Clock settings set_mcu_speed_xt2_mclk_8MHz_smclk_8MHz(); // used by CDMA set_aclk_div(1); // ACKL is at 32768Hz // used for clock synchronization // Initialize the UART0 uart0_init(UART0_CONFIG_8MHZ_115200); // 115kbaud, SMCLK is at 8MHz uart0_register_callback(char_rx); // Set the UART callback function // Initialize random number ds2411_init(); rnd = (((uint16_t)ds2411_id.serial0) << 8) + (uint16_t)ds2411_id.serial1; // Timer settings time_1w = 0; timerA_init(); timerA_start_ACLK_div(TIMERA_DIV_1); // timerA period = 2s timerA_register_cb(TIMERA_ALARM_OVER, timer_overflow); // timerA overflow event timerA_register_cb(TIMERA_ALARM_CCR0, run_algorithm); // run algorithm at CCR0 timerA_register_cb(TIMERA_ALARM_CCR1, skew_correction); // compensate skew error at CCR1 timerA_set_alarm_from_now(TIMERA_ALARM_CCR0, rnd, 54983); // same period 1.678s, different phase timerA_set_alarm_from_now(TIMERA_ALARM_CCR1, 35000, skew); // skew compensation happens every 'skew' ticks // Initialize the MAC layer (radio) mac_init(11); mac_set_rx_cb(frame_rx); mac_set_error_cb(frame_error); mac_set_sent_cb(frame_sent); // Enable Interrupts eint(); while (1) { } return 0; }
void net_init() { int i; // initialize MAC layer, and timerB mac_init(4); // register mac callback mac_set_rx_cb(frame_received); // init callback rx_cb = 0x0; state = STATE_RX; for (i=0; i<MAX_KNOWN_PACKETS; i++) { known_packets[i].src_addr[0] = 0; known_packets[i].src_addr[1] = 0; known_packets[i].id = 0; } }
void main() { // Initialize RobotNet stack hal_init(); mac_init(); trans_init(); // Main loop while (1) { // Keep stack rolling mac_FSM(); // Deal with newly frame? if ( trans_frm_avail() ) { trans_frm_parse(); } } }
int main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer eint(); clock_dco_set(8); // DCO 8MHz clock_mclk_set(CLOCK_SOURCE_DCO, 1); // MCLK 8MHz clock_smclk_set(CLOCK_SOURCE_DCO, 8); // SMCLK 1MHz clock_aclk_set(1); leds_init(); leds_off(LEDS_ALL); mac_init(); mac_set_tx_cb(sent); mac_set_rx_cb(rx); timer_start(TIMER_SOURCE_ACLK, 1); timer_register_cb(TIMER_ALARM_0, send); timer_set_alarm(TIMER_ALARM_0, 12000, 12000, TIMER_MODE_FROM_NOW, 0); leds_on(LEDS_ALL); while (1) { event = 0; LPM0; switch (event) { case EVENT_SEND: mac_send(msg, strlen(msg), MAC_BROADCAST); break; case EVENT_SENT: leds_toggle(LED_GREEN); break; case EVENT_RX: leds_toggle(LED_RED); break; } } return 0; }
// ----------------------------------------------------------------------------- // Main // ----------------------------------------------------------------------------- void main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer PM5CTL0 &= ~LOCKLPM5; init_clock(); event_init(); timers_init(); srand(NODE_ADDRESS); debug_comm_uart_init(debug_uart_cmdline_handler); tascam_uart_init(tascam_uart_cmdline_handler); gpio_init_player_dev(player_dev_sw1_handler, player_dev_sw2_handler); mac_init(lora_rx_packet_handler, false, true); // Enabling global interrupts _EINT(); // Starting the event loop event_loop(); }
int mac_valid(const char *names) { char *maclist, *cp, *p; if (names == NULL || strcmp(names, "") == 0) return (0); maclist = cp = xstrdup(names); for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0'; (p = strsep(&cp, MAC_SEP))) { if (mac_init(NULL, p) < 0) { debug("bad mac %s [%s]", p, names); xfree(maclist); return (0); } else { debug3("mac ok: %s [%s]", p, names); } } debug3("macs ok: [%s]", names); xfree(maclist); return (1); }
int main (void) { WDTCTL = WDTPW+WDTHOLD; // Stop watchdog timer set_mcu_speed_xt2_mclk_8MHz_smclk_1MHz(); set_aclk_div(1); LEDS_INIT(); LEDS_OFF(); uart0_init(UART0_CONFIG_1MHZ_115200); printf("\n-----------------------------------\n"); printf("TDMA_NODE test\r\n"); eint(); mac_init(0); mac_set_access_allowed_cb(mac_ready); printf("*** I'm %u ***\n", node_addr); uint8_t dodo = 'a'; while(1) { if (mac_is_access_allowed()) { mac_payload[0] = dodo; mac_send(); dodo++; if (dodo>'z')dodo='a'; LED_RED_TOGGLE(); } LPM3; } return 0; }
int main(void) { WDTCTL = WDTPW+WDTHOLD; set_mcu_speed_xt2_mclk_8MHz_smclk_1MHz(); set_aclk_div(1); LEDS_INIT(); LEDS_OFF(); ds2411_init(); nodeaddr = (((uint16_t)ds2411_id.serial1)<<8) + (ds2411_id.serial0); uart0_init(UART0_CONFIG_1MHZ_115200); uart0_register_callback(char_rx); eint(); printf("[APP];BOOTING;%.4x\n",nodeaddr); //check if this node is the sink if (nodeaddr == sink_nodes) { type = SINK; level = DEFAULT_LEVEL; } else { //retrieve father for (idx=0; idx<NUMBER_NODES; idx++) { if (list_nodes[idx] == nodeaddr) { if(father_nodes1[idx] != 0x0000) { parent_id = father_nodes1[idx]; level = 12; break; } } } } //hack for mobile /*if(nodeaddr == 0x1f5d) { parent_id = 0x0000; mac_set_mobile(1); level = 12; }*/ mac_init(10); mac_set_rx_cb(packet_received); mac_set_error_cb(packet_error); mac_set_sent_cb(packet_sent); timerB_set_alarm_from_now(TIMERB_ALARM_CCR6, 32768, 32768); timerB_register_cb(TIMERB_ALARM_CCR6, inc_clock); while (1) { LPM1; if (state == SM_TX) { if (level != UNDEF_LEVEL && type != SINK) { seq_max = NUM_SEQ_MAX; delay = rand(); delay &= 0xCFFF; delay += 12000; //(369ms < delay < 1991ms) timerB_set_alarm_from_now(TIMERB_ALARM_CCR5, delay, 0); timerB_register_cb(TIMERB_ALARM_CCR5, next_send); } else { printf("[APP];NOROUTE\n"); } state = SM_IDLE; } else if (state == SM_LOOP_TX) { if (level != UNDEF_LEVEL) { sprintf(sourceaddr,"%.4x",nodeaddr); data_txframe[0] = DATA; data_txframe[1] = level-1; data_txframe[2] = sourceaddr[0]; data_txframe[3] = sourceaddr[1]; data_txframe[4] = sourceaddr[2]; data_txframe[5] = sourceaddr[3]; data_txframe[6] = seq; //sequence data_txframe[7] = 1; //hops txlength = 8; stat_add(STAT_APP_TX); printf("[APP];NODE_TX;%.4x;%.4x;%u;%u-%u\n", nodeaddr, parent_id, seq, global_clock, timerB_time()/32); seq++; mac_send(data_txframe, txlength, parent_id); if (DEBUG_LEDS == 1) { LED_GREEN_ON(); } if (seq < seq_max) { timerB_set_alarm_from_now(TIMERB_ALARM_CCR5, SEND_DATA_PERIOD, 0); timerB_register_cb(TIMERB_ALARM_CCR5, next_send); } } state = SM_IDLE; } } return 0; }
static void sys_init(void) { struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; u32 sysclkctrl; /* Set system state to SLOW */ sysclkctrl = readl(&misc_p->sys_clk_ctrl); sysclkctrl &= ~SYS_MODE_MASK; sysclkctrl |= XTAL_TIMEOUT_ENB | PLL_TIMEOUT_ENB | SYS_MODE_REQ_SLOW; writel(sysclkctrl, &misc_p->sys_clk_ctrl); writel(PLL_TIM, &misc_p->sys_clk_plltimer); writel(OSCI_TIM, &misc_p->sys_clk_oscitimer); #if defined(CONFIG_SPEAR1340) u32 plgpio_enb_3; /* * The code below modifies plgpio_enb_3 register * settings in order to add support for SPEAr1340 * rev AB DDR Board Modifications setting in output * GPIOs 88 and 89 on GPIO controller. */ plgpio_enb_3 = readl(PLGPIO_ENB_3); plgpio_enb_3 &= ~(PLGPIO_88_CFG | PLGPIO_89_CFG); writel(plgpio_enb_3, PLGPIO_ENB_3); u32 pad_pu_cfg_1, pad_pd_cfg_1; /* * The code below modifies pad_pu_cfg_1 and pad_pd_cfg_1 * registers settings in order to add support for SPEAr1340 * DDR Board Modifications: * - DDR_PHY_1v2 (XGPIO 21: PullDown = 1, PullUp = 0) * - DDR_PHY_1v5 (XGPIO 22: PullDown = 1, PullUp = 0) */ pad_pu_cfg_1 = readl(&misc_p->pad_pu_cfg_1); pad_pu_cfg_1 |= (PAD_21_PU_CFG | PAD_22_PU_CFG); writel(pad_pu_cfg_1, &misc_p->pad_pu_cfg_1); pad_pd_cfg_1 = readl(&misc_p->pad_pd_cfg_1); pad_pd_cfg_1 &= PAD_21_PD_CFG; pad_pd_cfg_1 &= PAD_22_PD_CFG; writel(pad_pd_cfg_1, &misc_p->pad_pd_cfg_1); #elif (defined(CONFIG_SPEAR1310) && !defined(CONFIG_SPEAR1380_REVC)) /* * Set the PAD function enable such that the PADs are routed to * IP */ writel(readl(&misc_p->pad_function_en_1) | 0x300, &misc_p->pad_function_en_1); /* * Set up the PAD direction in control of IP's / RAS by default */ writel(readl(&misc_p->pad_dir_sel_1) | 0x300, &misc_p->pad_dir_sel_1); #endif /* Initialize PLLs */ pll_init(); mac_init(); /* Set system state to NORMAL */ sysclkctrl = readl(&misc_p->sys_clk_ctrl); sysclkctrl &= ~SYS_MODE_MASK; sysclkctrl |= XTAL_TIMEOUT_ENB | PLL_TIMEOUT_ENB | SYS_MODE_REQ_NORMAL; writel(sysclkctrl, &misc_p->sys_clk_ctrl); /* Wait for system to switch to normal mode */ while ((readl(&misc_p->sys_clk_ctrl) & SYS_STATE_MASK) != SYS_STATE_NORMAL); }
/* * This routine will open a device as it is known by the V2 OBP. It * then goes thru the stuff necessary to initialize the network device, * get our network parameters, (using DHCP or rarp/bootparams), and * finally actually go and get the root filehandle. Sound like fun? * Suuurrrree. Take a look. * * Returns 0 if things worked. -1 if we crashed and burned. */ int boot_nfs_mountroot(char *str) { int status; enum clnt_stat rpc_stat; char *root_path = &root_pathbuf[0]; /* to make XDR happy */ struct timeval wait; int fd; int bufsize; char *opts, *val; int nfs_version = 0; int istcp = 1; int nfs_port = 0; /* Cause pmap to get port */ struct sockaddr_in tmp_addr; /* throw away */ if (root_CLIENT != NULL) { AUTH_DESTROY(root_CLIENT->cl_auth); CLNT_DESTROY(root_CLIENT); root_CLIENT = NULL; } root_to.sin_family = AF_INET; root_to.sin_addr.s_addr = htonl(INADDR_ANY); root_to.sin_port = htons(0); mac_init(str); (void) ipv4_setpromiscuous(TRUE); if (get_netconfig_strategy() == NCT_BOOTP_DHCP) { if (boothowto & RB_VERBOSE) printf("Using BOOTP/DHCP...\n"); if (dhcp() != 0 || setup_root_vars() != 0) { (void) ipv4_setpromiscuous(FALSE); if (boothowto & RB_VERBOSE) printf("BOOTP/DHCP configuration failed!\n"); return (-1); } /* now that we have an IP address, turn off promiscuous mode */ (void) ipv4_setpromiscuous(FALSE); } else { /* Use RARP/BOOTPARAMS. RARP will try forever... */ if (boothowto & RB_VERBOSE) printf("Using RARP/BOOTPARAMS...\n"); mac_call_rarp(); /* * Since there is no way to determine our netmask, and therefore * figure out if the router we got is useful, we assume all * services are local. Use DHCP if this bothers you. */ dontroute = TRUE; /* * We are trying to keep the ARP response * timeout on the lower side with BOOTP/RARP. * We are doing this for BOOTP/RARP where policy * doesn't allow to route the packets outside * the subnet as it has no idea about the * netmask. By doing so, we are reducing * ARP response timeout for any packet destined * for outside booting clients subnet. Client can * not expect such ARP replies and will finally * timeout after a long delay. This would cause * booting client to get stalled for a longer * time. We can not avoid accepting any outside * subnet packets accidentally destined for the * booting client. */ mac_set_arp_timeout(ARP_INETBOOT_TIMEOUT); /* now that we have an IP address, turn off promiscuous mode */ (void) ipv4_setpromiscuous(FALSE); /* get our hostname */ if (whoami() == FALSE) return (-1); /* get our bootparams. */ if (getfile("root", root_hostname, &root_to.sin_addr, root_pathbuf) == FALSE) return (-1); /* get our rootopts. */ (void) getfile("rootopts", root_hostname, &tmp_addr.sin_addr, rootopts); } /* mount root */ if (boothowto & RB_VERBOSE) { printf("root server: %s (%s)\n", root_hostname, inet_ntoa(root_to.sin_addr)); printf("root directory: %s\n", root_pathbuf); } /* * Assumes we've configured the stack and thus know our * IP address/hostname, either by using DHCP or rarp/bootparams. */ gethostname(my_hostname, sizeof (my_hostname)); wait.tv_sec = RPC_RCVWAIT_MSEC / 1000; wait.tv_usec = 0; /* * Parse out the interesting root options, if an invalid * or unknown option is provided, silently ignore it and * use the defaults. */ opts = rootopts; while (*opts) { int ival; switch (getsubopt(&opts, optlist, &val)) { case OPT_RSIZE: if (val == NULL || !isdigit(*val)) break; nfs_readsize = atoi(val); break; case OPT_TIMEO: if (val == NULL || !isdigit(*val)) break; ival = atoi(val); wait.tv_sec = ival / 10; wait.tv_usec = (ival % 10) * 100000; break; case OPT_VERS: if (val == NULL || !isdigit(*val)) break; nfs_version = atoi(val); break; case OPT_PROTO: if (val == NULL || isdigit(*val)) break; if ((strncmp(val, "udp", 3) == 0)) istcp = 0; else istcp = 1; /* must be tcp */ break; case OPT_PORT: if (val == NULL || !isdigit(*val)) break; nfs_port = atoi(val); /* * Currently nfs_dlinet.c doesn't support setting * the root NFS port. Delete this when it does. */ nfs_port = 0; break; default: /* * Unknown options are silently ignored */ break; } } /* * If version is set, then try that version first. */ switch (nfs_version) { case NFS_VERSION: if (nfsmountroot(root_path, &roothandle) == 0) goto domount; break; case NFS_V3: if (nfs3mountroot(root_path, &roothandle) == 0) goto domount; break; case NFS_V4: /* * With v4 we skip the mount and go straight to * setting the root filehandle. Because of this we * do things slightly differently and obtain our * client handle first. */ if (istcp && nfs4init(root_path, nfs_port) == 0) { /* * If v4 init succeeded then we are done. Just return. */ return (0); } } /* * If there was no chosen version or the chosen version failed * try all versions in order, this may still fail to boot * at the kernel level if the options are not right, but be * generous at this early stage. */ if (istcp && nfs4init(root_path, nfs_port) == 0) { /* * If v4 init succeeded then we are done. Just return. */ return (0); } if (nfs3mountroot(root_path, &roothandle) == 0) goto domount; if ((status = nfsmountroot(root_path, &roothandle)) != 0) return (status); domount: /* * Only v2 and v3 go on from here. */ roothandle.offset = (uint_t)0; /* it's a directory! */ root_to.sin_port = htons(nfs_port); /* NFS is next after mount */ /* * Create the CLIENT handle for NFS operations */ if (roothandle.version == NFS_VERSION) bufsize = NFSBUF_SIZE; else bufsize = NFS3BUF_SIZE; /* * First try TCP then UDP (unless UDP asked for explicitly), if mountd * alows this version but neither transport is available we are stuck. */ if (istcp) { fd = -1; root_CLIENT = clntbtcp_create(&root_to, NFS_PROGRAM, roothandle.version, wait, &fd, bufsize, bufsize); if (root_CLIENT != NULL) { root_CLIENT->cl_auth = authunix_create(my_hostname, 0, 1, 1, &fake_gids); /* * Send NULL proc, check if the server really exists */ rpc_stat = CLNT_CALL(root_CLIENT, 0, xdr_void, NULL, xdr_void, NULL, wait); if (rpc_stat == RPC_SUCCESS) return (0); AUTH_DESTROY(root_CLIENT->cl_auth); CLNT_DESTROY(root_CLIENT); root_CLIENT = NULL; } /* Fall through to UDP case */ } fd = -1; root_CLIENT = clntbudp_bufcreate(&root_to, NFS_PROGRAM, roothandle.version, wait, &fd, bufsize, bufsize); if (root_CLIENT == NULL) return (-1); root_CLIENT->cl_auth = authunix_create(my_hostname, 0, 1, 1, &fake_gids); /* * Send NULL proc, check if the server really exists */ rpc_stat = CLNT_CALL(root_CLIENT, 0, xdr_void, NULL, xdr_void, NULL, wait); if (rpc_stat == RPC_SUCCESS) return (0); AUTH_DESTROY(root_CLIENT->cl_auth); CLNT_DESTROY(root_CLIENT); root_CLIENT = NULL; return (-1); }
//------------------------------------------------------------------------- // FUNCTION DECLARATION //------------------------------------------------------------------------- void hardware_init(void){ init_IO(); // WATCHDOG SETUP FOR MSP430 // After PUC, watchdog is enabled by default // with a timeout of 32 ms. Till we support // watchdog, we will simply disable it DISABLE_WDT(); // CLOCK SUBSYSTEM clock_hal_init(); // LEDS led_init(); // HARDWARE TIMERS timerb_hal_init(); // SYSTEM TIMER timer_hardware_init(DEFAULT_INTERVAL); // UART uart_hardware_init(); uart_system_init(); #ifndef NO_SOS_UART //! Initialize uart comm channel sos_uart_init(); #endif // I2C //! Limited I2C support for the ARL deployment #ifdef NEW_SENSING_API #ifdef TMOTE_INVENT_SENSOR_BOARD invent_sensor_init(); #endif #endif // SPI spi_hardware_init(); // RADIO //#ifndef NO_SOS_RADIO // cc2420_hardware_init(); mac_init(); //#endif // ADC #ifdef NEW_SENSING_API adc_driver_init(); #else adc_proc_init(); #endif // Interrupt controller interrupt_init(); // SHT1x chip communication controller #ifdef NEW_SENSING_API #ifdef TMOTE_SENSOR_BOARD sht1x_comm_init(); #endif #endif // Ram - I dont know which flash this is ? // init_flash(); // EXTERNAL FLASH // Currently there is no support // MSP430 PERIPHERALS (Optional) }
/* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size. * Returns the actual compressed packet size. */ int _gnutls_ciphertext2compressed (gnutls_session_t session, opaque * compress_data, int compress_size, gnutls_datum_t ciphertext, uint8_t type) { uint8_t MAC[MAX_HASH_SIZE]; uint16_t c_length; uint8_t pad; int length; digest_hd_st td; uint16_t blocksize; int ret, i, pad_failed = 0; uint8_t major, minor; gnutls_protocol_t ver; int hash_size = _gnutls_hash_get_algo_len (session->security_parameters. read_mac_algorithm); ver = gnutls_protocol_get_version (session); minor = _gnutls_version_get_minor (ver); major = _gnutls_version_get_major (ver); blocksize = _gnutls_cipher_get_block_size (session->security_parameters. read_bulk_cipher_algorithm); /* initialize MAC */ ret = mac_init (&td, session->security_parameters.read_mac_algorithm, session->connection_state.read_mac_secret.data, session->connection_state.read_mac_secret.size, ver); if (ret < 0 && session->security_parameters.read_mac_algorithm != GNUTLS_MAC_NULL) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } /* actual decryption (inplace) */ switch (_gnutls_cipher_is_block (session->security_parameters.read_bulk_cipher_algorithm)) { case CIPHER_STREAM: if ((ret = _gnutls_cipher_decrypt (&session->connection_state. read_cipher_state, ciphertext.data, ciphertext.size)) < 0) { gnutls_assert (); return ret; } length = ciphertext.size - hash_size; break; case CIPHER_BLOCK: if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0)) { gnutls_assert (); return GNUTLS_E_DECRYPTION_FAILED; } if ((ret = _gnutls_cipher_decrypt (&session->connection_state. read_cipher_state, ciphertext.data, ciphertext.size)) < 0) { gnutls_assert (); return ret; } /* ignore the IV in TLS 1.1. */ if (session->security_parameters.version >= GNUTLS_TLS1_1) { ciphertext.size -= blocksize; ciphertext.data += blocksize; if (ciphertext.size == 0) { gnutls_assert (); return GNUTLS_E_DECRYPTION_FAILED; } } pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */ if ((int) pad > (int) ciphertext.size - hash_size) { gnutls_assert (); _gnutls_record_log ("REC[%x]: Short record length %d > %d - %d (under attack?)\n", session, pad, ciphertext.size, hash_size); /* We do not fail here. We check below for the * the pad_failed. If zero means success. */ pad_failed = GNUTLS_E_DECRYPTION_FAILED; } length = ciphertext.size - hash_size - pad; /* Check the pading bytes (TLS 1.x) */ if (ver >= GNUTLS_TLS1 && pad_failed == 0) for (i = 2; i < pad; i++) { if (ciphertext.data[ciphertext.size - i] != ciphertext.data[ciphertext.size - 1]) pad_failed = GNUTLS_E_DECRYPTION_FAILED; } break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } if (length < 0) length = 0; c_length = _gnutls_conv_uint16 ((uint16_t) length); /* Pass the type, version, length and compressed through * MAC. */ if (session->security_parameters.read_mac_algorithm != GNUTLS_MAC_NULL) { _gnutls_hmac (&td, UINT64DATA (session->connection_state. read_sequence_number), 8); _gnutls_hmac (&td, &type, 1); if (ver >= GNUTLS_TLS1) { /* TLS 1.x */ _gnutls_hmac (&td, &major, 1); _gnutls_hmac (&td, &minor, 1); } _gnutls_hmac (&td, &c_length, 2); if (length > 0) _gnutls_hmac (&td, ciphertext.data, length); mac_deinit (&td, MAC, ver); } /* This one was introduced to avoid a timing attack against the TLS * 1.0 protocol. */ if (pad_failed != 0) return pad_failed; /* HMAC was not the same. */ if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0) { gnutls_assert (); return GNUTLS_E_DECRYPTION_FAILED; } /* copy the decrypted stuff to compress_data. */ if (compress_size < length) { gnutls_assert (); return GNUTLS_E_DECOMPRESSION_FAILED; } memcpy (compress_data, ciphertext.data, length); return length; }
/* This is the actual encryption * Encrypts the given compressed datum, and puts the result to cipher_data, * which has cipher_size size. * return the actual encrypted data length. */ int _gnutls_compressed2ciphertext (gnutls_session_t session, opaque * cipher_data, int cipher_size, gnutls_datum_t compressed, content_type_t _type, int random_pad) { uint8_t MAC[MAX_HASH_SIZE]; uint16_t c_length; uint8_t pad; int length, ret; digest_hd_st td; uint8_t type = _type; uint8_t major, minor; int hash_size = _gnutls_hash_get_algo_len (session->security_parameters. write_mac_algorithm); gnutls_protocol_t ver; int blocksize = _gnutls_cipher_get_block_size (session->security_parameters. write_bulk_cipher_algorithm); cipher_type_t block_algo = _gnutls_cipher_is_block (session->security_parameters. write_bulk_cipher_algorithm); opaque *data_ptr; ver = gnutls_protocol_get_version (session); minor = _gnutls_version_get_minor (ver); major = _gnutls_version_get_major (ver); /* Initialize MAC */ ret = mac_init (&td, session->security_parameters.write_mac_algorithm, session->connection_state.write_mac_secret.data, session->connection_state.write_mac_secret.size, ver); if (ret < 0 && session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL) { gnutls_assert (); return ret; } c_length = _gnutls_conv_uint16 (compressed.size); if (session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL) { /* actually when the algorithm in not the NULL one */ _gnutls_hmac (&td, UINT64DATA (session->connection_state. write_sequence_number), 8); _gnutls_hmac (&td, &type, 1); if (ver >= GNUTLS_TLS1) { /* TLS 1.0 or higher */ _gnutls_hmac (&td, &major, 1); _gnutls_hmac (&td, &minor, 1); } _gnutls_hmac (&td, &c_length, 2); _gnutls_hmac (&td, compressed.data, compressed.size); mac_deinit (&td, MAC, ver); } /* Calculate the encrypted length (padding etc.) */ length = calc_enc_length (session, compressed.size, hash_size, &pad, random_pad, block_algo, blocksize); if (length < 0) { gnutls_assert (); return length; } /* copy the encrypted data to cipher_data. */ if (cipher_size < length) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } data_ptr = cipher_data; if (block_algo == CIPHER_BLOCK && session->security_parameters.version >= GNUTLS_TLS1_1) { /* copy the random IV. */ ret = _gnutls_rnd (GNUTLS_RND_NONCE, data_ptr, blocksize); if (ret < 0) { gnutls_assert (); return ret; } data_ptr += blocksize; } memcpy (data_ptr, compressed.data, compressed.size); data_ptr += compressed.size; if (hash_size > 0) { memcpy (data_ptr, MAC, hash_size); data_ptr += hash_size; } if (block_algo == CIPHER_BLOCK && pad > 0) { memset (data_ptr, pad - 1, pad); } /* Actual encryption (inplace). */ ret = _gnutls_cipher_encrypt (&session->connection_state.write_cipher_state, cipher_data, length); if (ret < 0) { gnutls_assert (); return ret; } return length; }
int main(int ac, char **av) { const char *pathName = "/var/run/vknet"; const char *tapName = "auto"; const char *bridgeName = NULL; int net_fd; int connectOpt = 0; int c; ioinfo_t tap_info; pthread_t dummy_td; while ((c = getopt(ac, av, "b:cdp:i:t:U")) != -1) { switch (c) { case 'U': SecureOpt = 0; break; case 'b': bridgeName = optarg; break; case 'd': DebugOpt = 1; break; case 'p': pathName = optarg; break; case 'i': pidfile = optarg; break; case 't': tapName = optarg; break; case 'c': connectOpt = 1; break; default: usage(); } } av += optind; ac -= optind; if (ac) SetAddrOpt = 1; /* * Special connect/debug mode */ if (connectOpt) { net_fd = vknet_connect(pathName); if (net_fd < 0) { perror("connect"); exit(1); } vknet_monitor(net_fd); exit(0); } /* * In secure mode (the default), a network address/mask must be * specified. e.g. 10.1.0.0/16. Any traffic going out the TAP * interface will be filtered. * * If non-secure mode the network address/mask is optional. */ if (SecureOpt || SetAddrOpt) { char *str; int masklen; u_int32_t mask; if (ac == 0 || strchr(av[0], '/') == NULL) usage(); str = strdup(av[0]); if (inet_pton(AF_INET, strtok(str, "/"), &NetAddress) <= 0) usage(); masklen = strtoul(strtok(NULL, "/"), NULL, 10); mask = (1 << (32 - masklen)) - 1; NetMask.s_addr = htonl(~mask); } /* * Normal operation, create the tap/bridge and listener. This * part is not threaded. */ mac_init(); if ((tap_info = vknet_tap(tapName, bridgeName)) == NULL) { perror("tap: "); exit(1); } if ((net_fd = vknet_listener(pathName)) < 0) { perror("listener: "); exit(1); } /* * Now make us a demon and start the threads going. */ if (DebugOpt == 0) daemon(1, 0); writepid(); signal(SIGINT, cleanup); signal(SIGHUP, cleanup); signal(SIGTERM, cleanup); pthread_mutex_init(&BridgeMutex, NULL); pthread_create(&dummy_td, NULL, vknet_io, tap_info); vknet_acceptor(net_fd); exit(0); }
int main(int argc, char *argv[]) { // Handle signals signal(SIGINT,shut_down); signal(SIGHUP,shut_down); signal(SIGTERM,shut_down); signal(SIGQUIT,shut_down); // HCI device number, MAC struct int device = 0; bdaddr_t bdaddr; bacpy(&bdaddr, BDADDR_ANY); // Time to scan. Scan time is roughly 1.28 seconds * scan_window // Originally this was always 8, now we adjust based on device: #ifdef OPENWRT int scan_window = 8; #elif PWNPLUG int scan_window = 5; #else int scan_window = 3; #endif // Maximum number of devices per scan int max_results = 255; int num_results; // Device cache and index int cache_index = 0; // HCI cache setting int flags = IREQ_CACHE_FLUSH; // Strings to hold MAC and name char addr[19] = {0}; char addr_buff[19] = {0}; // String for time char cur_time[20]; // Process ID read from PID file int ext_pid; // Pointers to filenames char *infofilename = LIVE_INF; // Change default filename based on date char OUT_FILE[1000] = OUT_PATH; strncat(OUT_FILE, file_timestamp(),sizeof(OUT_FILE)-strlen(OUT_FILE)-1); char *outfilename = OUT_FILE; // Mode to open output file in char *filemode = "a+"; // Output buffer char outbuffer[500]; // Buffer for data from the second loop char exitbuffer[500]; // Misc Variables int i, ri, opt; // Record numbner of BlueZ errors int error_count = 0; // Current epoch time long long int epoch; // Kernel version info struct utsname sysinfo; uname(&sysinfo); while ((opt=getopt_long(argc,argv,"+o:i:r:a:w:vxctghldbfenksmq", main_options, NULL)) != EOF) { switch (opt) { case 'i': if (!strncasecmp(optarg, "hci", 3)) hci_devba(atoi(optarg + 3), &bdaddr); else str2ba(optarg, &bdaddr); break; case 'o': outfilename = strdup(optarg); break; case 'r': config.retry_count = atoi(optarg); break; case 'a': config.amnesia = atoi(optarg); break; case 'w': config.scan_window = round((atoi(optarg) / 1.28)); break; case 'c': config.showclass = 1; break; case 'e': config.encode = 1; break; case 'f': config.friendlyclass = 1; break; case 'v': config.verbose = 1; break; case 'g': config.status = 1; break; case 't': config.showtime = 1; break; case 's': config.syslogonly = 1; break; case 'x': config.obfuscate = 1; break; case 'q': config.quiet = 1; break; case 'l': if(!LIVEMODE) { printf("Live mode has been disabled in this build. See documentation.\n"); exit(0); } else config.bluelive = 1; break; case 'b': config.bluepropro = 1; break; case 'd': config.daemon = 1; break; case 'n': config.getname = 1; break; case 'm': if(!OUILOOKUP) { printf("Manufacturer lookups have been disabled in this build. See documentation.\n"); exit(0); } else config.getmanufacturer = 1; break; case 'h': help(); exit(0); case 'k': // Read PID from file into variable ext_pid = read_pid(); if (ext_pid != 0) { printf("Killing Bluelog process with PID %i...",ext_pid); if(kill(ext_pid,15) != 0) { printf("ERROR!\n"); printf("Unable to kill Bluelog process. Check permissions.\n"); exit(1); } else printf("OK.\n"); // Delete PID file unlink(PID_FILE); } else printf("No running Bluelog process found.\n"); exit(0); default: printf("Unknown option. Use -h for help, or see README.\n"); exit(1); } } // See if there is already a process running if (read_pid() != 0) { printf("Another instance of Bluelog is already running!\n"); printf("Use the -k option to kill a running Bluelog process.\n"); exit(1); } // Load config from file if no options given on command line if(cfg_exists() && argc == 1) { if (cfg_read() != 0) { printf("Error opening config file!\n"); exit(1); } // Put interface into BT struct hci_devba(config.hci_device, &bdaddr); } // Perform sanity checks on varibles cfg_check(); // Setup libmackerel mac_init(); // Boilerplate if (!config.quiet) { printf("%s (v%s%s) by MS3FGX\n", APPNAME, VERSION, VER_MOD); #if defined OPENWRT || PWNPLUG printf("----"); #endif printf("---------------------------\n"); } // Show notification we loaded config from file if(cfg_exists() && argc == 1 && !config.quiet) printf("Config loaded from: %s\n", CFG_FILE); // Init Hardware ba2str(&bdaddr, config.addr); if (!strcmp(config.addr, "00:00:00:00:00:00")) { if (!config.quiet) printf("Autodetecting device..."); device = hci_get_route(NULL); // Put autodetected device MAC into addr hci_devba(device, &bdaddr); ba2str(&bdaddr, config.addr); } else { if (!config.quiet) printf("Initializing device..."); device = hci_devid(config.addr); } // Open device and catch errors config.bt_socket = hci_open_dev(device); if (device < 0 || config.bt_socket < 0) { // Failed to open device, that can't be good printf("\n"); printf("Error initializing Bluetooth device!\n"); exit(1); } // If we get here the device should be online. if (!config.quiet) printf("OK\n"); // Status message for BPP if (!config.quiet) if (config.bluepropro) printf("Output formatted for BlueProPro.\n" "More Info: www.hackfromacave.com\n"); // Open socket if (config.udponly) open_udp_socket(); // Open output file, unless in networking mode if (!config.syslogonly && !config.udponly) { if (config.bluelive) { // Change location of output file outfilename = LIVE_OUT; filemode = "w"; if (!config.quiet) printf("Starting Bluelog Live...\n"); } if (!config.quiet) printf("Opening output file: %s...", outfilename); if ((outfile = fopen(outfilename, filemode)) == NULL) { printf("\n"); printf("Error opening output file!\n"); exit(1); } if (!config.quiet) printf("OK\n"); } else if (!config.quiet) printf("Network mode enabled, not creating log file.\n"); // Open status file if (config.bluelive) { if (!config.quiet) printf("Opening info file: %s...", infofilename); if ((infofile = fopen(infofilename,"w")) == NULL) { printf("\n"); printf("Error opening info file!\n"); exit(1); } if (!config.quiet) printf("OK\n"); } // Write PID file if (!config.daemon) write_pid(getpid()); // Get and print time to console and file strcpy(cur_time, get_localtime()); if (!config.daemon) printf("Scan started at [%s] on %s\n", cur_time, config.addr); if (config.showtime && (outfile != NULL)) { fprintf(outfile,"[%s] Scan started on %s\n", cur_time, config.addr); // Make sure this gets written out fflush(outfile); } // Write info file for Bluelog Live if (config.bluelive) { fprintf(infofile,"<div class=\"sideitem\">%s Version: %s%s</div>\n", APPNAME, VERSION, VER_MOD); fprintf(infofile,"<div class=\"sideitem\">Device: %s</div>\n", config.addr); fprintf(infofile,"<div class=\"sideitem\">Started: %s</div>\n", cur_time); // Think we are done with you now fclose(infofile); } // Log success to this point syslog(LOG_INFO,"Init OK!"); // Daemon switch if (config.daemon) daemonize(); else if (!config.quiet) #if defined PWNPAD printf("Close this window to end scan.\n"); #else printf("Hit Ctrl+C to end scan.\n"); #endif // Init result struct results = (inquiry_info*)malloc(max_results * sizeof(inquiry_info)); // Start scan, be careful with this infinite loop... for(;;) { // Flush results buffer memset(results, '\0', max_results * sizeof(inquiry_info)); // Scan and return number of results num_results = hci_inquiry(device, scan_window, max_results, NULL, &results, flags); // A negative number here means an error during scan if(num_results < 0) { // Increment error count error_count++; // Ignore occasional errors on Pwn Plug and OpenWRT #if !defined PWNPLUG || OPENWRT // All other platforms, print error and bail out syslog(LOG_ERR,"Received error from BlueZ!"); printf("Scan failed!\n"); // Check for kernel 3.0.x if (!strncmp("3.0.",sysinfo.release,4)) { printf("\n"); printf("-----------------------------------------------------\n"); printf("Device scanning failed, and you are running a 3.0.x\n"); printf("Linux kernel. This failure is probably due to the\n"); printf("following kernel bug:\n"); printf("\n"); printf("http://marc.info/?l=linux-kernel&m=131629118406044\n"); printf("\n"); printf("You will need to upgrade your kernel to at least the\n"); printf("the 3.1 series to continue.\n"); printf("-----------------------------------------------------\n"); } shut_down(1); #else // Exit on back to back errors if (error_count > 5) { printf("Scan failed!\n"); syslog(LOG_ERR,"BlueZ not responding, unrecoverable!"); shut_down(1); } // Otherwise, throttle back a bit, might help sleep(1); #endif } else { // Clear error counter error_count = 0; } // Check if we need to reset device cache if ((cache_index + num_results) >= MAX_DEV) { syslog(LOG_INFO,"Resetting device cache..."); memset(dev_cache, 0, sizeof(dev_cache)); cache_index = 0; } // Loop through results for (i = 0; i < num_results; i++) { // Return current MAC from struct ba2str(&(results+i)->bdaddr, addr); // Compare to device cache for (ri = 0; ri <= cache_index; ri++) { // Determine if device is already logged if (strcmp (addr, dev_cache[ri].priv_addr) == 0) { // This device has been seen before // Increment seen count, update printed time dev_cache[ri].seen++; strcpy(dev_cache[ri].time, get_localtime()); dev_cache[ri].missing_count = 0; // If we don't have a name, query again if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen > config.retry_count)) { syslog(LOG_INFO,"Unable to find name for %s!", addr); dev_cache[ri].print = 1; } else if ((dev_cache[ri].print == 3) && (dev_cache[ri].seen < config.retry_count)) { // Query name strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr)); // Did we get one? if (strcmp (dev_cache[ri].name, "VOID") != 0) { syslog(LOG_INFO,"Name retry for %s successful!", addr); // Force print dev_cache[ri].print = 1; } else syslog(LOG_INFO,"Name retry %i for %s failed!",dev_cache[ri].seen, addr); } // Amnesia mode if (config.amnesia >= 0) { // Find current epoch time epoch = time(NULL); if ((epoch - dev_cache[ri].epoch) >= (config.amnesia * 60)) { // Update epoch time dev_cache[ri].epoch = epoch; // Set device to print dev_cache[ri].print = 1; } } // This device is seen before, but has been away if (strcmp (dev_cache[ri].status, "gone") == 0) { dev_cache[ri].print = 1; strcpy(dev_cache[ri].status, "returned"); } // Unless we need to get printed, move to next result if (dev_cache[ri].print != 1) break; } else if (strcmp (dev_cache[ri].addr, "") == 0) { // Write new device MAC (visible and internal use) strcpy(dev_cache[ri].addr, addr); strcpy(dev_cache[ri].priv_addr, addr); // Query for name if (config.getname) strcpy(dev_cache[ri].name, namequery(&(results+i)->bdaddr)); else strcpy(dev_cache[ri].name, "IGNORED"); // Get time found strcpy(dev_cache[ri].time, get_localtime()); dev_cache[ri].epoch = time(NULL); // Class info dev_cache[ri].flags = (results+i)->dev_class[2]; dev_cache[ri].major_class = (results+i)->dev_class[1]; dev_cache[ri].minor_class = (results+i)->dev_class[0]; // Init misc variables dev_cache[ri].seen = 1; dev_cache[ri].missing_count = 0; strcpy(dev_cache[ri].status, "new"); // Increment index cache_index++; // If we have a device name, get printed if (strcmp (dev_cache[ri].name, "VOID") != 0) dev_cache[ri].print = 1; else { // Found with no name. // Print message to syslog, prevent printing, and move on syslog(LOG_INFO,"Device %s discovered with no name, will retry", dev_cache[ri].addr); dev_cache[ri].print = 3; break; } } // Ready to print? if (dev_cache[ri].print == 1) { // Encode MAC if (config.encode || config.obfuscate) { // Clear buffer memset(addr_buff, '\0', sizeof(addr_buff)); if (config.obfuscate) strcpy(addr_buff, mac_obfuscate(dev_cache[ri].priv_addr)); if (config.encode) strcpy(addr_buff, mac_encode(dev_cache[ri].priv_addr)); // Copy to cache strcpy(dev_cache[ri].addr, addr_buff); } // Print everything to console if verbose is on, optionally friendly class info if (config.verbose) { if (config.friendlyclass) { printf("[%s] %s,%s,%s,(%s) - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, device_class(dev_cache[ri].major_class,\ dev_cache[ri].minor_class), device_capability(dev_cache[ri].flags), dev_cache[ri].status); } else { printf("[%s] %s,%s,0x%02x%02x%02x - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class, dev_cache[ri].status); } } if (config.bluelive) { // Write result with live function live_entry(ri); } else if (config.bluepropro) { // Set output format for BlueProPro fprintf(outfile,"%s", dev_cache[ri].addr); fprintf(outfile,",0x%02x%02x%02x", dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class); fprintf(outfile,",%s\n", dev_cache[ri].name); } else { // Flush buffer memset(outbuffer, 0, sizeof(outbuffer)); // Print time first if enabled if (config.showtime) sprintf(outbuffer,"[%s],", dev_cache[ri].time); // Always output MAC sprintf(outbuffer+strlen(outbuffer),"%s", dev_cache[ri].addr); // Optionally output class if (config.showclass) sprintf(outbuffer+strlen(outbuffer),",0x%02x%02x%02x", dev_cache[ri].flags,\ dev_cache[ri].major_class, dev_cache[ri].minor_class); // "Friendly" version of class info if (config.friendlyclass) sprintf(outbuffer+strlen(outbuffer),",%s,(%s)",\ device_class(dev_cache[ri].major_class, dev_cache[ri].minor_class),\ device_capability(dev_cache[ri].flags)); // Get manufacturer if (config.getmanufacturer) sprintf(outbuffer+strlen(outbuffer),",%s", mac_get_vendor(dev_cache[ri].priv_addr)); // Append the name if (config.getname) sprintf(outbuffer+strlen(outbuffer),",%s", dev_cache[ri].name); // Append the status if (config.status) sprintf(outbuffer+strlen(outbuffer)," - %s", dev_cache[ri].status); // Send buffer, else file. File needs newline if (config.syslogonly) syslog(LOG_INFO,"%s", outbuffer); else if (config.udponly) { // Append newline to socket, kind of hacky sprintf(outbuffer+strlen(outbuffer),"\n"); send_udp_msg(outbuffer); } else fprintf(outfile,"%s\n",outbuffer); } dev_cache[ri].print = 0; break; } // If we make it this far, it means we will check next stored device } // If there's a file open, write changes if (outfile != NULL) fflush(outfile); } // Now check if any devices are missing // Loop through the cache for (ri = 0; ri < cache_index; ri++) { for (i = 0; i <= num_results; i++) { // Return current MAC from struct ba2str(&(results+i)->bdaddr, addr); // Determine if device still present if (strcmp (addr, dev_cache[ri].priv_addr) == 0) { break; } // Device not found. if (i == num_results) { // The device is missing but not marked as gone -> it has just disappeared if (strcmp(dev_cache[ri].status, "gone") != 0) { // Devices aren't present every time. Wait a while before marking it gone if (dev_cache[ri].missing_count < 10) { dev_cache[ri].missing_count++; } else // It's really gone :( { strcpy(dev_cache[ri].status,"gone"); // Print to console if (config.verbose) { printf("[%s] %s,%s - %s\n",\ dev_cache[ri].time, dev_cache[ri].addr,\ dev_cache[ri].name, dev_cache[ri].status); } // Flush buffer memset(exitbuffer, 0, sizeof(exitbuffer)); // Print time first if enabled if (config.showtime) sprintf(exitbuffer,"[%s],", dev_cache[ri].time); // Always output MAC sprintf(exitbuffer+strlen(exitbuffer),"%s", dev_cache[ri].addr); // Append the name if (config.getname) sprintf(exitbuffer+strlen(exitbuffer),",%s", dev_cache[ri].name); // Append the status if (config.status) sprintf(exitbuffer+strlen(exitbuffer)," - %s", dev_cache[ri].status); // Send buffer, else file. File needs newline if (config.syslogonly) syslog(LOG_INFO,"%s", exitbuffer); else if (config.udponly) { // Append newline to socket, kind of hacky sprintf(exitbuffer+strlen(exitbuffer),"\n"); send_udp_msg(exitbuffer); } else fprintf(outfile,"%s\n",exitbuffer); // If there's a file open, write changes if (outfile != NULL) fflush(outfile); } } } } } } // If we get here, shut down shut_down(0); // STFU return (1); }
/* This is the actual encryption * Encrypts the given compressed datum, and puts the result to cipher_data, * which has cipher_size size. * return the actual encrypted data length. */ int _gnutls_compressed2ciphertext (gnutls_session_t session, opaque * cipher_data, int cipher_size, gnutls_datum_t compressed, content_type_t _type, int random_pad, record_parameters_st * params) { uint8_t MAC[MAX_HASH_SIZE]; uint16_t c_length; uint8_t pad; int length, ret; uint8_t type = _type; opaque preamble[PREAMBLE_SIZE]; int preamble_size; int hash_size = _gnutls_hash_get_algo_len (params->mac_algorithm); int blocksize = gnutls_cipher_get_block_size (params->cipher_algorithm); cipher_type_t block_algo = _gnutls_cipher_is_block (params->cipher_algorithm); opaque *data_ptr; int ver = gnutls_protocol_get_version (session); /* Initialize MAC */ c_length = _gnutls_conv_uint16 (compressed.size); if (params->mac_algorithm != GNUTLS_MAC_NULL) { /* actually when the algorithm in not the NULL one */ digest_hd_st td; ret = mac_init (&td, params->mac_algorithm, params->write.mac_secret.data, params->write.mac_secret.size, ver); if (ret < 0) { gnutls_assert (); return ret; } preamble_size = make_preamble (UINT64DATA (params->write.sequence_number), type, c_length, ver, preamble); mac_hash (&td, preamble, preamble_size, ver); mac_hash (&td, compressed.data, compressed.size, ver); mac_deinit (&td, MAC, ver); } /* Calculate the encrypted length (padding etc.) */ length = calc_enc_length (session, compressed.size, hash_size, &pad, random_pad, block_algo, blocksize); if (length < 0) { gnutls_assert (); return length; } /* copy the encrypted data to cipher_data. */ if (cipher_size < length) { gnutls_assert (); return GNUTLS_E_MEMORY_ERROR; } data_ptr = cipher_data; if (block_algo == CIPHER_BLOCK && _gnutls_version_has_explicit_iv (session->security_parameters.version)) { /* copy the random IV. */ ret = _gnutls_rnd (GNUTLS_RND_NONCE, data_ptr, blocksize); if (ret < 0) { gnutls_assert (); return ret; } data_ptr += blocksize; } memcpy (data_ptr, compressed.data, compressed.size); data_ptr += compressed.size; if (hash_size > 0) { memcpy (data_ptr, MAC, hash_size); data_ptr += hash_size; } if (block_algo == CIPHER_BLOCK && pad > 0) { memset (data_ptr, pad - 1, pad); } /* Actual encryption (inplace). */ ret = _gnutls_cipher_encrypt (¶ms->write.cipher_state, cipher_data, length); if (ret < 0) { gnutls_assert (); return ret; } return length; }
/* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size. * Returns the actual compressed packet size. */ int _gnutls_ciphertext2compressed (gnutls_session_t session, opaque * compress_data, int compress_size, gnutls_datum_t ciphertext, uint8_t type, record_parameters_st * params) { uint8_t MAC[MAX_HASH_SIZE]; uint16_t c_length; uint8_t pad; int length; uint16_t blocksize; int ret, i, pad_failed = 0; opaque preamble[PREAMBLE_SIZE]; int preamble_size; int ver = gnutls_protocol_get_version (session); int hash_size = _gnutls_hash_get_algo_len (params->mac_algorithm); blocksize = gnutls_cipher_get_block_size (params->cipher_algorithm); /* actual decryption (inplace) */ switch (_gnutls_cipher_is_block (params->cipher_algorithm)) { case CIPHER_STREAM: if ((ret = _gnutls_cipher_decrypt (¶ms->read.cipher_state, ciphertext.data, ciphertext.size)) < 0) { gnutls_assert (); return ret; } length = ciphertext.size - hash_size; break; case CIPHER_BLOCK: if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0)) { gnutls_assert (); return GNUTLS_E_DECRYPTION_FAILED; } if ((ret = _gnutls_cipher_decrypt (¶ms->read.cipher_state, ciphertext.data, ciphertext.size)) < 0) { gnutls_assert (); return ret; } /* ignore the IV in TLS 1.1. */ if (_gnutls_version_has_explicit_iv (session->security_parameters.version)) { ciphertext.size -= blocksize; ciphertext.data += blocksize; if (ciphertext.size == 0) { gnutls_assert (); return GNUTLS_E_DECRYPTION_FAILED; } } pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */ if ((int) pad > (int) ciphertext.size - hash_size) { gnutls_assert (); _gnutls_record_log ("REC[%p]: Short record length %d > %d - %d (under attack?)\n", session, pad, ciphertext.size, hash_size); /* We do not fail here. We check below for the * the pad_failed. If zero means success. */ pad_failed = GNUTLS_E_DECRYPTION_FAILED; } length = ciphertext.size - hash_size - pad; /* Check the pading bytes (TLS 1.x) */ if (_gnutls_version_has_variable_padding (ver) && pad_failed == 0) for (i = 2; i < pad; i++) { if (ciphertext.data[ciphertext.size - i] != ciphertext.data[ciphertext.size - 1]) pad_failed = GNUTLS_E_DECRYPTION_FAILED; } break; default: gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } if (length < 0) length = 0; c_length = _gnutls_conv_uint16 ((uint16_t) length); /* Pass the type, version, length and compressed through * MAC. */ if (params->mac_algorithm != GNUTLS_MAC_NULL) { digest_hd_st td; ret = mac_init (&td, params->mac_algorithm, params->read.mac_secret.data, params->read.mac_secret.size, ver); if (ret < 0) { gnutls_assert (); return GNUTLS_E_INTERNAL_ERROR; } preamble_size = make_preamble (UINT64DATA (params->read.sequence_number), type, c_length, ver, preamble); mac_hash (&td, preamble, preamble_size, ver); if (length > 0) mac_hash (&td, ciphertext.data, length, ver); mac_deinit (&td, MAC, ver); } /* This one was introduced to avoid a timing attack against the TLS * 1.0 protocol. */ if (pad_failed != 0) { gnutls_assert (); return pad_failed; } /* HMAC was not the same. */ if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0) { gnutls_assert (); return GNUTLS_E_DECRYPTION_FAILED; } /* copy the decrypted stuff to compress_data. */ if (compress_size < length) { gnutls_assert (); return GNUTLS_E_DECOMPRESSION_FAILED; } memcpy (compress_data, ciphertext.data, length); return length; }
static int captured_main (void *data) { struct captured_main_args *context = data; int argc = context->argc; char **argv = context->argv; int count; static int quiet = 0; static int batch = 0; static int set_args = 0; /* Pointers to various arguments from command line. */ char *symarg = NULL; char *execarg = NULL; char *corearg = NULL; char *cdarg = NULL; char *ttyarg = NULL; /* These are static so that we can take their address in an initializer. */ static int print_help; static int print_version; /* Pointers to all arguments of --command option. */ char **cmdarg; /* Allocated size of cmdarg. */ int cmdsize; /* Number of elements of cmdarg used. */ int ncmd; /* Indices of all arguments of --directory option. */ char **dirarg; /* Allocated size. */ int dirsize; /* Number of elements used. */ int ndir; struct stat homebuf, cwdbuf; char *homedir, *homeinit; register int i; long time_at_startup = get_run_time (); #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) setlocale (LC_MESSAGES, ""); #endif #if defined (HAVE_SETLOCALE) setlocale (LC_CTYPE, ""); #endif bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); START_PROGRESS (argv[0], 0); #ifdef MPW /* Do all Mac-specific setup. */ mac_init (); #endif /* MPW */ /* This needs to happen before the first use of malloc. */ init_malloc ((PTR) NULL); #if defined (ALIGN_STACK_ON_STARTUP) i = (int) &count & 0x3; if (i != 0) alloca (4 - i); #endif cmdsize = 1; cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg)); ncmd = 0; dirsize = 1; dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg)); ndir = 0; quit_flag = 0; line = (char *) xmalloc (linesize); line[0] = '\0'; /* Terminate saved (now empty) cmd line */ instream = stdin; getcwd (gdb_dirbuf, sizeof (gdb_dirbuf)); current_directory = gdb_dirbuf; gdb_stdout = stdio_fileopen (stdout); gdb_stderr = stdio_fileopen (stderr); gdb_stdlog = gdb_stderr; /* for moment */ gdb_stdtarg = gdb_stderr; /* for moment */ /* initialize error() */ error_init (); /* Parse arguments and options. */ { int c; /* When var field is 0, use flag field to record the equivalent short option (or arbitrary numbers starting at 10 for those with no equivalent). */ static struct option long_options[] = { {"async", no_argument, &event_loop_p, 1}, {"noasync", no_argument, &event_loop_p, 0}, #if defined(TUI) {"tui", no_argument, &tui_version, 1}, #endif {"xdb", no_argument, &xdb_commands, 1}, {"dbx", no_argument, &dbx_commands, 1}, {"readnow", no_argument, &readnow_symbol_files, 1}, {"r", no_argument, &readnow_symbol_files, 1}, {"mapped", no_argument, &mapped_symbol_files, 1}, {"m", no_argument, &mapped_symbol_files, 1}, {"quiet", no_argument, &quiet, 1}, {"q", no_argument, &quiet, 1}, {"silent", no_argument, &quiet, 1}, {"nx", no_argument, &inhibit_gdbinit, 1}, {"n", no_argument, &inhibit_gdbinit, 1}, {"batch", no_argument, &batch, 1}, {"epoch", no_argument, &epoch_interface, 1}, /* This is a synonym for "--annotate=1". --annotate is now preferred, but keep this here for a long time because people will be running emacses which use --fullname. */ {"fullname", no_argument, 0, 'f'}, {"f", no_argument, 0, 'f'}, {"annotate", required_argument, 0, 12}, {"help", no_argument, &print_help, 1}, {"se", required_argument, 0, 10}, {"symbols", required_argument, 0, 's'}, {"s", required_argument, 0, 's'}, {"exec", required_argument, 0, 'e'}, {"e", required_argument, 0, 'e'}, {"core", required_argument, 0, 'c'}, {"c", required_argument, 0, 'c'}, {"pid", required_argument, 0, 'p'}, {"p", required_argument, 0, 'p'}, {"command", required_argument, 0, 'x'}, {"version", no_argument, &print_version, 1}, {"x", required_argument, 0, 'x'}, #ifdef GDBTK {"tclcommand", required_argument, 0, 'z'}, {"enable-external-editor", no_argument, 0, 'y'}, {"editor-command", required_argument, 0, 'w'}, #endif {"ui", required_argument, 0, 'i'}, {"interpreter", required_argument, 0, 'i'}, {"i", required_argument, 0, 'i'}, {"directory", required_argument, 0, 'd'}, {"d", required_argument, 0, 'd'}, {"cd", required_argument, 0, 11}, {"tty", required_argument, 0, 't'}, {"baud", required_argument, 0, 'b'}, {"b", required_argument, 0, 'b'}, {"nw", no_argument, &use_windows, 0}, {"nowindows", no_argument, &use_windows, 0}, {"w", no_argument, &use_windows, 1}, {"windows", no_argument, &use_windows, 1}, {"statistics", no_argument, 0, 13}, {"write", no_argument, &write_files, 1}, {"args", no_argument, &set_args, 1}, /* Allow machine descriptions to add more options... */ #ifdef ADDITIONAL_OPTIONS ADDITIONAL_OPTIONS #endif {0, no_argument, 0, 0} }; while (1) { int option_index; c = getopt_long_only (argc, argv, "", long_options, &option_index); if (c == EOF || set_args) break; /* Long option that takes an argument. */ if (c == 0 && long_options[option_index].flag == 0) c = long_options[option_index].val; switch (c) { case 0: /* Long option that just sets a flag. */ break; case 10: symarg = optarg; execarg = optarg; break; case 11: cdarg = optarg; break; case 12: /* FIXME: what if the syntax is wrong (e.g. not digits)? */ annotation_level = atoi (optarg); break; case 13: /* Enable the display of both time and space usage. */ display_time = 1; display_space = 1; break; case 'f': annotation_level = 1; /* We have probably been invoked from emacs. Disable window interface. */ use_windows = 0; break; case 's': symarg = optarg; break; case 'e': execarg = optarg; break; case 'c': corearg = optarg; break; case 'p': /* "corearg" is shared by "--core" and "--pid" */ corearg = optarg; break; case 'x': cmdarg[ncmd++] = optarg; if (ncmd >= cmdsize) { cmdsize *= 2; cmdarg = (char **) xrealloc ((char *) cmdarg, cmdsize * sizeof (*cmdarg)); } break; #ifdef GDBTK case 'z': { extern int gdbtk_test (char *); if (!gdbtk_test (optarg)) { fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""), argv[0], optarg); exit (1); } break; } case 'y': /* Backwards compatibility only. */ break; case 'w': { external_editor_command = xstrdup (optarg); break; } #endif /* GDBTK */ case 'i': interpreter_p = optarg; break; case 'd': dirarg[ndir++] = optarg; if (ndir >= dirsize) { dirsize *= 2; dirarg = (char **) xrealloc ((char *) dirarg, dirsize * sizeof (*dirarg)); } break; case 't': ttyarg = optarg; break; case 'q': quiet = 1; break; case 'b': { int i; char *p; i = strtol (optarg, &p, 0); if (i == 0 && p == optarg) /* Don't use *_filtered or warning() (which relies on current_target) until after initialize_all_files(). */ fprintf_unfiltered (gdb_stderr, _("warning: could not set baud rate to `%s'.\n"), optarg); else baud_rate = i; } break; case 'l': { int i; char *p; i = strtol (optarg, &p, 0); if (i == 0 && p == optarg) /* Don't use *_filtered or warning() (which relies on current_target) until after initialize_all_files(). */ fprintf_unfiltered (gdb_stderr, _("warning: could not set timeout limit to `%s'.\n"), optarg); else remote_timeout = i; } break; #ifdef ADDITIONAL_OPTION_CASES ADDITIONAL_OPTION_CASES #endif case '?': fprintf_unfiltered (gdb_stderr, _("Use `%s --help' for a complete list of options.\n"), argv[0]); exit (1); } } /* If --help or --version, disable window interface. */ if (print_help || print_version) { use_windows = 0; #ifdef TUI /* Disable the TUI as well. */ tui_version = 0; #endif } #ifdef TUI /* An explicit --tui flag overrides the default UI, which is the window system. */ if (tui_version) use_windows = 0; #endif if (set_args) { /* The remaining options are the command-line options for the inferior. The first one is the sym/exec file, and the rest are arguments. */ if (optind >= argc) { fprintf_unfiltered (gdb_stderr, _("%s: `--args' specified but no program specified\n"), argv[0]); exit (1); } symarg = argv[optind]; execarg = argv[optind]; ++optind; set_inferior_args_vector (argc - optind, &argv[optind]); } else { /* OK, that's all the options. The other arguments are filenames. */ count = 0; for (; optind < argc; optind++) switch (++count) { case 1: symarg = argv[optind]; execarg = argv[optind]; break; case 2: /* The documentation says this can be a "ProcID" as well. We will try it as both a corefile and a pid. */ corearg = argv[optind]; break; case 3: fprintf_unfiltered (gdb_stderr, _("Excess command line arguments ignored. (%s%s)\n"), argv[optind], (optind == argc - 1) ? "" : " ..."); break; } } if (batch) quiet = 1; } /* Initialize all files. Give the interpreter a chance to take control of the console via the init_ui_hook()) */ gdb_init (argv[0]); /* Do these (and anything which might call wrap_here or *_filtered) after initialize_all_files. */ if (print_version) { print_gdb_version (gdb_stdout); wrap_here (""); printf_filtered ("\n"); exit (0); } if (print_help) { print_gdb_help (gdb_stdout); fputs_unfiltered ("\n", gdb_stdout); exit (0); } if (!quiet) { /* Print all the junk at the top, with trailing "..." if we are about to read a symbol file (possibly slowly). */ print_gdb_version (gdb_stdout); if (symarg) printf_filtered (".."); wrap_here (""); gdb_flush (gdb_stdout); /* Force to screen during slow operations */ } error_pre_print = "\n\n"; quit_pre_print = error_pre_print; /* We may get more than one warning, don't double space all of them... */ warning_pre_print = _("\nwarning: "); /* Read and execute $HOME/.gdbinit file, if it exists. This is done *before* all the command line arguments are processed; it sets global parameters, which are independent of what file you are debugging or what directory you are in. */ homedir = getenv ("HOME"); if (homedir) { homeinit = (char *) alloca (strlen (homedir) + strlen (gdbinit) + 10); strcpy (homeinit, homedir); strcat (homeinit, "/"); strcat (homeinit, gdbinit); if (!inhibit_gdbinit) { catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL); } /* Do stats; no need to do them elsewhere since we'll only need them if homedir is set. Make sure that they are zero in case one of them fails (this guarantees that they won't match if either exists). */ memset (&homebuf, 0, sizeof (struct stat)); memset (&cwdbuf, 0, sizeof (struct stat)); stat (homeinit, &homebuf); stat (gdbinit, &cwdbuf); /* We'll only need this if homedir was set. */ } /* Now perform all the actions indicated by the arguments. */ if (cdarg != NULL) { catch_command_errors (cd_command, cdarg, 0, RETURN_MASK_ALL); } for (i = 0; i < ndir; i++) catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL); xfree (dirarg); if (execarg != NULL && symarg != NULL && STREQ (execarg, symarg)) { /* The exec file and the symbol-file are the same. If we can't open it, better only print one error message. catch_command_errors returns non-zero on success! */ if (catch_command_errors (exec_file_attach, execarg, !batch, RETURN_MASK_ALL)) catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL); } else { if (execarg != NULL) catch_command_errors (exec_file_attach, execarg, !batch, RETURN_MASK_ALL); if (symarg != NULL) catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL); } /* After the symbol file has been read, print a newline to get us beyond the copyright line... But errors should still set off the error message with a (single) blank line. */ if (!quiet) printf_filtered ("\n"); error_pre_print = "\n"; quit_pre_print = error_pre_print; warning_pre_print = _("\nwarning: "); if (corearg != NULL) { /* corearg may be either a corefile or a pid. If its first character is a digit, try attach first and then corefile. Otherwise try corefile first. */ if (isdigit (corearg[0])) { if (catch_command_errors (attach_command, corearg, !batch, RETURN_MASK_ALL) == 0) catch_command_errors (core_file_command, corearg, !batch, RETURN_MASK_ALL); } else /* Can't be a pid, better be a corefile. */ catch_command_errors (core_file_command, corearg, !batch, RETURN_MASK_ALL); } if (ttyarg != NULL) catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL); #ifdef ADDITIONAL_OPTION_HANDLER ADDITIONAL_OPTION_HANDLER; #endif /* Error messages should no longer be distinguished with extra output. */ error_pre_print = NULL; quit_pre_print = NULL; warning_pre_print = _("warning: "); /* Read the .gdbinit file in the current directory, *if* it isn't the same as the $HOME/.gdbinit file (it should exist, also). */ if (!homedir || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat))) if (!inhibit_gdbinit) { catch_command_errors (source_command, gdbinit, 0, RETURN_MASK_ALL); } for (i = 0; i < ncmd; i++) { #if 0 /* NOTE: cagney/1999-11-03: SET_TOP_LEVEL() was a macro that expanded into a call to setjmp(). */ if (!SET_TOP_LEVEL ()) /* NB: This is #if 0'd out */ { /* NOTE: I am commenting this out, because it is not clear where this feature is used. It is very old and undocumented. ezannoni: 1999-05-04 */ #if 0 if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0') read_command_file (stdin); else #endif source_command (cmdarg[i], !batch); do_cleanups (ALL_CLEANUPS); } #endif catch_command_errors (source_command, cmdarg[i], !batch, RETURN_MASK_ALL); } xfree (cmdarg); /* Read in the old history after all the command files have been read. */ init_history (); if (batch) { /* We have hit the end of the batch file. */ exit (0); } /* Do any host- or target-specific hacks. This is used for i960 targets to force the user to set a nindy target and spec its parameters. */ #ifdef BEFORE_MAIN_LOOP_HOOK BEFORE_MAIN_LOOP_HOOK; #endif END_PROGRESS (argv[0]); /* Show time and/or space usage. */ if (display_time) { long init_time = get_run_time () - time_at_startup; printf_unfiltered (_("Startup time: %ld.%06ld\n"), init_time / 1000000, init_time % 1000000); } if (display_space) { #ifdef HAVE_SBRK extern char **environ; char *lim = (char *) sbrk (0); printf_unfiltered (_("Startup size: data size %ld\n"), (long) (lim - (char *) &environ)); #endif } #if 0 /* FIXME: cagney/1999-11-06: The original main loop was like: */ while (1) { if (!SET_TOP_LEVEL ()) { do_cleanups (ALL_CLEANUPS); /* Do complete cleanup */ /* GUIs generally have their own command loop, mainloop, or whatever. This is a good place to gain control because many error conditions will end up here via longjmp(). */ if (command_loop_hook) command_loop_hook (); else command_loop (); quit_command ((char *) 0, instream == stdin); } } /* NOTE: If the command_loop() returned normally, the loop would attempt to exit by calling the function quit_command(). That function would either call exit() or throw an error returning control to SET_TOP_LEVEL. */ /* NOTE: The function do_cleanups() was called once each time round the loop. The usefulness of the call isn't clear. If an error was thrown, everything would have already been cleaned up. If command_loop() returned normally and quit_command() was called, either exit() or error() (again cleaning up) would be called. */ #endif /* NOTE: cagney/1999-11-07: There is probably no reason for not moving this loop and the code found in captured_command_loop() into the command_loop() proper. The main thing holding back that change - SET_TOP_LEVEL() - has been eliminated. */ while (1) { catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL); } /* No exit -- exit is through quit_command. */ }