codice:
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h> /* if this gives you an error try pcap/pcap.h */
#include <unistd.h> // Standard Unix
#include <net/if.h> // Contiene la struttura ifreq e la costante simbolica IF_NAMESIZE
#include <net/ethernet.h> // Contiene la costante simbolica ETHERTYPE_IP
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h> /* includes net/ethernet.h */
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
#include <net/ethernet.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h> // Contiene la struttura sockaddr_ll
#include <netinet/if_ether.h>
#include <strings.h>
#include <string.h>
#include <stropts.h>
#include <sys/ioctl.h>
#define srcip "192.168.1.2"
#define dstip "198.168.1.4"
#define sport 1988
#define dport 1987
#define SRC_ETHER_ADDR "00:C0:9F:4A:41:10"
#define DST_ETHER_ADDR "00:90:4b:8d:9f:ec"
int raw; // raw socket descriptor
char *packet;
struct iphdr *ip_header;
struct udphdr *udp;
struct ethhdr *ethernet_header;
int data_size = 20;
int packet_size;
int udp_opt_size = 0;
// Calcolo della checksum ripreso dal libro di Richard Stevens
unsigned short checksum(unsigned char *header, int len)
{
long sum = 0; /* assume 32 bit long, 16 bit short */
unsigned short *ip_header = (unsigned short *)header;
while(len > 1){
sum = sum + (*((unsigned short*) ip_header))++;
if(sum & 0x80000000) /* if high order bit set, fold */
sum = (sum & 0xFFFF) + (sum >> 16);
len -= 2;
}
if(len) /* take care of left over byte */
sum += (unsigned short) *(unsigned char *)ip_header;
while(sum>>16)
sum = (sum & 0xFFFF) + (sum >> 16);
return ~sum;
}
// Crea un raw socket
int raw_socket(int protocol)
{
int rawsock;
if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(protocol)))== -1) {
perror("Error creating raw socket: ");
exit(-1);
}
return rawsock;
}
// Collega il raw socket a una data interfaccia. L'interfaccia e' gestita
// come un semplice numero dal Kernel. Questo numero viene ricavato con la
// chiamata a ioctl.
int raw_bind(char *device, int rawsock, int protocol)
{
struct sockaddr_ll sll;
struct ifreq ifr;
bzero(&sll, sizeof(sll));
bzero(&ifr, sizeof(ifr));
// Ricava l'interface index
strncpy((char *)ifr.ifr_name, device, IFNAMSIZ);
if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1) {
printf("Error getting Interface index !\n");
exit(-1);
}
// Popola struttura sll e fai bind
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(protocol);
if((bind(rawsock, (struct sockaddr *)&sll, sizeof(sll)))== -1) {
perror("Error binding raw socket to interface\n");
exit(-1);
}
return 0;
}
// Invia un packetto sul socket
int raw_send(int rawsock, char *packet, int len)
{
printf("CIAO1\n");
int sent = 0;
if((sent=write(rawsock, packet, len)) != len) {
printf("Error: could only send %d bytes of %d\n", sent, len);
return 0;
}
printf("CIAO\n");
return 1;
}
/* PREPARA PACCHETTO DA SPEDIRE*/
void prepara_Pacchetto() {
// Allocca memoria per l'header Ethernet
ethernet_header = (struct ethhdr *) malloc(sizeof(struct ethhdr));
// Setta campi dell'header Ethernet
memcpy((void *)ethernet_header->h_source, (void *)ether_aton(SRC_ETHER_ADDR), 6);
memcpy((void *)ethernet_header->h_dest, (void *)ether_aton(DST_ETHER_ADDR), 6);
ethernet_header->h_proto = htons(ETHERTYPE_IP);
udp = (struct udphdr *) malloc(sizeof(struct udphdr));
udp->source=htons(sport);
udp->dest = htons(dport);
udp->check=0;
// Setta campi dell'header IP
ip_header->version = 4;
ip_header->ihl = (sizeof(struct iphdr))/4;
ip_header->tos = 0;
ip_header->tot_len = htons(sizeof(struct iphdr) + sizeof(struct udphdr));
ip_header->id = htons(0);
ip_header->frag_off = 0;
ip_header->ttl = 64;
ip_header->protocol = IPPROTO_UDP;
ip_header->saddr = inet_addr(srcip);
ip_header->daddr = inet_addr(srcip);
ip_header->check = checksum((unsigned char *) ip_header, ip_header->ihl*4);
packet = (char *) malloc( (sizeof(struct ethhdr)) + (sizeof(struct iphdr)) + (sizeof(struct udphdr)) );
memcpy(packet, ethernet_header, sizeof(struct ethhdr));
memcpy(packet + sizeof(struct ethhdr), ip_header, sizeof(struct iphdr));
memcpy(packet + sizeof(struct ethhdr) + sizeof(struct iphdr), udp, sizeof(struct udphdr));
}
/* just print a count every time we have a packet...
*/
void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet) {
static int count = 1;
fprintf(stdout,"%d, ",count);
fflush(stdout);
count++;
}
int main(int argc,char **argv)
{
//int i;
char *dev;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* descr;
struct bpf_program fp;
bpf_u_int32 maskp;
bpf_u_int32 netp;
char filtro[] = "dst port 80";
/* grab a device to peak into... */
dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ fprintf(stderr,"%s\n",errbuf); exit(1); }
/* ask pcap for the network address and mask of the device */
pcap_lookupnet(dev,&netp,&maskp,errbuf);
/* open device for reading this time lets set it in promiscuous
* mode so we can monitor traffic to another machine*/
descr = pcap_open_live(dev,BUFSIZ,1,-1,errbuf);
if(descr == NULL) {
printf("pcap_open_live(): %s\n",errbuf);
exit(1);
}
/* Lets try and compile the program.. non-optimized */
if(pcap_compile(descr,&fp,filtro,0,netp) == -1)
{
fprintf(stderr,"Error calling pcap_compile\n");
exit(1);
}
/* set the compiled program as the filter */
if(pcap_setfilter(descr,&fp) == -1)
{ fprintf(stderr,"Error setting filter\n"); exit(1); }
/* ... and loop */
// crea raw socket
raw = raw_socket(ETH_P_ALL);
// Bind socket all'interface
raw_bind(argv[1], raw, ETH_P_ALL);
prepara_Pacchetto();
pcap_loop(descr,1,my_callback,NULL);
if(!raw_send(raw, packet, sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct udphdr)))
perror("Error sending packet");
else
printf("Packet sent successfully\n");
return 0;
}
........