#include <pcap.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "datagrams/Datagram.h"
#include "datagrams/Beacon.h"
#include "indata.h"
InData* indat;
char br1[100];
char br2[100];
char br3[100];
char ip1[100];
char ip2[100];
char ip3[100];
#include "routing.h"
/* default snap length (maximum bytes per packet to capture) */
#define SNAP_LEN 1518
/* ethernet headers are always exactly 14 bytes [1] */
#define SIZE_ETHERNET 14
/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN 6
/* Ethernet header */
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN]; /* destination host address */
u_char ether_shost[ETHER_ADDR_LEN]; /* source host address */
u_short ether_type; /* IP? ARP? RARP? etc */
};
/* IP header */
struct sniff_ip {
u_char ip_vhl; /* version << 4 | header length >> 2 */
u_char ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_char ip_ttl; /* time to live */
u_char ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
/* TCP header */
typedef u_int tcp_seq;
struct sniff_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
/*
* dissect/print packet
*/
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
char buff[512];
char echo[2048];
static int count = 1;
const struct sniff_ethernet *ethernet;
const struct sniff_ip *ip;
const struct sniff_tcp *tcp;
const u_char *payload;
int size_ip;
int size_tcp;
int size_payload;
ethernet = (struct sniff_ethernet*)(packet);
char hostip[100];
memset(hostip, '\0', strlen(hostip));
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
return;
}
sprintf(buff, "%s: [%d]\t",args, count);
count++;
strcpy(echo, buff);
switch(ip->ip_p) {
case IPPROTO_TCP:
sprintf(buff, "TCP\t");
break;
case IPPROTO_UDP:
sprintf(buff,"UDP\t");
break;
case IPPROTO_ICMP:
sprintf(buff,"ICMP\t");
break;
case IPPROTO_IP:
sprintf(buff,"IP\t");
break;
default:
sprintf(buff,"n/a ");
break;
}
strcat(echo, buff);
sprintf(hostip, "%s", inet_ntoa(ip->ip_src));
sprintf(buff, "Z: %s", inet_ntoa(ip->ip_src));
strcat(echo, buff);
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
return;
}
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);
size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp);
/*
Jeśli przyszedł dowolny pakiet IP od węzła mobilnego (adres sieci 10.1.100.0) to tworzę routing
*/
char net[100];
memset(net, '\0', strlen(net));
int k=0;
for(int i=0; i<strlen(hostip); i++){
if(hostip[i]=='.'){
k++;
}
if(k==3){
net[i]='.';
net[i+1]='0';
break;
}else{
net[i]=hostip[i];
}
}
//printf("%s\n", echo);
if(strcmp(net, "10.1.100.0")==0){
if(strncmp((char *)args, "eth0", 4)==0){
//printf("Uaktualniam routing dla %s\n", hostip);
//printf("%s\n", echo);
//printf("Uaktualniam routing dla %s\n", hostip);
CreateRoute(hostip, indat->ip2gr, (char *)"eth0");
}else if(strncmp((char *)args, "eth1", 4)==0){
//printf("%s\n", echo);
//printf("Uaktualniam routing dla %s\n", hostip);
CreateRoute(hostip, (char *)"eth1");
}else if(strncmp((char *)args, "eth2", 4)==0){
//printf("%s\n", echo);
//printf("Uaktualniam routing dla %s\n", hostip);
CreateRoute(hostip, indat->ip2bs, (char *)"eth2");
}else if(strncmp((char *)args, "eth3", 4)==0){
//printf("%s\n", echo);
//printf("Uaktualniam routing dla %s\n", hostip);
CreateRoute(hostip, indat->ip2gr, (char *)"eth3");
}
}
return;
}
int bs2mobile(InData* dat){
indat=dat;
/*scanf("%s", br1);
scanf("%s", br2);
scanf("%s", br3);
scanf("%s", ip1);
scanf("%s", ip2);
scanf("%s", ip3);*/
char dev[] = "eth1";
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *handle;
char filter_exp[] = "ip";
struct bpf_program fp;
bpf_u_int32 mask;
bpf_u_int32 net;
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Nie mogę pobrać maski urządzenia %s: %s\n",
dev, errbuf);
net = 0;
mask = 0;
}
handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Nie moge otworzyć urządzenia %s: %s\n", dev, errbuf);
exit(EXIT_FAILURE);
}
if (pcap_datalink(handle) != DLT_EN10MB) {
fprintf(stderr, "%s nie jest urządzeniem Ethernet\n", dev);
exit(EXIT_FAILURE);
}
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Błąd filtra %s: %s\n", filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "nie mogę zastosować filtra %s: %s\n",
filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
u_char ifc[]={'e', 't', 'h', '1', '\0'};
pcap_setdirection(handle, PCAP_D_IN);
pcap_loop(handle, -1, got_packet, ifc);
pcap_freecode(&fp);
pcap_close(handle);
return 0;
}
int mobile2net(InData* dat, char dev1[], char dev2[]){
indat=dat;
char dev[100];
int f=fork();
//routing
if(f==-1){
printf("błąd!\n");
return -1;
}else if(f==0){
strcpy(dev, dev1);
}else{
strcpy(dev, dev2);
}
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *handle;
char filter_exp[] = "ip";
struct bpf_program fp;
bpf_u_int32 mask;
bpf_u_int32 net;
if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
fprintf(stderr, "Nie mogę pobrać maski urządzenia %s: %s\n",
dev, errbuf);
net = 0;
mask = 0;
}
handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Nie moge otworzyć urządzenia %s: %s\n", dev, errbuf);
exit(EXIT_FAILURE);
}
if (pcap_datalink(handle) != DLT_EN10MB) {
fprintf(stderr, "%s nie jest urządzeniem Ethernet\n", dev);
exit(EXIT_FAILURE);
}
if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
fprintf(stderr, "Błąd filtra %s: %s\n", filter_exp, pcap_geterr(handle));
exit(EXIT_FAILURE);
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "nie mogę zastosować