int tx_switch(struct cli_def *cli) { // These handles are only used when creating L3 and above packets. libnet_t *l; // the context libnet_ptag_t t2=0, t3=0, t4=0; // handles to layers double cpu_time_used; switch (mode) { case BYTE_STREAM: send_eth(); break; case ARP: if (send_arp()==-1) return 0; break; case BPDU: if (send_bpdu()==-1) return 0; break; case CDP: if (send_cdp()==-1) return 0; break; case IP: // From now on a new much more modular method is used: l = get_link_context(); t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case ICMP: tx.ip_proto = 1; l = get_link_context(); t4 = create_icmp_packet(l); // t4 can be used for later header changes if (t4==-1) return 0; t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case UDP: tx.ip_proto = 17; l = get_link_context(); t4 = create_udp_packet(l); // t4 can be used for later header changes if (t4==-1) return 0; t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case TCP: tx.ip_proto = 6; l = get_link_context(); t4 = create_tcp_packet(l); // t4 can be used for later header changes if (t4==-1) return 0; t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case DNS: tx.ip_proto = 17; l = get_link_context(); if (create_dns_packet()==-1) return 0; t4 = create_udp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case RTP: tx.ip_proto = 17; l = get_link_context(); if (create_rtp_packet()==-1) return 0; cli_print(cli, "RTP mode! (count=%u, delay=%u usec)\n", tx.count, tx.delay); t4 = create_udp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case RX_RTP: // Receive RTP packets rcv_rtp_init(); rcv_rtp(); break; case SYSLOG: tx.ip_proto = 17; l = get_link_context(); if (create_syslog_packet()==-1) return 0; t4 = create_udp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case LLDP: // start with a new concept here //l = get_link_context(); //(void) create_lldp_packet(); // // // printf("SIZE=%lu\n",sizeof(struct tx_struct)); break; default: cli_print(cli,"Unknown mode!\n"); return (1); } // ***** Re-init packet functions: ***** tx.ip_payload_s = 0; tx.udp_len = 0; tx.tcp_payload_s = 0; tx.icmp_payload_s = 0; tx.cdp_sum = 0; mode = 0; // ************************************** mz_stop = clock(); cpu_time_used = ((double) (mz_stop - mz_start)) / CLOCKS_PER_SEC; if (cpu_time_used > 0) { total_d /= cpu_time_used; cli_print(cli, "%.2f seconds (%.Lf packets per second)\n",cpu_time_used,total_d); } return 0; }
int rtp_connection_kick(struct rtp_connection *connection) { int n, err = 0, retval = 0, i = 0, bytes_available = 0, sk = 0; struct hostent *hp; char buffer[1000]; struct rtp_packet *packet; fd_set rfds; int readchars = 0; struct timeval tv; packet = create_rtp_packet(get_payload_size(connection)); if(packet == NULL) { err = RTP_PACKET_ALLOC_ERROR; goto exit_no_packet; } /* Initialize rtp packet */ init_rtp_packet(packet, connection->seq_no, connection->timestamp, connection->ssrc); while(1) { /* TODO Here we should take into account the * processing time taken to send the packets, * so that we don't introduce extra latency * between samples */ tv.tv_sec = connection->send_interval.tv_sec; tv.tv_usec = connection->send_interval.tv_usec; /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); retval = select(fileno(stdin)+1, &rfds, NULL, NULL, &tv); if (retval < 0) { perror("Error in select: "); goto exit; } // Check amount of data in pipe err = ioctl(connection->data_input, FIONREAD, &bytes_available); if(err != 0) { perror("Error while checking size of pipe: "); goto exit; } if (FD_ISSET(fileno(stdin), &rfds)) { // stdin read(fileno(stdin), buffer, 1); if(buffer[0] == 'e' || buffer[0] == 'E') { goto exit; } else if(buffer[0] == 'f' || buffer[0] == 'F') { // Flush flush_file(connection->data_input); continue; } } if (bytes_available >= packet->payload_size) { // audio stream readchars = read(connection->data_input, packet->payload, packet->payload_size); for(i = 0; i < connection->howmany; i++) { sk = (connection->destinations[i].addr.ss_family == AF_INET) ? connection->bind_sk4 : connection->bind_sk6; n = sendto(sk, packet->start, packet->packet_size, 0, (const struct sockaddr *) &connection->destinations[i].addr, connection->destinations[i].length); if (n < 0) { err = UDP_SEND_ERROR; goto exit; } } // printf("."); // fflush(stdout); connection->seq_no++; connection->timestamp += get_timestamp_per_packet_inc(connection); /* TODO packet no as seq no might wrap */ init_rtp_packet(packet, htons(connection->seq_no), htonl(connection->timestamp), connection->ssrc); } } exit: free(packet); exit_no_packet: return err; }
int main(int argc, char **argv) { // These handles are only used when creating L3 and above packets. libnet_t *l; // the context libnet_ptag_t t2=0, t3=0, t4=0; // handles to layers double cpu_time_used; reset(); if ( getopts(argc, argv) ) { (void) fprintf(stderr, " Invalid command line parameters!\n"); help(); } // Check whether hires timers are supported or not: (void) check_timer(); signal(SIGINT, signal_handler); // to close all file pointers etc upon SIGINT switch (mode) { case BYTE_STREAM: send_eth(); break; case ARP: (void) send_arp(); break; case BPDU: (void) send_bpdu(); break; case CDP: (void) send_cdp(); break; case IP: // From now on a new much more modular method is used: l = get_link_context(); t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case ICMP: tx.ip_proto = 1; l = get_link_context(); t4 = create_icmp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case ICMP6: tx.ip_proto = 58; l = get_link_context(); t4 = create_icmp6_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (ipv6_mode) update_ISUM(l, t4); if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case UDP: tx.ip_proto = 17; l = get_link_context(); t4 = create_udp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (ipv6_mode) update_USUM(l, t4); if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case TCP: tx.ip_proto = 6; l = get_link_context(); t4 = create_tcp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (ipv6_mode) update_TSUM(l, t4); if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case DNS: tx.ip_proto = 17; l = get_link_context(); (void) create_dns_packet(); t4 = create_udp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case RTP: tx.ip_proto = 17; l = get_link_context(); if (!quiet) fprintf(stderr, " mz: RTP mode! (count=%u, delay=%u usec)\n\n", tx.count, tx.delay); (void) create_rtp_packet(); t4 = create_udp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case RX_RTP: // Receive RTP packets rcv_rtp_init(); rcv_rtp(); break; case SYSLOG: tx.ip_proto = 17; l = get_link_context(); (void) create_syslog_packet(); t4 = create_udp_packet(l); // t4 can be used for later header changes t3 = create_ip_packet(l); // t3 can be used for later header changes if (!quiet) complexity(); if (tx.packet_mode==0) // Ethernet manipulation features does NOT use ARP to determine eth_dst t2 = create_eth_frame(l, t3, t4); // t2 can be used for later header changes else send_frame (l, t3, t4); // NOTE: send_frame also destroys context finaly break; case LLDP: // start with a new concept here //l = get_link_context(); //(void) create_lldp_packet(); // // // printf("SIZE=%lu\n",sizeof(struct tx_struct)); fprintf(stderr, "LLDP is currently only supported via the interactive mode\n"); exit(1); break; default: (void) fprintf(stderr," mz/main: unknown mode! Stop.\n"); return (1); } if (!quiet) { mz_stop = clock(); cpu_time_used = ((double) (mz_stop - mz_start)) / CLOCKS_PER_SEC; if (cpu_time_used > 0) { total_d /= cpu_time_used; fprintf(stderr, "%.2f seconds (%.Lf packets per second)\n",cpu_time_used,total_d); } else { fprintf(stderr, "\n"); } } return(0); }