00001 #include "packet_linux_raw.h"
00002
00003 #ifdef _LINUX_
00004 #include <sys/types.h>
00005 #include <sys/socket.h>
00006 #include <netinet/in.h>
00007 #include <unistd.h>
00008 #include <fcntl.h>
00009 #include <sys/ioctl.h>
00010 #include <net/if.h>
00011 #include <sys/time.h>
00012 #include <linux/if_ether.h>
00013 #include <linux/if_packet.h>
00014 #include <sys/poll.h>
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <stdlib.h>
00018
00019
00020
00021 extern GlobalVars Globals;
00022
00023
00024
00025
00026 int GetIfrMTU(char *name) {
00027 int fd;
00028 struct ifreq ifr;
00029 int retval;
00030
00031 retval = -1;
00032 fd = socket(AF_INET, SOCK_DGRAM, 0);
00033 if ( fd < 0) {
00034 printf("Couldn't create socket for MTU\n");
00035 return -1;
00036 }
00037
00038 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
00039 if (ioctl(fd, SIOCGIFMTU, &ifr) == 0)
00040 retval = ifr.ifr_metric;
00041 else
00042 printf("ioctl(SIOCGIFMTU)");
00043 close(fd);
00044 return retval;
00045 }
00046
00047
00048
00049
00050
00051 int get_device_id(int fd, char* name){
00052 struct ifreq ifr;
00053
00054 bzero(&ifr, sizeof(struct ifreq));
00055 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
00056 if (ioctl(fd, SIOGIFINDEX, &ifr) == -1) return -1;
00057 return ifr.ifr_ifindex;
00058 }
00059
00060
00061
00062
00063 int OpenInterfaceLinuxRaw(int InterfaceID){
00064 int fd;
00065 struct sockaddr_ll sll;
00066 int ssize;
00067 int errnum;
00068 struct packet_mreq mr;
00069 InterfaceRec* Interface;
00070
00071 DEBUGPATH;
00072
00073 Interface=&Globals.Interfaces[InterfaceID];
00074
00075 #ifdef DEBUG
00076 printf("Opening interface %s\n", Interface->Name);
00077 #endif
00078
00079 fd=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
00080 bzero(&sll,sizeof(struct sockaddr_ll));
00081 sll.sll_family=AF_PACKET;
00082 sll.sll_ifindex=get_device_id(fd, Interface->Name);
00083 sll.sll_protocol=htons(ETH_P_ALL);
00084 ssize=sizeof(struct sockaddr_ll);
00085
00086 errnum=bind(fd, (struct sockaddr*)&sll, sizeof(sll));
00087 if (errnum==-1){
00088 printf("Error Binding socket\n");
00089 return FALSE;
00090 }
00091
00092
00093 memset(&mr, 0, sizeof(mr));
00094 mr.mr_ifindex=get_device_id(fd, Interface->Name);
00095 mr.mr_type=PACKET_MR_PROMISC;
00096 if (setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr))==-1){
00097 printf("Failed to set promisc mode\n");
00098 return FALSE;
00099 }
00100
00101 Interface->FD=fd;
00102 Interface->MTU=GetIfrMTU(Interface->Name);
00103 if (Interface->MTU==-1) Interface->MTU=1500;
00104
00105 Interface->IsPollable=TRUE;
00106
00107 return TRUE;
00108 }
00109
00110
00111
00112
00113 int ReadPacketLinuxRaw(int InterfaceID){
00114 int count;
00115 InterfaceRec* Interface;
00116 int PacketSlot;
00117 PacketRec* p;
00118 #ifdef DEBUG
00119 int i;
00120 #endif
00121
00122 DEBUGPATH;
00123
00124 Interface=&Globals.Interfaces[InterfaceID];
00125 if ( (PacketSlot=GetEmptyPacket())==-1){
00126 printf("Unable to allocate packet for reading\n");
00127 #ifdef DEBUG
00128 printf("Packets are in the following states:\n");
00129 for (i=0;i<MAX_PACKETS;i++){
00130 switch (Globals.Packets[i].Status){
00131 case PACKET_STATUS_IDLE:
00132 printf("%i: idle\n",i);
00133 break;
00134 case PACKET_STATUS_PENDING:
00135 printf("%i: pending\n",i);
00136 break;
00137 case PACKET_STATUS_SAVED:
00138 printf("%i: saved\n",i);
00139 break;
00140 case PACKET_STATUS_ALLOCATED:
00141 printf("%i: allocated\n",i);
00142 break;
00143 case PACKET_STATUS_PROCESSING:
00144 printf("%i: processing\n",i);
00145 break;
00146 default:
00147 printf("%i: unknown(%i)\n",i, Globals.Packets[i].Status);
00148 }
00149 }
00150 #endif
00151 return FALSE;
00152 }
00153
00154
00155 p=&Globals.Packets[PacketSlot];
00156
00157 p->InterfaceNum=InterfaceID;
00158
00159 count = read(Interface->FD, (char*)p->RawPacket, TYPICAL_PACKET_SIZE-1);
00160 if (count==-1){
00161 #ifdef DEBUG
00162 printf("Failed to read packet. FD %i\n", Interface->FD);
00163 #endif
00164 ReturnEmptyPacket(PacketSlot);
00165 return FALSE;
00166 }
00167 p->PacketLen=count;
00168
00169 if (ioctl(Interface->FD, SIOCGSTAMP, &p->tv)==-1){
00170 #ifdef DEBUG
00171 printf("Failed to get timestamp\n");
00172 #endif
00173 ReturnEmptyPacket(PacketSlot);
00174 return FALSE;
00175 }
00176
00177 if (!AddPacketToPending(PacketSlot)){
00178 printf("Coulnd't add packet to pending queue\n");
00179 ReturnEmptyPacket(PacketSlot);
00180 return FALSE;
00181 }
00182
00183 return TRUE;
00184 }
00185
00186
00187
00188
00189 int WritePacketLinuxRaw(int InterfaceID, unsigned char* Packet, int PacketLen){
00190 int count;
00191 InterfaceRec* interface;
00192
00193 DEBUGPATH;
00194
00195 interface=&Globals.Interfaces[InterfaceID];
00196
00197 count=write(interface->FD, Packet, PacketLen);
00198 if (count==-1){
00199 printf("Failed to write packet to interface %s\n",interface->Name);
00200 return FALSE;
00201 }
00202
00203 return TRUE;
00204 }
00205
00206
00207
00208
00209 void* LinuxRawLoopFunc(void* v){
00210 int InterfaceID;
00211
00212 DEBUGPATH;
00213
00214 InterfaceID=(int)v;
00215 while (!Globals.Done){
00216 ReadPacketLinuxRaw(InterfaceID);
00217 }
00218
00219 return NULL;
00220 }
00221
00222
00223
00224
00225 int LoopThreadLinuxRaw(int InterfaceID){
00226
00227 DEBUGPATH;
00228
00229 #ifndef HAS_THREADS
00230 return FALSE;
00231 #else
00232
00233 #ifdef DEBUG
00234 printf("Starting Thread for interface %s\n",Globals.Interfaces[InterfaceID].Name);
00235 #endif
00236
00237 Globals.Interfaces[InterfaceID].ThreadID=pthread_create(
00238 &Globals.Interfaces[InterfaceID].Thread,
00239 NULL,
00240 LinuxRawLoopFunc,
00241 (void*)InterfaceID
00242 );
00243
00244 return (!Globals.Interfaces[InterfaceID].ThreadID);
00245 #endif
00246
00247 }
00248
00249 #endif