1 /*
2   The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)
3   Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9 
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14 
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 #include <osipparser2/internal.h>
21 
22 #include <osipparser2/osip_const.h>
23 #include <osipparser2/sdp_message.h>
24 #include <osipparser2/osip_message.h>
25 #include <osipparser2/osip_port.h>
26 
27 #define ERR_ERROR -1  /* bad header */
28 #define ERR_DISCARD 0 /* wrong header */
29 #define OSIP_WF 1     /* well formed header */
30 
31 static int sdp_message_parse_v(sdp_message_t *sdp, char *buf, char **next);
32 static int sdp_message_parse_o(sdp_message_t *sdp, char *buf, char **next);
33 static int sdp_message_parse_s(sdp_message_t *sdp, char *buf, char **next);
34 static int sdp_message_parse_i(sdp_message_t *sdp, char *buf, char **next);
35 static int sdp_message_parse_u(sdp_message_t *sdp, char *buf, char **next);
36 static int sdp_message_parse_e(sdp_message_t *sdp, char *buf, char **next);
37 static int sdp_message_parse_p(sdp_message_t *sdp, char *buf, char **next);
38 static int sdp_message_parse_c(sdp_message_t *sdp, char *buf, char **next);
39 static int sdp_message_parse_b(sdp_message_t *sdp, char *buf, char **next);
40 static int sdp_message_parse_t(sdp_message_t *sdp, char *buf, char **next);
41 static int sdp_message_parse_r(sdp_message_t *sdp, char *buf, char **next);
42 static int sdp_message_parse_z(sdp_message_t *sdp, char *buf, char **next);
43 static int sdp_message_parse_k(sdp_message_t *sdp, char *buf, char **next);
44 static int sdp_message_parse_a(sdp_message_t *sdp, char *buf, char **next);
45 static int sdp_message_parse_m(sdp_message_t *sdp, char *buf, char **next);
46 
47 static int sdp_append_media(char **string, int *size, char *tmp, sdp_media_t *media, char **next_tmp);
48 static int sdp_append_attribute(char **string, int *size, char *tmp, sdp_attribute_t *attribute, char **next_tmp);
49 static int sdp_append_key(char **string, int *size, char *tmp, sdp_key_t *key, char **next_tmp);
50 static int sdp_append_time_descr(char **string, int *size, char *tmp, sdp_time_descr_t *time_descr, char **next_tmp);
51 static int sdp_append_bandwidth(char **string, int *size, char *tmp, sdp_bandwidth_t *bandwidth, char **next_tmp);
52 static int sdp_append_connection(char **string, int *size, char *tmp, sdp_connection_t *conn, char **next_tmp);
53 
54 static char *__osip_sdp_append_string(char **string, int *size, char *cur, char *string_osip_to_append);
55 
sdp_bandwidth_init(sdp_bandwidth_t ** b)56 int sdp_bandwidth_init(sdp_bandwidth_t **b) {
57   *b = (sdp_bandwidth_t *) osip_malloc(sizeof(sdp_bandwidth_t));
58 
59   if (*b == NULL)
60     return OSIP_NOMEM;
61 
62   (*b)->b_bwtype = NULL;
63   (*b)->b_bandwidth = NULL;
64   return OSIP_SUCCESS;
65 }
66 
sdp_bandwidth_free(sdp_bandwidth_t * b)67 void sdp_bandwidth_free(sdp_bandwidth_t *b) {
68   if (b == NULL)
69     return;
70 
71   osip_free(b->b_bwtype);
72   osip_free(b->b_bandwidth);
73   osip_free(b);
74 }
75 
sdp_time_descr_init(sdp_time_descr_t ** td)76 int sdp_time_descr_init(sdp_time_descr_t **td) {
77   *td = (sdp_time_descr_t *) osip_malloc(sizeof(sdp_time_descr_t));
78 
79   if (*td == NULL)
80     return OSIP_NOMEM;
81 
82   (*td)->t_start_time = NULL;
83   (*td)->t_stop_time = NULL;
84   osip_list_init(&(*td)->r_repeats);
85   return OSIP_SUCCESS;
86 }
87 
sdp_time_descr_free(sdp_time_descr_t * td)88 void sdp_time_descr_free(sdp_time_descr_t *td) {
89   if (td == NULL)
90     return;
91 
92   osip_free(td->t_start_time);
93   osip_free(td->t_stop_time);
94   osip_list_ofchar_free(&td->r_repeats);
95   osip_free(td);
96 }
97 
sdp_key_init(sdp_key_t ** key)98 int sdp_key_init(sdp_key_t **key) {
99   *key = (sdp_key_t *) osip_malloc(sizeof(sdp_key_t));
100 
101   if (*key == NULL)
102     return OSIP_NOMEM;
103 
104   (*key)->k_keytype = NULL;
105   (*key)->k_keydata = NULL;
106   return OSIP_SUCCESS;
107 }
108 
sdp_key_free(sdp_key_t * key)109 void sdp_key_free(sdp_key_t *key) {
110   if (key == NULL)
111     return;
112 
113   osip_free(key->k_keytype);
114   osip_free(key->k_keydata);
115   osip_free(key);
116 }
117 
sdp_attribute_init(sdp_attribute_t ** attribute)118 int sdp_attribute_init(sdp_attribute_t **attribute) {
119   *attribute = (sdp_attribute_t *) osip_malloc(sizeof(sdp_attribute_t));
120 
121   if (*attribute == NULL)
122     return OSIP_NOMEM;
123 
124   (*attribute)->a_att_field = NULL;
125   (*attribute)->a_att_value = NULL;
126   return OSIP_SUCCESS;
127 }
128 
sdp_attribute_free(sdp_attribute_t * attribute)129 void sdp_attribute_free(sdp_attribute_t *attribute) {
130   if (attribute == NULL)
131     return;
132 
133   osip_free(attribute->a_att_field);
134   osip_free(attribute->a_att_value);
135   osip_free(attribute);
136 }
137 
sdp_connection_init(sdp_connection_t ** connection)138 int sdp_connection_init(sdp_connection_t **connection) {
139   *connection = (sdp_connection_t *) osip_malloc(sizeof(sdp_connection_t));
140 
141   if (*connection == NULL)
142     return OSIP_NOMEM;
143 
144   (*connection)->c_nettype = NULL;
145   (*connection)->c_addrtype = NULL;
146   (*connection)->c_addr = NULL;
147   (*connection)->c_addr_multicast_ttl = NULL;
148   (*connection)->c_addr_multicast_int = NULL;
149   return OSIP_SUCCESS;
150 }
151 
sdp_connection_free(sdp_connection_t * connection)152 void sdp_connection_free(sdp_connection_t *connection) {
153   if (connection == NULL)
154     return;
155 
156   osip_free(connection->c_nettype);
157   osip_free(connection->c_addrtype);
158   osip_free(connection->c_addr);
159   osip_free(connection->c_addr_multicast_ttl);
160   osip_free(connection->c_addr_multicast_int);
161   osip_free(connection);
162 }
163 
sdp_media_init(sdp_media_t ** media)164 int sdp_media_init(sdp_media_t **media) {
165   int i;
166 
167   *media = (sdp_media_t *) osip_malloc(sizeof(sdp_media_t));
168 
169   if (*media == NULL)
170     return OSIP_NOMEM;
171 
172   (*media)->m_media = NULL;
173   (*media)->m_port = NULL;
174   (*media)->m_number_of_port = NULL;
175   (*media)->m_proto = NULL;
176   i = osip_list_init(&(*media)->m_payloads);
177 
178   if (i != 0) {
179     osip_free(*media);
180     *media = NULL;
181     return OSIP_NOMEM;
182   }
183 
184   (*media)->i_info = NULL;
185   i = osip_list_init(&(*media)->c_connections);
186 
187   if (i != 0) {
188     osip_list_ofchar_free(&(*media)->m_payloads);
189     osip_free(*media);
190     *media = NULL;
191     return OSIP_NOMEM;
192   }
193 
194   i = osip_list_init(&(*media)->b_bandwidths);
195 
196   if (i != 0) {
197     osip_list_ofchar_free(&(*media)->m_payloads);
198     osip_list_special_free(&(*media)->c_connections, (void (*)(void *)) & sdp_connection_free);
199     osip_free(*media);
200     *media = NULL;
201     return OSIP_NOMEM;
202   }
203 
204   i = osip_list_init(&(*media)->a_attributes);
205 
206   if (i != 0) {
207     osip_list_ofchar_free(&(*media)->m_payloads);
208     osip_list_special_free(&(*media)->c_connections, (void (*)(void *)) & sdp_connection_free);
209     osip_list_special_free(&(*media)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
210     osip_free(*media);
211     *media = NULL;
212     return OSIP_NOMEM;
213   }
214 
215   (*media)->k_key = NULL;
216   return OSIP_SUCCESS;
217 }
218 
sdp_media_free(sdp_media_t * media)219 void sdp_media_free(sdp_media_t *media) {
220   if (media == NULL)
221     return;
222 
223   osip_free(media->m_media);
224   osip_free(media->m_port);
225   osip_free(media->m_number_of_port);
226   osip_free(media->m_proto);
227   osip_list_ofchar_free(&media->m_payloads);
228   osip_free(media->i_info);
229   osip_list_special_free(&media->c_connections, (void (*)(void *)) & sdp_connection_free);
230   osip_list_special_free(&media->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
231   osip_list_special_free(&media->a_attributes, (void (*)(void *)) & sdp_attribute_free);
232   sdp_key_free(media->k_key);
233   osip_free(media);
234 }
235 
236 /* to be changed to sdp_message_init(sdp_message_t **dest) */
sdp_message_init(sdp_message_t ** sdp)237 int sdp_message_init(sdp_message_t **sdp) {
238   int i;
239 
240   (*sdp) = (sdp_message_t *) osip_malloc(sizeof(sdp_message_t));
241 
242   if (*sdp == NULL)
243     return OSIP_NOMEM;
244 
245   (*sdp)->v_version = NULL;
246   (*sdp)->o_username = NULL;
247   (*sdp)->o_sess_id = NULL;
248   (*sdp)->o_sess_version = NULL;
249   (*sdp)->o_nettype = NULL;
250   (*sdp)->o_addrtype = NULL;
251   (*sdp)->o_addr = NULL;
252   (*sdp)->s_name = NULL;
253   (*sdp)->i_info = NULL;
254   (*sdp)->u_uri = NULL;
255 
256   i = osip_list_init(&(*sdp)->e_emails);
257 
258   if (i != 0) {
259     osip_list_ofchar_free(&(*sdp)->e_emails);
260     osip_free(*sdp);
261     *sdp = NULL;
262     return OSIP_NOMEM;
263   }
264 
265   i = osip_list_init(&(*sdp)->p_phones);
266 
267   if (i != 0) {
268     osip_list_ofchar_free(&(*sdp)->e_emails);
269     osip_free(*sdp);
270     *sdp = NULL;
271     return OSIP_NOMEM;
272   }
273 
274   (*sdp)->c_connection = NULL;
275 
276   i = osip_list_init(&(*sdp)->b_bandwidths);
277 
278   if (i != 0) {
279     osip_list_ofchar_free(&(*sdp)->e_emails);
280     osip_list_ofchar_free(&(*sdp)->p_phones);
281     osip_free(*sdp);
282     *sdp = NULL;
283     return OSIP_NOMEM;
284   }
285 
286   i = osip_list_init(&(*sdp)->t_descrs);
287 
288   if (i != 0) {
289     osip_list_ofchar_free(&(*sdp)->e_emails);
290     osip_list_ofchar_free(&(*sdp)->p_phones);
291     osip_list_special_free(&(*sdp)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
292     osip_free(*sdp);
293     *sdp = NULL;
294     return OSIP_NOMEM;
295   }
296 
297   (*sdp)->z_adjustments = NULL;
298   (*sdp)->k_key = NULL;
299 
300   i = osip_list_init(&(*sdp)->a_attributes);
301 
302   if (i != 0) {
303     osip_list_ofchar_free(&(*sdp)->e_emails);
304     osip_list_ofchar_free(&(*sdp)->p_phones);
305     osip_list_special_free(&(*sdp)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
306     osip_list_special_free(&(*sdp)->t_descrs, (void (*)(void *)) & sdp_time_descr_free);
307     osip_free(*sdp);
308     *sdp = NULL;
309     return OSIP_NOMEM;
310   }
311 
312   i = osip_list_init(&(*sdp)->m_medias);
313 
314   if (i != 0) {
315     osip_list_ofchar_free(&(*sdp)->e_emails);
316     osip_list_ofchar_free(&(*sdp)->p_phones);
317     osip_list_special_free(&(*sdp)->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
318     osip_list_special_free(&(*sdp)->t_descrs, (void (*)(void *)) & sdp_time_descr_free);
319     osip_list_special_free(&(*sdp)->a_attributes, (void (*)(void *)) & sdp_attribute_free);
320     osip_free(*sdp);
321     *sdp = NULL;
322     return OSIP_NOMEM;
323   }
324 
325   return OSIP_SUCCESS;
326 }
327 
328 /* append string_osip_to_append to string at position cur
329    size is the current allocated size of the element
330 */
__osip_sdp_append_string(char ** string,int * size,char * cur,char * string_osip_to_append)331 static char *__osip_sdp_append_string(char **string, int *size, char *cur, char *string_osip_to_append) {
332   int length = (int) strlen(string_osip_to_append);
333 
334   if (cur - (*string) + length + 1 > *size) {
335     int length2;
336 
337     length2 = (int) (cur - *string);
338     (*string) = osip_realloc((*string), *size + length + 500);
339     *size = *size + length + 500; /* optimize: avoid too much realloc */
340     cur = (*string) + length2;    /* the initial allocation may have changed! */
341   }
342 
343   osip_strncpy(cur, string_osip_to_append, length);
344   return cur + strlen(cur);
345 }
346 
sdp_message_parse_v(sdp_message_t * sdp,char * buf,char ** next)347 static int sdp_message_parse_v(sdp_message_t *sdp, char *buf, char **next) {
348   char *equal;
349   char *crlf;
350 
351   *next = buf;
352 
353   equal = buf;
354 
355   while ((*equal != '=') && (*equal != '\0'))
356     equal++;
357 
358   if (*equal == '\0')
359     return ERR_ERROR;
360 
361   if (equal == buf)
362     return ERR_DISCARD;
363 
364   /* check if header is "v" */
365   if (equal[-1] != 'v')
366     return ERR_DISCARD;
367 
368   crlf = equal + 1;
369 
370   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
371     crlf++;
372 
373   if (*crlf == '\0')
374     return ERR_ERROR;
375 
376   if (crlf == equal + 1)
377     return ERR_ERROR; /*v=\r ?? bad header */
378 
379   sdp->v_version = osip_malloc(crlf - (equal + 1) + 1);
380 
381   if (sdp->v_version == NULL)
382     return OSIP_NOMEM;
383 
384   osip_strncpy(sdp->v_version, equal + 1, crlf - (equal + 1));
385 
386   if (crlf[1] == '\n')
387     *next = crlf + 2;
388 
389   else
390     *next = crlf + 1;
391 
392   return OSIP_WF;
393 }
394 
sdp_message_parse_o(sdp_message_t * sdp,char * buf,char ** next)395 static int sdp_message_parse_o(sdp_message_t *sdp, char *buf, char **next) {
396   char *equal;
397   char *crlf;
398   char *tmp;
399   char *tmp_next;
400   int i;
401 
402   *next = buf;
403 
404   equal = buf;
405 
406   while ((*equal != '=') && (*equal != '\0'))
407     equal++;
408 
409   if (*equal == '\0')
410     return ERR_ERROR;
411 
412   /* check if header is "o" */
413   if (equal[-1] != 'o')
414     return ERR_DISCARD;
415 
416   crlf = equal + 1;
417 
418   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
419     crlf++;
420 
421   if (*crlf == '\0')
422     return ERR_ERROR;
423 
424   if (crlf == equal + 1)
425     return ERR_ERROR; /* o=\r ?? bad header */
426 
427   tmp = equal + 1;
428   /* o=username sess-id sess-version nettype addrtype addr */
429 
430   /* useranme can contain any char (ascii) except "space" and CRLF */
431 #ifdef FIREFLY_BUG_SUPPORT
432 
433   if (tmp[0] == ' ') {
434     sdp->o_username = osip_strdup("firefly");
435     tmp++;
436 
437   } else {
438     i = __osip_set_next_token(&(sdp->o_username), tmp, ' ', &tmp_next);
439 
440     if (i != 0)
441       return -1;
442 
443     tmp = tmp_next;
444   }
445 
446 #else
447   i = __osip_set_next_token(&(sdp->o_username), tmp, ' ', &tmp_next);
448 
449   if (i != 0)
450     return -1;
451 
452   tmp = tmp_next;
453 #endif
454 
455   /* sess_id contains only numeric characters */
456   i = __osip_set_next_token(&(sdp->o_sess_id), tmp, ' ', &tmp_next);
457 
458   if (i != 0)
459     return -1;
460 
461   tmp = tmp_next;
462 
463   /* sess_id contains only numeric characters */
464   i = __osip_set_next_token(&(sdp->o_sess_version), tmp, ' ', &tmp_next);
465 
466   if (i != 0)
467     return -1;
468 
469   tmp = tmp_next;
470 
471   /* nettype is "IN" but will surely be extented!!! assume it's some alpha-char */
472   i = __osip_set_next_token(&(sdp->o_nettype), tmp, ' ', &tmp_next);
473 
474   if (i != 0)
475     return -1;
476 
477   tmp = tmp_next;
478 
479   /* addrtype  is "IP4" or "IP6" but will surely be extented!!! */
480   i = __osip_set_next_token(&(sdp->o_addrtype), tmp, ' ', &tmp_next);
481 
482   if (i != 0)
483     return -1;
484 
485   tmp = tmp_next;
486 
487   /* addr  is "IP4" or "IP6" but will surely be extented!!! */
488   i = __osip_set_next_token(&(sdp->o_addr), tmp, '\r', &tmp_next);
489 
490   if (i != 0) { /* could it be "\n" only??? rfc says to accept CR or LF instead of CRLF */
491     i = __osip_set_next_token(&(sdp->o_addr), tmp, '\n', &tmp_next);
492 
493     if (i != 0)
494       return -1;
495   }
496 
497   if (crlf[1] == '\n')
498     *next = crlf + 2;
499 
500   else
501     *next = crlf + 1;
502 
503   return OSIP_WF;
504 }
505 
sdp_message_parse_s(sdp_message_t * sdp,char * buf,char ** next)506 static int sdp_message_parse_s(sdp_message_t *sdp, char *buf, char **next) {
507   char *equal;
508   char *crlf;
509 
510   *next = buf;
511 
512   equal = buf;
513 
514   while ((*equal != '=') && (*equal != '\0'))
515     equal++;
516 
517   if (*equal == '\0')
518     return ERR_ERROR;
519 
520   /* check if header is "s" */
521   if (equal[-1] != 's')
522     return ERR_DISCARD;
523 
524   crlf = equal + 1;
525 
526   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
527     crlf++;
528 
529   if (*crlf == '\0')
530     return ERR_ERROR;
531 
532 #ifdef FIREFLY_BUG_SUPPORT
533 
534   if (crlf == equal + 1) {
535     sdp->s_name = osip_strdup(" ");
536 
537     if (crlf[1] == '\n')
538       *next = crlf + 2;
539 
540     else
541       *next = crlf + 1;
542 
543     return OSIP_WF; /* o=\r ?? bad header */
544   }
545 
546 #else
547 
548   if (crlf == equal + 1)
549     return ERR_ERROR; /* o=\r ?? bad header */
550 
551 #endif
552 
553   /* s=text */
554 
555   /* text is interpreted as ISO-10646 UTF8! */
556   /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */
557   sdp->s_name = osip_malloc(crlf - (equal + 1) + 1);
558 
559   if (sdp->s_name == NULL)
560     return OSIP_NOMEM;
561 
562   osip_strncpy(sdp->s_name, equal + 1, crlf - (equal + 1));
563 
564   if (crlf[1] == '\n')
565     *next = crlf + 2;
566 
567   else
568     *next = crlf + 1;
569 
570   return OSIP_WF;
571 }
572 
sdp_message_parse_i(sdp_message_t * sdp,char * buf,char ** next)573 static int sdp_message_parse_i(sdp_message_t *sdp, char *buf, char **next) {
574   char *equal;
575   char *crlf;
576   int i;
577   char *i_info;
578 
579   *next = buf;
580 
581   equal = buf;
582 
583   while ((*equal != '=') && (*equal != '\0'))
584     equal++;
585 
586   if (*equal == '\0')
587     return ERR_ERROR;
588 
589   /* check if header is "i" */
590   if (equal[-1] != 'i')
591     return ERR_DISCARD;
592 
593   crlf = equal + 1;
594 
595   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
596     crlf++;
597 
598   if (*crlf == '\0')
599     return ERR_ERROR;
600 
601   if (crlf == equal + 1)
602     return ERR_ERROR; /* o=\r ?? bad header */
603 
604   /* s=text */
605 
606   /* text is interpreted as ISO-10646 UTF8! */
607   /* using ISO 8859-1 requires "a=charset:ISO-8859-1 */
608   i_info = osip_malloc(crlf - (equal + 1) + 1);
609 
610   if (i_info == NULL)
611     return OSIP_NOMEM;
612 
613   osip_strncpy(i_info, equal + 1, crlf - (equal + 1));
614 
615   /* add the bandwidth at the correct place:
616      if there is no media line yet, then the "b=" is the
617      global one.
618    */
619   i = osip_list_size(&sdp->m_medias);
620 
621   if (i == 0)
622     sdp->i_info = i_info;
623 
624   else {
625     sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
626 
627     last_sdp_media->i_info = i_info;
628   }
629 
630   if (crlf[1] == '\n')
631     *next = crlf + 2;
632 
633   else
634     *next = crlf + 1;
635 
636   return OSIP_WF;
637 }
638 
sdp_message_parse_u(sdp_message_t * sdp,char * buf,char ** next)639 static int sdp_message_parse_u(sdp_message_t *sdp, char *buf, char **next) {
640   char *equal;
641   char *crlf;
642 
643   *next = buf;
644 
645   equal = buf;
646 
647   while ((*equal != '=') && (*equal != '\0'))
648     equal++;
649 
650   if (*equal == '\0')
651     return ERR_ERROR;
652 
653   /* check if header is "u" */
654   if (equal[-1] != 'u')
655     return ERR_DISCARD;
656 
657   crlf = equal + 1;
658 
659   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
660     crlf++;
661 
662   if (*crlf == '\0')
663     return ERR_ERROR;
664 
665   if (crlf == equal + 1)
666     return ERR_ERROR; /* u=\r ?? bad header */
667 
668   /* u=uri */
669   /* we assume this is a URI */
670   sdp->u_uri = osip_malloc(crlf - (equal + 1) + 1);
671 
672   if (sdp->u_uri == NULL)
673     return OSIP_NOMEM;
674 
675   osip_strncpy(sdp->u_uri, equal + 1, crlf - (equal + 1));
676 
677   if (crlf[1] == '\n')
678     *next = crlf + 2;
679 
680   else
681     *next = crlf + 1;
682 
683   return OSIP_WF;
684 }
685 
sdp_message_parse_e(sdp_message_t * sdp,char * buf,char ** next)686 static int sdp_message_parse_e(sdp_message_t *sdp, char *buf, char **next) {
687   char *equal;
688   char *crlf;
689   char *e_email;
690 
691   *next = buf;
692 
693   equal = buf;
694 
695   while ((*equal != '=') && (*equal != '\0'))
696     equal++;
697 
698   if (*equal == '\0')
699     return ERR_ERROR;
700 
701   /* check if header is "e" */
702   if (equal[-1] != 'e')
703     return ERR_DISCARD;
704 
705   crlf = equal + 1;
706 
707   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
708     crlf++;
709 
710   if (*crlf == '\0')
711     return ERR_ERROR;
712 
713   if (crlf == equal + 1)
714     return ERR_ERROR; /* e=\r ?? bad header */
715 
716   /* e=email */
717   /* we assume this is an EMAIL-ADDRESS */
718   e_email = osip_malloc(crlf - (equal + 1) + 1);
719 
720   if (e_email == NULL)
721     return OSIP_NOMEM;
722 
723   osip_strncpy(e_email, equal + 1, crlf - (equal + 1));
724 
725   osip_list_add(&sdp->e_emails, e_email, -1);
726 
727   if (crlf[1] == '\n')
728     *next = crlf + 2;
729 
730   else
731     *next = crlf + 1;
732 
733   return OSIP_WF;
734 }
735 
sdp_message_parse_p(sdp_message_t * sdp,char * buf,char ** next)736 static int sdp_message_parse_p(sdp_message_t *sdp, char *buf, char **next) {
737   char *equal;
738   char *crlf;
739   char *p_phone;
740 
741   *next = buf;
742 
743   equal = buf;
744 
745   while ((*equal != '=') && (*equal != '\0'))
746     equal++;
747 
748   if (*equal == '\0')
749     return ERR_ERROR;
750 
751   /* check if header is "p" */
752   if (equal[-1] != 'p')
753     return ERR_DISCARD;
754 
755   crlf = equal + 1;
756 
757   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
758     crlf++;
759 
760   if (*crlf == '\0')
761     return ERR_ERROR;
762 
763   if (crlf == equal + 1)
764     return ERR_ERROR; /* p=\r ?? bad header */
765 
766   /* e=email */
767   /* we assume this is an EMAIL-ADDRESS */
768   p_phone = osip_malloc(crlf - (equal + 1) + 1);
769 
770   if (p_phone == NULL)
771     return OSIP_NOMEM;
772 
773   osip_strncpy(p_phone, equal + 1, crlf - (equal + 1));
774 
775   osip_list_add(&sdp->p_phones, p_phone, -1);
776 
777   if (crlf[1] == '\n')
778     *next = crlf + 2;
779 
780   else
781     *next = crlf + 1;
782 
783   return OSIP_WF;
784 }
785 
sdp_message_parse_c(sdp_message_t * sdp,char * buf,char ** next)786 static int sdp_message_parse_c(sdp_message_t *sdp, char *buf, char **next) {
787   char *equal;
788   char *crlf;
789   char *tmp;
790   char *tmp_next;
791   sdp_connection_t *c_header;
792   int i;
793 
794   *next = buf;
795 
796   equal = buf;
797 
798   while ((*equal != '=') && (*equal != '\0'))
799     equal++;
800 
801   if (*equal == '\0')
802     return ERR_ERROR;
803 
804   /* check if header is "c" */
805   if (equal[-1] != 'c')
806     return ERR_DISCARD;
807 
808   crlf = equal + 1;
809 
810   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
811     crlf++;
812 
813   if (*crlf == '\0')
814     return ERR_ERROR;
815 
816   if (crlf == equal + 1)
817     return ERR_ERROR; /* c=\r ?? bad header */
818 
819   tmp = equal + 1;
820   i = sdp_connection_init(&c_header);
821 
822   if (i != 0)
823     return ERR_ERROR;
824 
825   /* c=nettype addrtype (multicastaddr | addr) */
826 
827   /* nettype is "IN" and will be extended */
828   i = __osip_set_next_token(&(c_header->c_nettype), tmp, ' ', &tmp_next);
829 
830   if (i != 0) {
831     sdp_connection_free(c_header);
832     return -1;
833   }
834 
835   tmp = tmp_next;
836 
837   /* nettype is "IP4" or "IP6" and will be extended */
838   i = __osip_set_next_token(&(c_header->c_addrtype), tmp, ' ', &tmp_next);
839 
840   if (i != 0) {
841     sdp_connection_free(c_header);
842     return -1;
843   }
844 
845   tmp = tmp_next;
846 
847   /* there we have a multicast or unicast address */
848   /* multicast can be ip/ttl [/integer] */
849   /* unicast is FQDN or ip (no ttl, no integer) */
850 
851   /* is MULTICAST? */
852   {
853     char *slash = strchr(tmp, '/');
854 
855     if (slash != NULL && slash < crlf) { /* it's a multicast address! */
856       i = __osip_set_next_token(&(c_header->c_addr), tmp, '/', &tmp_next);
857 
858       if (i != 0) {
859         sdp_connection_free(c_header);
860         return -1;
861       }
862 
863       tmp = tmp_next;
864       slash = strchr(slash + 1, '/');
865 
866       if (slash != NULL && slash < crlf) { /* optionnal integer is there! */
867         i = __osip_set_next_token(&(c_header->c_addr_multicast_ttl), tmp, '/', &tmp_next);
868 
869         if (i != 0) {
870           sdp_connection_free(c_header);
871           return -1;
872         }
873 
874         tmp = tmp_next;
875         i = __osip_set_next_token(&(c_header->c_addr_multicast_int), tmp, '\r', &tmp_next);
876 
877         if (i != 0) {
878           i = __osip_set_next_token(&(c_header->c_addr_multicast_int), tmp, '\n', &tmp_next);
879 
880           if (i != 0) {
881             sdp_connection_free(c_header);
882             return -1;
883           }
884         }
885 
886       } else {
887         i = __osip_set_next_token(&(c_header->c_addr_multicast_ttl), tmp, '\r', &tmp_next);
888 
889         if (i != 0) {
890           i = __osip_set_next_token(&(c_header->c_addr_multicast_ttl), tmp, '\n', &tmp_next);
891 
892           if (i != 0) {
893             sdp_connection_free(c_header);
894             return -1;
895           }
896         }
897       }
898 
899     } else {
900       /* in this case, we have a unicast address */
901       i = __osip_set_next_token(&(c_header->c_addr), tmp, '\r', &tmp_next);
902 
903       if (i != 0) {
904         i = __osip_set_next_token(&(c_header->c_addr), tmp, '\n', &tmp_next);
905 
906         if (i != 0) {
907           sdp_connection_free(c_header);
908           return -1;
909         }
910       }
911     }
912   }
913 
914   /* add the connection at the correct place:
915      if there is no media line yet, then the "c=" is the
916      global one.
917    */
918   i = osip_list_size(&sdp->m_medias);
919 
920   if (i == 0)
921     sdp->c_connection = c_header;
922 
923   else {
924     sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
925 
926     osip_list_add(&last_sdp_media->c_connections, c_header, -1);
927   }
928 
929   if (crlf[1] == '\n')
930     *next = crlf + 2;
931 
932   else
933     *next = crlf + 1;
934 
935   return OSIP_WF;
936 }
937 
sdp_message_parse_b(sdp_message_t * sdp,char * buf,char ** next)938 static int sdp_message_parse_b(sdp_message_t *sdp, char *buf, char **next) {
939   char *equal;
940   char *crlf;
941   char *tmp;
942   char *tmp_next;
943   int i;
944   sdp_bandwidth_t *b_header;
945 
946   *next = buf;
947 
948   equal = buf;
949 
950   while ((*equal != '=') && (*equal != '\0'))
951     equal++;
952 
953   if (*equal == '\0')
954     return ERR_ERROR;
955 
956   /* check if header is "b" */
957   if (equal[-1] != 'b')
958     return ERR_DISCARD;
959 
960   crlf = equal + 1;
961 
962   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
963     crlf++;
964 
965   if (*crlf == '\0')
966     return ERR_ERROR;
967 
968   if (crlf == equal + 1)
969     return ERR_ERROR; /* b=\r ?? bad header */
970 
971   tmp = equal + 1;
972   /* b = bwtype: bandwidth */
973   i = sdp_bandwidth_init(&b_header);
974 
975   if (i != 0)
976     return ERR_ERROR;
977 
978   /* bwtype is alpha-numeric */
979   i = __osip_set_next_token(&(b_header->b_bwtype), tmp, ':', &tmp_next);
980 
981   if (i != 0) {
982     sdp_bandwidth_free(b_header);
983     return -1;
984   }
985 
986   tmp = tmp_next;
987 
988   i = __osip_set_next_token(&(b_header->b_bandwidth), tmp, '\r', &tmp_next);
989 
990   if (i != 0) {
991     i = __osip_set_next_token(&(b_header->b_bandwidth), tmp, '\n', &tmp_next);
992 
993     if (i != 0) {
994       sdp_bandwidth_free(b_header);
995       return -1;
996     }
997   }
998 
999   /* add the bandwidth at the correct place:
1000      if there is no media line yet, then the "b=" is the
1001      global one.
1002    */
1003   i = osip_list_size(&sdp->m_medias);
1004 
1005   if (i == 0)
1006     osip_list_add(&sdp->b_bandwidths, b_header, -1);
1007 
1008   else {
1009     sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
1010 
1011     osip_list_add(&last_sdp_media->b_bandwidths, b_header, -1);
1012   }
1013 
1014   if (crlf[1] == '\n')
1015     *next = crlf + 2;
1016 
1017   else
1018     *next = crlf + 1;
1019 
1020   return OSIP_WF;
1021 }
1022 
sdp_message_parse_t(sdp_message_t * sdp,char * buf,char ** next)1023 static int sdp_message_parse_t(sdp_message_t *sdp, char *buf, char **next) {
1024   char *equal;
1025   char *crlf;
1026   char *tmp;
1027   char *tmp_next;
1028   int i;
1029   sdp_time_descr_t *t_header;
1030 
1031   *next = buf;
1032 
1033   equal = buf;
1034 
1035   while ((*equal != '=') && (*equal != '\0'))
1036     equal++;
1037 
1038   if (*equal == '\0')
1039     return ERR_ERROR;
1040 
1041   /* check if header is "t" */
1042   if (equal[-1] != 't')
1043     return ERR_DISCARD;
1044 
1045   crlf = equal + 1;
1046 
1047   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1048     crlf++;
1049 
1050   if (*crlf == '\0')
1051     return ERR_ERROR;
1052 
1053   if (crlf == equal + 1)
1054     return ERR_ERROR; /* t=\r ?? bad header */
1055 
1056   tmp = equal + 1;
1057   /* t = start_time stop_time */
1058   i = sdp_time_descr_init(&t_header);
1059 
1060   if (i != 0)
1061     return ERR_ERROR;
1062 
1063   i = __osip_set_next_token(&(t_header->t_start_time), tmp, ' ', &tmp_next);
1064 
1065   if (i != 0) {
1066     sdp_time_descr_free(t_header);
1067     return -1;
1068   }
1069 
1070   tmp = tmp_next;
1071 
1072   i = __osip_set_next_token(&(t_header->t_stop_time), tmp, '\r', &tmp_next);
1073 
1074   if (i != 0) {
1075     i = __osip_set_next_token(&(t_header->t_stop_time), tmp, '\n', &tmp_next);
1076 
1077     if (i != 0) {
1078       sdp_time_descr_free(t_header);
1079       return -1;
1080     }
1081   }
1082 
1083   /* add the new time_description header */
1084   osip_list_add(&sdp->t_descrs, t_header, -1);
1085 
1086   if (crlf[1] == '\n')
1087     *next = crlf + 2;
1088 
1089   else
1090     *next = crlf + 1;
1091 
1092   return OSIP_WF;
1093 }
1094 
sdp_message_parse_r(sdp_message_t * sdp,char * buf,char ** next)1095 static int sdp_message_parse_r(sdp_message_t *sdp, char *buf, char **next) {
1096   char *equal;
1097   char *crlf;
1098   int index;
1099   char *r_header;
1100   sdp_time_descr_t *t_descr;
1101 
1102   *next = buf;
1103 
1104   equal = buf;
1105 
1106   while ((*equal != '=') && (*equal != '\0'))
1107     equal++;
1108 
1109   if (*equal == '\0')
1110     return ERR_ERROR;
1111 
1112   /* check if header is "r" */
1113   if (equal[-1] != 'r')
1114     return ERR_DISCARD;
1115 
1116   index = osip_list_size(&sdp->t_descrs);
1117 
1118   if (index == 0)
1119     return ERR_ERROR; /* r field can't come alone! */
1120 
1121   crlf = equal + 1;
1122 
1123   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1124     crlf++;
1125 
1126   if (*crlf == '\0')
1127     return ERR_ERROR;
1128 
1129   if (crlf == equal + 1)
1130     return ERR_ERROR; /* r=\r ?? bad header */
1131 
1132   /* r=far too complexe and somewhat useless... I don't parse it! */
1133   r_header = osip_malloc(crlf - (equal + 1) + 1);
1134 
1135   if (r_header == NULL)
1136     return OSIP_NOMEM;
1137 
1138   osip_strncpy(r_header, equal + 1, crlf - (equal + 1));
1139 
1140   /* r field carry information for the last "t" field */
1141   t_descr = (sdp_time_descr_t *) osip_list_get(&sdp->t_descrs, index - 1);
1142   osip_list_add(&t_descr->r_repeats, r_header, -1);
1143 
1144   if (crlf[1] == '\n')
1145     *next = crlf + 2;
1146 
1147   else
1148     *next = crlf + 1;
1149 
1150   return OSIP_WF;
1151 }
1152 
sdp_message_parse_z(sdp_message_t * sdp,char * buf,char ** next)1153 static int sdp_message_parse_z(sdp_message_t *sdp, char *buf, char **next) {
1154   char *equal;
1155   char *crlf;
1156   char *z_header;
1157 
1158   *next = buf;
1159 
1160   equal = buf;
1161 
1162   while ((*equal != '=') && (*equal != '\0'))
1163     equal++;
1164 
1165   if (*equal == '\0')
1166     return ERR_ERROR;
1167 
1168   /* check if header is "z" */
1169   if (equal[-1] != 'z')
1170     return ERR_DISCARD;
1171 
1172   crlf = equal + 1;
1173 
1174   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1175     crlf++;
1176 
1177   if (*crlf == '\0')
1178     return ERR_ERROR;
1179 
1180   if (crlf == equal + 1)
1181     return ERR_ERROR; /* z=\r ?? bad header */
1182 
1183   /* z=somewhat useless... I don't parse it! */
1184   z_header = osip_malloc(crlf - (equal + 1) + 1);
1185 
1186   if (z_header == NULL)
1187     return OSIP_NOMEM;
1188 
1189   osip_strncpy(z_header, equal + 1, crlf - (equal + 1));
1190 
1191   sdp->z_adjustments = z_header;
1192 
1193   if (crlf[1] == '\n')
1194     *next = crlf + 2;
1195 
1196   else
1197     *next = crlf + 1;
1198 
1199   return OSIP_WF;
1200 }
1201 
sdp_message_parse_k(sdp_message_t * sdp,char * buf,char ** next)1202 static int sdp_message_parse_k(sdp_message_t *sdp, char *buf, char **next) {
1203   char *equal;
1204   char *crlf;
1205   int i;
1206   char *colon;
1207   sdp_key_t *k_header;
1208   char *tmp;
1209   char *tmp_next;
1210 
1211   *next = buf;
1212 
1213   equal = buf;
1214 
1215   while ((*equal != '=') && (*equal != '\0'))
1216     equal++;
1217 
1218   if (*equal == '\0')
1219     return ERR_ERROR;
1220 
1221   /* check if header is "k" */
1222   if (equal[-1] != 'k')
1223     return ERR_DISCARD;
1224 
1225   crlf = equal + 1;
1226 
1227   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1228     crlf++;
1229 
1230   if (*crlf == '\0')
1231     return ERR_ERROR;
1232 
1233   if (crlf == equal + 1)
1234     return ERR_ERROR; /* k=\r ?? bad header */
1235 
1236   tmp = equal + 1;
1237 
1238   i = sdp_key_init(&k_header);
1239 
1240   if (i != 0)
1241     return ERR_ERROR;
1242 
1243   /* k=key-type[:key-data] */
1244 
1245   /* is there any key-data? */
1246   colon = strchr(equal + 1, ':');
1247 
1248   if ((colon != NULL) && (colon < crlf)) {
1249     /* att-field is alpha-numeric */
1250     i = __osip_set_next_token(&(k_header->k_keytype), tmp, ':', &tmp_next);
1251 
1252     if (i != 0) {
1253       sdp_key_free(k_header);
1254       return -1;
1255     }
1256 
1257     tmp = tmp_next;
1258 
1259     i = __osip_set_next_token(&(k_header->k_keydata), tmp, '\r', &tmp_next);
1260 
1261     if (i != 0) {
1262       i = __osip_set_next_token(&(k_header->k_keydata), tmp, '\n', &tmp_next);
1263 
1264       if (i != 0) {
1265         sdp_key_free(k_header);
1266         return -1;
1267       }
1268     }
1269 
1270   } else {
1271     i = __osip_set_next_token(&(k_header->k_keytype), tmp, '\r', &tmp_next);
1272 
1273     if (i != 0) {
1274       i = __osip_set_next_token(&(k_header->k_keytype), tmp, '\n', &tmp_next);
1275 
1276       if (i != 0) {
1277         sdp_key_free(k_header);
1278         return -1;
1279       }
1280     }
1281   }
1282 
1283   /* add the key at the correct place:
1284      if there is no media line yet, then the "k=" is the
1285      global one.
1286    */
1287   i = osip_list_size(&sdp->m_medias);
1288 
1289   if (i == 0)
1290     sdp->k_key = k_header;
1291 
1292   else {
1293     sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
1294 
1295     /* fixed Jan 10,2020: avoid a possible memory leak with k appearing several times after media line */
1296     /* fixed Nov 04,2020: wrong test was applied. Any media k= line was being rejected */
1297     if (last_sdp_media->k_key != NULL) {
1298       /* I believe such condition cannot happen any more: the method can't be called twice on a media */
1299       sdp_key_free(k_header);
1300       return -1;
1301     }
1302 
1303     last_sdp_media->k_key = k_header;
1304   }
1305 
1306   if (crlf[1] == '\n')
1307     *next = crlf + 2;
1308 
1309   else
1310     *next = crlf + 1;
1311 
1312   return OSIP_WF;
1313 }
1314 
sdp_message_parse_a(sdp_message_t * sdp,char * buf,char ** next)1315 static int sdp_message_parse_a(sdp_message_t *sdp, char *buf, char **next) {
1316   char *equal;
1317   char *crlf;
1318   char *tmp;
1319   char *tmp_next;
1320   int i;
1321   sdp_attribute_t *a_attribute;
1322   char *colon;
1323 
1324   *next = buf;
1325 
1326   equal = buf;
1327 
1328   while ((*equal != '=') && (*equal != '\0'))
1329     equal++;
1330 
1331   if (*equal == '\0')
1332     return ERR_ERROR;
1333 
1334   /* check if header is "a" */
1335   if (equal[-1] != 'a')
1336     return ERR_DISCARD;
1337 
1338   crlf = equal + 1;
1339 
1340   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1341     crlf++;
1342 
1343   if (*crlf == '\0')
1344     return ERR_ERROR;
1345 
1346   if (crlf == equal + 1)
1347     return ERR_ERROR; /* a=\r ?? bad header */
1348 
1349   tmp = equal + 1;
1350 
1351   i = sdp_attribute_init(&a_attribute);
1352 
1353   if (i != 0)
1354     return ERR_ERROR;
1355 
1356   /* a=att-field[:att-value] */
1357 
1358   /* is there any att-value? */
1359   colon = strchr(equal + 1, ':');
1360 
1361   if ((colon != NULL) && (colon < crlf)) {
1362     /* att-field is alpha-numeric */
1363     i = __osip_set_next_token(&(a_attribute->a_att_field), tmp, ':', &tmp_next);
1364 
1365     if (i != 0) {
1366       sdp_attribute_free(a_attribute);
1367       return -1;
1368     }
1369 
1370     tmp = tmp_next;
1371 
1372     i = __osip_set_next_token(&(a_attribute->a_att_value), tmp, '\r', &tmp_next);
1373 
1374     if (i != 0) {
1375       i = __osip_set_next_token(&(a_attribute->a_att_value), tmp, '\n', &tmp_next);
1376 
1377       if (i != 0) {
1378         sdp_attribute_free(a_attribute);
1379         return -1;
1380       }
1381     }
1382 
1383   } else {
1384     i = __osip_set_next_token(&(a_attribute->a_att_field), tmp, '\r', &tmp_next);
1385 
1386     if (i != 0) {
1387       i = __osip_set_next_token(&(a_attribute->a_att_field), tmp, '\n', &tmp_next);
1388 
1389       if (i != 0) {
1390         sdp_attribute_free(a_attribute);
1391         return -1;
1392       }
1393     }
1394   }
1395 
1396   /* add the attribute at the correct place:
1397      if there is no media line yet, then the "a=" is the
1398      global one.
1399    */
1400   i = osip_list_size(&sdp->m_medias);
1401 
1402   if (i == 0)
1403     osip_list_add(&sdp->a_attributes, a_attribute, -1);
1404 
1405   else {
1406     sdp_media_t *last_sdp_media = (sdp_media_t *) osip_list_get(&sdp->m_medias, i - 1);
1407 
1408     osip_list_add(&last_sdp_media->a_attributes, a_attribute, -1);
1409   }
1410 
1411   if (crlf[1] == '\n')
1412     *next = crlf + 2;
1413 
1414   else
1415     *next = crlf + 1;
1416 
1417   return OSIP_WF;
1418 }
1419 
sdp_message_parse_m(sdp_message_t * sdp,char * buf,char ** next)1420 static int sdp_message_parse_m(sdp_message_t *sdp, char *buf, char **next) {
1421   char *equal;
1422   char *crlf;
1423   char *tmp;
1424   char *tmp_next;
1425   int i;
1426   sdp_media_t *m_header;
1427   char *slash;
1428   char *space;
1429 
1430   *next = buf;
1431 
1432   equal = buf;
1433 
1434   while ((*equal != '=') && (*equal != '\0'))
1435     equal++;
1436 
1437   if (*equal == '\0')
1438     return ERR_ERROR;
1439 
1440   /* check if header is "m" */
1441   if (equal[-1] != 'm')
1442     return ERR_ERROR; /* fixed Jan 10,2020: avoid a possible memory leak with m being not detected */
1443 
1444   crlf = equal + 1;
1445 
1446   while ((*crlf != '\r') && (*crlf != '\n') && (*crlf != '\0'))
1447     crlf++;
1448 
1449   if (*crlf == '\0')
1450     return ERR_ERROR;
1451 
1452   if (crlf == equal + 1)
1453     return ERR_ERROR; /* a=\r ?? bad header */
1454 
1455   tmp = equal + 1;
1456 
1457   i = sdp_media_init(&m_header);
1458 
1459   if (i != 0)
1460     return ERR_ERROR;
1461 
1462   /* m=media port ["/"integer] proto *(payload_number) */
1463 
1464   /* media is "audio" "video" "application" "data" or other... */
1465   i = __osip_set_next_token(&(m_header->m_media), tmp, ' ', &tmp_next);
1466 
1467   if (i != 0) {
1468     sdp_media_free(m_header);
1469     return -1;
1470   }
1471 
1472   tmp = tmp_next;
1473 
1474   slash = strchr(tmp, '/');
1475   space = strchr(tmp, ' ');
1476 
1477   if (space == NULL) { /* not possible! */
1478     sdp_media_free(m_header);
1479     return ERR_ERROR;
1480   }
1481 
1482   if ((slash != NULL) && (slash < space)) { /* a number of port is specified! */
1483     i = __osip_set_next_token(&(m_header->m_port), tmp, '/', &tmp_next);
1484 
1485     if (i != 0) {
1486       sdp_media_free(m_header);
1487       return -1;
1488     }
1489 
1490     tmp = tmp_next;
1491 
1492     i = __osip_set_next_token(&(m_header->m_number_of_port), tmp, ' ', &tmp_next);
1493 
1494     if (i != 0) {
1495       sdp_media_free(m_header);
1496       return -1;
1497     }
1498 
1499     tmp = tmp_next;
1500 
1501   } else {
1502     i = __osip_set_next_token(&(m_header->m_port), tmp, ' ', &tmp_next);
1503 
1504     if (i != 0) {
1505       sdp_media_free(m_header);
1506       return -1;
1507     }
1508 
1509     tmp = tmp_next;
1510   }
1511 
1512   i = __osip_set_next_token(&(m_header->m_proto), tmp, ' ', &tmp_next);
1513 
1514   if (i != 0) {
1515     /* a few stack don't add SPACE after m_proto when rejecting all payloads */
1516     i = __osip_set_next_token(&(m_header->m_proto), tmp, '\r', &tmp_next);
1517 
1518     if (i != 0) {
1519       i = __osip_set_next_token(&(m_header->m_proto), tmp, '\n', &tmp_next);
1520 
1521       if (i != 0) {
1522         sdp_media_free(m_header);
1523         return -1;
1524       }
1525     }
1526   }
1527 
1528   tmp = tmp_next;
1529 
1530   {
1531     char *str;
1532     int more_space_before_crlf;
1533 
1534     space = strchr(tmp + 1, ' ');
1535 
1536     if (space == NULL)
1537       more_space_before_crlf = 1;
1538 
1539     else if ((space != NULL) && (space > crlf))
1540       more_space_before_crlf = 1;
1541 
1542     else
1543       more_space_before_crlf = 0;
1544 
1545     while (more_space_before_crlf == 0) {
1546       i = __osip_set_next_token(&str, tmp, ' ', &tmp_next);
1547 
1548       if (i != 0) {
1549         sdp_media_free(m_header);
1550         return -1;
1551       }
1552 
1553       tmp = tmp_next;
1554       osip_list_add(&m_header->m_payloads, str, -1);
1555 
1556       space = strchr(tmp + 1, ' ');
1557 
1558       if (space == NULL)
1559         more_space_before_crlf = 1;
1560 
1561       else if ((space != NULL) && (space > crlf))
1562         more_space_before_crlf = 1;
1563 
1564       else
1565         more_space_before_crlf = 0;
1566     }
1567 
1568     if (tmp_next < crlf) { /* tmp_next is still less than clrf: no space */
1569       i = __osip_set_next_token(&str, tmp, '\r', &tmp_next);
1570 
1571       if (i != 0) {
1572         i = __osip_set_next_token(&str, tmp, '\n', &tmp_next);
1573 
1574         if (i != 0) {
1575           sdp_media_free(m_header);
1576           return -1;
1577         }
1578       }
1579 
1580       osip_list_add(&m_header->m_payloads, str, -1);
1581     }
1582   }
1583 
1584   osip_list_add(&sdp->m_medias, m_header, -1);
1585 
1586   if (crlf[1] == '\n')
1587     *next = crlf + 2;
1588 
1589   else
1590     *next = crlf + 1;
1591 
1592   return OSIP_WF;
1593 }
1594 
sdp_message_parse(sdp_message_t * sdp,const char * buf)1595 int sdp_message_parse(sdp_message_t *sdp, const char *buf) {
1596   /* In SDP, headers must be in the right order */
1597   /* This is a simple example
1598      v=0
1599      o=user1 53655765 2353687637 IN IP4 128.3.4.5
1600      s=Mbone Audio
1601      i=Discussion of Mbone Engineering Issues
1602      e=mbone@somewhere.com
1603      c=IN IP4 224.2.0.1/127
1604      t=0 0
1605      m=audio 3456 RTP/AVP 0
1606      a=rtpmap:0 PCMU/8000
1607    */
1608 
1609   char *next_buf;
1610   char *ptr;
1611   int i;
1612 
1613   ptr = (char *) buf;
1614   /* mandatory */
1615   i = sdp_message_parse_v(sdp, ptr, &next_buf);
1616 
1617   if (i == -1) /* header is bad */
1618     return -1;
1619 
1620   else if (0 == i) /* header is not "v" */
1621     return -1;
1622 
1623   ptr = next_buf;
1624 
1625   /* adtech phone use the wrong ordering and place "s" before "o" */
1626   i = sdp_message_parse_s(sdp, ptr, &next_buf);
1627 
1628   if (i == -1) /* header is bad */
1629     return -1;
1630 
1631   /* else if (0==i) header is not "s" */
1632   /* else ADTECH PHONE DETECTED */
1633 
1634   ptr = next_buf;
1635 
1636   i = sdp_message_parse_o(sdp, ptr, &next_buf);
1637 
1638   if (i == -1) /* header is bad */
1639     return -1;
1640 
1641   else if (0 == i) /* header is not "o" */
1642     return -1;
1643 
1644   ptr = next_buf;
1645 
1646   if (sdp->s_name == NULL) { /* fixed Jan 10,2020: avoid a possible memory leak with s appearing both before o and after o */
1647     i = sdp_message_parse_s(sdp, ptr, &next_buf);
1648 
1649     if (i == -1) /* header is bad */
1650       return -1;
1651 
1652     else if (0 == i) { /* header is not "s" */
1653       /* return -1; */
1654       OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "The \"s\" parameter is mandatory, but this packet does not contain any! - anyway, we don't mind about it.\n"));
1655     }
1656 
1657     ptr = next_buf;
1658   }
1659 
1660   i = sdp_message_parse_i(sdp, ptr, &next_buf);
1661 
1662   if (i == -1) /* header is bad */
1663     return -1;
1664 
1665   ptr = next_buf;
1666 
1667   i = sdp_message_parse_u(sdp, ptr, &next_buf);
1668 
1669   if (i == -1) /* header is bad */
1670     return -1;
1671 
1672   ptr = next_buf;
1673 
1674   i = 1;
1675 
1676   while (i == 1) {
1677     i = sdp_message_parse_e(sdp, ptr, &next_buf);
1678 
1679     if (i == -1) /* header is bad */
1680       return -1;
1681 
1682     ptr = next_buf;
1683   }
1684 
1685   i = 1;
1686 
1687   while (i == 1) {
1688     i = sdp_message_parse_p(sdp, ptr, &next_buf);
1689 
1690     if (i == -1) /* header is bad */
1691       return -1;
1692 
1693     ptr = next_buf;
1694   }
1695 
1696   /* rfc2327: there should be at least of email or phone number! */
1697   if (osip_list_size(&sdp->e_emails) == 0 && osip_list_size(&sdp->p_phones) == 0) {
1698     OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO4, NULL, "The rfc2327 says there should be at least an email or a phone header!- anyway, we don't mind about it.\n"));
1699   }
1700 
1701   i = sdp_message_parse_c(sdp, ptr, &next_buf);
1702 
1703   if (i == -1) /* header is bad */
1704     return -1;
1705 
1706   ptr = next_buf;
1707 
1708   i = 1;
1709 
1710   while (i == 1) {
1711     i = sdp_message_parse_b(sdp, ptr, &next_buf);
1712 
1713     if (i == -1) /* header is bad */
1714       return -1;
1715 
1716     ptr = next_buf;
1717   }
1718 
1719   /* 1 or more "t" header + 0 or more "r" header for each "t" header */
1720   i = sdp_message_parse_t(sdp, ptr, &next_buf);
1721 
1722   if (i == -1) /* header is bad */
1723     return -1;
1724 
1725   else if (i == ERR_DISCARD)
1726     return -1; /* t is mandatory */
1727 
1728   ptr = next_buf;
1729 
1730   if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1731     return OSIP_SUCCESS;
1732 
1733   i = 1;
1734 
1735   while (i == 1) { /* is a "r" header */
1736     i = sdp_message_parse_r(sdp, ptr, &next_buf);
1737 
1738     if (i == -1) /* header is bad */
1739       return -1;
1740 
1741     ptr = next_buf;
1742 
1743     if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1744       return OSIP_SUCCESS;
1745   }
1746 
1747   {
1748     int more_t_header = 1;
1749 
1750     i = sdp_message_parse_t(sdp, ptr, &next_buf);
1751 
1752     if (i == -1) /* header is bad */
1753       return -1;
1754 
1755     ptr = next_buf;
1756 
1757     if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1758       return OSIP_SUCCESS;
1759 
1760     while (more_t_header == 1) {
1761       i = 1;
1762 
1763       while (i == 1) { /* is a "r" header */
1764         i = sdp_message_parse_r(sdp, ptr, &next_buf);
1765 
1766         if (i == -1) /* header is bad */
1767           return -1;
1768 
1769         ptr = next_buf;
1770 
1771         if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1772           return OSIP_SUCCESS;
1773       }
1774 
1775       i = sdp_message_parse_t(sdp, ptr, &next_buf);
1776 
1777       if (i == -1) /* header is bad */
1778         return -1;
1779 
1780       else if (i == ERR_DISCARD)
1781         more_t_header = 0;
1782 
1783       else
1784         more_t_header = 1; /* no more "t" headers */
1785 
1786       ptr = next_buf;
1787 
1788       if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1789         return OSIP_SUCCESS;
1790     }
1791   }
1792 
1793   i = sdp_message_parse_z(sdp, ptr, &next_buf);
1794 
1795   if (i == -1) /* header is bad */
1796     return -1;
1797 
1798   ptr = next_buf;
1799 
1800   if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1801     return OSIP_SUCCESS;
1802 
1803   i = sdp_message_parse_k(sdp, ptr, &next_buf);
1804 
1805   if (i == -1) /* header is bad */
1806     return -1;
1807 
1808   ptr = next_buf;
1809 
1810   if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1811     return OSIP_SUCCESS;
1812 
1813   /* 0 or more "a" header */
1814   i = 1;
1815 
1816   while (i == 1) { /* no more "a" header */
1817     i = sdp_message_parse_a(sdp, ptr, &next_buf);
1818 
1819     if (i == -1) /* header is bad */
1820       return -1;
1821 
1822     ptr = next_buf;
1823 
1824     if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1825       return OSIP_SUCCESS;
1826   }
1827 
1828   /* 0 or more media headers */
1829   {
1830     int more_m_header = 1;
1831 
1832     while (more_m_header == 1) {
1833       more_m_header = sdp_message_parse_m(sdp, ptr, &next_buf);
1834 
1835       if (more_m_header == -1) /* header is bad */
1836         return -1;
1837 
1838       ptr = next_buf;
1839 
1840       if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1841         return OSIP_SUCCESS;
1842 
1843       i = sdp_message_parse_i(sdp, ptr, &next_buf);
1844 
1845       if (i == -1) /* header is bad */
1846         return -1;
1847 
1848       ptr = next_buf;
1849 
1850       if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1851         return OSIP_SUCCESS;
1852 
1853       i = 1;
1854 
1855       while (i == 1) {
1856         i = sdp_message_parse_c(sdp, ptr, &next_buf);
1857 
1858         if (i == -1) /* header is bad */
1859           return -1;
1860 
1861         ptr = next_buf;
1862 
1863         if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1864           return OSIP_SUCCESS;
1865       }
1866 
1867       i = 1;
1868 
1869       while (i == 1) {
1870         i = sdp_message_parse_b(sdp, ptr, &next_buf);
1871 
1872         if (i == -1) /* header is bad */
1873           return -1;
1874 
1875         ptr = next_buf;
1876 
1877         if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1878           return OSIP_SUCCESS;
1879       }
1880 
1881       i = sdp_message_parse_k(sdp, ptr, &next_buf);
1882 
1883       if (i == -1) /* header is bad */
1884         return -1;
1885 
1886       ptr = next_buf;
1887 
1888       if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1889         return OSIP_SUCCESS;
1890 
1891       /* 0 or more a headers */
1892       i = 1;
1893 
1894       while (i == 1) {
1895         i = sdp_message_parse_a(sdp, ptr, &next_buf);
1896 
1897         if (i == -1) /* header is bad */
1898           return -1;
1899 
1900         ptr = next_buf;
1901 
1902         if (*ptr == '\0' || (*ptr == '\r') || (*ptr == '\n'))
1903           return OSIP_SUCCESS;
1904       }
1905     }
1906   }
1907 
1908   return OSIP_SUCCESS;
1909 }
1910 
sdp_append_connection(char ** string,int * size,char * tmp,sdp_connection_t * conn,char ** next_tmp)1911 static int sdp_append_connection(char **string, int *size, char *tmp, sdp_connection_t *conn, char **next_tmp) {
1912   if (conn->c_nettype == NULL)
1913     return -1;
1914 
1915   if (conn->c_addrtype == NULL)
1916     return -1;
1917 
1918   if (conn->c_addr == NULL)
1919     return -1;
1920 
1921   tmp = __osip_sdp_append_string(string, size, tmp, "c=");
1922   tmp = __osip_sdp_append_string(string, size, tmp, conn->c_nettype);
1923   tmp = __osip_sdp_append_string(string, size, tmp, " ");
1924   tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addrtype);
1925   tmp = __osip_sdp_append_string(string, size, tmp, " ");
1926   tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addr);
1927 
1928   if (conn->c_addr_multicast_ttl != NULL) {
1929     tmp = __osip_sdp_append_string(string, size, tmp, "/");
1930     tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addr_multicast_ttl);
1931   }
1932 
1933   if (conn->c_addr_multicast_int != NULL) {
1934     tmp = __osip_sdp_append_string(string, size, tmp, "/");
1935     tmp = __osip_sdp_append_string(string, size, tmp, conn->c_addr_multicast_int);
1936   }
1937 
1938   tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1939   *next_tmp = tmp;
1940   return OSIP_SUCCESS;
1941 }
1942 
sdp_append_bandwidth(char ** string,int * size,char * tmp,sdp_bandwidth_t * bandwidth,char ** next_tmp)1943 static int sdp_append_bandwidth(char **string, int *size, char *tmp, sdp_bandwidth_t *bandwidth, char **next_tmp) {
1944   if (bandwidth->b_bwtype == NULL)
1945     return -1;
1946 
1947   if (bandwidth->b_bandwidth == NULL)
1948     return -1;
1949 
1950   tmp = __osip_sdp_append_string(string, size, tmp, "b=");
1951   tmp = __osip_sdp_append_string(string, size, tmp, bandwidth->b_bwtype);
1952   tmp = __osip_sdp_append_string(string, size, tmp, ":");
1953   tmp = __osip_sdp_append_string(string, size, tmp, bandwidth->b_bandwidth);
1954   tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1955 
1956   *next_tmp = tmp;
1957   return OSIP_SUCCESS;
1958 }
1959 
sdp_append_time_descr(char ** string,int * size,char * tmp,sdp_time_descr_t * time_descr,char ** next_tmp)1960 static int sdp_append_time_descr(char **string, int *size, char *tmp, sdp_time_descr_t *time_descr, char **next_tmp) {
1961   int pos;
1962 
1963   if (time_descr->t_start_time == NULL)
1964     return -1;
1965 
1966   if (time_descr->t_stop_time == NULL)
1967     return -1;
1968 
1969   tmp = __osip_sdp_append_string(string, size, tmp, "t=");
1970   tmp = __osip_sdp_append_string(string, size, tmp, time_descr->t_start_time);
1971   tmp = __osip_sdp_append_string(string, size, tmp, " ");
1972   tmp = __osip_sdp_append_string(string, size, tmp, time_descr->t_stop_time);
1973 
1974   tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1975 
1976   pos = 0;
1977 
1978   while (!osip_list_eol(&time_descr->r_repeats, pos)) {
1979     char *str = (char *) osip_list_get(&time_descr->r_repeats, pos);
1980 
1981     tmp = __osip_sdp_append_string(string, size, tmp, "r=");
1982     tmp = __osip_sdp_append_string(string, size, tmp, str);
1983     tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
1984     pos++;
1985   }
1986 
1987   *next_tmp = tmp;
1988   return OSIP_SUCCESS;
1989 }
1990 
sdp_append_key(char ** string,int * size,char * tmp,sdp_key_t * key,char ** next_tmp)1991 static int sdp_append_key(char **string, int *size, char *tmp, sdp_key_t *key, char **next_tmp) {
1992   if (key->k_keytype == NULL)
1993     return -1;
1994 
1995   tmp = __osip_sdp_append_string(string, size, tmp, "k=");
1996   tmp = __osip_sdp_append_string(string, size, tmp, key->k_keytype);
1997 
1998   if (key->k_keydata != NULL) {
1999     tmp = __osip_sdp_append_string(string, size, tmp, ":");
2000     tmp = __osip_sdp_append_string(string, size, tmp, key->k_keydata);
2001   }
2002 
2003   tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2004   *next_tmp = tmp;
2005   return OSIP_SUCCESS;
2006 }
2007 
sdp_append_attribute(char ** string,int * size,char * tmp,sdp_attribute_t * attribute,char ** next_tmp)2008 static int sdp_append_attribute(char **string, int *size, char *tmp, sdp_attribute_t *attribute, char **next_tmp) {
2009   if (attribute->a_att_field == NULL)
2010     return -1;
2011 
2012   tmp = __osip_sdp_append_string(string, size, tmp, "a=");
2013   tmp = __osip_sdp_append_string(string, size, tmp, attribute->a_att_field);
2014 
2015   if (attribute->a_att_value != NULL) {
2016     tmp = __osip_sdp_append_string(string, size, tmp, ":");
2017     tmp = __osip_sdp_append_string(string, size, tmp, attribute->a_att_value);
2018   }
2019 
2020   tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2021 
2022   *next_tmp = tmp;
2023   return OSIP_SUCCESS;
2024 }
2025 
2026 /* internal facility */
sdp_append_media(char ** string,int * size,char * tmp,sdp_media_t * media,char ** next_tmp)2027 static int sdp_append_media(char **string, int *size, char *tmp, sdp_media_t *media, char **next_tmp) {
2028   int pos;
2029 
2030   if (media->m_media == NULL)
2031     return -1;
2032 
2033   if (media->m_port == NULL)
2034     return -1;
2035 
2036   if (media->m_proto == NULL)
2037     return -1;
2038 
2039   tmp = __osip_sdp_append_string(string, size, tmp, "m=");
2040   tmp = __osip_sdp_append_string(string, size, tmp, media->m_media);
2041   tmp = __osip_sdp_append_string(string, size, tmp, " ");
2042   if (media->m_port[0] == '0')
2043     tmp = __osip_sdp_append_string(string, size, tmp, "0");
2044   else
2045     tmp = __osip_sdp_append_string(string, size, tmp, media->m_port);
2046 
2047   if (media->m_number_of_port != NULL) {
2048     tmp = __osip_sdp_append_string(string, size, tmp, "/");
2049     tmp = __osip_sdp_append_string(string, size, tmp, media->m_number_of_port);
2050   }
2051 
2052   tmp = __osip_sdp_append_string(string, size, tmp, " ");
2053   tmp = __osip_sdp_append_string(string, size, tmp, media->m_proto);
2054   pos = 0;
2055 
2056   while (!osip_list_eol(&media->m_payloads, pos)) {
2057     char *str = (char *) osip_list_get(&media->m_payloads, pos);
2058 
2059     tmp = __osip_sdp_append_string(string, size, tmp, " ");
2060     tmp = __osip_sdp_append_string(string, size, tmp, str);
2061     pos++;
2062   }
2063 
2064   tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2065 
2066   if (media->i_info != NULL) {
2067     tmp = __osip_sdp_append_string(string, size, tmp, "i=");
2068     tmp = __osip_sdp_append_string(string, size, tmp, media->i_info);
2069     tmp = __osip_sdp_append_string(string, size, tmp, OSIP_CRLF);
2070   }
2071 
2072   pos = 0;
2073 
2074   while (!osip_list_eol(&media->c_connections, pos)) {
2075     sdp_connection_t *conn = (sdp_connection_t *) osip_list_get(&media->c_connections, pos);
2076     char *next_tmp2;
2077     int i;
2078 
2079     i = sdp_append_connection(string, size, tmp, conn, &next_tmp2);
2080 
2081     if (i != 0)
2082       return -1;
2083 
2084     tmp = next_tmp2;
2085     pos++;
2086   }
2087 
2088   pos = 0;
2089 
2090   while (!osip_list_eol(&media->b_bandwidths, pos)) {
2091     sdp_bandwidth_t *band = (sdp_bandwidth_t *) osip_list_get(&media->b_bandwidths, pos);
2092     char *next_tmp2;
2093     int i;
2094 
2095     i = sdp_append_bandwidth(string, size, tmp, band, &next_tmp2);
2096 
2097     if (i != 0)
2098       return -1;
2099 
2100     tmp = next_tmp2;
2101     pos++;
2102   }
2103 
2104   if (media->k_key != NULL) {
2105     char *next_tmp2;
2106     int i;
2107 
2108     i = sdp_append_key(string, size, tmp, media->k_key, &next_tmp2);
2109 
2110     if (i != 0)
2111       return -1;
2112 
2113     tmp = next_tmp2;
2114   }
2115 
2116   pos = 0;
2117 
2118   while (!osip_list_eol(&media->a_attributes, pos)) {
2119     sdp_attribute_t *attr = (sdp_attribute_t *) osip_list_get(&media->a_attributes, pos);
2120     char *next_tmp2;
2121     int i;
2122 
2123     i = sdp_append_attribute(string, size, tmp, attr, &next_tmp2);
2124 
2125     if (i != 0)
2126       return -1;
2127 
2128     tmp = next_tmp2;
2129     pos++;
2130   }
2131 
2132   *next_tmp = tmp;
2133   return OSIP_SUCCESS;
2134 }
2135 
sdp_message_to_str(sdp_message_t * sdp,char ** dest)2136 int sdp_message_to_str(sdp_message_t *sdp, char **dest) {
2137   int size;
2138   int pos;
2139   char *tmp;
2140   char *string;
2141 
2142   *dest = NULL;
2143 
2144   if (!sdp || sdp->v_version == NULL)
2145     return -1;
2146 
2147   if (sdp->o_username == NULL || sdp->o_sess_id == NULL || sdp->o_sess_version == NULL || sdp->o_nettype == NULL || sdp->o_addrtype == NULL || sdp->o_addr == NULL)
2148     return -1;
2149 
2150   /* RFC says "s=" is mandatory... rfc2543 (SIP) recommends to
2151      accept SDP datas without s_name... as some buggy implementations
2152      often forget it...
2153    */
2154   /* if (sdp->s_name == NULL)
2155      return -1; */
2156 
2157   size = BODY_MESSAGE_MAX_SIZE;
2158   tmp = (char *) osip_malloc(size);
2159 
2160   if (tmp == NULL)
2161     return OSIP_NOMEM;
2162 
2163   string = tmp;
2164 
2165   tmp = __osip_sdp_append_string(&string, &size, tmp, "v=");
2166   tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->v_version);
2167   tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2168   tmp = __osip_sdp_append_string(&string, &size, tmp, "o=");
2169   tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_username);
2170   tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2171   tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_sess_id);
2172   tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2173   tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_sess_version);
2174   tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2175   tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_nettype);
2176   tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2177   tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_addrtype);
2178   tmp = __osip_sdp_append_string(&string, &size, tmp, " ");
2179   tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->o_addr);
2180   tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2181 
2182   if (sdp->s_name != NULL) {
2183     tmp = __osip_sdp_append_string(&string, &size, tmp, "s=");
2184     tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->s_name);
2185     tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2186   }
2187 
2188   if (sdp->i_info != NULL) {
2189     tmp = __osip_sdp_append_string(&string, &size, tmp, "i=");
2190     tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->i_info);
2191     tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2192   }
2193 
2194   if (sdp->u_uri != NULL) {
2195     tmp = __osip_sdp_append_string(&string, &size, tmp, "u=");
2196     tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->u_uri);
2197     tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2198   }
2199 
2200   pos = 0;
2201 
2202   while (!osip_list_eol(&sdp->e_emails, pos)) {
2203     char *email = (char *) osip_list_get(&sdp->e_emails, pos);
2204 
2205     tmp = __osip_sdp_append_string(&string, &size, tmp, "e=");
2206     tmp = __osip_sdp_append_string(&string, &size, tmp, email);
2207     tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2208     pos++;
2209   }
2210 
2211   pos = 0;
2212 
2213   while (!osip_list_eol(&sdp->p_phones, pos)) {
2214     char *phone = (char *) osip_list_get(&sdp->p_phones, pos);
2215 
2216     tmp = __osip_sdp_append_string(&string, &size, tmp, "p=");
2217     tmp = __osip_sdp_append_string(&string, &size, tmp, phone);
2218     tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2219     pos++;
2220   }
2221 
2222   if (sdp->c_connection != NULL) {
2223     char *next_tmp;
2224     int i;
2225 
2226     i = sdp_append_connection(&string, &size, tmp, sdp->c_connection, &next_tmp);
2227 
2228     if (i != 0) {
2229       osip_free(string);
2230       return -1;
2231     }
2232 
2233     tmp = next_tmp;
2234   }
2235 
2236   pos = 0;
2237 
2238   while (!osip_list_eol(&sdp->b_bandwidths, pos)) {
2239     sdp_bandwidth_t *header = (sdp_bandwidth_t *) osip_list_get(&sdp->b_bandwidths, pos);
2240     char *next_tmp;
2241     int i;
2242 
2243     i = sdp_append_bandwidth(&string, &size, tmp, header, &next_tmp);
2244 
2245     if (i != 0) {
2246       osip_free(string);
2247       return -1;
2248     }
2249 
2250     tmp = next_tmp;
2251     pos++;
2252   }
2253 
2254   pos = 0;
2255 
2256   while (!osip_list_eol(&sdp->t_descrs, pos)) {
2257     sdp_time_descr_t *header = (sdp_time_descr_t *) osip_list_get(&sdp->t_descrs, pos);
2258     char *next_tmp;
2259     int i;
2260 
2261     i = sdp_append_time_descr(&string, &size, tmp, header, &next_tmp);
2262 
2263     if (i != 0) {
2264       osip_free(string);
2265       return -1;
2266     }
2267 
2268     tmp = next_tmp;
2269     pos++;
2270   }
2271 
2272   if (sdp->z_adjustments != NULL) {
2273     tmp = __osip_sdp_append_string(&string, &size, tmp, "z=");
2274     tmp = __osip_sdp_append_string(&string, &size, tmp, sdp->z_adjustments);
2275     tmp = __osip_sdp_append_string(&string, &size, tmp, OSIP_CRLF);
2276   }
2277 
2278   if (sdp->k_key != NULL) {
2279     char *next_tmp;
2280     int i;
2281 
2282     i = sdp_append_key(&string, &size, tmp, sdp->k_key, &next_tmp);
2283 
2284     if (i != 0) {
2285       osip_free(string);
2286       return -1;
2287     }
2288 
2289     tmp = next_tmp;
2290   }
2291 
2292   pos = 0;
2293 
2294   while (!osip_list_eol(&sdp->a_attributes, pos)) {
2295     sdp_attribute_t *header = (sdp_attribute_t *) osip_list_get(&sdp->a_attributes, pos);
2296     char *next_tmp;
2297     int i;
2298 
2299     i = sdp_append_attribute(&string, &size, tmp, header, &next_tmp);
2300 
2301     if (i != 0) {
2302       osip_free(string);
2303       return -1;
2304     }
2305 
2306     tmp = next_tmp;
2307     pos++;
2308   }
2309 
2310   pos = 0;
2311 
2312   while (!osip_list_eol(&sdp->m_medias, pos)) {
2313     sdp_media_t *header = (sdp_media_t *) osip_list_get(&sdp->m_medias, pos);
2314     char *next_tmp;
2315     int i;
2316 
2317     i = sdp_append_media(&string, &size, tmp, header, &next_tmp);
2318 
2319     if (i != 0) {
2320       osip_free(string);
2321       return -1;
2322     }
2323 
2324     tmp = next_tmp;
2325     pos++;
2326   }
2327 
2328   *dest = string;
2329   return OSIP_SUCCESS;
2330 }
2331 
sdp_message_free(sdp_message_t * sdp)2332 void sdp_message_free(sdp_message_t *sdp) {
2333   if (sdp == NULL)
2334     return;
2335 
2336   osip_free(sdp->v_version);
2337   osip_free(sdp->o_username);
2338   osip_free(sdp->o_sess_id);
2339   osip_free(sdp->o_sess_version);
2340   osip_free(sdp->o_nettype);
2341   osip_free(sdp->o_addrtype);
2342   osip_free(sdp->o_addr);
2343   osip_free(sdp->s_name);
2344   osip_free(sdp->i_info);
2345   osip_free(sdp->u_uri);
2346 
2347   osip_list_ofchar_free(&sdp->e_emails);
2348 
2349   osip_list_ofchar_free(&sdp->p_phones);
2350 
2351   sdp_connection_free(sdp->c_connection);
2352 
2353   osip_list_special_free(&sdp->b_bandwidths, (void (*)(void *)) & sdp_bandwidth_free);
2354 
2355   osip_list_special_free(&sdp->t_descrs, (void (*)(void *)) & sdp_time_descr_free);
2356 
2357   osip_free(sdp->z_adjustments);
2358   sdp_key_free(sdp->k_key);
2359 
2360   osip_list_special_free(&sdp->a_attributes, (void (*)(void *)) & sdp_attribute_free);
2361 
2362   osip_list_special_free(&sdp->m_medias, (void (*)(void *)) & sdp_media_free);
2363 
2364   osip_free(sdp);
2365 }
2366 
sdp_message_clone(sdp_message_t * sdp,sdp_message_t ** dest)2367 int sdp_message_clone(sdp_message_t *sdp, sdp_message_t **dest) {
2368   int i;
2369   char *body;
2370 
2371   i = sdp_message_init(dest);
2372 
2373   if (i != 0)
2374     return -1;
2375 
2376   i = sdp_message_to_str(sdp, &body);
2377 
2378   if (i != 0)
2379     goto error_sc1;
2380 
2381   i = sdp_message_parse(*dest, body);
2382   osip_free(body);
2383 
2384   if (i != 0)
2385     goto error_sc1;
2386 
2387   return OSIP_SUCCESS;
2388 
2389 error_sc1:
2390   sdp_message_free(*dest);
2391   return -1;
2392 }
2393