pthread 로 패킷을 송신하고 수신 하는 각각의 쓰레드 4개를 생성하는데.. 수신 부분에서
송신후 수신 부분에서 받은 패킷과 패킷 바이트를 저장하여 출력 해야하는데..
pcap_loop 부분에서 무한루프로 빠져서 나오질 못해서 시그널로 빠져나오는데
패킷수가 이상하게 안맞네요
보낸 패킷은 총 각각 eth2 12 eth3 12 eth4 10 eth5 12로 보냈는데
받은 패킷은 각각 22 22 22 22 로 뜨는데 ㅠ.ㅠ 소스좀 봐주세요
void
do_packets(port_t * file)
{
//printf("%s in\n", __FUNCTION__);
eth_hdr_t *eth_hdr = NULL;
ip_hdr_t *ip_hdr = NULL;
ip_hdr_t *ip_hdr2 = NULL;
arp_hdr_t *arp_hdr = NULL;
tcp_hdr_t *tcp_hdr= NULL;
udp_hdr_t *udp_hdr=NULL;
libnet_t *l = NULL;
struct pcap_pkthdr pkthdr;
const u_char *nextpkt = NULL;
u_char *pktdata = NULL;
#ifdef FORCE_ALIGN
u_char *ipbuff = NULL;
#endif
struct timeval last;
static int firsttime = 1;
int ret, newl2len;
u_int64_t packetnum = 0;
int datalen = 0;
int newchar = 0;
if ((pktdata = (u_char *) malloc(maxpacket)) == NULL){
errx(1, "Unable to malloc pktdata buffer");
}
didsig = 0;
if (!options.one_at_a_time) {
(void)signal(SIGINT, catcher);
}
if (firsttime) {
timerclear(&last);
firsttime = 0;
}
if (file->pcap == NULL){
file->pcap = pcapnav_pcap(file->pcapnav);
}
while (((nextpkt = pcap_next(file->pcap, &pkthdr)) != NULL) &&
(options.limit_send != pkts_sent)) {
printf("while\n");
printf("%s\n", file->dev);
dbg(2, "packets sent %llu", pkts_sent);
packetnum++;
dbg(2, "packet %llu caplen %d", packetnum, pkthdr.caplen);
memset(pktdata, '\0', maxpacket);
if ((newl2len = rewrite_l2(&pkthdr, pktdata, nextpkt,
file->linktype, file->l2enabled,file->l2data, file->l2len)) == 0)
continue;
file->l2len = newl2len;
eth_hdr = (eth_hdr_t *) pktdata;
if (ntohs(eth_hdr->ether_type) == ETHERTYPE_IP) {
#ifdef FORCE_ALIGN
ip_hdr = (ip_hdr_t *) ipbuff;
memcpy(ip_hdr, (&pktdata[file->l2len]), pkthdr.caplen - file->l2len);
#else
ip_hdr = (ip_hdr_t *) (&pktdata[file->l2len]);
#endif
}
else {
ip_hdr = NULL;
}
if(options.intf1 != NULL){
if(strcmp("a.pcap",file->pcapFilename)==0){
l = options.intf1;
file->stat.txBytes+=pkthdr.caplen;
file->stat.txPackets++;
if (memcmp(options.intf1_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_dhost, options.intf1_mac, ETHER_ADDR_LEN);
}
if (memcmp(options.intf1_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_shost, options.intf1_smac, ETHER_ADDR_LEN);
}
}
}
if (options.intf2 != NULL){
if(strcmp("b.pcap",file->pcapFilename)==0){
l=options.intf2;
file->stat.txBytes+=pkthdr.caplen;
file->stat.txPackets++;
if(memcmp(options.intf2_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_dhost, options.intf2_mac, ETHER_ADDR_LEN);
}
if (memcmp(options.intf2_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_shost, options.intf2_smac, ETHER_ADDR_LEN);
}
}
}
if (options.intf3 != NULL){
if(strcmp("c.pcap",file->pcapFilename)==0){
l=options.intf3;
file->stat.txBytes+=pkthdr.caplen;
file->stat.txPackets++;
if(memcmp(options.intf3_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_dhost, options.intf3_mac, ETHER_ADDR_LEN);
}
if (memcmp(options.intf3_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_shost, options.intf3_smac, ETHER_ADDR_LEN);
}
}
}
if (options.intf4 != NULL){
if(strcmp("d.pcap",file->pcapFilename)==0){
l=options.intf4;
file->stat.txBytes+=pkthdr.caplen;
file->stat.txPackets++;
if(memcmp(options.intf4_mac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_dhost, options.intf4_mac, ETHER_ADDR_LEN);
}
if (memcmp(options.intf4_smac, NULL_MAC, ETHER_ADDR_LEN) != 0) {
memcpy(eth_hdr->ether_shost, options.intf4_smac, ETHER_ADDR_LEN);
}
}
}
/* sometimes we should not send the packet */
if (l == CACHE_NOSEND)
continue;
do {
ret = libnet_adv_write_link(l, pktdata, pkthdr.caplen);
if (ret == -1) {
if (errno == ENOBUFS) {
failed++;
}
else {
printf("libnet_adv_write_link(): %s\n", strerror(errno));
}
}
/* keep trying if fail, unless user Ctrl-C's */
} while (ret == -1 && !didsig);
bytes_sent += pkthdr.caplen;
pkts_sent++;
memcpy(&last, &pkthdr.ts, sizeof(struct timeval));
}
/* free buffers */
free(pktdata);
if (options.limit_send == pkts_sent) {
exit(1);
}
usleep(1);
packet_stats(file);
//printf("%s out\n", __FUNCTION__);
pthread_exit((void *) 0);
}
void
init(char* filename)
{
bytes_sent = failed = pkts_sent = 0;
memset(&options, 0, sizeof(options));
options.mult = 1.0;
options.n_iter = 1;
options.mtu = DEFAULT_MTU;
options.poll_timeout = -1;
options.limit_send = -1;
}
int initPort(port_t *port, char *configFile)
{
stats_t *stat = &port->stat;
char devName[8];
char pcapFileName[64];
char ebuf[256];
int i;
memset(stat, 0, sizeof(stats_t));
sprintf(devName, "interface%d", port->id);
sprintf(pcapFileName, "pcapfile%d", port->id);
if(readConfig(configFile, devName, port->dev) < 0) {
printf("port[%d] device(%s) read fail.\n", port->id, devName);
return -1;
}
if(readConfig(configFile, pcapFileName, port->pcapFilename) < 0) {
printf("port[%d] pcap file(%s) read fail.\n", port->id, pcapFileName);
return -1;
}
if(strcmp("eth2",port->dev)==0){
options.intf1 = libnet_init(LIBNET_LINK_ADV,port->dev, ebuf);
if(options.intf1==NULL)
printf("Libnet can't open %s: %s", port->dev, ebuf);
}
else if (strcmp("eth3",port->dev)==0){
options.intf2 = libnet_init(LIBNET_LINK_ADV,port->dev, ebuf);
if(options.intf2==NULL)
printf("Libnet can't open %s: %s", port->dev, ebuf);
}
else if (strcmp("eth4",port->dev)==0){
options.intf3 = libnet_init(LIBNET_LINK_ADV,port->dev, ebuf);
if(options.intf3==NULL)
printf("Libnet can't open %s: %s", port->dev, ebuf);
}
else if (strcmp("eth5",port->dev)==0){
options.intf4 = libnet_init(LIBNET_LINK_ADV,port->dev, ebuf);
if(options.intf4==NULL)
printf("Libnet can't open %s: %s", port->dev, ebuf);
}
port->pcapnav= pcapnav_open_offline(port->pcapFilename);
if (port->pcapnav == NULL) {
printf("Error opening pcap file %s: %s", port->pcapFilename, ebuf);
return -1;
}
port->recv= pcap_open_live(port->dev, 1024, 1, 3000, ebuf);
if(port->recv==NULL){
printf("pcap_open_live(): %s\n", ebuf);
exit(1);
}
return 0;
}
int initPorts(ports_t *ports)
{
int i;
char value[256];
port_t *port;
stats_t *stat;
if(readConfig(ports->confFile, "UsedPortCount", value) < 0) {
printf("port count read Fail\n");
return -1;
}
ports->portCount = atoi(value);
for(i = 0; i < ports->portCount; i++) {
port = &ports->ports[i];
port->id = i;
if(initPort(port, ports->confFile) < 0) {
printf("Port Init Fail(id:%ld)\n", i);
return -1;
}
}
return 0;
}
void recv_callback(port_t *user,const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
//printf("call\n");
char buf[80];
eth_hdr_t *eth_hdr = NULL;
ip_hdr_t *ip_hdr = NULL;
arp_hdr_t *arp_hdr = NULL;
tcp_hdr_t *tcp_hdr= NULL;
udp_hdr_t *udp_hdr=NULL;
int size=69880;
//signal(SIGINT,sig_int);
printf("callback %s\n", user->dev);
user->stat.rxBytes+=pkthdr->caplen;
user->stat.rxPackets++;
recv_pkts++;
if (pcap_stats(user->recv, &ps) < 0) {
printf("errprstats\n");
exit(1);
}
}
void recvpcap(port_t * port)
{
printf("%s in\n", __FUNCTION__);
int i=0;
char ebuf[256];
const u_char *packet;
struct pcap_pkthdr pkthdr;
signal(SIGINT,sig_int);
if((pcap_loop(port->recv, 0 ,recv_callback, (port_t *)port))==-1)
exit(1);
if(port->portThread1 ==0)
if (pcap_stats(port->recv, &ps) < 0) {
printf("errprstats\n");
exit(1);
}
usleep(1);
pthread_exit((void *) 0);
//pcap_close(port->recv);
}
void stats_service(port_t * port)
{
printf("%s : tx %llu Byte %llu\n",port->dev,port->stat.txPackets, port->stat.txBytes);
//printf("received : %u, dropped : %u\n", ps.ps_recv, ps.ps_drop);
printf("%s : rx %llu Byte %llu\n",port->dev,port->stat.rxPackets,port->stat.rxBytes);
printf("%d\n",recv_pkts);
pthread_exit((void *) 0);
}
void stats_thread(ports_t *ports)
{
int i=0;
port_t *port;
int thr_id;
int status;
for(i = 0; i < 4; i++) {
port = &ports->ports[i];
thr_id=pthread_create(&port->portThread2,NULL, (void *)stats_service,(port_t *)port);
}
for(i=3;i>=0;i--){
port = &ports->ports[i];
pthread_join(port->portThread2, (void **) &status);
}
}
void
replay_file(ports_t *ports, int l2enabled, char *l2data, int l2len)
{
//printf("%s in\n", __FUNCTION__);
int i;
port_t *port;
pcap_t *pcap1;
u_int32_t linktype = 0;
int thr_id, thr_id1, thr_id2;
int status,status1,status2;
char ebuf[256];
struct files file[MAX_PORTS];
for(i = 0; i < 4; i++) {
port = &ports->ports[i];
pcap1 = pcapnav_pcap(port->pcapnav);
linktype = pcap_datalink(pcap1);
validate_l2(port->pcapFilename, l2enabled, l2data, l2len, linktype);
port->linktype=linktype;
port->l2data=l2data;
port->l2len=l2len;
port->l2enabled=l2enabled;
port->pcap=NULL;
thr_id1=pthread_create(&port->portThread1[i], NULL, (void *)do_packets,(port_t *) port);
thr_id=pthread_create(&port->portThread[i], NULL, (void *)recvpcap,(port_t *) port);
//thr_id1=pthread_create(&port->portThread1[i], NULL, (void *)do_packets,(port_t *) port);
//thr_id2=pthread_create(&port->portThread3[i], NULL, (void *)recvpcap,(port_t *) port);
}
for(i=3;i>=0;i--){
port = &ports->ports[i];
pthread_join(port->portThread1[i], (void **) &status1);
//pthread_cancel(port->portThread[i]);
pthread_join(port->portThread[i], (void **) &status);
//pthread_join(port->portThread3[i], (void **) &status);
}
pcapnav_close(port->pcapnav);
pcap_close(port->recv);
sleep(2);
printf("%s out\n", __FUNCTION__);
}
int main(int argc, char *argv[])
{
char configFileName[64];
FILE *fp;
int l2enabled = 0;
port_t *port=NULL;;
strcpy(configFileName, "config.config");
strcpy(ports.confFile, configFileName);
init(configFileName);
if(initPorts(&ports) < 0) {
printf("initPorts return Error!\n");
return -1;
}
if (gettimeofday(&begin, NULL) < 0)
printf("gettimeofday() failed");
replay_file(&ports, l2enabled, l2data, l2len);
// stats_thread(&ports);
return 0;
}
댓글 달기