Re: Code working with LIBNET_RAW4, not with LIBNET_LINK
Karen Pease <[email protected]> Tue, 1 Feb 2005 15:55:49 -0600
| Newsgroups | gmane.comp.security.libnet |
|---|---|
| Message-ID | <[email protected]> |
On Tuesday 01 February 2005 2:05 am, Manu Garg wrote: > Karen, > > Let me first try to understand your problem. You have an arrangement like > this: A (local/home m/c) ---->Internet----->B(work m/c) A (local/home m/c) ----> router (NAT, with port forwarding) ----> Internet ----> B (work m/c) > First thing: It's NOT possible for you to find out hw address of the > machine at the OTHER side of the router/gateway and it's NOT REQUIRED > also. I already understood that :) I still need to be able to get the gateway's MAC, however, and this is causing problems. > To make your packet reach machine B, > you need to first get it to your router and to do that you need your > router's hw address NOT machine B's. Yes; unfortunately, I have been unable to get its hw addr. When sending to my work machine, I can use FF.FF.FF.FF.FF.FF and the packets will get there. The same does not hold true in reverse, however. > Code pointed by Mike does exactly that. The code first reads the > kernel's routing table to find out the proper route for the > destination and then it finds out hw address of that router(gateway) > by arp cache lookup. That's what you need. As I demonstrated in the previous email, the code provided by Mike fails on looking up arbitrary addresses; it only works for the gateway. In my example, I ran it at home and attempted to look up my gateway (192.168.0.1); that succeeded. Then I ran it at home and attempted to look up my work computer; it failed. The output was included in the previous email. Thanks for your help, Manu. - Karen > > > On Tue, 1 Feb 2005 00:34:46 -0600, Karen Pease > > <[email protected]> wrote: > > Just as the libnet code examples only work for hard-coded mac addrs, this > > code only works for the gateway. For example, lets try to generalize it > > (I'll cut out my actual target ip; it's non-local): > > > > struct arp_entry arp; > > #if 1 > > int ret=addr_pton("192.168.0.1",&(arp.arp_pa)); //My gateway > > #else > > int ret=addr_pton("AAA.BBB.CCC.DDD",&(arp.arp_pa)); //IP snipped > > out #endif > > printf("IP: %d.%d.%d.%d > > (%d)\n",((u_int8_t*)(&arp.arp_pa.addr_eth)) > > [0],((u_int8_t*)(&arp.arp_pa.addr_eth))[1],((u_int8_t*) > > (&arp.arp_pa.addr_eth))[2],((u_int8_t*)(&arp.arp_pa.addr_eth))[3],ret); > > > > arp_t* a=arp_open(); > > printf("arp_t: %d\n",a); > > > > ret=arp_get(a,&arp); > > printf("%d\n",ret); > > > > arp_close(a); > > > > for (int i=0; i<6; i++) > > uc.dest_mac[i]=((u_int8_t*)(&arp.arp_ha.addr_eth))[i]; > > > > printf("saddr: %02x.%02x.%02x.%02x.%02x.%02x daddr: > > %02x.%02x.%02x. %02x.%02x. > > %02x\n",uc.src_mac[0],uc.src_mac[1],uc.src_mac[2],uc.src_mac[3],uc.src_ma > >c[4],uc.src_mac[5],uc.dest_mac[0],uc.dest_mac[1],uc.dest_mac[2],uc.dest_ma > >c[3],uc.dest_mac[4],uc.dest_mac[5]); send(&uc,argv[3]); > > > > If we run this code as-is, we get: > > > > IP: 192.168.0.1 (0) > > arp_t: 134564104 > > 0 > > saddr: 00.50.04.6c.e7.30 daddr: 00.20.e0.35.54.40 > > > > However, if we change the #if 1 to a #if 0, we get: > > > > IP: AAA.BBB.CCC.DDD (0) > > arp_t: 134564104 > > -1 > > saddr: 00.50.04.6c.e7.30 daddr: 00.00.00.00.00.00 > > > > As you'll note, arp_get gives an error (by returning -1) and doesn't set > > the hardware address. > > > > - Karen > > > > On Monday 31 January 2005 12:31 am, Mike Schiffman wrote: > > > I mentioned this in last email. You need to use libdnet's route lookup > > > and ARP cache query routines. Firewalk does exactly this. Below is the > > > relevant function from Firewalk-5.0/src/packet_build.c. > > > > > > int > > > fw_packet_build_probe(struct firepack **fp) > > > { > > > arp_t *a; > > > route_t *r; > > > struct arp_entry arp; > > > struct route_entry route; > > > > > > /* first build our transport layer header */ > > > switch ((*fp)->protocol) > > > { > > > case IPPROTO_UDP: > > > if (fw_packet_build_udp(fp) == -1) > > > { > > > /* error msg set in fw_packet_build_udp() */ > > > return (-1); > > > } > > > break; > > > case IPPROTO_TCP: > > > if (fw_packet_build_tcp(fp) == -1) > > > { > > > /* error msg set in fw_packet_build_tcp() */ > > > return (-1); > > > } > > > break; > > > default: > > > sprintf((*fp)->errbuf, > > > "fw_packet_build_probe(): unknown protocol"); > > > return (-1); > > > } > > > > > > /* build our IPv4 header */ > > > (*fp)->ip = libnet_build_ipv4( > > > (*fp)->packet_size, /* packetlength */ > > > 0, /* IP tos */ > > > (*fp)->id, /* IP id */ > > > 0, /* IP frag bits */ > > > (*fp)->ttl, /* IP time to live */ > > > (*fp)->protocol, /* transport protocol > > > */ 0, /* checksum */ > > > (*fp)->sin.sin_addr.s_addr, /* IP source */ (*fp)->metric, > > > /* IP destination */ NULL, > > > /* IP payload */ 0, /* IP payload > > > size */ (*fp)->l, /* libnet context */ 0); > > > /* No saved ptag */ > > > > > > if ((*fp)->ip == -1) > > > { > > > snprintf((*fp)->errbuf, FW_ERRBUF_SIZE, "libnet_build_ipv4() > > > %s", > > > libnet_geterror((*fp)->l)); > > > return (-1); > > > } > > > > > > /* > > > * Now we need to get the MAC address of our first hop gateway. > > > * Dnet to the rescue! We start by doing a route table lookup > > > * to determine the IP address we use to get to the > > > * destination host (the metric). > > > */ > > > r = route_open(); > > > if (r == NULL) > > > { > > > snprintf((*fp)->errbuf, FW_ERRBUF_SIZE, "route_open()"); > > > route_close(r); > > > return (-1); > > > } > > > > > > /* convert the metric address to dnet's native addr_t format */ > > > if (addr_aton(libnet_addr2name4((*fp)->metric, 0), > > > &route.route_dst) < 0) > > > { > > > snprintf((*fp)->errbuf, FW_ERRBUF_SIZE, "addr_aton()"); > > > route_close(r); > > > return (-1); > > > } > > > /* get the route entry telling us how to reach the metric */ > > > if (route_get(r, &route) < 0) > > > { > > > snprintf((*fp)->errbuf, FW_ERRBUF_SIZE, "route_get()"); > > > route_close(r); > > > return (-1); > > > } > > > route_close(r); > > > > > > a = arp_open(); > > > if (a == NULL) > > > { > > > snprintf((*fp)->errbuf, FW_ERRBUF_SIZE, "arp_open()"); > > > return (-1); > > > } > > > /* get the MAC of the first hop gateway */ > > > arp.arp_pa = route.route_gw; > > > if (arp_get(a, &arp) < 0) > > > { > > > snprintf((*fp)->errbuf, FW_ERRBUF_SIZE, "route_get()"); > > > arp_close(a); > > > return (-1); > > > } > > > arp_close(a); > > > > > > /* build our ethernet header */ > > > if (libnet_autobuild_ethernet( > > > (u_char *)&arp.arp_ha.addr_eth, > > > ETHERTYPE_IP, > > > (*fp)->l) == -1) > > > { > > > snprintf((*fp)->errbuf, FW_ERRBUF_SIZE, > > > "libnet_autobuild_ethernet() %s", > > > libnet_geterror((*fp)->l)); > > > arp_close(a); > > > return (-1); > > > } > > > > > > return (1); > > > } > > > > > > On Jan 30, 2005, at 8:27 PM, Karen Pease wrote: > > > > A couple weeks ago, I posted here with problems sending packets via > > > > LIBNET_LINk when they worked with LIBNET_RAW4. Last I posted, I > > > > thought I > > > > had resolved the problem by using the libnet_ethernet_autobuild > > > > function; > > > > however, it turns out that it was only working in a situation that I > > > > previously had working (sending from my home computer to my work > > > > computer) (I > > > > discovered this shortly after I send my last emaiL); I've tried to > > > > work on it > > > > on my own, but have had no success in getting packets to arrive the > > > > other > > > > way. So, I'm still stuck where I was before. > > > > > > > > The main problem is mac addrs. The libnet example code for raw > > > > sockets (which > > > > I was pointed to before) uses hard coded mac addrs; naturally, as I > > > > mentioned > > > > before, this means that the code is effectively worthless in > > > > real-world applications, since you don't know beforehand what a > > > > target machine's mac > > > > addr will be. I can get packets from my home computer to my work > > > > computer > > > > using mac addr ff.ff.ff.ff.ff.ff; however, the same does not work in > > > > reverse. > > > > Assumedly this has something to do with my router (I'm behind NAT > > > > with port > > > > forwarding for the port being sent to). To send packets from work to > > > > home, I > > > > need to be able to look up the router's mac addr (in fact, if I hard > > > > code it, > > > > they make it home just fine). I previously asked if there was a > > > > libnet function to do this for you. I got no clear response, so I > > > > assume the answer > > > > is "no". > > > > > > > > So as not to bother the list any more, I decided to try and look it > > > > up myself; > > > > to the best of my knowlege, this is done with arp who-has requests. > > > > So, I > > > > tried sending who-has requests, and set up this nice system to send > > > > them out > > > > and sniff the results back off the network. I got no response. > > > > Looking in > > > > tcpdump, only a small percentage of all machines on the network that > > > > issued > > > > who-has requests got them answered - at least, so far as I could see > > > > in sniffed network traffic. All of the who-has requests seemed to be > > > > structured > > > > the same (including mine). So, I'm not sure what I'm missing. > > > > > > > > In short, I have to ask: How can I get a remote machine's mac addr to > > > > use with > > > > libnet? I'm getting somewhat frustrated here. :( > > > > > > > > - Karen > > > > > > -- > > > Mike Schiffman, CISSP > > > http://www.packetfactory.net/schiffman > > > Doveryay No Proveryay