📄 sender.c
字号:
#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <stdlib.h>#include <sys/time.h>#include <fcntl.h>/* Local defines */#include "netconfig.h"#include "functions.h"#define MAXRETRIES 20extern int FlgDebug;extern int FlgExtraDebug;extern int FlgVerbose;extern pid_t PidSender;extern u_short NumSends;extern struct host *Head;extern struct icmp_item *ICMP_Send;extern struct udp_item *UDP_Send;extern struct tcp_item *TCP_Send;int connect_to = 0;void sender(){ /* Get busy and send datagrams */ if (FlgVerbose) { printf("Running icmp tests\n"); fflush(NULL); } icmp_send(); if (FlgVerbose) { printf("Running udp tests\n"); fflush(NULL); } udp_send(); if (FlgVerbose) { printf("Running tcp tests\n"); fflush(NULL); } tcp_send();}/* * Signal handler for connect() timeout's cuz some broken TCP/IP stacks * and firewalled machines don't send back RST/FIN */void signal_alarm(int signo){ /* printf("Broken TCP/IP Stack or Firewalled Host: "); connect_to =1; */}/* * tcp_send() allows a client to send data from a specified port to a * specified port using TCP. My algorithm is to go through the list * of tests and perform each one on a host. The reason for this is * that a new tcp socket needs to be created per test (because the * source port may change). A side effect of the source port changing * is I need to set SO_LINGER on the socket, something I'm not suppose * to do according to Steven's. Oh Well. */void tcp_send() {struct host *current;struct tcp_item *tcp_current;int TcpSock;char *buf;int cc, i, j, sockfails;struct linger l;struct sockaddr_in clnt; /* Turn on SO_LINGER */ l.l_onoff=1; l.l_linger=0; sockfails=0; tcp_current=TCP_Send; while(tcp_current){ if (FlgVerbose) { printf(" Sending %s probe ...\n",tcp_current->name); fflush(NULL); } current=Head; buf=tcp_current->string; cc=strlen(buf); /* * If we have a specified source port, try to allocate it. Otherwise * notify user and let the server assign a port. */ if(tcp_current->sport != -1){ /* printf("%d\n", tcp_current->sport); */ clnt.sin_family = AF_INET; clnt.sin_port = htons(tcp_current->sport); clnt.sin_addr.s_addr = INADDR_ANY; } /* Iterate through hosts */ while(current){ TcpSock = createsock("tcp"); if(TcpSock < 0){ sockfails++; if(sockfails > 100){ fprintf(stderr, "socket(tcp) failed too much. skipping TCP\n"); return; } usleep(10); continue; } /* Advertise port as reusable in TIME_WAIT. */ if(setsockopt(TcpSock, SOL_SOCKET, SO_LINGER, (void *) &l, sizeof(struct linger)) != 0){ perror("trouble setting setsockopt(SO_LINGER)"); } if(tcp_current->sport != -1) j = bind(TcpSock, (struct sockaddr *) &clnt, sizeof(clnt)); current->sad.sin_port = htons(tcp_current->dport); signal(SIGALRM, signal_alarm); connect_to = 0; alarm(2); if(connect(TcpSock, (struct sockaddr *) &(current->sad), sizeof(current->sad)) == 0){ alarm(0); send(TcpSock, buf, cc, 0); sleep(2); } if(connect_to == 1){ printf("%s\n", inet_ntoa(current->sad.sin_addr)); } alarm(0); close(TcpSock); current=current->Next; } /* End host loop */ tcp_current=tcp_current->Next; } /* End test while loop */}void icmp_send(){ struct host *current; struct icmp_item *icmp_current; static u_char outpack[IP_MAXPACKET]; register struct icmp *icp = (struct icmp *)outpack; char *data = &outpack[8]; int cc, i, j; int RawSock; RawSock = createsock("icmp"); if(RawSock< 0){ fprintf(stderr, "Skipping ICMP tests....\n"); return; } icmp_current = ICMP_Send; while(icmp_current){ if (FlgVerbose) { printf(" Sending %s probe ...\n",icmp_current->name); fflush(NULL); } current=Head; bzero(outpack, IP_MAXPACKET); /* Set up packet default */ if(icmp_current->string != NULL){ memcpy(outpack + sizeof(struct icmp), icmp_current->string, strlen(icmp_current->string)); cc = sizeof(struct icmp) + strlen(icmp_current->string); } else cc = sizeof(struct icmp); if(icmp_current->type != -1) icp->icmp_type = icmp_current->type; else icp->icmp_type = 0; if(icmp_current->id != -1) icp->icmp_id = htons(icmp_current->id); else icp->icmp_id = htons(0); if(icmp_current->code != -1) icp->icmp_code = icmp_current->code; else icp->icmp_code = 0; if(icmp_current->seq != -1) icp->icmp_seq = htons(icmp_current->seq); else icp->icmp_seq = 0; icp->icmp_cksum = ip_cksum((u_short *) icp, cc); /* Send packet to all hosts */ while(current){ for(j = 0; j<NumSends; j++){ i = sendto(RawSock, outpack, cc, 0, (struct sockaddr *) ¤t->sad, sizeof(current->sad)); if(i != cc || i < 0){ perror("icmp_send"); fprintf(stderr, "error sending %s packet\n", icmp_current->name); } usleep(10); } /* End FOR */ current=current->Next; } /* end while current */ icmp_current=icmp_current->Next; } /* End while icmp_current */ close(RawSock);}/* * udp_send() allows a client to send data from a specified port to a * specified port using UDP My algorithm is to go through the list * of tests and perform each one on a host. The reason for this is * that a new tcp socket needs to be created per test (because the * source port may change). A side effect of the source port changing * is I need to set SO_LINGER on the socket, something I'm not suppose * to do according to Steven's. Oh Well. */void udp_send() {struct host *current;struct udp_item *udp_current;int UdpSock;char *buf;int cc, i, j, counter;struct linger l;struct sockaddr_in clnt; /* Turn on SO_LINGER */ l.l_onoff=1; l.l_linger=0; udp_current=UDP_Send; while(udp_current){ if (FlgVerbose) { printf(" Sending %s probe ...\n",udp_current->name); fflush(NULL); } current=Head; /* Set up socket */ buf=udp_current->string; cc=strlen(buf); UdpSock = createsock("udp"); if(UdpSock < 0){ fprintf(stderr, "Skipping UDP tests....\n"); return; } /* Advertise port as reusable in TIME_WAIT. */ if(setsockopt(UdpSock, SOL_SOCKET, SO_LINGER, (void *) &l, sizeof(struct linger)) != 0){ perror("trouble setting setsockopt(SO_LINGER)"); } /* * If we have a specified source port, try to allocate it. Otherwise * notify user and let the server assign a port. */ if(udp_current->sport != -1){ clnt.sin_family = AF_INET; clnt.sin_port = htons(udp_current->sport); clnt.sin_addr.s_addr = INADDR_ANY; j = bind(UdpSock, (struct sockaddr *) &clnt, sizeof(clnt)); } /* Iterate through hosts */ while(current){ current->sad.sin_port = htons(udp_current->dport); /* * Removed per linux connect problems.. we'll just brute force getting * our packet out :) We'll, okay I'll hard code a max number */ /* i=sendto(UdpSock, buf, strlen(buf), 0, (struct sockaddr *) ¤t->sad, sizeof(current->sad)); */ counter=0; do { i=sendto(UdpSock, buf, strlen(buf), 0, (struct sockaddr *) ¤t->sad, sizeof(current->sad)); counter++; } while ( counter < MAXRETRIES && i == -1 && errno == ECONNREFUSED ); if(i!=cc){ perror("udp_send"); fprintf(stderr, "Didn't send whole UDP packet. Data=%s\n", buf); } usleep(10); if(errno==EBADF){ UdpSock = createsock("udp"); if(UdpSock < 0){ perror("socket(udp)"); return; } } current=current->Next; } /* End host loop */ udp_current=udp_current->Next; close(UdpSock); } /* End test while loop */}/* Creates a socket, returns FD or -1 if something goes wrong */int createsock(char *type){int s; /* Socket we're creating */struct protoent *proto; /* Protocol */ proto = getprotobyname(type); if(proto == NULL){ perror("unknown protocol\n"); return -1; } switch(proto->p_proto){ case IPPROTO_ICMP: s = socket(AF_INET, SOCK_RAW, proto->p_proto); break; case IPPROTO_UDP: s = socket(AF_INET, SOCK_DGRAM,proto->p_proto); break; case IPPROTO_TCP: s=socket(AF_INET, SOCK_STREAM, proto->p_proto); break; default: s=-1; break; } return s;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -