/var/log/messages

debugging with sixth sense

プロミスキャスモードな Socket プログラム

とりあえずリモホに接続できるので Linux な man ができる、ということで (何

接続確立な初期処理では以下な手順を踏んでいます。

  • socket 手続き呼び出し
  • ifrec 構造体の初期化
  • ifrec 構造体にデバイスな文字列設定
  • ioctl に socket なデバイス番号と SIOCGIFINDEX と ifrec を渡して呼び出し
  • sockaddr_ll 構造体メンバの設定
  • bind
  • プロミスキャスモードの設定

このあたり、おもしろそうなので確認してみます。

まず、socket なディクリプタの取得が以下な模様。

    if((soc=socket(PF_PACKET,SOCK_RAW,htons(ETH_P_ALL)))<0){

man 見ると AF_* しか出てきていませんが

   AF_UNIX, AF_LOCAL   Local communication              unix(7)
   AF_INET             IPv4 Internet protocols          ip(7)
   AF_INET6            IPv6 Internet protocols          ipv6(7)
   AF_IPX              IPX - Novell protocols
   AF_NETLINK          Kernel user interface device     netlink(7)
   AF_X25              ITU-T X.25 / ISO-8208 protocol   x25(7)
   AF_AX25             Amateur radio AX.25 protocol
   AF_ATMPVC           Access to raw ATM PVCs
   AF_APPLETALK        Appletalk                        ddp(7)
   AF_PACKET           Low level packet interface       packet(7)

確認してみるに以下な定義みたいです。

$ find /usr/include |xargs grep PF_PACKET 2>/dev/null
/usr/include/x86_64-linux-gnu/bits/socket.h:#define     PF_PACKET       17      /* Packet family.  */
/usr/include/x86_64-linux-gnu/bits/socket.h:#define     AF_PACKET       PF_PACKET

通常は AF_INET なのかどうか。次に ifreq 構造体を初期化してデバイスな文字列を設定して ioctl してます。

    memset(&ifreq,0,sizeof(struct ifreq));
    strncpy(ifreq.ifr_name,device,sizeof(ifreq.ifr_name)-1);
    if(ioctl(soc,SIOCGIFINDEX,&ifreq)<0){

この ioctl がアレですね。以下な man によれば

インターフェースの interface index を取得し、ift_ifindex に入れて返すということで三番目の struct ifreq な引数のオブジェクトに soc な情報が設定されるのか。 このプログラム、某所の学生さんな課題なのですがまだ面白さが分からない模様。これはこれで勿体ないですね。なんとかならないものか。

Comments