⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 145.htm

📁 unix高级编程原吗
💻 HTM
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://apue.dhs.org"><font face="黑体"><big><big>123</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center">               ● UNIX网络编程                       (BM: clown)                </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p   align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="100" align="center" valign="top"><br><p align="center">[<a href="index.htm">回到开始</a>][<a href="135.htm">上一层</a>][<a href="146.htm">下一篇</a>]
<hr><p align="left"><small>发信人: guru (好读书,不求甚解), 信区: UNP <br>

标  题: Using SOCK_PACKET to gain full access to Ethernet <br>

发信站: UNIX编程 (2001年08月15日09:48:20 星期三), 站内信件 <br>

  <br>

Using the SOCK_PACKET mechanism in Linux <br>

To Gain Complete Control of an Ethernet Interface <br>

Daniel Senie <br>

Amaranth Networks, Inc. <br>

I have put together this web page in response to many queries from multiple peop <br>

le. Rather than continue to write individual responses, I have put together this <br>

 page to explain what I was trying to do, and how I got it to work. <br>

  <br>

  <br>

First, some background. To simulate software that was intended to run on a diffe <br>

rent (and not yet built) platform, I needed a convenient way to exercise the cod <br>

e against live networks. I first tried using a Solaris system, using the DLPI dr <br>

iver. This <br>

allowed me to do most things, but failed when I needed to be able to set the sou <br>

rce Ethernet MAC address. The Solaris DLPI driver provides no way to override th <br>

e hardware on a per-packet basis. <br>

  <br>

  <br>

Next, I started looking at mechanisms in Linux. The mechanism that seemed to fit <br>



 the best was SOCK_PACKET, which is used by tcpdump among other things. To Make <br>

this work for me, though, it was necessary to keep the Linux machine from doing <br>

anything on <br>

the interface, other than letting my programs at it. <br>

  <br>

How To Do It <br>

This information and these instructions work for RedHat Linux 4.2 with a 2.0.30 <br>

kernel. I expect they'll work fine on a 2.0.32 kernel as well, and with other Li <br>

nux distributions. I have heard that a better mechanism for providing this facil <br>

ity is <br>

coming in a newer kernel. If or when I get more information on that, I'll see ab <br>

out adding another page on that. <br>

  <br>

First, the interface needs to be told NOT to run ARP. Promiscuous mode should be <br>

 enabled if you need to hear everything on the wire.: <br>

  <br>

        ifconfig eth1 -ARP PROMISC UP 10.1.1.1 <br>

  <br>

Then tell the Linux stack it's not supposed to see any of the traffic to or from <br>

 this port: <br>

  <br>

  <br>

  <br>

 ipfwadm -O -a deny -P all -S 0/0 -D 0/0 -W eth1 <br>

 ipfwadm -I -a deny -P all -S 0/0 -D 0/0 -W eth1 <br>

  <br>

In the program, you need to do several things. First, the socket call: <br>

  <br>

        s = socket(AF_INET, SOCK_PACKET, htons(0x0003)); <br>

  <br>

to get the socket set up. <br>

  <br>

Next I bind the specific Ethernet NIC I want: <br>

  <br>

        struct sockaddr myaddr; <br>

  <br>

        memset(&myaddr, '\0', sizeof(myaddr)); <br>

        myaddr.sa_family = AF_INET; <br>

        strcpy(myaddr.sa_data, "eth1");  /* or whatever device */ <br>

  <br>

        r = bind(s, &myaddr, sizeof(struct sockaddr)); <br>

  <br>

and check the return code for any errors. <br>

  <br>

Now, when you want to send or receive, this socket is bound to the proper device <br>



. One word of caution, though, ALWAYS check the received packets to be sure you <br>

got them on the right device. There's a race condition between making the socket <br>

 call and <br>

the bind call where you'll get all packets from ALL interfaces... not what you w <br>

ant! <br>

  <br>

So, to send a packet: <br>

  <br>

        struct sockaddr from; <br>

        int fromlen; <br>

  <br>

        memset(&from, '\0', sizeof(from)); <br>

        from.sa_family = AF_INET; <br>

        strcpy(from.sa_data, "eth1"); /* or whatever device */ <br>

        fromlen = sizeof(from); <br>

  <br>

        r = sendto(s, msg, msglen, 0, &from, fromlen); <br>

  <br>

and check the return code. Note that msg is the pointer to the packet, starting <br>

with the MAC header. Be sure you put the proper source MAC address into your pac <br>

kets! Also, msglen is the length of the packet including the MAC header, but not <br>

 including <br>

 including <br>

the CRC (which I do not worry about, but the hardware does supply). <br>

  <br>

Receive is pretty similar: <br>

  <br>

        struct sockaddr from; <br>

        int fromlen; <br>

  <br>

        fromlen = sizeof(from); <br>

  <br>

        r = recvfrom(s, msg, 2048, 0, &from, &fromlen); <br>

        if (r == -1) <br>

        { <br>

                /* deal with error */ <br>

        } <br>

        if (strcmp(from.sa_data, "eth1") != 0) <br>

        { <br>

                /* not from the interface we wanted, discard */ <br>

        } <br>

  <br>

if r == -1, you have an error. If r > 0, then r is the length of the received pa <br>

cket. The strcmp ensures the packet came from the right interface. <br>

  <br>

  <br>

If you want to receive for MAC addresses other than the one the board has in it, <br>

 use promiscuous mode. To get the mac address from your program, there's an ioct <br>

l call SIOCGIFHWADDR. In the return from that call is also the hardware type, so <br>

 you can <br>

ensure it's Ethernet. Another call, SIOCGIFMTU will tell you the MTU of the inte <br>

rface. <br>

  <br>

Caveats <br>

Do not use this methodology on your primary Ethernet interface. Instead, install <br>

 a second (and if needed, third) NIC card for use in this way. I've successfully <br>

 used 5 NIC cards in one machine, 1 under the control of Linux, the rest bypasse <br>

d to my <br>

programs. <br>

Be VERY sure you set up the ipfwadm commands. Failure to do so will make a huge <br>

mess, likely causing networking problems for other hosts on your lan. <br>

  <br>

-------------------------------------------------------------------------------- <br>

  <br>

If you found this information helpful and useful, please let me know. If you req <br>

uire further information or assistance in this area, this can be arranged. For c <br>

onsultation beyond simple questions, Amaranth Networks, Inc. can provide advice, <br>

 services <br>



and information for a fee. <br>

  <br>

  <br>

Copyright ? 1998, Amaranth Networks, Inc. <br>

All Rights Reserved <br>

-- <br>

Target Locked:Guru In Darkness. <br>

我只是一只静静卧着的狮子。。。 <br>

※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 202.114.36.225] <br>

</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="135.htm">上一层</a>][<a href="146.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</table>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -