Skip to content

Commit 46095ef

Browse files
committed
Allow m=image in SDP to pcap_play faxes/images.
Taken from https://code.osso.nl/projects/sipp/changeset/c939d058337f/ and adapted. (Still root-only pcap_play.)
1 parent bc7b536 commit 46095ef

File tree

9 files changed

+88
-41
lines changed

9 files changed

+88
-41
lines changed

include/actions.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class CAction
7171
E_AT_CLOSE_CON,
7272
#ifdef PCAPPLAY
7373
E_AT_PLAY_PCAP_AUDIO,
74+
E_AT_PLAY_PCAP_IMAGE,
7475
E_AT_PLAY_PCAP_VIDEO,
7576
#endif
7677
#ifdef RTP_STREAM

include/call.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ class call : virtual public task, virtual public listener, public virtual socket
168168
int hasMediaInformation;
169169
pthread_t media_thread;
170170
play_args_t play_args_a;
171+
play_args_t play_args_i;
171172
play_args_t play_args_v;
172173
#endif
173174

include/rtpstream.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ void rtpstream_shutdown (void);
4747

4848
int rtpstream_get_audioport (rtpstream_callinfo_t *callinfo);
4949
int rtpstream_get_videoport (rtpstream_callinfo_t *callinfo);
50-
void rtpstream_set_remote (rtpstream_callinfo_t *callinfo, int ip_ver, char *ip_addr, int audio_port, int video_port);
50+
void rtpstream_set_remote (rtpstream_callinfo_t *callinfo, int ip_ver, char *ip_addr,
51+
int audio_port, int image_port, int video_port);
5152

5253
int rtpstream_cache_file (char *filename);
5354
void rtpstream_play (rtpstream_callinfo_t *callinfo, rtpstream_actinfo_t *actioninfo);

src/actions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ void CAction::afficheInfo()
147147
} else if (M_action == E_AT_VAR_TO_DOUBLE) {
148148
printf("Type[%d] - toDouble varId[%s]", M_action, display_scenario->allocVars->getName(M_varId));
149149
#ifdef PCAPPLAY
150-
} else if ((M_action == E_AT_PLAY_PCAP_AUDIO) || (M_action == E_AT_PLAY_PCAP_VIDEO)) {
150+
} else if ((M_action == E_AT_PLAY_PCAP_AUDIO) || (M_action == E_AT_PLAY_PCAP_IMAGE) || (M_action == E_AT_PLAY_PCAP_VIDEO)) {
151151
printf("Type[%d] - file[%s]", M_action, M_pcapArgs->file);
152152
#endif
153153

@@ -635,7 +635,7 @@ CAction::CAction(scenario *scenario)
635635
#endif
636636

637637
#ifdef RTP_STREAM
638-
memset (&M_rtpstream_actinfo,0,sizeof(M_rtpstream_actinfo));
638+
memset(&M_rtpstream_actinfo, 0, sizeof(M_rtpstream_actinfo));
639639
#endif
640640

641641
M_scenario = scenario;

src/call.cpp

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -195,19 +195,24 @@ uint8_t get_remote_ipv6_media(char *msg, struct in6_addr *addr)
195195
}
196196

