/* * This file was generated automatically by ExtUtils::ParseXS version 2.18 from the * contents of ARP.xs. Do not edit this file, edit ARP.xs instead. * * ANY CHANGES MADE HERE WILL BE LOST! * */ #line 1 "ARP.xs" /* Perl ARP Extension Create and send an arp packets, lookup mac addresses Programmed by Bastian Ballmann Last update: 31.01.2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include #include #include #include #include #include #include #include "arp.h" #ifndef PERL_UNUSED_VAR # define PERL_UNUSED_VAR(var) if (0) var = var #endif #line 48 "ARP.c" XS(XS_Net__ARP_send_packet); /* prototype to pass -Wmissing-prototypes */ XS(XS_Net__ARP_send_packet) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif if (items != 6) Perl_croak(aTHX_ "Usage: %s(%s)", "Net::ARP::send_packet", "dev, sip, dip, smac, dmac, type"); PERL_UNUSED_VAR(cv); /* -W */ { unsigned char * dev = (unsigned char *)SvPV_nolen(ST(0)); unsigned char * sip = (unsigned char *)SvPV_nolen(ST(1)); unsigned char * dip = (unsigned char *)SvPV_nolen(ST(2)); unsigned char * smac = (unsigned char *)SvPV_nolen(ST(3)); unsigned char * dmac = (unsigned char *)SvPV_nolen(ST(4)); unsigned char * type = (unsigned char *)SvPV_nolen(ST(5)); int RETVAL; dXSTARG; #line 46 "ARP.xs" int uid; unsigned int packetsize = sizeof(struct arphdr) + sizeof(struct ether_header); unsigned char packet[packetsize]; struct ether_header *ethhdr = (struct ether_header *)packet; struct arphdr *arp = (struct arphdr *)(packet + sizeof(struct ether_header)); u_short op; RETVAL = 1; // Are you root? uid = getuid(); if(uid != 0) { printf("You must have UID 0 instead of %d.\n",uid); exit(0); } // Initialize packet buffer memset(packet,0,packetsize); // What's the ARP operation type? if(!strcmp(type,"request")) { op = ARPOP_REQUEST; } else if(!strcmp(type,"reply")) { op = ARPOP_REPLY; } else if(!strcmp(type,"revrequest")) { op = ARPOP_REVREQUEST; } else if(!strcmp(type,"revreply")) { op = ARPOP_REVREPLY; } else if(!strcmp(type,"invrequest")) { op = ARPOP_INVREQUEST; } else if(!strcmp(type,"invreply")) { op = ARPOP_INVREPLY; } else { op = ARPOP_REPLY; } if(smac == NULL) { printf("Parameter smac is NULL! Terminating.\n"); RETVAL = 0; } if(dmac == NULL) { printf("Parameter dmac is NULL! Terminating.\n"); RETVAL = 0; } // Found a dollar sign? if(strchr(smac,36)) { printf("Found a $ char in smac! Terminating.\n"); RETVAL = 0; } if(strchr(dmac,36)) { printf("Found a $ char in dmac! Terminating.\n"); RETVAL = 0; } if(ether_aton(smac) == NULL) { printf("Invalid source mac address! Terminating.\n"); RETVAL = 0; } if(ether_aton(dmac) == NULL) { printf("Invalid destination mac address! Terminating.\n"); RETVAL = 0; } // Check ips if(inet_addr(sip) == INADDR_NONE) { printf("Invalid source ip address! Terminating.\n"); RETVAL = 0; } if(inet_addr(dip) == INADDR_NONE) { printf("Invalid destination ip address! Terminating.\n"); RETVAL = 0; } // Construct and send packet if(RETVAL != 0) { // Ethernet header memcpy(ethhdr->ether_dhost,(u_char *)ether_aton(dmac),ETHER_ADDR_LEN); // Destination MAC memcpy(ethhdr->ether_shost,(u_char *)ether_aton(smac),ETHER_ADDR_LEN); // Source MAC ethhdr->ether_type = htons(ETHERTYPE_ARP); // ARP protocol // ARP header arp->hw_type = htons(ARPHDR_ETHER); // Hardware address type arp->proto_type = htons(ETH_P_IP); // Protocol address type arp->ha_len = ETH_ALEN; // Hardware address length arp->pa_len = IP_ALEN; // Protocol address length arp->opcode = htons(op); // ARP operation memcpy(arp->source_add,(u_char *)ether_aton(smac),ETH_ALEN); // Source MAC *(u_long *)arp->source_ip = inet_addr(sip); // Source IP if(strcmp(dmac,"ff:ff:ff:ff:ff:ff")) memcpy(arp->dest_add,(u_char *)ether_aton(dmac),ETH_ALEN); // Destination MAC *(u_long *)arp->dest_ip = inet_addr(dip); // Destination IP // Run packet!! Run! // FreeBSD code if(SOCK_TYPE == SOCK_RAW) { RETVAL = send_packet_bsd(dev,packet,packetsize); } // Linux code else { RETVAL = send_packet_linux(dev,packet,packetsize); } } #line 208 "ARP.c" XSprePUSH; PUSHi((IV)RETVAL); } XSRETURN(1); } XS(XS_Net__ARP_get_mac); /* prototype to pass -Wmissing-prototypes */ XS(XS_Net__ARP_get_mac) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif if (items != 1) Perl_croak(aTHX_ "Usage: %s(%s)", "Net::ARP::get_mac", "dev"); PERL_UNUSED_VAR(cv); /* -W */ { unsigned char * dev = (unsigned char *)SvPV_nolen(ST(0)); char * RETVAL; dXSTARG; #line 191 "ARP.xs" char tmp[20] = "unknown"; if(SOCK_TYPE == SOCK_RAW) { get_mac_bsd(dev,tmp); } else { get_mac_linux(dev,tmp); } RETVAL = tmp; #line 244 "ARP.c" sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; } XSRETURN(1); } XS(XS_Net__ARP_arp_lookup); /* prototype to pass -Wmissing-prototypes */ XS(XS_Net__ARP_arp_lookup) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif if (items != 2) Perl_croak(aTHX_ "Usage: %s(%s)", "Net::ARP::arp_lookup", "dev, ip"); PERL_UNUSED_VAR(cv); /* -W */ { unsigned char * dev = (unsigned char *)SvPV_nolen(ST(0)); unsigned char * ip = (unsigned char *)SvPV_nolen(ST(1)); char * RETVAL; dXSTARG; #line 214 "ARP.xs" char tmp[20] = "unknown"; if(SOCK_TYPE == SOCK_RAW) { arp_lookup_bsd(dev,ip,tmp); } else { arp_lookup_linux(dev,ip,tmp); } RETVAL = tmp; #line 281 "ARP.c" sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; } XSRETURN(1); } #ifdef __cplusplus extern "C" #endif XS(boot_Net__ARP); /* prototype to pass -Wmissing-prototypes */ XS(boot_Net__ARP) { #ifdef dVAR dVAR; dXSARGS; #else dXSARGS; #endif char* file = __FILE__; PERL_UNUSED_VAR(cv); /* -W */ PERL_UNUSED_VAR(items); /* -W */ XS_VERSION_BOOTCHECK ; newXS("Net::ARP::send_packet", XS_Net__ARP_send_packet, file); newXS("Net::ARP::get_mac", XS_Net__ARP_get_mac, file); newXS("Net::ARP::arp_lookup", XS_Net__ARP_arp_lookup, file); XSRETURN_YES; }