/*
 * This code is GPL.
 */
#include <linux/netfilter.h>
#include <libipq.h>
#include <stdio.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>

#define BUFSIZE 2048 

static void die(struct ipq_handle *h)
{
    ipq_perror("passer");
    ipq_destroy_handle(h);
    exit(1);
}

int main(int argc, char **argv)
{
    int status;
    unsigned char buf[BUFSIZE];
    struct ipq_handle *h;

    int sequence[5] = {3000, 1000, 3000, 3000, 7000};
    int state = 0;
    
    h = ipq_create_handle(0, PF_INET);
    if (!h)
        die(h);

    status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);
    if (status < 0)
        die(h);

    do{
        status = ipq_read(h, buf, BUFSIZE, 0);
        if (status < 0)
            die(h);

        switch (ipq_message_type(buf)) {
            case NLMSG_ERROR:
                fprintf(stderr, "Received error message %d\n",
                        ipq_get_msgerr(buf));
                break;

            case IPQM_PACKET: {
                                  ipq_packet_msg_t *m = ipq_get_packet(buf);

                                  struct iphdr *ip = (struct iphdr*) m->payload;

                                  struct tcphdr *tcp = (struct tcphdr*)
                                      (m->payload + (4 * ip->ihl));
                                  
                                  int port = htons(tcp->dest);        
                                  
                                  switch (state) {
                                      case 0:
                                      case 2:
                                      case 3:
                                            if (port == 3000)
                                                state++;
                                            break;
                                      case 1:
                                            if (port == 1000)
                                                state++;
                                            break;
                                      case 4:
                                            if (port == 7000) {
                                                state++;
                                                fprintf(stderr, 
                                                        "Sequence Complete!");
                                            }
                                      default:
                                            break;
                                  }

                                  
                                  if (port == 22 && state != 5) {
                                      status = ipq_set_verdict(h, m->packet_id,
                                          NF_DENY, 0, NULL);
                                  }
                                  else
                                      status = ipq_set_verdict(h, m->packet_id,
                                          NF_ACCEPT, 0, NULL);      
                                  if (status < 0)
                                      die(h);
                                  break;
                              }

            default:
                              fprintf(stderr, "Unknown message type!\n");
                              break;
        }
    } while (1);

    ipq_destroy_handle(h);
    return 0;
}

