#include < stdio.h > #include < stdlib.h > #include < string.h > #include < sys/socket.h > #include < netinet/in.h > #define BUFFER_SIZE 1500 #define PING 1 #define PONG 2 typedef struct ip_header_t { unsigned char ihl:4, version:4; unsigned char tos; unsigned short tot_len; unsigned short id; unsigned short frag_off; unsigned char ttl; unsigned char protocol; unsigned short check; unsigned int saddr; unsigned int daddr; /*The options start here. */ } * ip_header_t; typedef struct udp_header_t { unsigned short source; unsigned short dest; unsigned short len; unsigned short check; } * udp_header_t; typedef struct tcp_header_t { unsigned short source; unsigned short dest; unsigned int seq; unsigned int ack_seq; unsigned short res1:4, doff:4, fin:1, syn:1, rst:1, psh:1, ack:1, urg:1, ece:1, cwr:1; unsigned short window; unsigned short check; unsigned short urg_ptr; } * tcp_header_t; int main(int argc, char * argv[]) { int sock; struct sockaddr_in sin; unsigned short local_port; unsigned short remote_port; unsigned char protocol; char * buffer; int ret; ip_header_t ip_header; udp_header_t udp_header; char * remote_ip_str; unsigned char ping = 0; unsigned int * count = 0; unsigned int this_count = 0; int semantics = 0; int linux_socket = 0; unsigned short buffer_size = 0; int tmp; if (argc < 5 || argc > 7) { fprintf(stderr, "USAGE: %s {UDP|TCP} remote_ip local_port remote_port (PING|PONG) [LINUX]\n", argv[0]); return 1; } if (strncmp(argv[1], "TCP", 3) == 0) { protocol = IPPROTO_TCP; } else if (strncmp(argv[1], "UDP", 3) == 0) { protocol = IPPROTO_UDP; } else { fprintf(stderr, "Protocol must be UDP or TCP.\n"); return 1; } remote_ip_str = argv[2]; local_port = atoi(argv[3]); remote_port = atoi(argv[4]); if (argc >= 6) { if (strncmp(argv[5], "PONG", 4) == 0) { ping = 0; } else if (strncmp(argv[5], "PING", 4) == 0) { ping = 1; } else { fprintf(stderr, "PING or PONG ?.\n"); return 1; } } if (argc == 7) { if (strncmp(argv[6], "LINUX", 5) == 0) { linux_socket = 1; } else { linux_socket = 0; } } printf("Protocol %s, remote ip %s, local port %d, remote port %d%s%s\n", protocol == IPPROTO_TCP ? "TCP" : "UDP", remote_ip_str, local_port, remote_port, ping ? ", PING" : ", PONG", linux_socket ? ", LINUX_SOCKET" : ""); if (linux_socket) { if (protocol == IPPROTO_UDP) { semantics = SOCK_DGRAM; } else if (protocol == IPPROTO_TCP) { semantics = SOCK_STREAM; } } else { semantics = SOCK_RAW; } if((sock = socket(PF_INET, semantics, protocol)) < 0) { perror("socket"); exit(1); } bzero((char *)& sin, sizeof(sin)); sin.sin_port = htons(local_port); if ((bind(sock, (struct sockaddr *)& sin, sizeof(sin))) < 0) { perror("bind"); exit(1); } tmp = 1; setsockopt(sock, 0, IP_HDRINCL, & tmp, sizeof(tmp)); if (linux_socket) { bzero((char *)& sin, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(remote_port); sin.sin_addr.s_addr = inet_addr(remote_ip_str); if ((connect(sock, (struct sockaddr *)& sin, sizeof(sin))) < 0) { perror("connct"); exit(1); } } buffer_size = BUFFER_SIZE - (linux_socket ? ( (protocol == IPPROTO_TCP) ? (sizeof (struct ip_header_t) + sizeof (struct tcp_header_t)) : (sizeof (struct ip_header_t) + sizeof (struct udp_header_t)) ) : 0); printf("buff %d, %d\n", buffer_size, BUFFER_SIZE); buffer = (char *) malloc(buffer_size); while ( 1 ) { if (!linux_socket) { ip_header = (ip_header_t) buffer; ip_header->ihl = 5; ip_header->version = 4; ip_header->tos = 0; ip_header->tot_len = htons(buffer_size); ip_header->id = 0; ip_header->ttl = 64; ip_header->frag_off = 0x40; ip_header->protocol = protocol; ip_header->check = 0; /* This will be done in the kernel */ ip_header->daddr = inet_addr(remote_ip_str); ip_header->saddr = 0; /* If src ip address is NULL, kernel will fillout the default src ip */ udp_header = (udp_header_t) (ip_header + 1); udp_header->source = htons(local_port); udp_header->dest = htons(remote_port); udp_header->len = htons(buffer_size - sizeof(struct ip_header_t)); udp_header->check = 0; } if (ping) { if (linux_socket) { count = (unsigned int *) buffer; } else { count = (unsigned int *) (udp_header + 1); } * count = this_count ++; if (! (this_count % 1)) { fprintf(stderr, "%d\n", this_count); } if (send(sock, buffer, buffer_size, 0) < 0) { perror("send"); } } ping = 1; if (recv(sock, buffer, buffer_size, 0) < 0) { perror("recv"); return 1; } } close(sock); return 0; }