Table of Contents
Be Events: IT Forum/Comdex, Paris, France, BeOS Demos: SD'98 in San Francisco; Be Developer Conference in Santa Clara
BE ENGINEERING INSIGHTS: Sniffing the WiresFor network administration or low-level development it's useful to be able to monitor and interpret the network traffic at the physical level with a network monitor/analyzer. These tools are expensive, however, and they pose security concerns and moral dilemmas that need to be resolved. For network development, though, it can also be helpful to watch the traffic as it passes through the layers of the protocol stack. Every layer strips the corresponding envelope from a received packet on its way up. The reverse process of adding headers and/or trailers takes place when a packet is sent out. Examples of protocol stacks are TCP/IP, AppleTalk, and IPX. A protocol is simply a set of rules. Protocols are present wherever there is a need to communicate: language, auto traffic rules, human behavior... Not to mention networks and computers. If protocol is broken, communication is #@$#@$%@! Technically, today's sample is a protocol driver, but instead of passing packets up, it unconditionally rejects each of them after spitting it out to a file. "Reject" in protocolese means: "I'm not consuming this packet, it's meant for some other protocol stack." Here's what Netdump's output looks like: ... Frame# 2, Length=60, deltaTime= 1288.5380, Protocol=ARP, PID=0x0806 Dst=[ff:ff:ff:ff:ff:ff], Src=[00:c0:f0:22:c0:81], Entire frame follows ff ff ff ff ff ff 00 c0 f0 22 c0 81 08 06 00 01 08 00 06 04 00 01 00 c0 f0 22 c0 81 cf 71 d7 de 00 00 00 00 00 00 cf 71 d7 dd 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Frame# 3, Length=98, deltaTime= 0.4600, Protocol=IP, PID=0x0800 Dst=[00:60:08:a2:33:0f], Src=[00:c0:f0:22:c0:81], Entire frame follows 00 60 08 a2 33 0f 00 c0 f0 22 c0 81 08 00 45 00 ... The complete code is available by anonymous ftp at: ftp://ftp.be.com/pub/samples/network_kit/obsolete/netdump.zip Here is a self-explanatory code excerpt. #include <NetDevice.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <OS.h> #include <byteorder.h> #include "netdump.h" static FILE *f; static short just_started; void NetdumpController::AddDevice( BNetDevice *dev, const char *name ) { if (dev->Type() != B_ETHER_NET_DEVICE) return; f = fopen(DUMPTO, "w+"); if (!f) return; just_started = true; register_packet_handler(this, dev, NETDUMP_PRIO); } bool NetdumpController::PacketReceived( BNetPacket *pkt, BNetDevice *dev ) { static double time0; static ulong pktn; ushort pkt_size, i; uchar mac_addr[MAC_ADDR_LEN]; char protostr[12]; ushort protoid; if (just_started) { just_started = false; pktn = 0; time0 = system_time(); } if (pktn++ == MAX_PKT_N) { //There! Now close and cleanup unregister_packet_handler(this, dev); fclose(f); // From now on, only counter will get incremented. // No output } if (pktn >= MAX_PKT_N) // are we "there" yet? return false; // else... pkt_size = pkt->Size(); fprintf(f, "Frame# %u, Length=%d, ", pktn, pkt_size); fprintf(f, "deltaTime=%10.4f, ", (system_time() - time0) / 1000); // PID/len pkt->Read(ETHDR_PROTOID_OFS, (char *)&protoid, sizeof(protoid)); protoid = B_BENDIAN_TO_HOST_INT16(protoid); // net is big-endian // interpret it if (protoid > MAX_ETH_LEN) { switch (protoid) { case PROTOID_IP: strcpy(protostr, "IP"); break; case PROTOID_ARP: strcpy(protostr, "ARP"); break; case PROTOID_RARP: strcpy(protostr, "RARP"); break; case PROTOID_APLTK: strcpy(protostr, "AppleTalk"); break; default: strcpy(protostr, "#Unknown#"); break; } fprintf(f, "Protocol=%s, ", protostr); } // else //This is IEEE 802.3 len. See RFC 894, 1042... // frame destination... fprintf(f, "PID=0x%04x\nDst=[", protoid); pkt->Read(0, (char *) &mac_addr, MAC_ADDR_LEN); for (i = 0; i < MAC_ADDR_LEN; i++) fprintf(f, "%02x%s", (uchar) mac_addr[i], (i == MAC_ADDR_LEN -1) ? "], " : ":"); // ...and source fprintf(f, "Src=["); pkt->Read(MAC_ADDR_LEN, (char *) &mac_addr, MAC_ADDR_LEN); for (i = 0; i < MAC_ADDR_LEN; i++) fprintf(f, "%02x%s", (uchar) mac_addr[i], (i == MAC_ADDR_LEN -1) ? "], " : ":"); fprintf(f, "Entire frame follows"); for (i = 0; i < pkt_size; i++) { fprintf(f, "%s%02x", (i % 0x10) == 0 ? "\n\t" : " ", (uchar) (pkt->Data())[i]); } fprintf(f, "\n"); fflush(f); time0 = system_time(); // there's always next time() return false; // let others enjoy this frame, too } #pragma export on extern "C" BNetProtocol * open_protocol( const char *device ) { NetdumpController *dev; dev = new NetdumpController(); return (dev); } #pragma export reset Thanks to the BNetDevice and BNetPacket classes, most of the
job is already done for us. A "normal" protocol would do a
more useful job in Netdump is not a tcpdump port but rather a simple debug utility. A quick look at a serious network monitor is enough to reveal the shortcomings in this sample. Needless to say, all of its features were carefully selected and organically grown for today's presentation. Current limitations and areas for improvement:
To install Netdump, follow these steps:
Currently netdump captures only the first Thanks to Bradley Taylor for his help and to my kids for lending me their computer over the holidays.
Newsletter Article Version 4.1.2b6
By Ron Theis Recently, I found myself working once again as team commander for a fighting force attempting to save the world. This time, I was with the Global Defense Initiative, and I was trying to stop the evil Brotherhood of Nod from taking over the planet. I was part way through my mission and was feeling pretty confident after taking out two of the three gun turrets marked for destruction, when suddenly, my old foe "Sorry, System Error. Unimplemented Trap" reared his ugly head. Blast it, I was so close! Now the Brotherhood would conquer the world while I was hitting "Restart"! After some investigating, I found that my Mac demo of
"Command & Conquer" was crashing because of the extension
In half an hour of searching, I found references to versions 1.0.6 and 1.0.8, but nothing about 1.1 or the latest version. I found source code for integrating 1.0.6 into an application (yippee), but nothing about downloading the latest version of DrawSprocketLib. Eventually, I reinstalled the demo and it installed a beta version of DrawSprocketLib 1.1; somehow the older version hadn't been replaced during my earlier install. So I was thinking (as I often do) that it would be great if I could check the versions of my applications without having to search for each one individually. I have at least a hundred applications on my hard drive, and I don't want to visit a separate web site to check the version status of each one. I want to scan my hard drive and check with a central repository of information to see if I've got the latest versions of everything. But in order to do that, gosh, I'd need an up-to-date archive of application information. The archive would need to encompass absolutely every application available on a platform and be maintained by the application developers themselves. Like BeWare. So I wrote a little application called VersionCheck which does exactly that. It searches through a hard drive, finds all the applications, and checks with the Be web site for the latest versions. The original DR8 version of VersionCheck was clunky and slow, but the most recent PR2 version is clunky and fast. It returns information about the latest available versions of your installed applications, and provides FTP and HTTP links for folks to download an updater or read more about the latest version. VersionCheck is not as smooth as Software Valet, which
allows your computer to check for the latest versions of
your installed packages and upgrade them while you sleep.
But if you're interested in testing out a raw,
proof-of-concept application, contact me at I'll post VersionCheck to BeWare within the next week or
two, so if you'd rather not bother with rawness, please
don't. I'm basically interested in seeing whether something
like this would get used -- unless I'm the only person who
has this problem....
A sister application to VersionCheck, of course, is one that
checks BeWare for newly available applications. When I want
to know what games have been released in the last two
months, I don't want to scour several gaming web sites for
tidbits. I just want a list that shows up in a window, with
links to download or find out more information. This sister
app is on the drawing board, but again, maybe I'm alone on
this one...
Always With The Questions
And now, a standard feature of my articles -- a few of the
recent questions I've been asked regarding the BeOS at trade
shows and via: webmaster@be.com
That's it from the web side of things. For folks who haven't
seen the new BeWare subcategory layouts
or the excellent Developer Library
on the site yet, do check them out. As
always, your comments, especially on the revamped sections,
are welcome at webmaster@be.com.
[This article was written using
Pe on the BeOS. Try it, you'll like it.]
"Developers' Workshop" is a new weekly feature that
provides answers to our developers' questions. Each week, a
Be technical support or documentation professional will
choose a question (or two) sent in by an actual developer
and provide an answer.
We've created a new section on our website. Please send us
your Newsletter topic suggestions by visiting the website
at: http://www.be.com/developers/suggestion_box.html.
Way back in mid-November (Issue 99
of the Be Newsletter, to
be exact), I wrote an article called "Sounds That Go Bump In
the Night," which described in fairly excruciating detail
how to create a sound mixing function that handles multiple
sound formats.
This brings up the obvious follow-up question: where does
sound come from? How does sound get from a file on disk into
the audio stream?
Don't be embarrassed. Lots of programmers ask this question
at some point in their lives.
The Media Kit
provides the BSoundFile class, which provides
an incredibly easy mechanism for reading sounds from disk.
This week, we'll create a simple class to play back sound
files from disk.
The SoundPlayer class discussed here is only capable of
playing 16-bit audio. You should be able to easily change
this code to use the As always, let's start by looking at the class The public API for the SoundPlayer class consists of three
functions: There are two private functions: The class also includes a BDACStream object, a BSubscriber,
and a BSoundFile, as well as a buffer (transfer_buf) we'll
be using for loading the sound data from disk.
Let's start by having a look at the The function starts by setting the BSoundFile, soundFile, to
the specified entry_ref, and marks the BSoundFile as
read-only. An additional function performed by the
BSoundFile class's If the If the sound is 16-bit, we ask our subscriber to subscribe
to the BDACStream called stream. If that returns B_OK,
meaning that no error occurred, we set the BDACStream's
sampling rate to match that of soundFile, and set the stream
buffers for the stream to be the same size as our class's
transfer buffer by calling And the The stream function, Now let's look at the real heart of the SoundPlayer class.
The We begin by establishing a 16-bit pointer to the DAC stream
buffer passed into the Then we compute the number of frames that we need to read
from disk to fill the buffer, and cache locally the number
of channels in the sound (whether it's stereo or mono):
Then we read in the appropriate number of frames, to fill
the transfer_buf buffer. If we read zero frames, or a
negative result is returned (which indicates an error
occurred), we return false, which indicates that the sound
has finished playing and that we want to be automatically
removed from the stream.
Once we've loaded the next few frames of sound from disk,
it's time to mix the sound into the buffer. This should look
familiar if you read
"Sounds That Go Bump In the Night,"
but, briefly, here's how it works: For each frame of audio,
we add the sample already in the DAC buffer to the sample in
the transfer buffer. If the sound we're playing is stereo
(if channelCount is 2) we do the same thing again to cover
the right channel, otherwise we just increment the soundData
pointer to leave the DAC stream's right channel alone.
Note that we handle clipping; if the sum of the two samples
is outside the range -32768...32768, we clip it to the
appropriate value.
Finally, if the number of frames read from disk is less than
the number of frames we could have put in the DAC buffer, we
return false, since that means we've played the entire
sound. Otherwise, we return true, so our subscriber will
remain in the stream.
To play a sound, just use the following code:
If you want to stop the sound:
This is a pretty basic sound file player. You can beef it up
without too much effort, and I just happen to have a couple
of suggestions for things you might try doing:
By Jean-Louis Gassée Allow me to add a few words to what my associates have
already said regarding the upcoming
Developer
Conference. This one is a turning point in the life of the
company and its developers, as it will mark our first real
step into the Intel space, moving from demos to CDs, with
all the attendant expectations and nervousness.
As discussed earlier, the players, the competition, the
hardware technology, the buying habits are different from
what we've seen on the PowerPC, not merely bigger. As a
result, the March '98 Be DC will focus on both product and
market strategy for the new
Intel
version of the BeOS. If past conferences are any indication,
we know we can look forward to articulate, energetic discussions of
technical as well as business issues.
There is more good news. We still are a very small company
with little staff; so, instead of platoons of product
managers, PR flacks, middle managers and other
acetate-flingers and PowerPoint users, you'll be able to
interact directly with the Be team, including the
engineers who designed and wrote the BeOS -- and use it
every day in advancing the platform. Since this release is
not just a port of the previous release, but has many
important new features of its own, direct contact with the
engineers is essential. For their part, the engineers are
always nervous before the conference, but are happy after
meeting with people who are building a product and a
business using their work.
Still on the good news, you'll see existing, shipping,
revenue-making BeOS applications, as well as
works-in-progress from your colleagues and competitors. Of
course, we'll try to put a special emphasis on work
showing off the best examples of real-time WYSIWYG
benefits, on features, speed, rendering, and acquisition
performance not available on other platforms.
On that last topic, we'll re-state our position vis-à-vis
Windows. In contrast to an example we don't want to follow
-- OS/2, a better DOS than DOS, a better Windows than
Windows -- we offer Linux and happy coexistence with
Windows, as a complement or supplement, rather than an
improbable replacement.
We'll need to clarify the differences, technical and
otherwise, between the BeOS and the various versions of
Linux, the latest one looking very good, what we can
learn, what we'll do differently -- but that's for another
column.
You're welcome to attend, even if you're not a registered
developer. This is an opportunity for us to make our case,
and for you to make a decision.
But there is some bad news. Seating is limited and, if
informal polling is worth anything, the Intel version will
increase participation. So, please take a minute and
register on our site. As a
consideration for your effort, we'll give you a $20 early
registration discount.
I look forward to seeing you March 19-20 in Santa Clara.
Recent Be Newsletters | | |||
Copyright ©1997 Be, Inc. Be is a registered trademark, and BeOS, BeBox, BeWare, GeekPort, the Be logo and the BeOS logo are trademarks of Be, Inc. All other trademarks mentioned are the property of their respective owners. Comments about this site? Please write us at webmaster@be.com. |