On 22/3/18 3:08 am, Eugene Grosbein wrote:
22.03.2018 1:08, Ronald F. Guilmette wrote:

OK, so, if I have understood all that has been said in this thread so
far, then I would assert that, from the perspective of a simple-minded
and naive end user (e.g. me), the assertion that I originally quoted
-is- in fact correct, i.e. one -cannot- just simply do sendto/recvfrom
(and expect to get back responses) if the raw packets that one sends out
happen to be, for example, well formed TCP or UDP packets.
Not exactly. You can't use raw sockets to receive but that does not mean
you cannot use sendto/recvfrom (or similar calls) at all: there are
libpcap, libdnet and NETGRAPH allowing to send requests and receive answers.

If I have correctly understood Matt Joras, there -are- ways to get hold
of such reply packets, under FreeBSD, but those require getting a bit more
"under the hood" in order to actually get hold of them... more than just
a simple recvfrom on the RAW socket.
Why should you concentrate on RAW sockets?

I have small perl script that sends manually crafted PPPoE frames
and receives replies using simple libpcap interface:

use Net::Pcap qw(:DEFAULT :functions);

use constant V8021Q                     => 0x8100;
use constant ETHERTYPE_PPPOEDISC        => 0x8863;
use constant PPPOE_VER                  => 1;
use constant PPPOE_TYPE                 => 1;
use constant PADO_CODE                  => 7;
use constant PADI_CODE                  => 9;
use constant TAG_END_OF_LIST            => 0x0000;
use constant TAG_SERVICE_NAME           => 0x0101;
use constant TAG_AC_NAME                => 0x0102;
use constant TAG_HOST_UNIQ              => 0x0103;

$packet =
     # Ethernet header: dst MAC, src MAC, TYPE
     ether_aton('ff:ff:ff:ff:ff:ff') . $bmac . pack('n', ETHERTYPE_PPPOEDISC) .
     # PPPoE PADI: VER, TYPE, CODE, SESSION_ID=0
     pack('C', (PPPOE_VER<<4) + PPPOE_TYPE) . pack('C', PADI_CODE) . pack('n', 
0)
     # LENGTH, tags
     pack('n', $tlen) . $tags;
# zero padding upto 60 bytes ethernet frame length (without checksum)
$packet .= pack('a' . (40-$tlen) , '') if $tlen < 40;

err("cannot open interface $interface: $err")
     unless $pcap = pcap_open_live($interface, $snaplen, 0, 0, \$err);
err("could not send PADI")
   if pcap_sendpacket($pcap, $packet) != 0;

$filter = "ether proto " . ETHERTYPE_PPPOEDISC . " and ether dst $mac";
err("cannot compile filter: $filter")
   if pcap_compile($pcap, \$bpf, $filter, 1, 0) < 0;
pcap_setfilter($pcap, $bpf);

$ec = 0;
while($ec == 0) {
   $ec = pcap_loop($pcap, -1, \&callback, undef);
}
pcap_close($pcap);
exit(0);

sub callback($$$) {
   return if $_[1]->{'len'} < 20;        # sanity check: short frame
   my ($dst, $src, $ftype, $ftag, $fp) = unpack('a6a6na4a*' , $_[2]);
   ...
}
why not just use the ng-pppoe node? :-)
_______________________________________________
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"


_______________________________________________
freebsd-net@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to