| /* GStreamer |
| * Copyright (C) <2005> Wim Taymans <wim@fluendo.com> |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with this library; if not, write to the |
| * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| * Boston, MA 02111-1307, USA. |
| */ |
| |
| /** |
| * SECTION:gstnetbuffer |
| * @short_description: Buffer for use in network sources and sinks |
| * |
| * #GstNetBuffer is a subclass of a normal #GstBuffer that contains two |
| * additional metadata fields of type #GstNetAddress named 'to' and 'from'. The |
| * buffer can be used to store additional information about the origin of the |
| * buffer data and is used in various network elements to track the to and from |
| * addresses. |
| * |
| * Last reviewed on 2006-08-21 (0.10.10) |
| */ |
| |
| #include <string.h> |
| |
| #include "gstnetbuffer.h" |
| |
| static void |
| meta_net_address_copy (GstBuffer * copybuf, GstMetaNetAddress * meta, |
| GstBuffer * buffer, gsize offset, gsize size) |
| { |
| GstMetaNetAddress *naddr; |
| |
| naddr = gst_buffer_add_meta_net_address (copybuf); |
| memcpy (&naddr->naddr, &meta->naddr, sizeof (meta->naddr)); |
| } |
| |
| const GstMetaInfo * |
| gst_meta_net_address_get_info (void) |
| { |
| static const GstMetaInfo *meta_info = NULL; |
| |
| if (meta_info == NULL) { |
| meta_info = gst_meta_register ("GstMetaNetAddress", "GstMetaNetAddress", |
| sizeof (GstMetaNetAddress), |
| (GstMetaInitFunction) NULL, |
| (GstMetaFreeFunction) NULL, |
| (GstMetaCopyFunction) meta_net_address_copy, |
| (GstMetaTransformFunction) NULL); |
| } |
| return meta_info; |
| } |
| |
| /** |
| * gst_netaddress_set_ip4_address: |
| * @naddr: a network address |
| * @address: an IPv4 network address. |
| * @port: a port number to set. |
| * |
| * Set @naddr with the IPv4 @address and @port pair. |
| * |
| * Note that @port and @address must be expressed in network byte order, |
| * use g_htons() and g_htonl() to convert them to network byte order. |
| */ |
| void |
| gst_netaddress_set_ip4_address (GstNetAddress * naddr, guint32 address, |
| guint16 port) |
| { |
| g_return_if_fail (naddr != NULL); |
| |
| naddr->type = GST_NET_TYPE_IP4; |
| naddr->address.ip4 = address; |
| naddr->port = port; |
| } |
| |
| /** |
| * gst_netaddress_set_ip6_address: |
| * @naddr: a network address |
| * @address: an IPv6 network address. |
| * @port: a port number to set. |
| * |
| * Set @naddr with the IPv6 @address and @port pair. |
| * |
| * Note that @port must be expressed in network byte order, use g_htons() to convert |
| * it to network byte order. |
| */ |
| void |
| gst_netaddress_set_ip6_address (GstNetAddress * naddr, guint8 address[16], |
| guint16 port) |
| { |
| g_return_if_fail (naddr != NULL); |
| |
| naddr->type = GST_NET_TYPE_IP6; |
| memcpy (&naddr->address.ip6, address, 16); |
| naddr->port = port; |
| } |
| |
| /** |
| * gst_netaddress_get_net_type: |
| * @naddr: a network address |
| * |
| * Get the type of address stored in @naddr. |
| * |
| * Returns: the network type stored in @naddr. |
| */ |
| GstNetType |
| gst_netaddress_get_net_type (const GstNetAddress * naddr) |
| { |
| g_return_val_if_fail (naddr != NULL, GST_NET_TYPE_UNKNOWN); |
| |
| return naddr->type; |
| } |
| |
| /** |
| * gst_netaddress_get_ip4_address: |
| * @naddr: a network address |
| * @address: a location to store the address. |
| * @port: a location to store the port. |
| * |
| * Get the IPv4 address stored in @naddr into @address. This function requires |
| * that the address type of @naddr is of type #GST_NET_TYPE_IP4. |
| * |
| * Note that @port and @address are expressed in network byte order, use |
| * g_ntohs() and g_ntohl() to convert them to host order. |
| * |
| * Returns: TRUE if the address could be retrieved. |
| */ |
| gboolean |
| gst_netaddress_get_ip4_address (const GstNetAddress * naddr, guint32 * address, |
| guint16 * port) |
| { |
| g_return_val_if_fail (naddr != NULL, FALSE); |
| |
| if (naddr->type == GST_NET_TYPE_UNKNOWN || naddr->type == GST_NET_TYPE_IP6) |
| return FALSE; |
| |
| if (address) |
| *address = naddr->address.ip4; |
| if (port) |
| *port = naddr->port; |
| |
| return TRUE; |
| } |
| |
| /** |
| * gst_netaddress_get_ip6_address: |
| * @naddr: a network address |
| * @address: a location to store the result. |
| * @port: a location to store the port. |
| * |
| * Get the IPv6 address stored in @naddr into @address. |
| * |
| * If @naddr is of type GST_NET_TYPE_IP4, the transitional IP6 address is |
| * returned. |
| * |
| * Note that @port is expressed in network byte order, use g_ntohs() to convert |
| * it to host order. |
| * |
| * Returns: TRUE if the address could be retrieved. |
| */ |
| gboolean |
| gst_netaddress_get_ip6_address (const GstNetAddress * naddr, guint8 address[16], |
| guint16 * port) |
| { |
| static guint8 ip4_transition[16] = |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF }; |
| g_return_val_if_fail (naddr != NULL, FALSE); |
| |
| if (naddr->type == GST_NET_TYPE_UNKNOWN) |
| return FALSE; |
| |
| if (address) { |
| if (naddr->type == GST_NET_TYPE_IP6) { |
| memcpy (address, naddr->address.ip6, 16); |
| } else { /* naddr->type == GST_NET_TYPE_IP4 */ |
| memcpy (address, ip4_transition, 12); |
| memcpy (address + 12, (guint8 *) & (naddr->address.ip4), 4); |
| } |
| } |
| if (port) |
| *port = naddr->port; |
| |
| return TRUE; |
| } |
| |
| /** |
| * gst_netaddress_get_address_bytes: |
| * @naddr: a network address |
| * @address: a location to store the result. |
| * @port: a location to store the port. |
| * |
| * Get just the address bytes stored in @naddr into @address. |
| * |
| * Note that @port is expressed in network byte order, use g_ntohs() to convert |
| * it to host order. IP4 addresses are also stored in network byte order. |
| * |
| * Returns: number of bytes actually copied |
| * |
| * Since: 0.10.22 |
| */ |
| gint |
| gst_netaddress_get_address_bytes (const GstNetAddress * naddr, |
| guint8 address[16], guint16 * port) |
| { |
| gint ret = 0; |
| |
| g_return_val_if_fail (naddr != NULL, FALSE); |
| |
| if (naddr->type == GST_NET_TYPE_UNKNOWN) |
| return 0; |
| |
| if (address) { |
| if (naddr->type == GST_NET_TYPE_IP6) { |
| memcpy (address, naddr->address.ip6, 16); |
| ret = 16; |
| } else { /* naddr->type == GST_NET_TYPE_IP4 */ |
| memcpy (address, (guint8 *) & (naddr->address.ip4), 4); |
| ret = 4; |
| } |
| } |
| if (port) |
| *port = naddr->port; |
| |
| return ret; |
| } |
| |
| /** |
| * gst_netaddress_set_address_bytes: |
| * @naddr: a network address |
| * @type: the address type (IPv4 or IPV6) |
| * @address: a location to store the result. |
| * @port: a location to store the port. |
| * |
| * Set just the address bytes stored in @naddr into @address. |
| * |
| * Note that @port must be expressed in network byte order, use g_htons() to |
| * convert it to network byte order order. IP4 address bytes must also be |
| * stored in network byte order. |
| * |
| * Returns: number of bytes actually copied |
| * |
| * Since: 0.10.22 |
| */ |
| gint |
| gst_netaddress_set_address_bytes (GstNetAddress * naddr, GstNetType type, |
| guint8 address[16], guint16 port) |
| { |
| gint len = 0; |
| |
| g_return_val_if_fail (naddr != NULL, 0); |
| |
| naddr->type = type; |
| switch (naddr->type) { |
| case GST_NET_TYPE_UNKNOWN: |
| case GST_NET_TYPE_IP6: |
| len = 16; |
| memcpy (naddr->address.ip6, address, 16); |
| break; |
| case GST_NET_TYPE_IP4: |
| len = 4; |
| memcpy ((guint8 *) & (naddr->address.ip4), address, 4); |
| break; |
| } |
| |
| if (port) |
| naddr->port = port; |
| |
| return len; |
| } |
| |
| /** |
| * gst_netaddress_equal: |
| * @naddr1: The first #GstNetAddress |
| * @naddr2: The second #GstNetAddress |
| * |
| * Compare two #GstNetAddress structures |
| * |
| * Returns: TRUE if they are identical, FALSE otherwise |
| * |
| * Since: 0.10.18 |
| */ |
| gboolean |
| gst_netaddress_equal (const GstNetAddress * naddr1, |
| const GstNetAddress * naddr2) |
| { |
| g_return_val_if_fail (naddr1 != NULL, FALSE); |
| g_return_val_if_fail (naddr2 != NULL, FALSE); |
| |
| if (naddr1->type != naddr2->type) |
| return FALSE; |
| |
| if (naddr1->port != naddr2->port) |
| return FALSE; |
| |
| switch (naddr1->type) { |
| case GST_NET_TYPE_IP4: |
| if (naddr1->address.ip4 != naddr2->address.ip4) |
| return FALSE; |
| break; |
| case GST_NET_TYPE_IP6: |
| if (memcmp (naddr1->address.ip6, naddr2->address.ip6, |
| sizeof (naddr1->address.ip6))) |
| return FALSE; |
| break; |
| default: |
| break; |
| } |
| return TRUE; |
| } |
| |
| /** |
| * gst_netaddress_to_string: |
| * @naddr: a #GstNetAddress |
| * @dest: destination |
| * @len: len of @dest |
| * |
| * Copies a string representation of @naddr into @dest. Up to @len bytes are |
| * copied. |
| * |
| * Returns: the number of bytes which would be produced if the buffer was large |
| * enough |
| * |
| * Since: 0.10.24 |
| */ |
| gint |
| gst_netaddress_to_string (const GstNetAddress * naddr, gchar * dest, gulong len) |
| { |
| gint result; |
| |
| g_return_val_if_fail (naddr != NULL, FALSE); |
| g_return_val_if_fail (dest != NULL, FALSE); |
| |
| switch (naddr->type) { |
| case GST_NET_TYPE_IP4: |
| { |
| guint32 address; |
| guint16 port; |
| |
| gst_netaddress_get_ip4_address (naddr, &address, &port); |
| address = g_ntohl (address); |
| |
| result = g_snprintf (dest, len, "%d.%d.%d.%d:%d", (address >> 24) & 0xff, |
| (address >> 16) & 0xff, (address >> 8) & 0xff, address & 0xff, |
| g_ntohs (port)); |
| break; |
| } |
| case GST_NET_TYPE_IP6: |
| { |
| guint8 address[16]; |
| guint16 port; |
| |
| gst_netaddress_get_ip6_address (naddr, address, &port); |
| |
| result = |
| g_snprintf (dest, len, "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%d", |
| (address[0] << 8) | address[1], (address[2] << 8) | address[3], |
| (address[4] << 8) | address[5], (address[6] << 8) | address[7], |
| (address[8] << 8) | address[9], (address[10] << 8) | address[11], |
| (address[12] << 8) | address[13], (address[14] << 8) | address[15], |
| g_ntohs (port)); |
| break; |
| } |
| default: |
| dest[0] = 0; |
| result = 0; |
| break; |
| } |
| return result; |
| } |