197197
/*
198-
* Look for "m=audio " or "m=video " pattern in the message and extract the
199-
* following value which should be port number
198+
* Look for "m=audio ", "m=image " or "m=video " pattern in the message
199+
* and extract the following value which should be port number.
200200
*/
201-
#define PAT_AUDIO 1
202-
#define PAT_VIDEO 2
203-
uint16_t get_remote_port_media(const char *msg, int pattype)
201+
enum media_ptn {
202+
PAT_AUDIO,
203+
PAT_IMAGE,
204+
PAT_VIDEO
205+
};
206+
uint16_t get_remote_port_media(const char *msg, enum media_ptn pattype)
204207
{
205208
const char *pattern;
206209
char *begin, *end;
207210
char number[6];
208211

209212
if (pattype == PAT_AUDIO) {
210213
pattern = "m=audio ";
214+
} else if (pattype == PAT_IMAGE) {
215+
pattern = "m=image ";
211216
} else if (pattype == PAT_VIDEO) {
212217
pattern = "m=video ";
213218
} else {
@@ -244,7 +249,7 @@ uint16_t get_remote_port_media(const char *msg, int pattype)
244249
*/
245250
void call::get_remote_media_addr(char *msg)
246251
{
247-
uint16_t video_port, audio_port;
252+
uint16_t audio_port, image_port, video_port;
248253
if (media_ip_is_ipv6) {
249254
struct in6_addr ip_media;
250255
if (get_remote_ipv6_media(msg, &ip_media)) {
@@ -254,16 +259,25 @@ void call::get_remote_media_addr(char *msg)
254259
(_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_flowinfo = 0;
255260
(_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_scope_id = 0;
256261
(_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_family = AF_INET6;
257-
(_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_port = audio_port;
262+
(_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_port = htons(audio_port);
258263
(_RCAST(struct sockaddr_in6 *, &(play_args_a.to)))->sin6_addr = ip_media;
259264
}
265+
image_port = get_remote_port_media(msg, PAT_IMAGE);
266+
if (image_port) {
267+
/* We have image in the SDP: set the to_image addr */
268+
(_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_flowinfo = 0;
269+
(_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_scope_id = 0;
270+
(_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_family = AF_INET6;
271+
(_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_port = htons(image_port);
272+
(_RCAST(struct sockaddr_in6 *, &(play_args_i.to)))->sin6_addr = ip_media;
273+
}
260274
video_port = get_remote_port_media(msg, PAT_VIDEO);
261275
if (video_port) {
262276
/* We have video in the SDP: set the to_video addr */
263277
(_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_flowinfo = 0;
264278
(_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_scope_id = 0;
265279
(_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_family = AF_INET6;
266-
(_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_port = video_port;
280+
(_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_port = htons(video_port);
267281
(_RCAST(struct sockaddr_in6 *, &(play_args_v.to)))->sin6_addr = ip_media;
268282
}
269283
hasMediaInformation = 1;
@@ -276,14 +290,21 @@ void call::get_remote_media_addr(char *msg)
276290
if (audio_port) {
277291
/* We have audio in the SDP: set the to_audio addr */
278292
(_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_family = AF_INET;
279-
(_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_port = audio_port;
293+
(_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_port = htons(audio_port);
280294
(_RCAST(struct sockaddr_in *, &(play_args_a.to)))->sin_addr.s_addr = ip_media;
281295
}
296+
image_port = get_remote_port_media(msg, PAT_IMAGE);
297+
if (image_port) {
298+
/* We have image in the SDP: set the to_image addr */
299+
(_RCAST(struct sockaddr_in *, &(play_args_i.to)))->sin_family = AF_INET;
300+
(_RCAST(struct sockaddr_in *, &(play_args_i.to)))->sin_port = htons(image_port);
301+
(_RCAST(struct sockaddr_in *, &(play_args_i.to)))->sin_addr.s_addr = ip_media;
302+
}
282303
video_port = get_remote_port_media(msg, PAT_VIDEO);
283304
if (video_port) {
284305
/* We have video in the SDP: set the to_video addr */
285306
(_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_family = AF_INET;
286-
(_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_port = video_port;
307+
(_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_port = htons(video_port);
287308
(_RCAST(struct sockaddr_in *, &(play_args_v.to)))->sin_addr.s_addr = ip_media;
288309
}
289310
hasMediaInformation = 1;
@@ -299,15 +320,17 @@ void call::get_remote_media_addr(char *msg)
299320

300321
#define SDP_IPADDR_PREFIX "\nc=IN IP"
301322
#define SDP_AUDIOPORT_PREFIX "\nm=audio"
323+
#define SDP_IMAGEPORT_PREFIX "\nm=image"
302324
#define SDP_VIDEOPORT_PREFIX "\nm=video"
303325
void call::extract_rtp_remote_addr (char * msg)
304326
{
305327
char *search;
306328
char *copy;
307329
char ip_addr[128];
308330
int ip_ver;
309-
int audio_port= 0;
310-
int video_port= 0;
331+
int audio_port = 0;
332+
int image_port = 0;
333+
int video_port = 0;
311334

312335
/* Look for start of message body */
313336
search= strstr(msg,"\r\n\r\n");
@@ -349,6 +372,15 @@ void call::extract_rtp_remote_addr (char * msg)
349372
}
350373
sscanf (search,"%d",&audio_port);
351374
}
375+
/* And find the port number for the image stream */
376+
search= strstr(msg,SDP_IMAGEPORT_PREFIX);
377+
if (search) {
378+
search+= strlen(SDP_IMAGEPORT_PREFIX);
379+
while ( (*search==' ') || (*search=='\t') ) {
380+
search++;
381+
}
382+
sscanf (search,"%d",&image_port);
383+
}
352384
/* And find the port number for the video stream */
353385
search= strstr(msg,SDP_VIDEOPORT_PREFIX);
354386
if (search) {
@@ -358,10 +390,10 @@ void call::extract_rtp_remote_addr (char * msg)
358390
}
359391
sscanf (search,"%d",&video_port);
360392
}
361-
if ((audio_port==0)&&(video_port==0)) {
362-
ERROR("extract_rtp_remote_addr: no m=audio or m=video line found in SDP message body");
393+
if (audio_port == 0 && image_port == 0 && video_port == 0) {
394+
ERROR("extract_rtp_remote_addr: no m=audio, m=image or m=video line found in SDP message body");
363395
}
364-
rtpstream_set_remote (&rtpstream_callinfo,ip_ver,ip_addr,audio_port,video_port);
396+
rtpstream_set_remote(&rtpstream_callinfo, ip_ver, ip_addr, audio_port, image_port, video_port);
365397
}
366398
#endif
367399

@@ -612,8 +644,10 @@ void call::init(scenario * call_scenario, struct sipp_socket *socket, struct soc
612644

613645
#ifdef PCAPPLAY
614646
memset(&(play_args_a.to), 0, sizeof(struct sockaddr_storage));
647+
memset(&(play_args_i.to), 0, sizeof(struct sockaddr_storage));
615648
memset(&(play_args_v.to), 0, sizeof(struct sockaddr_storage));
616649
memset(&(play_args_a.from), 0, sizeof(struct sockaddr_storage));
650+
memset(&(play_args_i.from), 0, sizeof(struct sockaddr_storage));
617651
memset(&(play_args_v.from), 0, sizeof(struct sockaddr_storage));
618652
hasMediaInformation = 0;
619653
media_thread = 0;
@@ -2105,9 +2139,8 @@ char* call::createSendingMessage(SendingMessage *src, int P_index, char *msg_buf
21052139
(sockaddr *)(void *)&server_sockaddr, &len);
21062140

21072141
if (server_sockaddr.ss_family == AF_INET6) {
2108-
char * temp_dest;
2109-
temp_dest = (char *) malloc(INET6_ADDRSTRLEN);
2110-
memset(temp_dest,0,INET6_ADDRSTRLEN);
2142+
char temp_dest[INET6_ADDRSTRLEN]; /* fits both INET and INET6 */
2143+
temp_dest[0] = temp_dest[INET6_ADDRSTRLEN - 1] = '\0';
21112144
inet_ntop(AF_INET6,
21122145
&((_RCAST(struct sockaddr_in6 *,&server_sockaddr))->sin6_addr),
21132146
temp_dest,
@@ -2139,21 +2172,21 @@ char* call::createSendingMessage(SendingMessage *src, int P_index, char *msg_buf
21392172
if (begin == msg_buffer) {
21402173
ERROR("Can not find beginning of a line for the media port!\n");
21412174
}
2175+
play_args_t *play_args = NULL;
21422176
if (strstr(begin, "audio")) {
2143-
if (media_ip_is_ipv6) {
2144-
(_RCAST(struct sockaddr_in6 *, &(play_args_a.from)))->sin6_port = port;
2145-
} else {
2146-
(_RCAST(struct sockaddr_in *, &(play_args_a.from)))->sin_port = port;
2147-
}
2177+
play_args = &play_args_a;
2178+
} else if (strstr(begin, "image")) {
2179+
play_args = &play_args_i;
21482180
} else if (strstr(begin, "video")) {
2149-
if (media_ip_is_ipv6) {
2150-
(_RCAST(struct sockaddr_in6 *, &(play_args_v.from)))->sin6_port = port;
2151-
} else {
2152-
(_RCAST(struct sockaddr_in *, &(play_args_v.from)))->sin_port = port;
2153-
}
2181+
play_args = &play_args_v;
21542182
} else {
21552183
ERROR("media_port keyword with no audio or video on the current line (%s)", begin);
21562184
}
2185+
if (media_ip_is_ipv6) {
2186+
(_RCAST(struct sockaddr_in6 *, &(play_args->from)))->sin6_port = htons(port);
2187+
} else {
2188+
(_RCAST(struct sockaddr_in *, &(play_args->from)))->sin_port = htons(port);
2189+
}
21572190
#endif
21582191
dest += sprintf(dest, "%u", port);
21592192
break;
@@ -3835,16 +3868,18 @@ call::T_ActionResult call::executeAction(char * msg, message *curmsg)
38353868
}
38363869
#ifdef PCAPPLAY
38373870
} else if ((currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_AUDIO) ||
3871+
(currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_IMAGE) ||
38383872
(currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_VIDEO)) {
3839-
play_args_t *play_args = NULL;
3873+
play_args_t *play_args;
38403874
if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_AUDIO) {
38413875
play_args = &(this->play_args_a);
3876+
} else if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_IMAGE) {
3877+
play_args = &(this->play_args_i);
38423878
} else if (currentAction->getActionType() == CAction::E_AT_PLAY_PCAP_VIDEO) {
38433879
play_args = &(this->play_args_v);
3844-
}
3845-
3846-
if (!play_args)
3880+
} else {
38473881
ERROR("Can't find pcap data to play");
3882+
}
38483883

38493884
play_args->pcap = currentAction->getPcapPkts();
38503885
/* port number is set in [auto_]media_port interpolation */
@@ -3857,7 +3892,7 @@ call::T_ActionResult call::executeAction(char * msg, message *curmsg)
38573892
from->sin_family = AF_INET;
38583893
from->sin_addr.s_addr = inet_addr(media_ip);
38593894
}
3860-
/* Create a thread to send RTP packets */
3895+
/* Create a thread to send RTP or UDPTL packets */
38613896
pthread_attr_t attr;
38623897
pthread_attr_init(&attr);
38633898
#ifndef PTHREAD_STACK_MIN

src/prepare_pcap.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ int prepare_pkts(char *file, pcap_pkts *pkts)
141141
ethhdr = (ether_type_hdr *)(pktdata + ether_type_offset);
142142
if (ntohs(ethhdr->ether_type) != 0x0800 /* IPv4 */
143143
&& ntohs(ethhdr->ether_type) != 0x86dd) { /* IPv6 */
144-
fprintf(stderr, "Ignoring non IP{4,6} packet!\n");
144+
fprintf(stderr, "Ignoring non IP{4,6} packet, got ether_type %hu!\n",
145+
ntohs(ethhdr->ether_type));
145146
continue;
146147
}
147148
iphdr = (struct iphdr *)((char *)ethhdr + sizeof(*ethhdr));

src/rtpstream.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -886,16 +886,19 @@ int rtpstream_get_videoport (rtpstream_callinfo_t *callinfo)
886886
}
887887

888888
/* code checked */
889-
void rtpstream_set_remote (rtpstream_callinfo_t *callinfo, int ip_ver, char *ip_addr, int audio_port, int video_port)
889+
void rtpstream_set_remote (rtpstream_callinfo_t *callinfo, int ip_ver, char *ip_addr,
890+
int audio_port, int image_port, int video_port)
890891
{
892+
// TODO: we don't do anything with image_port right now..
891893
struct sockaddr_storage address;
892894
struct in_addr *ip4_addr;
893895
struct in6_addr *ip6_addr;
894896
taskentry_t *taskinfo;
895897
unsigned count;
896898
int nonzero_ip;
897899

898-
debugprint ("rtpstream_set_remote callinfo=%p, ip_ver %d ip_addr %s audio %d video %d\n",callinfo,ip_ver,ip_addr,audio_port,video_port);
900+
debugprint("rtpstream_set_remote callinfo=%p, ip_ver %d ip_addr %s audio %d image %d video %d\n",
901+
callinfo, ip_ver, ip_addr, audio_port, image_port, video_port);
899902

900903
taskinfo= callinfo->taskinfo;
901904
if (!taskinfo) {

src/scenario.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,9 @@ void scenario::parseAction(CActions *actions)
16081608
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
16091609
tmpAction->setPcapArgs(ptr);
16101610
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_AUDIO);
1611+
} else if ((ptr = xp_get_value((char *) "play_pcap_image"))) {
1612+
tmpAction->setPcapArgs(ptr);
1613+
tmpAction->setActionType(CAction::E_AT_PLAY_PCAP_IMAGE);
16111614
hasMedia = 1;
16121615
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
16131616
tmpAction->setPcapArgs(ptr);
@@ -1616,6 +1619,8 @@ void scenario::parseAction(CActions *actions)
16161619
#else
16171620
} else if ((ptr = xp_get_value((char *) "play_pcap_audio"))) {
16181621
ERROR("Scenario specifies a play_pcap_audio action, but this version of SIPp does not have PCAP support");
1622+
} else if ((ptr = xp_get_value((char *) "play_pcap_image"))) {
1623+
ERROR("Scenario specifies a play_pcap_image action, but this version of SIPp does not have PCAP support");
16191624
} else if ((ptr = xp_get_value((char *) "play_pcap_video"))) {
16201625
ERROR("Scenario specifies a play_pcap_video action, but this version of SIPp does not have PCAP support");
16211626
#endif

src/send_packets.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,8 @@ int send_packets (play_args_t * play_args)
199199
memcpy(udp, pkt_index->data, pkt_index->pktlen);
200200
port_diff = ntohs (udp->uh_dport) - pkts->base;
201201
// modify UDP ports
202-
udp->uh_sport = htons(port_diff + *from_port);
203-
udp->uh_dport = htons(port_diff + *to_port);
202+
udp->uh_sport = htons(port_diff + ntohs(*from_port));
203+
udp->uh_dport = htons(port_diff + ntohs(*to_port));
204204

205205
if (!media_ip_is_ipv6) {
206206
temp_sum = checksum_carry(pkt_index->partial_check + check((u_int16_t *) &(((struct sockaddr_in *)(void *) from)->sin_addr.s_addr), 4) + check((u_int16_t *) &(((struct sockaddr_in *)(void *) to)->sin_addr.s_addr), 4) + check((u_int16_t *) &udp->uh_sport, 4));

0 commit comments

Comments
 (0)