/*
 *  Copyright (C) McManus
 *  Author Patrick McManus <mcmanus@ducksong.com>

 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 */


#include <pcap.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <netinet/in.h>

#include <errno.h>

static char errbuf[PCAP_ERRBUF_SIZE];
static int raw_socket;
static struct sockaddr_in saddr;

// gcc pcap_ip_replay.c -o pcap_ip_replay -Wall -g -lpcap


void die (const char *s)
{
    fprintf (stderr,"%s\n",s);
    exit (1);
    return;
}


static void process (u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{
    const u_char *ip;
    unsigned short iplen;
    
    if (((unsigned short *)bytes)[6] != 0x0008) return; /* only process IP */
    
    ip = bytes + 14;                              /* right after the ether header */
    iplen = h->caplen - 14;
    
    saddr.sin_addr.s_addr = ((unsigned int *)ip)[4];
    
    if (sendto (raw_socket, ip, iplen, 0, (struct sockaddr *) &saddr, sizeof (struct sockaddr_in)) == -1)
        perror ("send failed");
    
    fprintf (stderr,"ok\n");
    

    return;
}


int main(int argc, char **argv)
{
    pcap_t *pcapt;

    if (argc != 2)
        die ("bad argument");

    pcapt = pcap_open_offline(argv[1], errbuf);
    
    if (!pcapt)
        die ("bad pcap input file");

    if (pcap_datalink(pcapt) != DLT_EN10MB)
        die ("not ethernet packet capture");

    raw_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
    
    if (raw_socket < 0)
        die ("cannot allocate raw socket (might need to be root)");
    
    saddr.sin_family = AF_INET;
    saddr.sin_port = 0;
    

    while (pcap_dispatch (pcapt, 1000, process, NULL) > 0);
        
    return 0;
}

