static int dhcp_get_offer(struct dhcp_context * context, int wait_ticks) { int error = 0; int gather_count = 0; const struct in_addr * ip; int last_rating = 0; int len; int n; int rating; struct dhcp * reply; struct in_addr server_id; struct socket * timer_arg; timer_arg = context->so; reply = dhcp_context_reply(context); timeout((timeout_fcn_t)dhcp_timeout, &timer_arg, wait_ticks); while (1) { error = receive_packet(context->so, context->reply, sizeof(context->reply), &n); if (error == 0) { dhcpol_t options; dprintf(("\ndhcp: received packet length %d\n", n)); if (n < (int)sizeof(struct dhcp)) { dprintf(("dhcp: packet is too short %d < %d\n", n, (int)sizeof(struct dhcp))); continue; } if (ntohl(reply->dp_xid) != context->xid || reply->dp_yiaddr.s_addr == 0 || reply->dp_yiaddr.s_addr == INADDR_BROADCAST || bcmp(reply->dp_chaddr, link_address(context->dl_p), link_address_length(context->dl_p)) != 0) { /* not for us */ continue; } (void)dhcpol_parse_packet(&options, reply, n); if (get_dhcp_msgtype(&options) != dhcp_msgtype_offer_e) { /* not an offer */ goto next_packet; } ip = (const struct in_addr *) dhcpol_find(&options, dhcptag_server_identifier_e, &len, NULL); if (ip == NULL || len < (int)sizeof(*ip)) { /* missing/invalid server identifier */ goto next_packet; } printf("dhcp: received OFFER: server " IP_FORMAT " IP address " IP_FORMAT "\n", IP_LIST(ip), IP_LIST(&reply->dp_yiaddr)); server_id = *ip; rating = rate_packet(&options); if (rating > last_rating) { context->iaddr = reply->dp_yiaddr; ip = (const struct in_addr *) dhcpol_find(&options, dhcptag_subnet_mask_e, &len, NULL); if (ip != NULL && len >= (int)sizeof(*ip)) { context->netmask = *ip; } ip = (const struct in_addr *) dhcpol_find(&options, dhcptag_router_e, &len, NULL); if (ip != NULL && len >= (int)sizeof(*ip)) { context->router = *ip; } context->server_id = server_id; } if (rating >= GOOD_RATING) { dhcpol_free(&options); /* packet is good enough */ untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg); break; } if (gather_count == 0) { untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg); timer_arg = context->so; timeout((timeout_fcn_t)dhcp_timeout, &timer_arg, hz * GATHER_TIME_SECS); } gather_count = 1; next_packet: dhcpol_free(&options); } else if ((error != EWOULDBLOCK)) { untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg); break; } else if (timer_arg == NULL) { /* timed out */ if (gather_count != 0) { dprintf(("dhcp: gathering time has expired\n")); error = 0; } break; } else { socket_lock(context->so, 1); error = sbwait(&context->so->so_rcv); socket_unlock(context->so, 1); } } return (error); }
/* Returns the length of the file received, or 0 on error: */ int ymodem_receive(char *buf, unsigned int length) { unsigned char packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD]; int packet_length, i, file_done, session_done, crc_tries, crc_nak, use_crc; unsigned int packets_received, errors, timeout, first_try = 1; char file_name[FILE_NAME_LENGTH], file_size[FILE_SIZE_LENGTH], *file_ptr; char *buf_ptr; unsigned long size = 0; #ifdef CONFIG_MD5 unsigned int sum[MD5_SUM_WORDS]; #endif if(crc16_init() < 0){ putstr("Unable to generate CRC16 lookup table\r\n"); return 0; } putstr("ready for YMODEM transfer...\r\n"); /* Give the user time to frantically type in the file name: */ timeout = INITIAL_TIMEOUT; for(session_done = 0, errors = 0; ; ){ crc_tries = crc_nak = use_crc = 1; if(!first_try) putc(CRC); first_try = 0; for(packets_received = 0, file_done = 0, buf_ptr = buf; ; ){ switch(receive_packet(packet_data, &packet_length, use_crc, timeout)){ case 0: errors = 0; switch(packet_length){ case -1: /* abort */ putc(ACK); return 0; case 0: /* end of transmission */ putc(ACK); /* Should add some sort of sanity check on the number of * packets received and the advertised file length. */ file_done = 1; break; default: /* normal packet */ if((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)){ putc(NAK); } else { if(packets_received == 0){ /* The spec suggests that the whole data section should * be zeroed, but I don't think all senders do this. If * we have a NULL filename and the first few digits of * the file length are zero, we'll call it empty. */ for(i = PACKET_HEADER; i < PACKET_HEADER + 4; ++i) if(packet_data[i] != 0) break; if(i < PACKET_HEADER + 4){ /* filename packet has data */ for(file_ptr = packet_data + PACKET_HEADER, i = 0; *file_ptr && i < FILE_NAME_LENGTH;) file_name[i++] = *file_ptr++; file_name[i++] = '\0'; for(++file_ptr, i = 0; *file_ptr != ' ' && i < FILE_SIZE_LENGTH;) file_size[i++] = *file_ptr++; file_size[i++] = '\0'; size = strtoul(file_size, NULL, 0); if(size > length){ putc(CAN); putc(CAN); delay_seconds(3); putstr("Receive buffer too small ("); putHexInt32(length); putLabeledWord(") to accept file size ", size); return 0; } putc(ACK); putc(crc_nak ? CRC : NAK); crc_nak = 0; } else { /* filename packet is empty; end session */ putc(ACK); file_done = 1; session_done = 1; break; } } else { /* This shouldn't happen, but we check anyway in case the * sender lied in its filename packet: */ if((buf_ptr + packet_length) - buf > length){ putc(CAN); putc(CAN); delay_seconds(3); putLabeledWord("Sender exceeded size of receive buffer: ", length); return 0; } memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); buf_ptr += packet_length; putc(ACK); } ++packets_received; } /* sequence number ok */ } break; default: if(++errors >= ((packets_received == 0 ? MAX_CRC_TRIES : 0) + MAX_ERRORS)){ putc(CAN); putc(CAN); delay_seconds(1); putstr("Too many errors during receive; giving up.\r\n"); return 0; } if(packets_received == 0){ if(crc_tries < MAX_CRC_TRIES) { ++crc_tries; timeout = CRC_TIMEOUT; } else { crc_nak = use_crc = 0; timeout = NAK_TIMEOUT; } } putc(crc_nak ? CRC : NAK); } if(file_done) break; } /* receive packets */ if(session_done) break; } /* receive files */ #ifdef CONFIG_MD5 /* Give sender time to exit so that the subsequent MD5 display will be * visible on the user's terminal: */ delay_seconds(1); md5_sum(buf, size, sum); md5_display(sum); putstr(" "); putstr(file_name); putstr("\r\n"); #endif return size; }
void cc110x_rx_handler(void *args) { uint8_t res = 0; /* Possible packet received, RX -> IDLE (0.1 us) */ cc110x_statistic.packets_in++; res = receive_packet((uint8_t *)&(cc110x_rx_buffer[rx_buffer_next].packet), sizeof(cc110x_packet_t)); if (res) { /* If we are sending a burst, don't accept packets. * Only ACKs are processed (for stopping the burst). * Same if state machine is in TX lock. */ if (radio_state == RADIO_SEND_BURST) { cc110x_statistic.packets_in_while_tx++; return; } cc110x_rx_buffer[rx_buffer_next].rssi = rflags._RSSI; cc110x_rx_buffer[rx_buffer_next].lqi = rflags._LQI; cc110x_strobe(CC1100_SFRX); /* ...for flushing the RX FIFO */ /* Valid packet. After a wake-up, the radio should be in IDLE. * So put CC110x to RX for WOR_TIMEOUT (have to manually put * the radio back to sleep/WOR). */ cc110x_write_reg(CC1100_MCSM2, 0x07); /* Configure RX_TIME (until end of packet) */ cc110x_strobe(CC1100_SRX); hwtimer_wait(IDLE_TO_RX_TIME); radio_state = RADIO_RX; #ifdef MODULE_TRANSCEIVER /* notify transceiver thread if any */ if (transceiver_pid != KERNEL_PID_UNDEF) { msg_t m; m.type = (uint16_t) RCV_PKT_CC1100; m.content.value = rx_buffer_next; msg_send_int(&m, transceiver_pid); } #endif #ifdef MODULE_NETDEV_BASE if (cc110x_recv_cb != NULL) { cc110x_packet_t p = cc110x_rx_buffer[rx_buffer_next].packet; cc110x_recv_cb(&cc110x_dev, &p.phy_src, sizeof(uint8_t), &p.address, sizeof(uint8_t), p.data, p.length - CC1100_HEADER_LENGTH); } #endif /* shift to next buffer element */ if (++rx_buffer_next == RX_BUF_SIZE) { rx_buffer_next = 0; } return; } else { /* CRC false or RX buffer full -> clear RX FIFO in both cases */ cc110x_strobe(CC1100_SIDLE); /* Switch to IDLE (should already be)... */ cc110x_strobe(CC1100_SFRX); /* ...for flushing the RX FIFO */ /* If currently sending, exit here (don't go to RX/WOR) */ if (radio_state == RADIO_SEND_BURST) { cc110x_statistic.packets_in_while_tx++; return; } /* No valid packet, so go back to RX/WOR as soon as possible */ cc110x_switch_to_rx(); } }
static int dhcp_get_ack(struct dhcp_context * context, int wait_ticks) { int error = 0; const struct in_addr * ip; int len; int n; struct dhcp * reply; struct in_addr server_id; struct socket * timer_arg; timer_arg = context->so; reply = dhcp_context_reply(context); timeout((timeout_fcn_t)dhcp_timeout, &timer_arg, wait_ticks); while (1) { error = receive_packet(context->so, context->reply, sizeof(context->reply), &n); if (error == 0) { dhcp_msgtype_t msg; dhcpol_t options; dprintf(("\ndhcp: received packet length %d\n", n)); if (n < (int)sizeof(struct dhcp)) { dprintf(("dhcp: packet is too short %d < %d\n", n, (int)sizeof(struct dhcp))); continue; } if (ntohl(reply->dp_xid) != context->xid || bcmp(reply->dp_chaddr, link_address(context->dl_p), link_address_length(context->dl_p)) != 0) { /* not for us */ continue; } (void)dhcpol_parse_packet(&options, reply, n); server_id.s_addr = 0; ip = (const struct in_addr *) dhcpol_find(&options, dhcptag_server_identifier_e, &len, NULL); if (ip != NULL && len >= (int)sizeof(*ip)) { server_id = *ip; } msg = get_dhcp_msgtype(&options); if (msg == dhcp_msgtype_nak_e && server_id.s_addr == context->server_id.s_addr) { /* server NAK'd us, start over */ dhcpol_free(&options); error = EPROTO; untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg); break; } if (msg != dhcp_msgtype_ack_e || reply->dp_yiaddr.s_addr == 0 || reply->dp_yiaddr.s_addr == INADDR_BROADCAST) { /* ignore the packet */ goto next_packet; } printf("dhcp: received ACK: server " IP_FORMAT " IP address " IP_FORMAT "\n", IP_LIST(&server_id), IP_LIST(&reply->dp_yiaddr)); context->iaddr = reply->dp_yiaddr; ip = (const struct in_addr *) dhcpol_find(&options, dhcptag_subnet_mask_e, &len, NULL); if (ip != NULL && len >= (int)sizeof(*ip)) { context->netmask = *ip; } ip = (const struct in_addr *) dhcpol_find(&options, dhcptag_router_e, &len, NULL); if (ip != NULL && len >= (int)sizeof(*ip)) { context->router = *ip; } dhcpol_free(&options); untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg); break; next_packet: dhcpol_free(&options); } else if ((error != EWOULDBLOCK)) { /* if some other error occurred, we're done */ untimeout((timeout_fcn_t)dhcp_timeout, &timer_arg); break; } else if (timer_arg == NULL) { /* timed out */ break; } else { /* wait for a wait to arrive, or a timeout to occur */ socket_lock(context->so, 1); error = sbwait(&context->so->so_rcv); socket_unlock(context->so, 1); } } return (error); }
static irqreturn_t elp_interrupt(int irq, void *dev_id) { int len; int dlen; int icount = 0; struct net_device *dev = dev_id; elp_device *adapter = netdev_priv(dev); unsigned long timeout; spin_lock(&adapter->lock); do { /* * has a DMA transfer finished? */ if (inb_status(dev->base_addr) & DONE) { if (!adapter->dmaing) pr_warning("%s: phantom DMA completed\n", dev->name); if (elp_debug >= 3) pr_debug("%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr)); outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev); if (adapter->current_dma.direction) { dev_kfree_skb_irq(adapter->current_dma.skb); } else { struct sk_buff *skb = adapter->current_dma.skb; if (skb) { if (adapter->current_dma.target) { /* have already done the skb_put() */ memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length); } skb->protocol = eth_type_trans(skb,dev); dev->stats.rx_bytes += skb->len; netif_rx(skb); } } adapter->dmaing = 0; if (adapter->rx_backlog.in != adapter->rx_backlog.out) { int t = adapter->rx_backlog.length[adapter->rx_backlog.out]; adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out); if (elp_debug >= 2) pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t); receive_packet(dev, t); } else { adapter->busy = 0; } } else { /* has one timed out? */ check_3c505_dma(dev); } /* * receive a PCB from the adapter */ timeout = jiffies + 3*HZ/100; while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) { if (receive_pcb(dev, &adapter->irx_pcb)) { switch (adapter->irx_pcb.command) { case 0: break; /* * received a packet - this must be handled fast */ case 0xff: case CMD_RECEIVE_PACKET_COMPLETE: /* if the device isn't open, don't pass packets up the stack */ if (!netif_running(dev)) break; len = adapter->irx_pcb.data.rcv_resp.pkt_len; dlen = adapter->irx_pcb.data.rcv_resp.buf_len; if (adapter->irx_pcb.data.rcv_resp.timeout != 0) { pr_err("%s: interrupt - packet not received correctly\n", dev->name); } else { if (elp_debug >= 3) { pr_debug("%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen); } if (adapter->irx_pcb.command == 0xff) { if (elp_debug >= 2) pr_debug("%s: adding packet to backlog (len = %d)\n", dev->name, dlen); adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen; adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in); } else { receive_packet(dev, dlen); } if (elp_debug >= 3) pr_debug("%s: packet received\n", dev->name); } break; /* * 82586 configured correctly */ case CMD_CONFIGURE_82586_RESPONSE: adapter->got[CMD_CONFIGURE_82586] = 1; if (elp_debug >= 3) pr_debug("%s: interrupt - configure response received\n", dev->name); break; /* * Adapter memory configuration */ case CMD_CONFIGURE_ADAPTER_RESPONSE: adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1; if (elp_debug >= 3) pr_debug("%s: Adapter memory configuration %s.\n", dev->name, adapter->irx_pcb.data.failed ? "failed" : "succeeded"); break; /* * Multicast list loading */ case CMD_LOAD_MULTICAST_RESPONSE: adapter->got[CMD_LOAD_MULTICAST_LIST] = 1; if (elp_debug >= 3) pr_debug("%s: Multicast address list loading %s.\n", dev->name, adapter->irx_pcb.data.failed ? "failed" : "succeeded"); break; /* * Station address setting */ case CMD_SET_ADDRESS_RESPONSE: adapter->got[CMD_SET_STATION_ADDRESS] = 1; if (elp_debug >= 3) pr_debug("%s: Ethernet address setting %s.\n", dev->name, adapter->irx_pcb.data.failed ? "failed" : "succeeded"); break; /* * received board statistics */ case CMD_NETWORK_STATISTICS_RESPONSE: dev->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv; dev->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit; dev->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC; dev->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align; dev->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun; dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res; adapter->got[CMD_NETWORK_STATISTICS] = 1; if (elp_debug >= 3) pr_debug("%s: interrupt - statistics response received\n", dev->name); break; /* * sent a packet */ case CMD_TRANSMIT_PACKET_COMPLETE: if (elp_debug >= 3) pr_debug("%s: interrupt - packet sent\n", dev->name); if (!netif_running(dev)) break; switch (adapter->irx_pcb.data.xmit_resp.c_stat) { case 0xffff: dev->stats.tx_aborted_errors++; pr_info("%s: transmit timed out, network cable problem?\n", dev->name); break; case 0xfffe: dev->stats.tx_fifo_errors++; pr_info("%s: transmit timed out, FIFO underrun\n", dev->name); break; } netif_wake_queue(dev); break; /* * some unknown PCB */ default: pr_debug("%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command); break; } } else { pr_warning("%s: failed to read PCB on interrupt\n", dev->name); adapter_reset(dev); } } } while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE))); prime_rx(dev); /* * indicate no longer in interrupt routine */ spin_unlock(&adapter->lock); return IRQ_HANDLED; }
int dhcp_init_ifc(const char *ifname) { dhcp_msg discover_msg; dhcp_msg request_msg; dhcp_msg reply; dhcp_msg *msg; dhcp_info info; int s, r, size; int valid_reply; uint32_t xid; unsigned char hwaddr[6]; struct pollfd pfd; unsigned int state; unsigned int timeout; int if_index; xid = (uint32_t) get_msecs(); if (ifc_get_hwaddr(ifname, hwaddr)) { return fatal("cannot obtain interface address"); } if (ifc_get_ifindex(ifname, &if_index)) { return fatal("cannot obtain interface index"); } s = open_raw_socket(ifname, hwaddr, if_index); timeout = TIMEOUT_INITIAL; state = STATE_SELECTING; info.type = 0; goto transmit; for (;;) { pfd.fd = s; pfd.events = POLLIN; pfd.revents = 0; r = poll(&pfd, 1, timeout); if (r == 0) { #if VERBOSE printerr("TIMEOUT\n"); #endif if (timeout >= TIMEOUT_MAX) { printerr("timed out\n"); if ( info.type == DHCPOFFER ) { printerr("no acknowledgement from DHCP server\nconfiguring %s with offered parameters\n", ifname); return dhcp_configure(ifname, &info); } errno = ETIME; close(s); return -1; } timeout = timeout * 2; transmit: size = 0; msg = NULL; switch(state) { case STATE_SELECTING: msg = &discover_msg; size = init_dhcp_discover_msg(msg, hwaddr, xid); break; case STATE_REQUESTING: msg = &request_msg; size = init_dhcp_request_msg(msg, hwaddr, xid, info.ipaddr, info.serveraddr); break; default: r = 0; } if (size != 0) { r = send_message(s, if_index, msg, size); if (r < 0) { printerr("error sending dhcp msg: %s\n", strerror(errno)); } } continue; } if (r < 0) { if ((errno == EAGAIN) || (errno == EINTR)) { continue; } return fatal("poll failed"); } errno = 0; r = receive_packet(s, &reply); if (r < 0) { if (errno != 0) { ALOGD("receive_packet failed (%d): %s", r, strerror(errno)); if (errno == ENETDOWN || errno == ENXIO) { return -1; } } continue; } #if VERBOSE > 1 dump_dhcp_msg(&reply, r); #endif decode_dhcp_msg(&reply, r, &info); if (state == STATE_SELECTING) { valid_reply = is_valid_reply(&discover_msg, &reply, r); } else { valid_reply = is_valid_reply(&request_msg, &reply, r); } if (!valid_reply) { printerr("invalid reply\n"); continue; } if (verbose) dump_dhcp_info(&info); switch(state) { case STATE_SELECTING: if (info.type == DHCPOFFER) { state = STATE_REQUESTING; timeout = TIMEOUT_INITIAL; xid++; goto transmit; } break; case STATE_REQUESTING: if (info.type == DHCPACK) { printerr("configuring %s\n", ifname); close(s); return dhcp_configure(ifname, &info); } else if (info.type == DHCPNAK) { printerr("configuration request denied\n"); close(s); return -1; } else { printerr("ignoring %s message in state %d\n", dhcp_type_to_name(info.type), state); } break; } } close(s); return 0; }
void cc110x_rx_handler(void) { uint8_t res = 0; /* Possible packet received, RX -> IDLE (0.1 us) */ rflags.CAA = 0; rflags.MAN_WOR = 0; cc110x_statistic.packets_in++; res = receive_packet((uint8_t *)&(cc110x_rx_buffer[rx_buffer_next].packet), sizeof(cc110x_packet_t)); if (res) { /* If we are sending a burst, don't accept packets. * Only ACKs are processed (for stopping the burst). * Same if state machine is in TX lock. */ if (radio_state == RADIO_SEND_BURST || rflags.TX) { cc110x_statistic.packets_in_while_tx++; return; } cc110x_rx_buffer[rx_buffer_next].rssi = rflags._RSSI; cc110x_rx_buffer[rx_buffer_next].lqi = rflags._LQI; cc110x_strobe(CC1100_SFRX); /* ...for flushing the RX FIFO */ /* Valid packet. After a wake-up, the radio should be in IDLE. * So put CC1100 to RX for WOR_TIMEOUT (have to manually put * the radio back to sleep/WOR). */ //cc110x_spi_write_reg(CC1100_MCSM0, 0x08); /* Turn off FS-Autocal */ cc110x_write_reg(CC1100_MCSM2, 0x07); /* Configure RX_TIME (until end of packet) */ cc110x_strobe(CC1100_SRX); hwtimer_wait(IDLE_TO_RX_TIME); radio_state = RADIO_RX; #ifdef DBG_IGNORE if (is_ignored(cc110x_rx_buffer[rx_buffer_next].packet.phy_src)) { LED_RED_TOGGLE; return; } #endif /* notify transceiver thread if any */ if (transceiver_pid) { msg_t m; m.type = (uint16_t) RCV_PKT_CC1100; m.content.value = rx_buffer_next; msg_send_int(&m, transceiver_pid); } /* shift to next buffer element */ if (++rx_buffer_next == RX_BUF_SIZE) { rx_buffer_next = 0; } return; } else { /* No ACK received so TOF is unpredictable */ rflags.TOF = 0; /* CRC false or RX buffer full -> clear RX FIFO in both cases */ cc110x_strobe(CC1100_SIDLE); /* Switch to IDLE (should already be)... */ cc110x_strobe(CC1100_SFRX); /* ...for flushing the RX FIFO */ /* If packet interrupted this nodes send call, * don't change anything after this point. */ if (radio_state == RADIO_AIR_FREE_WAITING) { cc110x_strobe(CC1100_SRX); hwtimer_wait(IDLE_TO_RX_TIME); return; } /* If currently sending, exit here (don't go to RX/WOR) */ if (radio_state == RADIO_SEND_BURST) { cc110x_statistic.packets_in_while_tx++; return; } /* No valid packet, so go back to RX/WOR as soon as possible */ cc110x_switch_to_rx(); } }
/* * Send a file via the TFTP data session. */ void tftp_send(int peer, uint16_t *block, struct tftp_stats *ts) { struct tftphdr *rp; int size, n_data, n_ack, try; uint16_t oldblock; char sendbuffer[MAXPKTSIZE]; char recvbuffer[MAXPKTSIZE]; rp = (struct tftphdr *)recvbuffer; *block = 1; ts->amount = 0; do { if (debug&DEBUG_SIMPLE) tftp_log(LOG_DEBUG, "Sending block %d", *block); size = read_file(sendbuffer, segsize); if (size < 0) { tftp_log(LOG_ERR, "read_file returned %d", size); send_error(peer, errno + 100); goto abort; } for (try = 0; ; try++) { n_data = send_data(peer, *block, sendbuffer, size); if (n_data > 0) { if (try == maxtimeouts) { tftp_log(LOG_ERR, "Cannot send DATA packet #%d, " "giving up", *block); return; } tftp_log(LOG_ERR, "Cannot send DATA packet #%d, trying again", *block); continue; } n_ack = receive_packet(peer, recvbuffer, MAXPKTSIZE, NULL, timeoutpacket); if (n_ack < 0) { if (n_ack == RP_TIMEOUT) { if (try == maxtimeouts) { tftp_log(LOG_ERR, "Timeout #%d send ACK %d " "giving up", try, *block); return; } tftp_log(LOG_WARNING, "Timeout #%d on ACK %d", try, *block); continue; } /* Either read failure or ERROR packet */ if (debug&DEBUG_SIMPLE) tftp_log(LOG_ERR, "Aborting: %s", rp_strerror(n_ack)); goto abort; } if (rp->th_opcode == ACK) { ts->blocks++; if (rp->th_block == *block) { ts->amount += size; break; } /* Re-synchronize with the other side */ (void) synchnet(peer); if (rp->th_block == (*block - 1)) { ts->retries++; continue; } } } oldblock = *block; (*block)++; if (oldblock > *block) { if (options[OPT_ROLLOVER].o_request == NULL) { /* * "rollover" option not specified in * tftp client. Default to rolling block * counter to 0. */ *block = 0; } else { *block = atoi(options[OPT_ROLLOVER].o_request); } ts->rollovers++; } gettimeofday(&(ts->tstop), NULL); } while (size == segsize); abort: return; } /* * Receive a file via the TFTP data session. * * - It could be that the first block has already arrived while * trying to figure out if we were receiving options or not. In * that case it is passed to this function. */ void tftp_receive(int peer, uint16_t *block, struct tftp_stats *ts, struct tftphdr *firstblock, size_t fb_size) { struct tftphdr *rp; uint16_t oldblock; int n_data, n_ack, writesize, i, retry; char recvbuffer[MAXPKTSIZE]; ts->amount = 0; if (firstblock != NULL) { writesize = write_file(firstblock->th_data, fb_size); ts->amount += writesize; for (i = 0; ; i++) { n_ack = send_ack(peer, *block); if (n_ack > 0) { if (i == maxtimeouts) { tftp_log(LOG_ERR, "Cannot send ACK packet #%d, " "giving up", *block); return; } tftp_log(LOG_ERR, "Cannot send ACK packet #%d, trying again", *block); continue; } break; } if (fb_size != segsize) { gettimeofday(&(ts->tstop), NULL); return; } } rp = (struct tftphdr *)recvbuffer; do { oldblock = *block; (*block)++; if (oldblock > *block) { if (options[OPT_ROLLOVER].o_request == NULL) { /* * "rollover" option not specified in * tftp client. Default to rolling block * counter to 0. */ *block = 0; } else { *block = atoi(options[OPT_ROLLOVER].o_request); } ts->rollovers++; } for (retry = 0; ; retry++) { if (debug&DEBUG_SIMPLE) tftp_log(LOG_DEBUG, "Receiving DATA block %d", *block); n_data = receive_packet(peer, recvbuffer, MAXPKTSIZE, NULL, timeoutpacket); if (n_data < 0) { if (retry == maxtimeouts) { tftp_log(LOG_ERR, "Timeout #%d on DATA block %d, " "giving up", retry, *block); return; } if (n_data == RP_TIMEOUT) { tftp_log(LOG_WARNING, "Timeout #%d on DATA block %d", retry, *block); send_ack(peer, oldblock); continue; } /* Either read failure or ERROR packet */ if (debug&DEBUG_SIMPLE) tftp_log(LOG_DEBUG, "Aborting: %s", rp_strerror(n_data)); goto abort; } if (rp->th_opcode == DATA) { ts->blocks++; if (rp->th_block == *block) break; tftp_log(LOG_WARNING, "Expected DATA block %d, got block %d", *block, rp->th_block); /* Re-synchronize with the other side */ (void) synchnet(peer); if (rp->th_block == (*block-1)) { tftp_log(LOG_INFO, "Trying to sync"); *block = oldblock; ts->retries++; goto send_ack; /* rexmit */ } } else { tftp_log(LOG_WARNING, "Expected DATA block, got %s block", packettype(rp->th_opcode)); } } if (n_data > 0) { writesize = write_file(rp->th_data, n_data); ts->amount += writesize; if (writesize <= 0) { tftp_log(LOG_ERR, "write_file returned %d", writesize); if (writesize < 0) send_error(peer, errno + 100); else send_error(peer, ENOSPACE); goto abort; } } send_ack: for (i = 0; ; i++) { n_ack = send_ack(peer, *block); if (n_ack > 0) { if (i == maxtimeouts) { tftp_log(LOG_ERR, "Cannot send ACK packet #%d, " "giving up", *block); return; } tftp_log(LOG_ERR, "Cannot send ACK packet #%d, trying again", *block); continue; } break; } gettimeofday(&(ts->tstop), NULL); } while (n_data == segsize); /* Don't do late packet management for the client implementation */ if (acting_as_client) return; for (i = 0; ; i++) { n_data = receive_packet(peer, (char *)rp, pktsize, NULL, timeoutpacket); if (n_data <= 0) break; if (n_data > 0 && rp->th_opcode == DATA && /* and got a data block */ *block == rp->th_block) /* then my last ack was lost */ send_ack(peer, *block); /* resend final ack */ } abort: return; }
/**************************************************************************** do a netbios name query to find someones IP returns an array of IP addresses or NULL if none *count will be set to the number of addresses returned ****************************************************************************/ struct in_addr * name_query (int fd, const char *name, int name_type, BOOL bcast, BOOL recurse, struct in_addr to_ip, int *count, void (*fn) (struct packet_struct *)) { BOOL found = False; int i, retries = 3; int retry_time = bcast ? 250 : 2000; struct timeval tval; struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; static int name_trn_id = 0; struct in_addr *ip_list = NULL; memset ((char *) &p, '\0', sizeof (p)); (*count) = 0; if (!name_trn_id) name_trn_id = ((unsigned) time (NULL) % (unsigned) 0x7FFF) + ((unsigned) getpid () % (unsigned) 100); name_trn_id = (name_trn_id + 1) % (unsigned) 0x7FFF; nmb->header.name_trn_id = name_trn_id; nmb->header.opcode = 0; nmb->header.response = False; nmb->header.nm_flags.bcast = bcast; nmb->header.nm_flags.recursion_available = False; nmb->header.nm_flags.recursion_desired = recurse; nmb->header.nm_flags.trunc = False; nmb->header.nm_flags.authoritative = False; nmb->header.rcode = 0; nmb->header.qdcount = 1; nmb->header.ancount = 0; nmb->header.nscount = 0; nmb->header.arcount = 0; make_nmb_name (&nmb->question.question_name, name, name_type); nmb->question.question_type = 0x20; nmb->question.question_class = 0x1; p.ip = to_ip; p.port = NMB_PORT; p.fd = fd; p.timestamp = time (NULL); p.packet_type = NMB_PACKET; GetTimeOfDay (&tval); if (!send_packet (&p)) return NULL; retries--; while (1) { struct timeval tval2; GetTimeOfDay (&tval2); if (TvalDiff (&tval, &tval2) > retry_time) { if (!retries) break; if (!found && !send_packet (&p)) return NULL; GetTimeOfDay (&tval); retries--; } if ((p2 = receive_packet (fd, NMB_PACKET, 90))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet (p2); if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response) { /* * Its not for us - maybe deal with it later * (put it on the queue?). */ if (fn) fn (p2); else free_packet (p2); continue; } if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || !nmb2->header.ancount) { /* * XXXX what do we do with this? Could be a redirect, but * we'll discard it for the moment. */ free_packet (p2); continue; } ip_list = (struct in_addr *) Realloc (ip_list, sizeof (ip_list[0]) * ((*count) + nmb2->answers->rdlength / 6)); if (ip_list) { DEBUG (fn ? 3 : 2, ("Got a positive name query response from %s ( ", inet_ntoa (p2->ip))); for (i = 0; i < nmb2->answers->rdlength / 6; i++) { putip ((char *) &ip_list[(*count)], &nmb2->answers->rdata[2 + i * 6]); DEBUG (fn ? 3 : 2, ("%s ", inet_ntoa (ip_list[(*count)]))); (*count)++; } DEBUG (fn ? 3 : 2, (")\n")); } found = True; retries = 0; free_packet (p2); if (fn) break; /* * If we're doing a unicast lookup we only * expect one reply. Don't wait the full 2 * seconds if we got one. JRA. */ if (!bcast && found) break; } } return ip_list; }
/* * RRQ - send a file to the client */ void tftp_rrq(int peer, char *recvbuffer, ssize_t size) { char *cp; int has_options = 0, ecode; char *filename, *mode; char fnbuf[PATH_MAX]; cp = parse_header(peer, recvbuffer, size, &filename, &mode); size -= (cp - recvbuffer) + 1; strcpy(fnbuf, filename); reduce_path(fnbuf); filename = fnbuf; if (size > 0) { if (options_rfc_enabled) has_options = !parse_options(peer, cp, size); else tftp_log(LOG_INFO, "Options found but not enabled"); } ecode = validate_access(peer, &filename, RRQ); if (ecode == 0) { if (has_options) { int n; char lrecvbuffer[MAXPKTSIZE]; struct tftphdr *rp = (struct tftphdr *)lrecvbuffer; send_oack(peer); n = receive_packet(peer, lrecvbuffer, MAXPKTSIZE, NULL, timeoutpacket); if (n < 0) { if (debug&DEBUG_SIMPLE) tftp_log(LOG_DEBUG, "Aborting: %s", rp_strerror(n)); return; } if (rp->th_opcode != ACK) { if (debug&DEBUG_SIMPLE) tftp_log(LOG_DEBUG, "Expected ACK, got %s on OACK", packettype(rp->th_opcode)); return; } } } if (logging) tftp_log(LOG_INFO, "%s: read request for %s: %s", peername, filename, errtomsg(ecode)); if (ecode) { /* * Avoid storms of naks to a RRQ broadcast for a relative * bootfile pathname from a diskless Sun. */ if (suppress_naks && *filename != '/' && ecode == ENOTFOUND) exit(0); send_error(peer, ecode); exit(1); } tftp_xmitfile(peer, mode); }
void *background_process(void *ptr) { extern int landebug; extern struct tm *time_ptr; static int i, t; static char prmessage[256]; static int lantimesync = 0; static int fldigi_rpc_cnt = 0; int n; char debugbuffer[160]; FILE *fp; i = 1; while (i) { while (stop_backgrnd_process == 1) { sleep(1); } usleep(10000); if (packetinterface != 0) { receive_packet(); } if (trxmode == DIGIMODE && digikeyer != NO_KEYER) rx_rtty(); /* * calling Fldigi XMLRPC method, which reads the Fldigi's carrier * this function helps to show the correct freq of the RIG: reads * the carrier value from Fldigi, and stores in a variable; then * it readable by fldigi_get_carrier() * only need at every 2nd cycle * see fldigixmlrpc.[ch] */ if (trxmode == DIGIMODE && (digikeyer == GMFSK || digikeyer == FLDIGI) && trx_control == 1) { if (fldigi_rpc_cnt == 0) { fldigi_xmlrpc_get_carrier(); } fldigi_rpc_cnt = 1 - fldigi_rpc_cnt; } if (stop_backgrnd_process == 0) { write_keyer(); cw_simulator(); } if (lan_active == 1) { if (lan_message[0] == '\0') { if (lan_recv() < 0) { recv_error++; } else { lan_message[strlen(lan_message) - 1] = '\0'; } } if (landebug == 1) { if ((fp = fopen("debuglog", "a")) == NULL) { fprintf(stdout, "store_qso.c: Error opening debug file.\n"); } else { get_time(); strftime(debugbuffer, 80, "%H:%M:%S-", time_ptr); if (strlen(lan_message) > 2) { strcat(debugbuffer, lan_message); strcat(debugbuffer, "\n"); fputs(debugbuffer, fp); } fclose(fp); } } if ((*lan_message != '\0') && (lan_message[0] == thisnode)) { mvprintw(24, 0, "Warning: NODE ID CONFLICT ?! You should use another ID! "); refreshp(); sleep(5); } if ((*lan_message != '\0') && (lan_message[0] != thisnode) && (stop_backgrnd_process != 1)) { switch (lan_message[1]) { case LOGENTRY: log_to_disk(true); break; case QTCRENTRY: store_recv_qtc(lan_message+2); break; case QTCSENTRY: store_sent_qtc(lan_message+2); break; case QTCFLAG: parse_qtc_flagline(lan_message+2); break; case CLUSTERMSG: strncpy(prmessage, lan_message + 2, 80); if (strstr(prmessage, call) != NULL) // alert for cluster messages { mvprintw(24, 0, " "); mvprintw(24, 0, "%s", prmessage); refreshp(); } addtext(prmessage); break; case TLFSPOT: strncpy(prmessage, lan_message + 2, 80); lanspotflg = 1; addtext(prmessage); lanspotflg = 0; break; case TLFMSG: for (t = 0; t < 4; t++) strcpy(talkarray[t], talkarray[t + 1]); talkarray[4][0] = lan_message[0]; talkarray[4][1] = ':'; talkarray[4][2] = '\0'; strncat(talkarray[4], lan_message + 2, 60); mvprintw(24, 0, " "); mvprintw(24, 0, " MSG from %s", talkarray[4]); refreshp(); break; case FREQMSG: if ((lan_message[0] >= 'A') && (lan_message[0] <= 'A' + MAXNODES)) { node_frequencies[lan_message[0] - 'A'] = atof(lan_message + 2); break; } case INCQSONUM: n = atoi(lan_message + 2); if (highqsonr < n) highqsonr = n; if ((qsonum <= n) && (n > 0)) { qsonum = highqsonr + 1; qsonr_to_str(); } lan_message[0] = '\0'; case TIMESYNC: if ((lan_message[0] >= 'A') && (lan_message[0] <= 'A' + MAXNODES)) { lantime = atoi(lan_message + 2); if (lantimesync == 1) timecorr = ((4 * timecorr) + lantime - (time(0) + (timeoffset * 3600L))) / 5; else { timecorr = lantime - (time(0) + (timeoffset * 3600L)); lantimesync = 1; } break; } } lan_message[0] = '\0'; lan_message[1] = '\0'; } } gettxinfo(); /* get freq info from TRX */ } return (NULL); }
void LLPacketBuffer::init (S32 hSocket) { mSize = receive_packet(hSocket, mData); mHost = ::get_sender(); }
static void rx_packet_handler( int fd, int events ) { char discardbuf[PACKET_BUF_SIZE]; rx_qentry_t *pkg; char *buf; int i, size; mac_enet_t *is; struct iovec iov; for( is=&enetif[0], i=0; i<numifs && IFACE.fd != fd ; i++, is++ ) ; if( i >= numifs ) { printm("rx_packet_handler: bad fd\n"); return; } if( !(events & POLLIN) ) printm("rx_packet_handler called with events %08X\n", events); for( ;; ) { if( is->free_head ) buf = (char *) is->free_head->packet; else { static int warned=0; if( ++warned < 10 ) printm("WARNING: Ethernet packet dropped\n"); buf = discardbuf; } /* read packet from device */ iov.iov_base = buf; iov.iov_len = PACKET_BUF_SIZE; if( (size=receive_packet(&IFACE, &iov, 1)) < 0 ) { if( errno == EAGAIN ) break; else perrorm("packet read"); } if( size < 14 + IFACE.packet_pad || !is->started || !is->free_head ) continue; if( !(buf[0+IFACE.packet_pad] & ETH_ADDR_MULTICAST) && memcmp( &IFACE.c_macaddr, buf+IFACE.packet_pad, 6) ) { // printm("Dropping packet with wrong HW-addr\n"); continue; } /* Queue packet */ // printm("Got packet size %d\n", size ); pkg = is->free_head; is->free_head = is->free_head->next; /* Truncate packets containing more than 1514 bytes */ if( size > IFACE.packet_pad + MAX_PACKET_SIZE ) size = IFACE.packet_pad + MAX_PACKET_SIZE; pkg->p_size = size; queue_rx_packet( is, pkg ); } }
int main(void) { usi_enable(); spiX_initslave(SPIMODE); sei(); //Initialize slave slave_init(); //Let settings catch up _delay_ms(100); //An initial packet, not sure what it's for, but the other code had it prepare_packet("", 0); spiX_put(0); unsigned char input; do{ //Wait for SS while(!slave_selected()); //Wait for pending transfers spiX_wait(); //Read first character from master input = spiX_get(); //Is the master telling us to receive? //If so, interpret the input and prepare a response packet if(input == RECEIVE_CHAR) { //Retrieve the rest of the packet from master receive_packet(); //Check integrity if(!check_integrity()) { prep_err(); continue; } //Lowercase are read operations if(incoming_packet[1] > 96 && incoming_packet[1] < 127) { prep_response(incoming_packet[1]); } else { do_action(incoming_packet[1]); } } //Is the master telling us that it's ready to receive? else if(input == SEND_CHAR) { //Send the prepared packet send_packet(); } if(waiting_measure){ slave_run_measure(); waiting_measure = 0; } if(waiting_write){ slave_apply(); waiting_write = 0; } } while(1); // Loop forever... }
// executive entrypoint int main(int argc, char** argv) { // variable declarations here int counter; pcap_t* handle; char errbuf[PCAP_ERRBUF_SIZE]; // contains verbose info about pcap failures struct pcap_pkthdr* info; const unsigned char* pkt; unsigned short proto; struct ethhdr* eth_hdr; struct iphdr* ip_header; struct tcphdr* tcp_hdr; // parse the command line if (argc < 2 || strcmp(argv[1], "-r") != 0 || argc < 3) { printf("usage: %s -r file_1 file_2 ... file_n\n", argv[0]); return 1; } hashtable_t* flowtable = create_table(65536, FLOW); hashtable_t* srctable = create_table(65536, SRC); // filenames are found in argv[2] to argv[argc-1] for (counter = 2; counter < argc; ++counter) { // open file for processing if ((handle = pcap_open_offline(argv[counter], errbuf)) == NULL) { printf("error loading [%s]. reason: [%s]\n", argv[counter], errbuf); return 1; } while (pcap_next_ex(handle, &info, &pkt) == 1) { //make sure packet can possibly be tcp if (info->len < sizeof(struct ethhdr*) + sizeof(struct iphdr*) + sizeof(struct tcphdr*)) { break; } //PARSE ETHERNET HEADER eth_hdr = (struct ethhdr*) pkt; // coerce cast proto = ntohs(eth_hdr->h_proto); if (proto != ETH_P_IP) { continue; } //PARSE IP HEADER ip_header = (struct iphdr*) (pkt+sizeof(struct ethhdr)); if (ip_header->protocol != 6) { continue; } //PARSE TCP HEADER tcp_hdr = (struct tcphdr*) (pkt+sizeof(struct ethhdr)+sizeof(struct iphdr)); //make the packet struct to send to hashtable enum packet_type type = OTR; if (tcp_hdr->syn == 1 && tcp_hdr->ack == 1) { type = SYN_ACK; } else if (tcp_hdr->rst == 1 && tcp_hdr->ack ==1) { type = RST_ACK; } else if (tcp_hdr->rst == 1) { type = RST; } else if (tcp_hdr->fin == 1 && tcp_hdr->urg == 1 && tcp_hdr->psh == 1) { type = XMAS; } else if (tcp_hdr->syn == 1 && tcp_hdr->ack == 0) { type = SYN; } else if (tcp_hdr->fin == 1 && tcp_hdr->ack == 0) { type = FIN; } else if (tcp_hdr->fin == 1 && tcp_hdr->ack == 1) { type = FIN_ACK; } else if (tcp_hdr->ack == 1 && tcp_hdr->syn == 0 && tcp_hdr->fin == 0 && tcp_hdr->rst == 0) { type = ACK; } else if (tcp_hdr->fin == 0 && tcp_hdr->syn == 0 && tcp_hdr->rst == 0 && tcp_hdr->psh == 0 && tcp_hdr->ack == 0 && tcp_hdr->urg == 0 && tcp_hdr->ece == 0 && tcp_hdr->cwr == 0) { type = NUL; } packet_t pkt = { .type = type, .four_tuple[0] = ip_header->saddr, .four_tuple[1] = tcp_hdr->source, .four_tuple[2] = ip_header->daddr, .four_tuple[3] = tcp_hdr->dest, .timestamp = info->ts }; packet_t* p = &pkt; receive_packet(p, flowtable, srctable); } print_portscanners(srctable); pcap_close(handle); } free_table(flowtable); free_table(srctable); return 0; }