Codebase list biblesync / 649afbb
New upstream version 2.1.0 Bastian Germann 3 years ago
9 changed file(s) with 426 addition(s) and 413 deletion(s). Raw diff Collapse all Expand all
00 **.swp
1 *~
12 build/
55 # - INCLUDEDIR (default "CMAKE_INSTALL_PREFIX/include") - set to directory where header files should be installed
66 # - BIBLESYNC_SOVERSION (defaults to BIBLESYNC_VERSION) - Manually set the SOVERSION of the installed file
77 PROJECT(libbiblesync CXX)
8 SET(BIBLESYNC_VERSION 1.2.0)
8 SET(BIBLESYNC_VERSION 2.1.0)
99 # A required CMake line
1010 CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
1111 # Where our custom Find* files are located
88 @SHAREDLIB_TRUE@Libs: -L${libdir} -lbiblesync
99 @SHAREDLIB_FALSE@Libs: -L${libdir} -lbiblesync @LIBS@
1010 Libs.private: -L${libdir} -lbiblesync @LIBS@
11 Cflags: -I${includedir}/bibleysnc
11 Cflags: -I${includedir}
7070 // bible, ref, alt, group, domain as arrived.
7171 // info + dump available.
7272 // 3. 'M' (mismatch) against passphrase or mode or listen status.
73 // info == "announce" or "sync" or "beacon" (+ user @ [ipaddr])
73 // info == "announce"/"sync"/"beacon"/"chat" (+ user @ [ipaddr])
7474 // sync: bible, ref, alt, group, domain as arrived.
7575 // announce: presence message in alt.
7676 // also, individual elements are also available:
7777 // overload: bible ref group domain
7878 // user [ipaddr] app+ver device
79 // chat: message in alt.
7980 // dump available.
8081 // 4. 'S' (new speaker)
8182 // param overload as above. alt unused. see listenToSpeaker().
8283 // 5. 'D' (dead speaker)
8384 // opposite of new speaker. only param is speakerkey.
84 // 6. 'E' (error) for network errors & malformed packets.
85 // 6. 'C' (chat)
86 // human chat message to be displayed to user.
87 // message in alt.
88 // 7. 'E' (error) for network errors & malformed packets.
8589 // only info + dump are useful.
8690 //
8791 // - get current mode.
120124 // - allow another speaker to drive us
121125 // void listenToSpeaker(bool listen, string speakerkey)
122126 // say yes/no to listening.
127 //
128 // - send a human chat message to others listening.
129 // BibleSync_xmit_status retval = Chat("your message for others here");
130 // sends your message to all other listeners. not restricted to Speakers.
123131 //
124132 // Receive() USAGE NOTE:
125133 // the application must call BibleSync::Receive(YourBibleSyncObjPtr)
220228 #define BSP_MAX_PAYLOAD (BSP_MAX_SIZE - BSP_HEADER_SIZE)
221229
222230 // message indications
223 #define BSP_MAGIC htonl(0x409CAF11)
224 #define BSP_PROTOCOL 2
231 #define BSP_MAGIC htonl(0x409CAF11)
232 #define BSP_PROTOCOL 3
233 #define BSP_OLD_PROTOCOL 2
225234
226235 // message types
227236 #define BSP_ANNOUNCE 1 // presence announcement.
228237 #define BSP_SYNC 2 // navigation synchronization.
229238 #define BSP_BEACON 3 // speaker availability beacon.
239 #define BSP_CHAT 4 // human chat message.
230240 // beacon packet is identical to presence announcement except for type.
231241
232242 // beacon constants
246256 #define BSP_MSG_SYNC_BIBLEABBREV "msg.sync.bibleAbbrev" // req'd
247257 #define BSP_MSG_SYNC_GROUP "msg.sync.group" // req'd
248258 #define BSP_MSG_PASSPHRASE "msg.sync.passPhrase" // req'd
259 #define BSP_MSG_CHAT "msg.chat" // req'd for BSP_CHAT
249260
250261 // required number of fields to send (out) or verify (in).
251262 #define BSP_FIELDS_RECV_ANNOUNCE 4
263 #define BSP_FIELDS_RECV_CHAT 5
252264 #define BSP_FIELDS_RECV_SYNC 8
265
253266 #define BSP_FIELDS_XMIT_ANNOUNCE 7
267 #define BSP_FIELDS_XMIT_CHAT 8
254268 #define BSP_FIELDS_XMIT_SYNC 12
255269
256270 #ifdef linux
365379
366380 #ifdef linux
367381 // network self-analysis, borrowed from the net.
368 int get_default_if_name(char *name, socklen_t size);
369 int parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo);
370 int readNlSock(int sockFd, char *bufPtr, size_t buf_size,
371 unsigned int seqNum, unsigned int pId);
382 int get_default_if_name(char *name);
372383 #else
373384 // no other support routines needed for Windows/Solaris/BSD.
374385 #endif /* linux */
402413 string domain = "BIBLE-VERSE")
403414 {
404415 return TransmitInternal(BSP_SYNC, bible, ref, alt, group, domain);
416 }
417
418 // simple chat interface
419 inline BibleSync_xmit_status Chat(string message)
420 {
421 return TransmitInternal(BSP_CHAT, message);
405422 }
406423
407424 // set privacy using TTL 0 in personal mode.
77 .\" make back to the origin repository. These obligations are non-
88 .\" binding for public domain software, but they are to be seriously
99 .\" handled nonetheless.
10 .TH BIBLESYNC 7 2014-10-31 "Linux" "Linux Programmer's Manual"
10 .TH BIBLESYNC 7 2018-04-27 "Linux" "Linux Programmer's Manual"
1111 .SH NAME
1212 biblesync \- multicast navigation synchronization in Bible programs
1313 .SH SYNOPSIS
4646 .br
4747 .BI "} BibleSync_xmit_status;"
4848 .sp
49 .BI "#define BSP_ANNOUNCE 1"
50 .br
51 .BI "#define BSP_SYNC 2"
52 .br
53 .BI "#define BSP_BEACON 3"
54 .sp
5549 .BI "typedef void (*BibleSync_navigate)(char " cmd ", string " speakerkey ","
5650 .br
5751 .BI " string " bible ", string " ref ", string " alt ","
8478 .br
8579 .BI " string " group ", string " domain ");"
8680 .br
81 .BI "BibleSync_xmit_status BibleSync::Chat(string " message ");"
82 .br
8783 .BI "static int BibleSync::Receive(void *" object ");"
8884 .br
8985 .BI "bool BibleSync::setPrivate(bool " privacy ");"
9086 .br
9187 .BI "void BibleSync::setBeaconCount(uint8_t " count ");"
88 .br
89 .BI "void BibleSync::setUser(string " user ");"
9290 .br
9391 .BI "void BibleSync::listenToSpeaker(bool " listen ", string " speakerkey ");"
9492 .fi
107105 all of which he wishes to follow along together.
108106
109107 Similarly, a group of people working closely together, such as
110 translators, can stay together as they work.
108 translators or a group Bible study, can stay together as they work.
111109
112110 In an instructional motif,
113111 .I BibleSync
147145
148146 Transmitters (Personal and Speaker modes) issue availability beacons every
149147 10 seconds. Received beacons for previously-unknown Speakers are handed
150 up to the application. These beacons provide for receivers (Personal and
151 Audience modes) to maintain a managed list of available Speakers.
152 Furthermore, when a transmitter ceases to issue beacons, its presence in
153 the list of available Speakers is aged out until being removed after 30
154 seconds of beacon silence. The application is again informed when a
155 Speaker goes dead.
148 up to the application as "new Speaker" events. These beacons provide for
149 receivers (Personal and Audience modes) to maintain a managed list of
150 available Speakers. Furthermore, when a transmitter ceases to issue
151 beacons, its presence in the list of available Speakers is aged out until
152 being removed after 30 seconds of beacon silence. The application is
153 again informed as a Speaker ages out with a "dead Speaker" event.
156154
157155 Default listening behavior is that the first Speaker heard via beacon is
158156 marked for listening. Other transmitters claiming Speaker status via
188186
189187 .I BibleSync
190188 transmits no packet when the application leaves the conversation.
191
192 Only the 3 packet types BSP_ANNOUNCE, BSP_SYNC, and BSP_BEACON are defined
193 in the protocol.
194189 .SH PUBLIC INTERFACE
195190 .SS Object creation
196191 The application must create a single BibleSync object, identifying the
219214 in
220215 .BI Transmit:
221216 KJV, Gen.1.1, empty alternate, 1, and BIBLE-VERSE.
217 .SS Chat
218 This is a method for transmission of casual text messages to all others in
219 the conversation. It is expected to be received by applications who will
220 display them in a suitable manner to the user.
222221 .SS Receive
223222 This is a static method accessible from either C or C++. It must be
224223 called with the object pointer so as to re-enter object context for the
240239 second. If the application will call Receive() less frequently, divide
241240 that time (say, 2 seconds) into 10 to get a value (5) to use with this
242241 call. Use setBeaconCount() prior to enabling Personal or Speaker mode.
242 .SS setUser
243 If the application allows the user to set a name via settings dialog,
244 setUser() is available to re-assign the associated user name as seen by
245 others.
243246 .SS listenToSpeaker
244247 Aside from default listen behavior detailed above, the application
245248 specifically asks to listen or not to listen to specific Speakers. The
246249 key is as provided during the notification of a new Speaker.
247250 .SH RECEIVE USE CASES
248 There are 6 values for the
251 There are 7 values for the
249252 .I cmd
250253 parameter of the
251254 .I nav_func.
283286 .I speakerkey
284287 holds the UUID key of a previously-identified application which is no
285288 longer a candidate for listening.
289 .SS 'C'
290 Chat.
291 Message text is in
292 .I alt
293 and other parameters are overloaded as per announce, above.
286294 .SS 'M'
287295 Mismatch. The incoming event packet is mismatched, either against the
288296 current passphrase or for a navigation synchronization packet when
323331 mode, Receive is again scheduled for polled use.
324332
325333 A 1-second poll interval is expected. Brief experience during development
326 has shown that longer intervals lead to a perception of lag.
334 has shown that longer intervals lead to a perception of lag. If the
335 application designer nonetheless expects to call
336 .BI Receive()
337 less frequently, it is necessary to use
338 .BI setBeaconCount()
339 to change the number of calls to it between beacon transmissions.
327340
328341 During every
329342 .BI Receive()
00 BIBLESYNC(7) Linux Programmer's Manual BIBLESYNC(7)
1
2
31
42 NAME
53 biblesync - multicast navigation synchronization in Bible programs
2523 N_BSP_XMIT
2624 } BibleSync_xmit_status;
2725
28 #define BSP_ANNOUNCE 1
29 #define BSP_SYNC 2
30 #define BSP_BEACON 3
31
3226 typedef void (*BibleSync_navigate)(char cmd, string speakerkey,
3327 string bible, string ref, string alt,
3428 string group, string domain,
4842 string BibleSync::getPassphrase(void);
4943 BibleSync_xmit_status BibleSync::Transmit(string bible, string ref, string alt,
5044 string group, string domain);
45 BibleSync_xmit_status BibleSync::Chat(string message);
5146 static int BibleSync::Receive(void *object);
5247 bool BibleSync::setPrivate(bool privacy);
48 void BibleSync::setBeaconCount(uint8_t count);
49 void BibleSync::setUser(string user);
5350 void BibleSync::listenToSpeaker(bool listen, string speakerkey);
5451
5552 DESCRIPTION
6461 ers/devices, all of which he wishes to follow along together.
6562
6663 Similarly, a group of people working closely together, such as transla-
67 tors, can stay together as they work.
64 tors or a group Bible study, can stay together as they work.
6865
6966 In an instructional motif, BibleSync takes either the active or passive
7067 mode, providing for a unidirectional navigation control.
10097
10198 Transmitters (Personal and Speaker modes) issue availability beacons
10299 every 10 seconds. Received beacons for previously-unknown Speakers are
103 handed up to the application. These beacons provide for receivers
104 (Personal and Audience modes) to maintain a managed list of available
105 Speakers. Furthermore, when a transmitter ceases to issue beacons, its
106 presence in the list of available Speakers is aged out until being
107 removed after 30 seconds of beacon silence. The application is again
108 informed when a Speaker goes dead.
109
110 Default listening behavior is that the first Speaker heard via beacon
111 is marked for listening. Other transmitters claiming Speaker status
112 via beacon are initially ignored, but their presence is made known to
113 the application. This provides for the application to maintain a list
114 from which the user can select Speakers he wishes to synchronize his
100 handed up to the application as "new Speaker" events. These beacons
101 provide for receivers (Personal and Audience modes) to maintain a man-
102 aged list of available Speakers. Furthermore, when a transmitter
103 ceases to issue beacons, its presence in the list of available Speakers
104 is aged out until being removed after 30 seconds of beacon silence.
105 The application is again informed as a Speaker ages out with a "dead
106 Speaker" event.
107
108 Default listening behavior is that the first Speaker heard via beacon
109 is marked for listening. Other transmitters claiming Speaker status
110 via beacon are initially ignored, but their presence is made known to
111 the application. This provides for the application to maintain a list
112 from which the user can select Speakers he wishes to synchronize his
115113 application. It is useful for the application to provide blanket "lis-
116 ten to all" and "listen to none" functions, as well as per-Speaker
117 selections, informing BibleSync of these choices. In any case, this
118 default "first Speaker only" policy can be overridden by the applica-
119 tion with any other policy desired, through the use of listenToS-
114 ten to all" and "listen to none" functions, as well as per-Speaker
115 selections, informing BibleSync of these choices. In any case, this
116 default "first Speaker only" policy can be overridden by the applica-
117 tion with any other policy desired, through the use of listenToS-
120118 peaker() as the application designer requires.
121119
122120 Synchronization events include 5 data elements: The Bible abbreviation;
123 the verse reference; an alternate reference (if desired; not required)
124 which may allow the application to interpret better based on variant
121 the verse reference; an alternate reference (if desired; not required)
122 which may allow the application to interpret better based on variant
125123 versification; a synchronization group identifier; and the domain.
126124
127125 The group identifier is a single digit between 1 and 9. The specifica-
128 tion is imprecise as to this parameter's use. The initial implementa-
129 tion of BibleSync in Xiphos uses the synchronization group as an indi-
130 cator of the tab number in its tabbed interface: Not only is the Bible
126 tion is imprecise as to this parameter's use. The initial implementa-
127 tion of BibleSync in Xiphos uses the synchronization group as an indi-
128 cator of the tab number in its tabbed interface: Not only is the Bible
131129 navigated, but the tab in which to navigate is selected.
132130
133131 The domain parameter is currently fixed as "BIBLE-VERSE". This will be
135133
136134 BibleSync transmits no packet when the application leaves the conversa-
137135 tion.
138
139 Only the 3 packet types BSP_ANNOUNCE, BSP_SYNC, and BSP_BEACON are
140 defined in the protocol.
141136
142137 PUBLIC INTERFACE
143138 Object creation
165160 tion may request the current passphrase, so as to provide a default.
166161
167162 Transmit
168 The protocol requires all the indicated parameters, but all have
169 defaults in Transmit: KJV, Gen.1.1, empty alternate, 1, and BIBLE-VERSE.
163 The protocol requires all the indicated parameters, but all have
164 defaults in Transmit: KJV, Gen.1.1, empty alternate, 1, and BIBLE-
165 VERSE.
166
167 Chat
168 This is a method for transmission of casual text messages to all others
169 in the conversation. It is expected to be received by applications who
170 will display them in a suitable manner to the user.
170171
171172 Receive
172 This is a static method accessible from either C or C++. It must be
173 This is a static method accessible from either C or C++. It must be
173174 called with the object pointer so as to re-enter object context for the
174 private internal receiver. Receive() must be called regularly (i.e.
175 private internal receiver. Receive() must be called regularly (i.e.
175176 polled) as long as it continues to return TRUE. When it returns FALSE,
176 it means that the mode has changed to BSP_MODE_DISABLE, and the sched-
177 it means that the mode has changed to BSP_MODE_DISABLE, and the sched-
177178 uled polling should stop. See also the note below on polled reception.
178179
179180 setPrivate
180 In the circumstance where the user has multiple programs running on a
181 In the circumstance where the user has multiple programs running on a
181182 single computer and does not want his navigation broadcast outside that
182 single system, when in Personal mode, the application may also request
183 privacy. The effect is to set multicast TTL to zero, meaning that
183 single system, when in Personal mode, the application may also request
184 privacy. The effect is to set multicast TTL to zero, meaning that
184185 packets will not go out on the wire.
185186
186187 setBeaconCount
187 Beacon transmission occurs during every Nth call to Receive(); the
188 default value is 10. This presumes the application will call Receive()
189 once per second. If the application will call Receive() less
190 frequently, divide that time (say, 2 seconds) into 10 to get a value
191 (5) to use with this call. Use setBeaconCount() prior to enabling
192 Personal or Speaker mode.
188 Beacon transmission occurs during every Nth call to Receive(); the
189 default value is 10. This presumes the application will call Receive()
190 once per second. If the application will call Receive() less fre-
191 quently, divide that time (say, 2 seconds) into 10 to get a value (5)
192 to use with this call. Use setBeaconCount() prior to enabling Personal
193 or Speaker mode.
194
195 setUser
196 If the application allows the user to set a name via settings dialog,
197 setUser() is available to re-assign the associated user name as seen by
198 others.
193199
194200 listenToSpeaker
195201 Aside from default listen behavior detailed above, the application
197203 key is as provided during the notification of a new Speaker.
198204
199205 RECEIVE USE CASES
200 There are 6 values for the cmd parameter of the nav_func. In all
206 There are 7 values for the cmd parameter of the nav_func. In all
201207 cases, the dump parameter provides the raw content of an arriving
202208 packet.
203209
220226 Dead Speaker. speakerkey holds the UUID key of a previously-identified
221227 application which is no longer a candidate for listening.
222228
229 'C'
230 Chat. Message text is in alt and other parameters are overloaded as
231 per announce, above.
232
223233 'M'
224 Mismatch. The incoming event packet is mismatched, either against the
225 current passphrase or for a navigation synchronization packet when
226 BibleSync is in Speaker mode. The info parameter begins with either
234 Mismatch. The incoming event packet is mismatched, either against the
235 current passphrase or for a navigation synchronization packet when
236 BibleSync is in Speaker mode. The info parameter begins with either
227237 "announce" or "sync", plus the user and IP address from whom the packet
228 came. As well, in the sync case, the regular bible, ref, alt, group,
229 and domain parameters are available. In the announce case, the pres-
238 came. As well, in the sync case, the regular bible, ref, alt, group,
239 and domain parameters are available. In the announce case, the pres-
230240 ence message is in alt, with overloaded individual parameters as previ-
231241 ously described.
232242
233243 'E'
234 Error. This indicates network errors and malformed packets. The
244 Error. This indicates network errors and malformed packets. The
235245 application's nav_func is provided only the info and dump parameters.
236246
237247 NOTES
238248 Polled reception
239 The application must provide a means by which to poll regularly for
240 incoming packets. In Xiphos, which is built on GTK and GLib, this is
249 The application must provide a means by which to poll regularly for
250 incoming packets. In Xiphos, which is built on GTK and GLib, this is
241251 readily provided by mechanisms like g_timeout_add(), which sets a regu-
242252 lar interval call of the indicated function. GLib will re-schedule the
243 call as long as the called function returns TRUE. When it returns
253 call as long as the called function returns TRUE. When it returns
244254 FALSE, GLib un-schedules the call. Receive() adheres to this straight-
245 forward convention. Therefore, it is imperative that every time the
246 application moves from disabled to any non-disabled mode, Receive is
255 forward convention. Therefore, it is imperative that every time the
256 application moves from disabled to any non-disabled mode, Receive is
247257 again scheduled for polled use.
248258
249259 A 1-second poll interval is expected. Brief experience during develop-
250 ment has shown that longer intervals lead to a perception of lag.
260 ment has shown that longer intervals lead to a perception of lag. If
261 the application designer nonetheless expects to call Receive() less
262 frequently, it is necessary to use setBeaconCount() to change the num-
263 ber of calls to it between beacon transmissions.
251264
252265 During every Receive() call, all waiting packets are processed.
253266
299312 and ip(7), especially sections on IP_ADD_MEMBERSHIP, IP_MULTICAST_IF,
300313 IP_MULTICAST_LOOP, and IP_MULTICAST_TTL.
301314
302
303
304 Linux 2018-04-10 BIBLESYNC(7)
315 Linux 2018-04-27 BIBLESYNC(7)
6363 0, so the user's entirely internal navigation is not also heard over the
6464 wire.
6565
66
67
6866 .ti 0
6967 Packet Structure
7068
8987 The magic value is 0x409CAF11, by which to determine that a packet is
9088 intended for BibleSync.
9189
92 The protocol version is 2.
93
94 Three message types are defined: 1 = presence announcement, 2 = navigation
95 synchronization, 3 = speaker availability beacon.
90 The protocol version is 3. The protocol interoperates with the previous
91 version 2, though lacking the distinguishing feature of chat messages.
92
93 Four message types are defined: 1 = presence announcement, 2 = navigation
94 synchronization, 3 = speaker availability beacon, 4 = chat message.
9695
9796 Currently BibleSync is specified as a single packet protocol, but the
9897 number of packets and packet index fields are included for possible future
126125
127126 The speaker beacon packet is identical to the presence announcement except
128127 for having message type 3, and is sent by transmitting applications every
129 10 seconds.
128 10 seconds. Beacon silence for 30 seconds indicates a dead Speaker.
129
130 The chat message packet contains only 1 field, the message content, beyond
131 those found in announce and beacon.
130132
131133 .ti 0
132134 Speaker Beacons
180182
181183 Continuation lines are not supported.
182184
183 There are 12 names defined for use in the body. The application may
185 There are 13 names defined for use in the body. The application may
184186 provide any others its designer finds useful, but these names define the
185187 protocol's interoperability.
186188
275277 .in 7
276278 Required in navigation. This field has a fixed value of "BIBLE-VERSE" but
277279 its use will be expanded in future revisions.
280
281 .in 3
282 13. msg.chat
283
284 .in 7
285 Required for chat and useful only there. A free-from, newline-less text
286 string to be shared in the conversation, intended to be displayed to all
287 users.
278288
279289
280290 .in 3
308318 Presence announcement:
309319
310320 magic: 0x409caf11
311 version: 0x02
321 version: 0x03
312322 type: 0x01
313323 uuid: 00112233-4455-6677-8899-aabbccddeeff
314324 #pkt: 1
318328 app.user=John Doe (jdoe)
319329 msg.sync.passPhrase=qwerty
320330
321 Beacon is identical to presence announcement except for being type 3.
331 Beacon is identical to presence announcement except for being type 0x03.
322332
323333 Navigation:
324334
325335 magic: 0x409caf11
326 version: 0x02
336 version: 0x03
327337 type: 0x02
328338 uuid: 00112233-4455-6677-8899-aabbccddeeff
329339 #pkt: 1
337347 msg.sync.bibleAbbrev=NET
338348 msg.sync.verse=Rom.14.4
339349
350 Chat:
351
352 magic: 0x409caf11
353 version: 0x03
354 type: 0x04
355 uuid: 00112233-4455-6677-8899-aabbccddeeff
356 #pkt: 1
357 pkt index: 0
358 app.name=TestBibleApp
359 app.inst.uuid=00112233-4455-6677-8899-aabbccddeeff
360 app.user=John Doe (jdoe)
361 msg.sync.passPhrase=qwerty
362 msg.chat=This is just a test message. No newlines permitted.
363
340364 Additional name/value examples, optional use:
341365
342366 app.version=2.7a
344368 app.device=i686
345369 msg.sync.altVerse=1Mac.1.2
346370
347 Real-world example, using all defined names:
371 Real-world example, navigation synchronization, using all defined names:
348372
349373 magic: 0x409caf11
350 version: 0x02
374 version: 0x03
351375 type: 0x02 (sync)
352376 uuid: 49b387bd-6324-4a2e-871a-4b24e065bff7
353377 #pkt: 1
354378 pkt index: 0
355379 app.name=Xiphos
356 app.version=3.2.1
380 app.version=4.1.1
357381 app.inst.uuid=49b387bd-6324-4a2e-871a-4b24e065bff7
358382 app.os=Linux
359383 app.device=x86_64: Linux @ awol.kleinpaste.org
4949 available by setting multicast TTL to 0, so the user’s entirely
5050 internal navigation is not also heard over the wire.
5151
52
52 Packet Structure
5353
5454
5555
6262
6363 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
6464
65
66 Packet Structure
6765
6866 Payload maximum length is 1280 bytes. Within this, the first 32
6967 bytes are a header identifying the sender’s protocol version, message
8684 The magic value is 0x409CAF11, by which to determine that a packet is
8785 intended for BibleSync.
8886
89 The protocol version is 2.
90
91 Three message types are defined: 1 = presence announcement, 2 =
92 navigation synchronization, 3 = speaker availability beacon.
87 The protocol version is 3. The protocol interoperates with the
88 previous version 2, though lacking the distinguishing feature of chat
89 messages.
90
91 Four message types are defined: 1 = presence announcement, 2 =
92 navigation synchronization, 3 = speaker availability beacon, 4 = chat
93 message.
9394
9495 Currently BibleSync is specified as a single packet protocol, but the
9596 number of packets and packet index fields are included for possible
110111
111112 The presence packet announces the application’s participation in the
112113 conversation. It is non-essential, but useful if the application
114
115
116
117 Stergiou et al [Page 2]
118
119
120
121
122
123 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
124
125
113126 designer chooses to make it visible to the user.
114
115
116
117 Stergiou et al [Page 2]
118
119
120
121
122
123 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
124
125127
126128 The navigation packet specifies a Bible name and a reference. It may
127129 also contain an alternate reference to provide a second means of
133135
134136 The speaker beacon packet is identical to the presence announcement
135137 except for having message type 3, and is sent by transmitting
136 applications every 10 seconds.
138 applications every 10 seconds. Beacon silence for 30 seconds
139 indicates a dead Speaker.
140
141 The chat message packet contains only 1 field, the message content,
142 beyond those found in announce and beacon.
137143
138144 Speaker Beacons
139145
165171 claiming speaker status by sending beacons, and a newly-started
166172 application begins to listen, it may first hear the interloper’s
167173 beacon and begin listening to it. The user must be able to consult a
174
175
176
177 Stergiou et al [Page 3]
178
179
180
181
182
183 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
184
185
168186 list of potential speakers and pick the one(s) actually needed.
169187
170188 Beacons must be sent at least every 10 seconds. Receivers must track
171189 speaker beacons, aging speakers toward removal. Each new beacon for
172190 a speaker restarts its aging countdown. A potential speaker that has
173191 gone beacon-silent for 30 seconds is considered a dead speaker and is
174
175
176
177 Stergiou et al [Page 3]
178
179
180
181
182
183 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
184
185
186192 removed from the list of available speakers.
187193
188194 Navigation synchronization received without beacon support is
199205
200206 Continuation lines are not supported.
201207
202 There are 12 names defined for use in the body. The application may
208 There are 13 names defined for use in the body. The application may
203209 provide any others its designer finds useful, but these names define
204210 the protocol’s interoperability.
205211
226232
227233 Optional; recommended. The application’s version stamp.
228234
235
236
237 Stergiou et al [Page 4]
238
239
240
241
242
243 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
244
245
229246 6. app.os
230247
231248 Optional. Identification of the OS under which the application
232249 runs.
233
234
235
236
237 Stergiou et al [Page 4]
238
239
240
241
242
243 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
244
245250
246251 7. app.device
247252
287292
288293 12. msg.sync.domain
289294
295
296
297 Stergiou et al [Page 5]
298
299
300
301
302
303 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
304
305
290306 Required in navigation. This field has a fixed value of "BIBLE-
291307 VERSE" but its use will be expanded in future revisions.
292308
293
294
295
296
297 Stergiou et al [Page 5]
298
299
300
301
302
303 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
309 13. msg.chat
310
311 Required for chat and useful only there. A free-from, newline-
312 less text string to be shared in the conversation, intended to be
313 displayed to all users.
304314
305315
306316 Security Considerations
331341 Presence announcement:
332342
333343 magic: 0x409caf11
334 version: 0x02
344 version: 0x03
335345 type: 0x01
336346 uuid: 00112233-4455-6677-8899-aabbccddeeff
337347 #pkt: 1
341351 app.user=John Doe (jdoe)
342352 msg.sync.passPhrase=qwerty
343353
344 Beacon is identical to presence announcement except for being type 3.
354
355
356
357 Stergiou et al [Page 6]
358
359
360
361
362
363 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
364
365
366 Beacon is identical to presence announcement except for being type 0x03.
345367
346368 Navigation:
347369
348370 magic: 0x409caf11
349 version: 0x02
371 version: 0x03
350372 type: 0x02
351373 uuid: 00112233-4455-6677-8899-aabbccddeeff
352374 #pkt: 1
353375 pkt index: 0
354
355
356
357 Stergiou et al [Page 6]
358
359
360
361
362
363 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
364
365
366376 app.name=TestBibleApp
367377 app.inst.uuid=00112233-4455-6677-8899-aabbccddeeff
368378 app.user=John Doe (jdoe)
372382 msg.sync.bibleAbbrev=NET
373383 msg.sync.verse=Rom.14.4
374384
385 Chat:
386
387 magic: 0x409caf11
388 version: 0x03
389 type: 0x04
390 uuid: 00112233-4455-6677-8899-aabbccddeeff
391 #pkt: 1
392 pkt index: 0
393 app.name=TestBibleApp
394 app.inst.uuid=00112233-4455-6677-8899-aabbccddeeff
395 app.user=John Doe (jdoe)
396 msg.sync.passPhrase=qwerty
397 msg.chat=This is just a test message. No newlines permitted.
398
375399 Additional name/value examples, optional use:
376400
377401 app.version=2.7a
379403 app.device=i686
380404 msg.sync.altVerse=1Mac.1.2
381405
382 Real-world example, using all defined names:
406 Real-world example, navigation synchronization, using all defined names:
383407
384408 magic: 0x409caf11
385 version: 0x02
409 version: 0x03
386410 type: 0x02 (sync)
387411 uuid: 49b387bd-6324-4a2e-871a-4b24e065bff7
388412 #pkt: 1
389413 pkt index: 0
414
415
416
417 Stergiou et al [Page 7]
418
419
420
421
422
423 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
424
425
390426 app.name=Xiphos
391 app.version=3.2.1
427 app.version=4.1.1
392428 app.inst.uuid=49b387bd-6324-4a2e-871a-4b24e065bff7
393429 app.os=Linux
394430 app.device=x86_64: Linux @ awol.kleinpaste.org
411447 UUID:
412448 RFC 4122
413449
414
415
416
417 Stergiou et al [Page 7]
418
419
420
421
422
423 RFC -BSP- BibleSync Protocol - DRAFT 15 June 2014
424
425
426450 This specification alters and extends technical aspects of the original
427451 specification (cf. wikispaces, above), notably max packet size, size and
428452 alignment of header, speaker beacons, use of app.user, and stipulations
450474
451475
452476
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477477 Stergiou et al [Page 8]
478478
479479
2020
2121 using namespace std;
2222
23 // sync is a proper superset of announce & beacon,
23 // chat is a proper superset of announce/beacon,
24 // sync is a proper superset of chat,
2425 // both inbound as well as outbound.
25 // in these 2 arrays of strings, sync-specific
26 // fields are placed after announce fields.
26 // in these 2 arrays of strings, chat-specific fields follow
27 // announce fields, and sync-specific follow chat fields.
28 // (chat overloads bible for this purpose.)
2729 // see field_count in ReceiveInternal + TransmitInternal.
2830 static string inbound_required[] = {
2931 BSP_APP_NAME,
3032 BSP_APP_INSTANCE_UUID,
3133 BSP_APP_USER,
3234 BSP_MSG_PASSPHRASE,
35 BSP_MSG_SYNC_BIBLEABBREV,
3336 BSP_MSG_SYNC_DOMAIN,
3437 BSP_MSG_SYNC_VERSE,
35 BSP_MSG_SYNC_BIBLEABBREV,
3638 BSP_MSG_SYNC_GROUP
39 };
40 #define CHAT_INBOUND_INDEX 4 // index in list above.
41
42 static int inbound_required_count[5] =
43 {
44 0, // unused
45 BSP_FIELDS_RECV_ANNOUNCE,
46 BSP_FIELDS_RECV_SYNC,
47 BSP_FIELDS_RECV_ANNOUNCE, // beacon identical to announce
48 BSP_FIELDS_RECV_CHAT
3749 };
3850
3951 static string outbound_fill[] = {
4456 BSP_APP_DEVICE,
4557 BSP_APP_USER,
4658 BSP_MSG_PASSPHRASE,
59 BSP_MSG_SYNC_BIBLEABBREV,
4760 BSP_MSG_SYNC_DOMAIN,
4861 BSP_MSG_SYNC_GROUP,
49 BSP_MSG_SYNC_BIBLEABBREV,
5062 BSP_MSG_SYNC_ALTVERSE,
5163 BSP_MSG_SYNC_VERSE // last: could go overly long, risk cutoff.
5264 };
65 #define CHAT_OUTBOUND_INDEX 7 // index in list above.
66
67 static int outbound_fill_count[5] =
68 {
69 0, // unused
70 BSP_FIELDS_XMIT_ANNOUNCE,
71 BSP_FIELDS_XMIT_SYNC,
72 BSP_FIELDS_XMIT_ANNOUNCE, // beacon identical to announce
73 BSP_FIELDS_XMIT_CHAT
74 };
75
76 static string chat_field = BSP_MSG_CHAT; // for referential substitution.
5377
5478 // BibleSync class constructor.
5579 // args identify the user of the class, by application, version, and user.
367391 ? "sync"
368392 : ((bsp.msg_type == BSP_BEACON)
369393 ? "beacon"
370 : "*???*"))),
394 : ((bsp.msg_type == BSP_CHAT)
395 ? "chat"
396 : "*???*")))),
371397 uuid_dump_string,
372398 bsp.num_packets, bsp.index_packet,
373399 bsp.body);
377403 (*nav_func)('E', EMPTY,
378404 EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
379405 BSP + _("bad magic"), dump);
380 else if (bsp.version != BSP_PROTOCOL)
406 else if ((bsp.version != BSP_PROTOCOL) && (bsp.version != BSP_OLD_PROTOCOL))
407 // we are fine with previous v2 protocol that lacks chat messages.
381408 (*nav_func)('E', EMPTY,
382409 EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
383410 BSP + _("bad protocol version"), dump);
384411 else if ((bsp.msg_type != BSP_ANNOUNCE) &&
385412 (bsp.msg_type != BSP_SYNC) &&
386 (bsp.msg_type != BSP_BEACON))
413 (bsp.msg_type != BSP_BEACON) &&
414 (bsp.msg_type != BSP_CHAT))
387415 (*nav_func)('E', EMPTY,
388416 EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
389417 BSP + _("bad msg type"), dump);
443471 else
444472 {
445473 // verify minimum body content.
446 int field_count = ((bsp.msg_type == BSP_SYNC)
447 ? BSP_FIELDS_RECV_SYNC
448 : BSP_FIELDS_RECV_ANNOUNCE); // or beacon.
474 int field_count = inbound_required_count[bsp.msg_type];
449475
450476 for (int i = 0; i < field_count; ++i)
451477 {
452 if (content.find(inbound_required[i]) == content.end())
478 string &locator = (((bsp.msg_type == BSP_CHAT) &&
479 (i == CHAT_INBOUND_INDEX))
480 ? chat_field
481 : inbound_required[i]);
482
483 if (content.find(locator) == content.end())
453484 {
454485 ok_so_far = false;
455486 string info = BSP + _("missing required header ")
526557 version = (string)"(version?)";
527558
528559 // generally good, so extract interesting content.
529 if (bsp.msg_type == BSP_SYNC)
560 if (bsp.msg_type == BSP_CHAT)
561 {
562 bible = content.find(BSP_APP_USER)->second;
563 ref = source_addr;
564 group = content.find(BSP_APP_NAME)->second
565 + " " + version;
566 domain = content.find(BSP_APP_DEVICE)->second;
567 alt = content.find(BSP_MSG_CHAT)->second;
568
569 info = (string)"chat: "
570 + content.find(BSP_APP_USER)->second
571 + " @ " + source_addr;
572
573 cmd = ((passphrase ==
574 content.find(BSP_MSG_PASSPHRASE)->second)
575 ? 'C' // chat message
576 : 'M'); // mismatch
577 }
578 else if (bsp.msg_type == BSP_SYNC)
530579 {
531580 // regular synchronized navigation
532581 bible = content.find(BSP_MSG_SYNC_BIBLEABBREV)->second;
744793
745794 if ((message_type != BSP_ANNOUNCE) &&
746795 (message_type != BSP_SYNC) &&
747 (message_type != BSP_BEACON))
796 (message_type != BSP_BEACON) &&
797 (message_type != BSP_CHAT))
748798 return BSP_XMIT_BAD_TYPE;
749799
750800 if ((mode == BSP_MODE_AUDIENCE) &&
756806 string body = "";
757807
758808 // all name/value pairs.
759 content[BSP_APP_NAME] = application;
760 content[BSP_APP_VERSION] = version;
761 content[BSP_APP_USER] = user;
762 content[BSP_APP_DEVICE] = device;
763 content[BSP_APP_OS] = BSP_OS;
764 content[BSP_APP_INSTANCE_UUID] = uuid_string;
765 content[BSP_MSG_SYNC_BIBLEABBREV] = bible;
766 content[BSP_MSG_SYNC_VERSE] = ref;
767 content[BSP_MSG_SYNC_ALTVERSE] = alt;
768 content[BSP_MSG_SYNC_GROUP] = group;
769 content[BSP_MSG_SYNC_DOMAIN] = domain;
770 content[BSP_MSG_PASSPHRASE] = passphrase;
809 content[BSP_APP_NAME] = application;
810 content[BSP_APP_VERSION] = version;
811 content[BSP_APP_USER] = user;
812 content[BSP_APP_DEVICE] = device;
813 content[BSP_APP_OS] = BSP_OS;
814 content[BSP_APP_INSTANCE_UUID] = uuid_string;
815 if (message_type != BSP_CHAT)
816 content[BSP_MSG_SYNC_BIBLEABBREV] = bible;
817 else {
818 content[BSP_MSG_CHAT] = bible; // overload.
819 // innoculate chat content against internal \n.
820 for (char *chase = (char *)bible.c_str(); chase = strchr(chase, '\n'); ++chase)
821 *chase = '\t';
822 }
823 content[BSP_MSG_SYNC_VERSE] = ref;
824 content[BSP_MSG_SYNC_ALTVERSE] = alt;
825 content[BSP_MSG_SYNC_GROUP] = group;
826 content[BSP_MSG_SYNC_DOMAIN] = domain;
827 content[BSP_MSG_PASSPHRASE] = passphrase;
771828
772829 // header.
773830 bsp.magic = BSP_MAGIC;
779836 memset((void *)&bsp.reserved, 0, BSP_RES_SIZE);
780837
781838 // body prep.
782 int field_count = ((message_type == BSP_SYNC)
783 ? BSP_FIELDS_XMIT_SYNC
784 : BSP_FIELDS_XMIT_ANNOUNCE); // or beacon.
839 int field_count = outbound_fill_count[message_type];
785840
786841 for (int i = 0; i < field_count; ++i)
787842 {
788 body += outbound_fill[i] + "=" + content[outbound_fill[i]] + "\n";
843 string &filler = (((message_type == BSP_CHAT) &&
844 (i == CHAT_OUTBOUND_INDEX))
845 ? chat_field
846 : outbound_fill[i]);
847 body += filler + "=" + content[filler] + "\n";
789848 }
790849
791850 // ship it.
794853 BSP_HEADER_SIZE + body.length());
795854
796855 // force last == newline: attempt to preserve body format when long.
856 // (cuts off excessively long verse references and chat messages.)
797857 ((unsigned char*)&bsp)[BSP_MAX_SIZE-1] = '\n';
798858
799859 BibleSync_xmit_status retval;
895955
896956 #ifdef linux
897957
898 // routines below imported from the net as workable examples.
899958 // in order to do multicast setup, we require the address
900 // of the interface that has our default route. code below
901 // finds the name of that interface. then getifaddrs(3)
902 // code (taken from its man page) lets us match that name
903 // against an entry that has the address we need.
904
905 // extra includes needed only for the
906 // route & gateway discovery code below.
959 // of the interface that has our default route.
960 // get_default_if_name() reads /proc/net/route to find that interface.
961 // then getifaddrs(3) code (taken from its man page) lets us
962 // match that name against an entry that has the address we need.
963 // this entire methodology is 100 times simpler than the former
964 // rtnetlink-driven nightmare
965
966 // lines in /proc/net/route consist of
967 // IFACE \t DESTINATION \t GATEWAY \t FLAGS \t ...
968 // DESTINATION is an 8-byte hex value (string), so look for \t00000000\t.
969
970 #define PROC_ROUTE "/proc/net/route"
907971
908972 #include <net/if.h>
909 #include <linux/rtnetlink.h>
910
911 struct route_info
912 {
913 struct in_addr dstAddr;
914 struct in_addr srcAddr;
915 struct in_addr gateWay;
916 char ifName[IF_NAMESIZE];
917 };
918
919 int BibleSync::readNlSock(int sockFd,
920 char *bufPtr,
921 size_t buf_size,
922 unsigned int seqNum,
923 unsigned int pId)
924 {
925 struct nlmsghdr *nlHdr;
926 int readLen = 0, msgLen = 0;
927
928 do
929 {
930 if((readLen = recv(sockFd, bufPtr, buf_size - msgLen, 0)) < 0)
931 {
932 return -1;
933 }
934
935 nlHdr = (struct nlmsghdr *)bufPtr;
936
937 if((NLMSG_OK(nlHdr, readLen) == 0) || (nlHdr->nlmsg_type == NLMSG_ERROR))
938 {
939 return -1;
940 }
941
942 /* check if last message */
943 if(nlHdr->nlmsg_type == NLMSG_DONE)
944 {
945 break;
946 }
947 else
948 {
949 /* else move pointer to buffer appropriately */
950 bufPtr += readLen;
951 msgLen += readLen;
952 }
953
954 /* check if multi part message */
955 if((nlHdr->nlmsg_flags & NLM_F_MULTI) == 0)
956 {
957 /* return if its not */
958 break;
959 }
960 }
961 while((nlHdr->nlmsg_seq != seqNum) || (nlHdr->nlmsg_pid != pId));
962
963 return msgLen;
964 }
965
966 int BibleSync::parseRoutes(struct nlmsghdr *nlHdr, struct route_info *rtInfo)
967 {
968 struct rtmsg *rtMsg;
969 struct rtattr *rtAttr;
970 int rtLen;
971
972 rtMsg = (struct rtmsg *)NLMSG_DATA(nlHdr);
973
974 /* if route is not AF_INET or not in main table, return. */
975 if((rtMsg->rtm_family != AF_INET) || (rtMsg->rtm_table != RT_TABLE_MAIN))
976 return -1;
977
978 rtAttr = (struct rtattr *)RTM_RTA(rtMsg);
979 rtLen = RTM_PAYLOAD(nlHdr);
980
981 for(; RTA_OK(rtAttr,rtLen); rtAttr = RTA_NEXT(rtAttr,rtLen))
982 {
983 switch(rtAttr->rta_type)
984 {
985 case RTA_OIF:
986 if_indextoname(*(int *)RTA_DATA(rtAttr), rtInfo->ifName);
987 break;
988
989 case RTA_GATEWAY:
990 memcpy(&rtInfo->gateWay, RTA_DATA(rtAttr), sizeof(rtInfo->gateWay));
991 break;
992
993 case RTA_PREFSRC:
994 memcpy(&rtInfo->srcAddr, RTA_DATA(rtAttr), sizeof(rtInfo->srcAddr));
995 break;
996
997 case RTA_DST:
998 memcpy(&rtInfo->dstAddr, RTA_DATA(rtAttr), sizeof(rtInfo->dstAddr));
999 break;
1000 }
1001 }
1002
1003 return 0;
1004 }
1005
1006 int BibleSync::get_default_if_name(char *name, socklen_t size)
1007 {
1008 int found_default = 0;
1009
1010 struct nlmsghdr *nlMsg;
1011 //struct rtmsg *rtMsg;
1012 struct route_info route_info;
1013 char msgBuf[4096];
1014
1015 int sock, len, msgSeq = 0;
1016
1017 name[1] = '\0'; // pre-set, in case of error.
1018
1019 if((sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE)) < 0)
973 #include <netdb.h>
974 #include <ifaddrs.h>
975
976 int BibleSync::get_default_if_name(char *name)
977 {
978 int found = 0;
979 char line[256], *field;
980 FILE *proc_route;
981
982 if ((proc_route = fopen(PROC_ROUTE, "r")) == NULL)
1020983 {
1021984 name[0] = 'x';
1022985 return -1;
1023986 }
1024987
1025 memset(msgBuf, 0, sizeof(msgBuf));
1026
1027 nlMsg = (struct nlmsghdr *)msgBuf;
1028 //rtMsg = (struct rtmsg *)NLMSG_DATA(nlMsg);
1029
1030 nlMsg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
1031 nlMsg->nlmsg_type = RTM_GETROUTE;
1032
1033 nlMsg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
1034 nlMsg->nlmsg_seq = msgSeq++;
1035 nlMsg->nlmsg_pid = getpid();
1036
1037 if(send(sock, nlMsg, nlMsg->nlmsg_len, 0) < 0)
1038 {
1039 name[0] = 'y';
1040 return -1;
1041 }
1042
1043 if((len = readNlSock(sock, msgBuf, sizeof(msgBuf), msgSeq, getpid())) < 0)
1044 {
1045 name[0] = 'z';
1046 return -1;
1047 }
1048
1049 for(; NLMSG_OK(nlMsg,len); nlMsg = NLMSG_NEXT(nlMsg,len))
1050 {
1051 memset(&route_info, 0, sizeof(route_info));
1052 if ( parseRoutes(nlMsg, &route_info) < 0 )
1053 continue; // don't check: not set up
1054
1055 if (strstr((char *)inet_ntoa(route_info.dstAddr), "0.0.0.0"))
988 while (fgets(line, 255, proc_route) != NULL)
989 {
990 if ((field = strchr(line, '\t')) == NULL)
991 continue; // invalid line?
992
993 if (strncmp(field, "\t00000000\t", 10) == 0)
1056994 {
1057 // copy it over
1058 strcpy(name, route_info.ifName);
1059 found_default = 1;
995 found = 1;
996 *field = '\0';
997 strcpy(name, line);
1060998 break;
1061999 }
10621000 }
1063
1064 close(sock);
1065 return found_default;
1066 }
1067
1068 #include <netdb.h>
1069 #include <ifaddrs.h>
1001 fclose(proc_route);
1002
1003 if (!found)
1004 {
1005 // no default route? fallback: we're holding a valid last line.
1006 // so we arbitrarily choose whatever was found there.
1007 *field = '\0';
1008 strcpy(name, line);
1009 }
1010
1011 return 0;
1012 }
10701013
10711014 void BibleSync::InterfaceAddress()
10721015 {
10761019
10771020 char gw_if[IF_NAMESIZE]; // default gateway interface.
10781021
1079 (void)get_default_if_name(gw_if, 100);
1022 (void)get_default_if_name(gw_if);
10801023
10811024 // if no error, search the interface list for that address.
10821025 if (gw_if[0] != '\0')
11081051
11091052 // Solaris & BSD.
11101053
1111 //
11121054 // this seeming grotesqueness is in fact the most general command
11131055 // that could be found which finds the interface holding the default
11141056 // route and then collects that interface's address. handles both
1115 // solaris and bsd. in fact, it suffices for linux as well, but
1116 // we're leaving the existing code above in place for linux, if for
1117 // no other reason than that it's more likely that someone will
1118 // foolishly screw up ifconfig output format in the linux world.
1119 //
1120 #define ADDRESS "PATH=/sbin:/usr/sbin:/bin:/usr/bin " \
1121 "ifconfig \"`netstat -rn | egrep '^0\\.0\\.0\\.0|^default' | " \
1122 "tr ' ' '\\n' | sed -e '/^$/d' | tail -1`\" | grep 'inet ' | " \
1057 // solaris and bsd. also an instance for linux using "ip", in case
1058 // whoever builds this doesn't like depending on /proc/net/route.
1059
1060 #ifdef linux
1061 #define ADDRESS "PATH=/sbin:/usr/sbin:/bin:/usr/bin " \
1062 "ip address show dev `ip route | egrep '^(default|0\\.0\\.0\\.0)' | " \
1063 "head -1 | sed 's/dev /DEV-/' | tr ' ' '\\n' | grep DEV | sed s/DEV-//` | " \
1064 "grep 'inet ' | tr '/ ' '\\n\\n' | grep '^[0-9.][0-9.]*' | head -1 | tr -d '\\n'"
1065 #else
1066 #define ADDRESS "PATH=/sbin:/usr/sbin:/bin:/usr/bin " \
1067 "ifconfig \"`netstat -rn | egrep '^0\\.0\\.0\\.0|^default' | " \
1068 "tr ' ' '\\n' | sed -e '/^$/d' | tail -1`\" | grep 'inet ' | " \
11231069 "tr ' ' '\\n' | grep '^[0-9.][0-9.]*$' | head -1 | tr -d '\\n'"
1070 #endif
11241071
11251072 void BibleSync::InterfaceAddress()
11261073 {