static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf, size_t size, loff_t *pos) { int status; void *wbuf; struct rmnet_ctrl_dev *dev = file->private_data; if (!dev) return -ENODEV; if (size <= 0) return -EINVAL; if (!is_dev_connected(dev)) return -ENETRESET; DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name); wbuf = kmalloc(size , GFP_KERNEL); if (!wbuf) return -ENOMEM; status = copy_from_user(wbuf , buf, size); if (status) { dev_err(dev->devicep, "%s: Unable to copy data from userspace %d\n", __func__, status); kfree(wbuf); return status; } DUMP_BUFFER("Write: ", size, buf); status = rmnet_usb_ctrl_write(dev, wbuf, size); if (status == size) return size; return status; }
static ACPI_STATUS AcpiNsDumpOneObject ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; ACPI_NAMESPACE_NODE *ThisNode; UINT8 *Value; ACPI_OPERAND_OBJECT *ObjDesc = NULL; ACPI_OBJECT_TYPE8 ObjType; ACPI_OBJECT_TYPE8 Type; UINT32 BytesToDump; UINT32 DownstreamSiblingMask = 0; UINT32 LevelTmp; UINT32 WhichBit; PROC_NAME ("NsDumpOneObject"); ThisNode = AcpiNsConvertHandleToEntry (ObjHandle); LevelTmp = Level; Type = ThisNode->Type; WhichBit = 1; if (!(AcpiDbgLevel & Info->DebugLevel)) { return (AE_OK); } if (!ObjHandle) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n")); return (AE_OK); } /* Check if the owner matches */ if ((Info->OwnerId != ACPI_UINT32_MAX) && (Info->OwnerId != ThisNode->OwnerId)) { return (AE_OK); } /* Indent the object according to the level */ while (LevelTmp--) { /* Print appropriate characters to form tree structure */ if (LevelTmp) { if (DownstreamSiblingMask & WhichBit) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|")); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); } WhichBit <<= 1; } else { if (AcpiNsExistDownstreamSibling (ThisNode + 1)) { DownstreamSiblingMask |= (1 << (Level - 1)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } else { DownstreamSiblingMask &= ACPI_UINT32_MAX ^ (1 << (Level - 1)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } if (ThisNode->Child == NULL) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); } else if (AcpiNsExistDownstreamSibling (ThisNode->Child)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); } } } /* Check the integrity of our data */ if (Type > INTERNAL_TYPE_MAX) { Type = INTERNAL_TYPE_DEF_ANY; /* prints as *ERROR* */ } if (!AcpiUtValidAcpiName (ThisNode->Name)) { REPORT_WARNING (("Invalid ACPI Name %08X\n", ThisNode->Name)); } /* * Now we can print out the pertinent information */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-9s ", &ThisNode->Name, AcpiUtGetTypeName (Type))); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p S:%p O:%p", ThisNode, ThisNode->Child, ThisNode->Object)); if (!ThisNode->Object) { /* No attached object, we are done */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); return (AE_OK); } switch (Type) { case ACPI_TYPE_METHOD: /* Name is a Method and its AML offset/length are set */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Method.Pcode, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Method.PcodeLength)); break; case ACPI_TYPE_INTEGER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Integer.Value)); break; case ACPI_TYPE_STRING: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->String.Pointer, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->String.Length)); break; case ACPI_TYPE_BUFFER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Buffer.Pointer, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Buffer.Length)); break; default: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); break; } /* If debug turned off, done */ if (!(AcpiDbgLevel & ACPI_LV_VALUES)) { return (AE_OK); } /* If there is an attached object, display it */ Value = ThisNode->Object; /* Dump attached objects */ while (Value) { ObjType = INTERNAL_TYPE_INVALID; /* Decode the type of attached object and dump the contents */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Attached Object %p: ", Value)); if (AcpiTbSystemTablePointer (Value)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to AML Code)\n")); BytesToDump = 16; } else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n")); BytesToDump = sizeof (ACPI_NAMESPACE_NODE); } else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_INTERNAL)) { ObjDesc = (ACPI_OPERAND_OBJECT *) Value; ObjType = ObjDesc->Common.Type; if (ObjType > INTERNAL_TYPE_MAX) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", ObjType)); BytesToDump = 32; } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [%s])\n", ObjType, AcpiUtGetTypeName (ObjType))); BytesToDump = sizeof (ACPI_OPERAND_OBJECT); } } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n", Value)); BytesToDump = 16; } DUMP_BUFFER (Value, BytesToDump); /* If value is NOT an internal object, we are done */ if ((AcpiTbSystemTablePointer (Value)) || (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED))) { goto Cleanup; } /* * Valid object, get the pointer to next level, if any */ switch (ObjType) { case ACPI_TYPE_STRING: Value = (UINT8 *) ObjDesc->String.Pointer; break; case ACPI_TYPE_BUFFER: Value = (UINT8 *) ObjDesc->Buffer.Pointer; break; case ACPI_TYPE_BUFFER_FIELD: Value = (UINT8 *) ObjDesc->BufferField.BufferObj; break; case ACPI_TYPE_PACKAGE: Value = (UINT8 *) ObjDesc->Package.Elements; break; case ACPI_TYPE_METHOD: Value = (UINT8 *) ObjDesc->Method.Pcode; break; case INTERNAL_TYPE_REGION_FIELD: Value = (UINT8 *) ObjDesc->Field.RegionObj; break; case INTERNAL_TYPE_BANK_FIELD: Value = (UINT8 *) ObjDesc->BankField.RegionObj; break; case INTERNAL_TYPE_INDEX_FIELD: Value = (UINT8 *) ObjDesc->IndexField.IndexObj; break; default: goto Cleanup; } ObjType = INTERNAL_TYPE_INVALID; /* Terminate loop after next pass */ } Cleanup: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); return (AE_OK); }
/* * PROXY_REWRITE_INVITATION_BODY * * rewrites the outgoing INVITATION request or response packet * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){ osip_body_t *body; sdp_message_t *sdp; struct in_addr map_addr, addr_sess, addr_media, outside_addr, inside_addr; int sts; char *bodybuff; int bodybuflen; char clen[8]; /* content length: probably never more than 7 digits !*/ int map_port, msg_port; int media_stream_no; sdp_connection_t *sdp_conn; sdp_media_t *sdp_med; int rtp_direction=0; int have_c_media=0; if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS; /* * get SDP structure */ sts = osip_message_get_body(mymsg, 0, &body); if (sts != 0) { #if 0 if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) && (MSG_IS_STATUS_1XX(mymsg))) { /* 1xx responses *MAY* contain SDP data */ DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: " "no body found in message"); return STS_SUCCESS; } else { /* INVITE request and 200 response *MUST* contain SDP data */ ERROR("rewrite_invitation_body: no body found in message"); return STS_FAILURE; } #else DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: " "no body found in message"); return STS_SUCCESS; #endif } sts = sip_body_to_str(body, &bodybuff, &bodybuflen); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sip_body_to_str"); } sts = sdp_message_init(&sdp); sts = sdp_message_parse (sdp, bodybuff); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sdp_message_parse body"); DUMP_BUFFER(-1, bodybuff, bodybuflen); osip_free(bodybuff); sdp_message_free(sdp); return STS_FAILURE; } osip_free(bodybuff); if (configuration.debuglevel) { /* just dump the buffer */ char *tmp, *tmp2; int tmplen; sts = osip_message_get_body(mymsg, 0, &body); sts = sip_body_to_str(body, &tmp, &tmplen); osip_content_length_to_str(mymsg->content_length, &tmp2); DEBUG("Body before rewrite (clen=%s, strlen=%i):\n%s\n----", tmp2, tmplen, tmp); osip_free(tmp); osip_free(tmp2); } /* * RTP proxy: get ready and start forwarding * start forwarding for each media stream ('m=' item in SIP message) */ /* get outbound address */ if (get_interface_ip(IF_OUTBOUND, &outside_addr) != STS_SUCCESS) { sdp_message_free(sdp); return STS_FAILURE; } /* get inbound address */ if (get_interface_ip(IF_INBOUND, &inside_addr) != STS_SUCCESS) { sdp_message_free(sdp); return STS_FAILURE; } /* figure out what address to use for RTP masquerading */ if (MSG_IS_REQUEST(mymsg)) { if (direction == DIR_INCOMING) { memcpy(&map_addr, &inside_addr, sizeof (map_addr)); rtp_direction = DIR_OUTGOING; } else { memcpy(&map_addr, &outside_addr, sizeof (map_addr)); rtp_direction = DIR_INCOMING; } } else /* MSG_IS_REPONSE(mymsg) */ { if (direction == DIR_INCOMING) { memcpy(&map_addr, &inside_addr, sizeof (map_addr)); rtp_direction = DIR_OUTGOING; } else { memcpy(&map_addr, &outside_addr, sizeof (map_addr)); rtp_direction = DIR_INCOMING; } } DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: SIP[%s %s] RTP[%s %s]", MSG_IS_REQUEST(mymsg)? "RQ" : "RS", (direction==DIR_INCOMING)? "IN" : "OUT", (rtp_direction==DIR_INCOMING)? "IN" : "OUT", utils_inet_ntoa(map_addr)); /* * first, check presence of a 'c=' item on session level */ if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) { /* * No 'c=' on session level, search on media level now * * According to RFC2327, ALL media description must * include a 'c=' item now: */ media_stream_no=0; while (!sdp_message_endof_media(sdp, media_stream_no)) { /* check if n'th media stream is present */ if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) { ERROR("SDP: have no 'c=' on session level and neither " "on media level (media=%i)",media_stream_no); sdp_message_free(sdp); return STS_FAILURE; } media_stream_no++; } /* while */ } /* Required 'c=' items ARE present */ /* * rewrite 'c=' item on session level if present and not yet done. * remember the original address in addr_sess */ memset(&addr_sess, 0, sizeof(addr_sess)); if (sdp->c_connection && sdp->c_connection->c_addr) { sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess); if (sts == STS_FAILURE) { ERROR("SDP: cannot resolve session 'c=' host [%s]", sdp->c_connection->c_addr); sdp_message_free(sdp); return STS_FAILURE; } /* * Rewrite * an IP address of 0.0.0.0 means *MUTE*, don't rewrite such */ if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) { osip_free(sdp->c_connection->c_addr); sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr)); } else { /* 0.0.0.0 - don't rewrite */ DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "got a MUTE c= record (on session level - legal?)"); } } /* * rewrite 'o=' item (originator) on session level if present. */ if (sdp->o_addrtype && sdp->o_addr) { if (strcmp(sdp->o_addrtype, "IP4") != 0) { ERROR("got IP6 in SDP originator - not yet suported by siproxd"); sdp_message_free(sdp); return STS_FAILURE; } osip_free(sdp->o_addr); sdp->o_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp->o_addr, "%s", utils_inet_ntoa(map_addr)); } /* * loop through all media descritions, * start RTP proxy and rewrite them */ for (media_stream_no=0;;media_stream_no++) { /* check if n'th media stream is present */ if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break; /* * check if a 'c=' item is present in this media description, * if so -> rewrite it */ memset(&addr_media, 0, sizeof(addr_media)); have_c_media=0; sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0); if (sdp_conn && sdp_conn->c_addr) { if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) { sts = get_ip_by_host(sdp_conn->c_addr, &addr_media); have_c_media=1; /* have a valid address */ osip_free(sdp_conn->c_addr); sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr)); } else { /* 0.0.0.0 - don't rewrite */ DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a " "MUTE c= record (media level)"); } } /* start an RTP proxying stream */ if (sdp_message_m_port_get(sdp, media_stream_no)) { msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no)); if (msg_port > 0) { osip_uri_t *cont_url = NULL; char *client_id=NULL; /* try to get some additional UA specific unique ID. * Try: * 1) User part of Contact header * 2) Host part of Contact header (will be different * between internal UA and external UA) */ if (!osip_list_eol(mymsg->contacts, 0)) cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url; if (cont_url) { client_id=cont_url->username; if (client_id == NULL) client_id=cont_url->host; } /* * do we have a 'c=' item on media level? * if not, use the same as on session level */ if (have_c_media == 0) { memcpy(&addr_media, &addr_sess, sizeof(addr_sess)); } /* * Am I running in front of the routing device? Then I cannot * use the external IP to bind a listen socket to, so force * the use of my inbound IP for listening. */ if ((rtp_direction == DIR_INCOMING) && (configuration.outbound_host) && (strcmp(configuration.outbound_host, "")!=0)) { DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "in-front-of-NAT-Router"); memcpy(&map_addr, &inside_addr, sizeof (map_addr)); } sts = rtp_start_fwd(osip_message_get_call_id(mymsg), client_id, rtp_direction, media_stream_no, map_addr, &map_port, addr_media, msg_port); if (sts == STS_SUCCESS) { /* and rewrite the port */ sdp_med=osip_list_get(sdp->m_medias, media_stream_no); if (sdp_med && sdp_med->m_port) { osip_free(sdp_med->m_port); sdp_med->m_port=osip_malloc(8); /* 5 digits, \0 + align */ sprintf(sdp_med->m_port, "%i", map_port); DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "m= rewrote port to [%i]",map_port); } else { ERROR("rewriting port in m= failed sdp_med=%p, " "m_number_of_port=%p", sdp_med, sdp_med->m_port); } } /* sts == success */ } /* if msg_port > 0 */ } else { /* no port defined - skip entry */ WARN("no port defined in m=(media) stream_no=%i", media_stream_no); continue; } } /* for media_stream_no */ /* remove old body */ sts = osip_list_remove(mymsg->bodies, 0); osip_body_free(body); /* dump new body */ sdp_message_to_str(sdp, &bodybuff); bodybuflen=strlen(bodybuff); /* free sdp structure */ sdp_message_free(sdp); /* include new body */ sip_message_set_body(mymsg, bodybuff, bodybuflen); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sip_message_set_body body"); } /* free content length resource and include new one*/ osip_content_length_free(mymsg->content_length); mymsg->content_length=NULL; sprintf(clen,"%i",bodybuflen); sts = osip_message_set_content_length(mymsg, clen); /* free old body */ osip_free(bodybuff); if (configuration.debuglevel) { /* just dump the buffer */ char *tmp, *tmp2; int tmplen; sts = osip_message_get_body(mymsg, 0, &body); sts = sip_body_to_str(body, &tmp, &tmplen); osip_content_length_to_str(mymsg->content_length, &tmp2); DEBUG("Body after rewrite (clen=%s, strlen=%i):\n%s\n----", tmp2, tmplen, tmp); osip_free(tmp); osip_free(tmp2); } return STS_SUCCESS; }
ACPI_STATUS AcpiDbLoadTable( FILE *fp, ACPI_TABLE_HEADER **TablePtr, UINT32 *TableLength) { ACPI_TABLE_HEADER TableHeader; UINT8 *AmlPtr; UINT32 AmlLength; UINT32 Actual; ACPI_STATUS Status; /* Read the table header */ if (fread (&TableHeader, 1, sizeof (TableHeader), fp) != sizeof (ACPI_TABLE_HEADER)) { AcpiOsPrintf ("Couldn't read the table header\n"); return (AE_BAD_SIGNATURE); } /* Validate the table header/length */ Status = AcpiTbValidateTableHeader (&TableHeader); if ((ACPI_FAILURE (Status)) || (TableHeader.Length > 524288)) /* 1/2 Mbyte should be enough */ { AcpiOsPrintf ("Table header is invalid!\n"); return (AE_ERROR); } /* We only support a limited number of table types */ if (STRNCMP ((char *) TableHeader.Signature, DSDT_SIG, 4) && STRNCMP ((char *) TableHeader.Signature, PSDT_SIG, 4) && STRNCMP ((char *) TableHeader.Signature, SSDT_SIG, 4)) { AcpiOsPrintf ("Table signature is invalid\n"); DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER)); return (AE_ERROR); } /* Allocate a buffer for the table */ *TableLength = TableHeader.Length; *TablePtr = ACPI_MEM_ALLOCATE ((size_t) *TableLength); if (!*TablePtr) { AcpiOsPrintf ("Could not allocate memory for ACPI table %4.4s (size=%X)\n", TableHeader.Signature, TableHeader.Length); return (AE_NO_MEMORY); } AmlPtr = (UINT8 *) *TablePtr + sizeof (TableHeader); AmlLength = *TableLength - sizeof (TableHeader); /* Copy the header to the buffer */ MEMCPY (*TablePtr, &TableHeader, sizeof (TableHeader)); /* Get the rest of the table */ Actual = fread (AmlPtr, 1, (size_t) AmlLength, fp); if (Actual == AmlLength) { return (AE_OK); } if (Actual > 0) { AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n", AmlLength, Actual); return (AE_OK); } AcpiOsPrintf ("Error - could not read the table file\n"); ACPI_MEM_FREE (*TablePtr); *TablePtr = NULL; *TableLength = 0; return (AE_ERROR); }
static ssize_t rmnet_ctl_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int retval = 0; int bytes_to_read; struct rmnet_ctrl_dev *dev; struct ctrl_pkt_list_elem *list_elem = NULL; unsigned long flags; char temp[100]; dev = file->private_data; if (!dev) return -ENODEV; DBG("%s: Read from %s\n", __func__, dev->name); ctrl_read: if (!is_dev_connected(dev)) { dev_dbg(dev->devicep, "%s: Device not connected\n", __func__); return -ENETRESET; } spin_lock_irqsave(&dev->rx_lock, flags); if (list_empty(&dev->rx_list)) { spin_unlock_irqrestore(&dev->rx_lock, flags); retval = wait_event_interruptible(dev->read_wait_queue, !list_empty(&dev->rx_list) || !is_dev_connected(dev)); if (retval < 0) return retval; goto ctrl_read; } list_elem = list_first_entry(&dev->rx_list, struct ctrl_pkt_list_elem, list); bytes_to_read = (uint32_t)(list_elem->cpkt.data_size); if (bytes_to_read > count) { spin_unlock_irqrestore(&dev->rx_lock, flags); dev_err(dev->devicep, "%s: Packet size %d > buf size %d\n", __func__, bytes_to_read, count); return -ENOMEM; } spin_unlock_irqrestore(&dev->rx_lock, flags); if (copy_to_user(buf, list_elem->cpkt.data, bytes_to_read)) { dev_err(dev->devicep, "%s: copy_to_user failed for %s\n", __func__, dev->name); return -EFAULT; } spin_lock_irqsave(&dev->rx_lock, flags); list_del(&list_elem->list); spin_unlock_irqrestore(&dev->rx_lock, flags); kfree(list_elem->cpkt.data); kfree(list_elem); DBG("%s: Returning %d bytes to %s\n", __func__, bytes_to_read, dev->name); snprintf(temp, sizeof(temp), "[%lluns]READ :", rd_poll_delta_time); DUMP_BUFFER(temp, bytes_to_read, buf); return bytes_to_read; }
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf, size_t size, loff_t *pos) { int status; size_t total_len; void *wbuf; void *actual_data; struct ctrl_pkt *cpkt; struct rmnet_ctrl_dev *dev = file->private_data; rewrite: if (!dev) return -ENODEV; if (!size) return -EINVAL; if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) return -ENETRESET; DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name); total_len = size; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4); wbuf = kmalloc(total_len , GFP_KERNEL); if (!wbuf) return -ENOMEM; cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL); if (!cpkt) { kfree(wbuf); return -ENOMEM; } actual_data = cpkt->data = wbuf; cpkt->data_size = total_len; cpkt->ctxt = dev; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) { actual_data = wbuf + sizeof(struct mux_hdr); rmnet_usb_ctrl_mux(dev->ch_id, cpkt); } status = copy_from_user(actual_data, buf, size); if (status) { dev_err(dev->devicep, "%s: Unable to copy data from userspace %d\n", __func__, status); kfree(wbuf); kfree(cpkt); return status; } DUMP_BUFFER("Write: ", size, buf); status = rmnet_usb_ctrl_write(dev, cpkt, size); if (status == size) return size; else if (status == -EAGAIN) { dev_err(dev->devicep, "%s: rewrite\n", __func__); goto rewrite; } return status; }
// TODO: these tests suck bool test_buffer_printf () { size_t n = 0; buffer_t *buf = buffer_new(); if (!buf) { FAIL("buffer_new() failed\n"); } n = buffer_printf(buf, "%s", "Hello, world!"); DUMP_BUFFER(); printf("n: %lu, strlen(\"Hello, world!\"): %lu\n", n, strlen("Hello, world!")); if (n != strlen("Hello, world!")) { FAIL("buffer_printf() \"Hello world!\" failed\n"); } n = buffer_printf(buf, "%d %d", 345, 543); DUMP_BUFFER(); printf("n: %lu, strlen(\"345 543\"): %lu\n", n, strlen("345 543")); if (n != strlen("345 543")) { FAIL("buffer_printf() \"345 543\" failed\n"); } n = buffer_printf(buf, "%s", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ); DUMP_BUFFER(); if (n != strlen( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ) ) { FAIL("buffer_printf() - big print failed"); } PASS(); }
int main (int argc, char *argv[]) { int sts; int i; int buflen; int access; char buff [BUFFER_SIZE]; sip_ticket_t ticket; extern char *optarg; /* Defined in libc getopt and unistd.h */ int ch1; char configfile[64]="siproxd"; /* basename of configfile */ int config_search=1; /* search the config file */ int cmdline_debuglevel=0; char *pidfilename=NULL; struct sigaction act; log_set_stderr(1); /* * setup signal handlers */ act.sa_handler=sighandler; sigemptyset(&act.sa_mask); act.sa_flags=SA_RESTART; if (sigaction(SIGTERM, &act, NULL)) { ERROR("Failed to install SIGTERM handler"); } if (sigaction(SIGINT, &act, NULL)) { ERROR("Failed to install SIGINT handler"); } if (sigaction(SIGUSR2, &act, NULL)) { ERROR("Failed to install SIGUSR2 handler"); } /* * prepare default configuration */ make_default_config(); log_set_pattern(configuration.debuglevel); /* * parse command line */ { #ifdef HAVE_GETOPT_LONG int option_index = 0; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"config", required_argument, NULL, 'c'}, {"debug", required_argument, NULL, 'd'}, {"pid-file", required_argument, NULL,'p'}, {0,0,0,0} }; while ((ch1 = getopt_long(argc, argv, "hc:d:p:", long_options, &option_index)) != -1) { #else /* ! HAVE_GETOPT_LONG */ while ((ch1 = getopt(argc, argv, "hc:d:p:")) != -1) { #endif switch (ch1) { case 'h': /* help */ DEBUGC(DBCLASS_CONFIG,"option: help"); fprintf(stderr,str_helpmsg); exit(0); break; case 'c': /* load config file */ DEBUGC(DBCLASS_CONFIG,"option: config file=%s",optarg); i=sizeof(configfile)-1; strncpy(configfile,optarg,i-1); configfile[i]='\0'; config_search=0; break; case 'd': /* set debug level */ DEBUGC(DBCLASS_CONFIG,"option: set debug level: %s",optarg); cmdline_debuglevel=atoi(optarg); log_set_pattern(cmdline_debuglevel); break; case 'p': pidfilename = optarg; break; default: DEBUGC(DBCLASS_CONFIG,"no command line options"); break; } } } /* * Init stuff */ INFO(PACKAGE"-"VERSION"-"BUILDSTR" "UNAME" starting up"); /* read the config file */ if (read_config(configfile, config_search) == STS_FAILURE) exit(1); /* if a debug level > 0 has been given on the commandline use its value and not what is in the config file */ if (cmdline_debuglevel != 0) { configuration.debuglevel=cmdline_debuglevel; } /* * open a the pwfile instance, so we still have access after * we possibly have chroot()ed to somewhere. */ if (configuration.proxy_auth_pwfile) { siproxd_passwordfile = fopen(configuration.proxy_auth_pwfile, "r"); } else { siproxd_passwordfile = NULL; } /* set debug level as desired */ log_set_pattern(configuration.debuglevel); log_set_listen_port(configuration.debugport); /* change user and group IDs */ secure_enviroment(); /* daemonize if requested to */ if (configuration.daemonize) { DEBUGC(DBCLASS_CONFIG,"daemonizing"); if (fork()!=0) exit(0); setsid(); if (fork()!=0) exit(0); log_set_stderr(0); INFO("daemonized, pid=%i", getpid()); } /* write PID file of main thread */ if (pidfilename == NULL) pidfilename = configuration.pid_file; if (pidfilename) { FILE *pidfile; DEBUGC(DBCLASS_CONFIG,"creating PID file [%s]", pidfilename); sts=unlink(configuration.pid_file); if ((sts==0) ||(errno == ENOENT)) { if ((pidfile=fopen(pidfilename, "w"))) { fprintf(pidfile,"%i\n",(int)getpid()); fclose(pidfile); } else { WARN("couldn't create new PID file: %s", strerror(errno)); } } else { WARN("couldn't delete old PID file: %s", strerror(errno)); } } /* initialize the RTP proxy */ sts=rtpproxy_init(); if (sts != STS_SUCCESS) { ERROR("unable to initialize RTP proxy - aborting"); exit(1); } /* init the oSIP parser */ parser_init(); /* listen for incoming messages */ sts=sipsock_listen(); if (sts == STS_FAILURE) { /* failure to allocate SIP socket... */ ERROR("unable to bind to SIP listening socket - aborting"); exit(1); } /* initialize the registration facility */ register_init(); /* * silence the log - if so required... */ log_set_silence(configuration.silence_log); INFO(PACKAGE"-"VERSION"-"BUILDSTR" "UNAME" started"); /***************************** * Main loop *****************************/ while (!exit_program) { DEBUGC(DBCLASS_BABBLE,"going into sipsock_wait\n"); while (sipsock_wait()<=0) { /* got no input, here by timeout. do aging */ register_agemap(); /* TCP log: check for a connection */ log_tcp_connect(); /* dump memory stats if requested to do so */ if (dmalloc_dump) { dmalloc_dump=0; #ifdef DMALLOC INFO("SIGUSR2 - DMALLOC statistics is dumped"); dmalloc_log_stats(); dmalloc_log_unfreed(); #else INFO("SIGUSR2 - DMALLOC support is not compiled in"); #endif } if (exit_program) goto exit_prg; } /* * got input, process */ DEBUGC(DBCLASS_BABBLE,"back from sipsock_wait"); ticket.direction=0; buflen=sipsock_read(&buff, sizeof(buff)-1, &ticket.from, &ticket.protocol); buff[buflen]='\0'; /* * evaluate the access lists (IP based filter) */ access=accesslist_check(ticket.from); if (access == 0) { DEBUGC(DBCLASS_ACCESS,"access for this packet was denied"); continue; /* there are no resources to free */ } /* * integrity checks */ sts=security_check_raw(buff, buflen); if (sts != STS_SUCCESS) { DEBUGC(DBCLASS_SIP,"security check (raw) failed"); continue; /* there are no resources to free */ } /* * init sip_msg */ sts=osip_message_init(&ticket.sipmsg); ticket.sipmsg->message=NULL; if (sts != 0) { ERROR("osip_message_init() failed... this is not good"); continue; /* skip, there are no resources to free */ } /* * RFC 3261, Section 16.3 step 1 * Proxy Behavior - Request Validation - Reasonable Syntax * (parse the received message) */ sts=sip_message_parse(ticket.sipmsg, buff, buflen); if (sts != 0) { ERROR("sip_message_parse() failed... this is not good"); DUMP_BUFFER(-1, buff, buflen); goto end_loop; /* skip and free resources */ } /* * integrity checks - parsed buffer */ sts=security_check_sip(&ticket); if (sts != STS_SUCCESS) { ERROR("security_check_sip() failed... this is not good"); DUMP_BUFFER(-1, buff, buflen); goto end_loop; /* skip and free resources */ } /* * RFC 3261, Section 16.3 step 2 * Proxy Behavior - Request Validation - URI scheme * (check request URI and refuse with 416 if not understood) */ /* NOT IMPLEMENTED */ /* * RFC 3261, Section 16.3 step 3 * Proxy Behavior - Request Validation - Max-Forwards check * (check Max-Forwards header and refuse with 483 if too many hops) */ { osip_header_t *max_forwards; int forwards_count = DEFAULT_MAXFWD; osip_message_get_max_forwards(ticket.sipmsg, 0, &max_forwards); if (max_forwards && max_forwards->hvalue) { forwards_count = atoi(max_forwards->hvalue); } DEBUGC(DBCLASS_PROXY,"checking Max-Forwards (=%i)",forwards_count); if (forwards_count <= 0) { DEBUGC(DBCLASS_SIP, "Forward count reached 0 -> 483 response"); sip_gen_response(&ticket, 483 /*Too many hops*/); goto end_loop; /* skip and free resources */ } } /* * RFC 3261, Section 16.3 step 4 * Proxy Behavior - Request Validation - Loop Detection check * (check for loop and return 482 if a loop is detected) */ if (check_vialoop(&ticket) == STS_TRUE) { /* make sure we don't end up in endless loop when detecting * an loop in an "loop detected" message - brrr */ if (MSG_IS_RESPONSE(ticket.sipmsg) && MSG_TEST_CODE(ticket.sipmsg, 482)) { DEBUGC(DBCLASS_SIP,"loop in loop-response detected, ignoring"); } else { DEBUGC(DBCLASS_SIP,"via loop detected, ignoring request"); sip_gen_response(&ticket, 482 /*Loop detected*/); } goto end_loop; /* skip and free resources */ } /* * RFC 3261, Section 16.3 step 5 * Proxy Behavior - Request Validation - Proxy-Require check * (check Proxy-Require header and return 420 if unsupported option) */ /* NOT IMPLEMENTED */ /* * RFC 3261, Section 16.5 * Proxy Behavior - Determining Request Targets */ /* NOT IMPLEMENTED */ DEBUGC(DBCLASS_SIP,"received SIP type %s:%s", (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES", (MSG_IS_REQUEST(ticket.sipmsg) ? ((ticket.sipmsg->sip_method)? ticket.sipmsg->sip_method : "NULL") : ((ticket.sipmsg->reason_phrase) ? ticket.sipmsg->reason_phrase : "NULL"))); /********************************* * The message did pass all the * tests above and is now ready * to be proxied. * Before we do so, we apply some * additional preprocessing *********************************/ /* Dial shortcuts */ if (configuration.pi_shortdial) { sts = plugin_shortdial(&ticket); if (sts == STS_SIP_SENT) goto end_loop; } /********************************* * finally proxy the message. * This includes the masquerading * of the local UA and starting/ * stopping the RTP proxy for this * call *********************************/ /* * if a REQ REGISTER, check if it is directed to myself, * or am I just the outbound proxy but no registrar. * - If I'm the registrar, register & generate answer * - If I'm just the outbound proxy, register, rewrite & forward */ if (MSG_IS_REGISTER(ticket.sipmsg) && MSG_IS_REQUEST(ticket.sipmsg)) { if (access & ACCESSCTL_REG) { osip_uri_t *url; struct in_addr addr1, addr2, addr3; int dest_port; url = osip_message_get_uri(ticket.sipmsg); dest_port= (url->port)?atoi(url->port):SIP_PORT; if ( (get_ip_by_host(url->host, &addr1) == STS_SUCCESS) && (get_interface_ip(IF_INBOUND,&addr2) == STS_SUCCESS) && (get_interface_ip(IF_OUTBOUND,&addr3) == STS_SUCCESS)) { if ((configuration.sip_listen_port == dest_port) && ((memcmp(&addr1, &addr2, sizeof(addr1)) == 0) || (memcmp(&addr1, &addr3, sizeof(addr1)) == 0))) { /* I'm the registrar, send response myself */ sts = register_client(&ticket, 0); sts = register_response(&ticket, sts); } else { /* I'm just the outbound proxy */ DEBUGC(DBCLASS_SIP,"proxying REGISTER request to:%s", url->host); sts = register_client(&ticket, 1); if (sts == STS_SUCCESS) { sts = proxy_request(&ticket); } } } else { sip_gen_response(&ticket, 408 /*request timeout*/); } } else { WARN("non-authorized registration attempt from %s", utils_inet_ntoa(ticket.from.sin_addr)); } /* * check if outbound interface is UP. * If not, send back error to UA and * skip any proxying attempt */ } else if (get_interface_ip(IF_OUTBOUND,NULL) != STS_SUCCESS) { DEBUGC(DBCLASS_SIP, "got a %s to proxy, but outbound interface " "is down", (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES"); if (MSG_IS_REQUEST(ticket.sipmsg)) sip_gen_response(&ticket, 408 /*request timeout*/); /* * MSG is a request, add current via entry, * do a lookup in the URLMAP table and * send to the final destination */ } else if (MSG_IS_REQUEST(ticket.sipmsg)) { if (access & ACCESSCTL_SIP) { sts = proxy_request(&ticket); } else { INFO("non-authorized request received from %s", utils_inet_ntoa(ticket.from.sin_addr)); } /* * MSG is a response, remove current via and * send to the next VIA in chain */ } else if (MSG_IS_RESPONSE(ticket.sipmsg)) { if (access & ACCESSCTL_SIP) { sts = proxy_response(&ticket); } else { INFO("non-authorized response received from %s", utils_inet_ntoa(ticket.from.sin_addr)); } /* * unsupported message */ } else { ERROR("received unsupported SIP type %s %s", (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES", ticket.sipmsg->sip_method); } /********************************* * Done with proxying. Message * has been sent to its destination. *********************************/ /* * free the SIP message buffers */ end_loop: osip_message_free(ticket.sipmsg); } /* while TRUE */ exit_prg: /* save current known SIP registrations */ register_save(); INFO("properly terminating siproxd"); /* remove PID file */ if (pidfilename) { DEBUGC(DBCLASS_CONFIG,"deleting PID file [%s]", pidfilename); sts=unlink(pidfilename); if (sts != 0) { WARN("couldn't delete old PID file: %s", strerror(errno)); } } /* END */ return 0; } /* main */ /* * Signal handler * * this one is called asynchronously whevener a registered * signal is applied. Just set a flag and don't do any funny * things here. */ static void sighandler(int sig) { if (sig==SIGTERM) exit_program=1; if (sig==SIGINT) exit_program=1; if (sig==SIGUSR2) dmalloc_dump=1; return; }
static ssize_t rmnet_ctl_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { int retval = 0; int bytes_to_read; unsigned int hdr_len = 0; struct rmnet_ctrl_dev *dev; struct ctrl_pkt_list_elem *list_elem = NULL; unsigned long flags; dev = file->private_data; if (!dev) return -ENODEV; DBG("%s: Read from %s\n", __func__, dev->name); ctrl_read: if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) { dev_err(dev->devicep, "%s: Device not connected\n", __func__); return -ENETRESET; } spin_lock_irqsave(&dev->rx_lock, flags); if (list_empty(&dev->rx_list)) { spin_unlock_irqrestore(&dev->rx_lock, flags); retval = wait_event_interruptible(dev->read_wait_queue, !list_empty(&dev->rx_list) || !test_bit(RMNET_CTRL_DEV_READY, &dev->status)); if (retval < 0) return retval; goto ctrl_read; } list_elem = list_first_entry(&dev->rx_list, struct ctrl_pkt_list_elem, list); bytes_to_read = (uint32_t)(list_elem->cpkt.data_size); if (bytes_to_read > count) { spin_unlock_irqrestore(&dev->rx_lock, flags); dev_err(dev->devicep, "%s: Packet size %d > buf size %d\n", __func__, bytes_to_read, count); return -ENOMEM; } spin_unlock_irqrestore(&dev->rx_lock, flags); if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) hdr_len = sizeof(struct mux_hdr); if (copy_to_user(buf, list_elem->cpkt.data + hdr_len, bytes_to_read)) { dev_err(dev->devicep, "%s: copy_to_user failed for %s\n", __func__, dev->name); return -EFAULT; } spin_lock_irqsave(&dev->rx_lock, flags); list_del(&list_elem->list); spin_unlock_irqrestore(&dev->rx_lock, flags); kfree(list_elem->cpkt.data); kfree(list_elem); DBG("%s: Returning %d bytes to %s\n", __func__, bytes_to_read, dev->name); DUMP_BUFFER("Read: ", bytes_to_read, buf); return bytes_to_read; }
acpi_status acpi_tb_convert_table_fadt (void) { #ifdef _IA64 fadt_descriptor_rev071 *FADT71; u8 pm1_address_space; u8 pm2_address_space; u8 pm_timer_address_space; u8 gpe0address_space; u8 gpe1_address_space; #else fadt_descriptor_rev1 *FADT1; #endif fadt_descriptor_rev2 *FADT2; acpi_table_desc *table_desc; FUNCTION_TRACE ("Tb_convert_table_fadt"); /* Acpi_gbl_FADT is valid */ /* Allocate and zero the 2.0 buffer */ FADT2 = ACPI_MEM_CALLOCATE (sizeof (fadt_descriptor_rev2)); if (FADT2 == NULL) { return_ACPI_STATUS (AE_NO_MEMORY); } /* The ACPI FADT revision number is FADT2_REVISION_ID=3 */ /* So, if the current table revision is less than 3 it is type 1.0 or 0.71 */ if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) { /* We have an ACPI 2.0 FADT but we must copy it to our local buffer */ *FADT2 = *((fadt_descriptor_rev2*) acpi_gbl_FADT); } else { #ifdef _IA64 /* * For the 64-bit case only, a revision ID less than V2.0 means the * tables are the 0.71 extensions */ /* The BIOS stored FADT should agree with Revision 0.71 */ FADT71 = (fadt_descriptor_rev071 *) acpi_gbl_FADT; /* Copy the table header*/ FADT2->header = FADT71->header; /* Copy the common fields */ FADT2->sci_int = FADT71->sci_int; FADT2->acpi_enable = FADT71->acpi_enable; FADT2->acpi_disable = FADT71->acpi_disable; FADT2->S4bios_req = FADT71->S4bios_req; FADT2->plvl2_lat = FADT71->plvl2_lat; FADT2->plvl3_lat = FADT71->plvl3_lat; FADT2->day_alrm = FADT71->day_alrm; FADT2->mon_alrm = FADT71->mon_alrm; FADT2->century = FADT71->century; FADT2->gpe1_base = FADT71->gpe1_base; /* * We still use the block length registers even though * the GAS structure should obsolete them. This is because * these registers are byte lengths versus the GAS which * contains a bit width */ FADT2->pm1_evt_len = FADT71->pm1_evt_len; FADT2->pm1_cnt_len = FADT71->pm1_cnt_len; FADT2->pm2_cnt_len = FADT71->pm2_cnt_len; FADT2->pm_tm_len = FADT71->pm_tm_len; FADT2->gpe0blk_len = FADT71->gpe0blk_len; FADT2->gpe1_blk_len = FADT71->gpe1_blk_len; FADT2->gpe1_base = FADT71->gpe1_base; /* Copy the existing 0.71 flags to 2.0. The other bits are zero.*/ FADT2->wb_invd = FADT71->flush_cash; FADT2->proc_c1 = FADT71->proc_c1; FADT2->plvl2_up = FADT71->plvl2_up; FADT2->pwr_button = FADT71->pwr_button; FADT2->sleep_button = FADT71->sleep_button; FADT2->fixed_rTC = FADT71->fixed_rTC; FADT2->rtcs4 = FADT71->rtcs4; FADT2->tmr_val_ext = FADT71->tmr_val_ext; FADT2->dock_cap = FADT71->dock_cap; /* We should not use these next two addresses */ /* Since our buffer is pre-zeroed nothing to do for */ /* the next three data items in the structure */ /* FADT2->Firmware_ctrl = 0; */ /* FADT2->Dsdt = 0; */ /* System Interrupt Model isn't used in ACPI 2.0*/ /* FADT2->Reserved1 = 0; */ /* This field is set by the OEM to convey the preferred */ /* power management profile to OSPM. It doesn't have any*/ /* 0.71 equivalence. Since we don't know what kind of */ /* 64-bit system this is, we will pick unspecified. */ FADT2->prefer_PM_profile = PM_UNSPECIFIED; /* Port address of SMI command port */ /* We shouldn't use this port because IA64 doesn't */ /* have or use SMI. It has PMI. */ FADT2->smi_cmd = (u32)(FADT71->smi_cmd & 0xFFFFFFFF); /* processor performance state control*/ /* The value OSPM writes to the SMI_CMD register to assume */ /* processor performance state control responsibility. */ /* There isn't any equivalence in 0.71 */ /* Again this should be meaningless for IA64 */ /* FADT2->Pstate_cnt = 0; */ /* The 32-bit Power management and GPE registers are */ /* not valid in IA-64 and we are not going to use them */ /* so leaving them pre-zeroed. */ /* Support for the _CST object and C States change notification.*/ /* This data item hasn't any 0.71 equivalence so leaving it zero.*/ /* FADT2->Cst_cnt = 0; */ /* number of flush strides that need to be read */ /* No 0.71 equivalence. Leave pre-zeroed. */ /* FADT2->Flush_size = 0; */ /* Processor's memory cache line width, in bytes */ /* No 0.71 equivalence. Leave pre-zeroed. */ /* FADT2->Flush_stride = 0; */ /* Processor's duty cycle index in processor's P_CNT reg*/ /* No 0.71 equivalence. Leave pre-zeroed. */ /* FADT2->Duty_offset = 0; */ /* Processor's duty cycle value bit width in P_CNT register.*/ /* No 0.71 equivalence. Leave pre-zeroed. */ /* FADT2->Duty_width = 0; */ /* Since there isn't any equivalence in 0.71 */ /* and since Big_sur had to support legacy */ FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; /* Copy to ACPI 2.0 64-BIT Extended Addresses */ FADT2->Xfirmware_ctrl = FADT71->firmware_ctrl; FADT2->Xdsdt = FADT71->dsdt; /* Extract the address space IDs */ pm1_address_space = (u8)((FADT71->address_space & PM1_BLK_ADDRESS_SPACE) >> 1); pm2_address_space = (u8)((FADT71->address_space & PM2_CNT_BLK_ADDRESS_SPACE) >> 2); pm_timer_address_space = (u8)((FADT71->address_space & PM_TMR_BLK_ADDRESS_SPACE) >> 3); gpe0address_space = (u8)((FADT71->address_space & GPE0_BLK_ADDRESS_SPACE) >> 4); gpe1_address_space = (u8)((FADT71->address_space & GPE1_BLK_ADDRESS_SPACE) >> 5); /* * Convert the 0.71 (non-GAS style) Block addresses to V2.0 GAS structures, * in this order: * * PM 1_a Events * PM 1_b Events * PM 1_a Control * PM 1_b Control * PM 2 Control * PM Timer Control * GPE Block 0 * GPE Block 1 */ ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_evt_blk, FADT71->pm1_evt_len, FADT71->pm1a_evt_blk, pm1_address_space); ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_evt_blk, FADT71->pm1_evt_len, FADT71->pm1b_evt_blk, pm1_address_space); ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1a_cnt_blk, pm1_address_space); ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1b_cnt_blk, pm1_address_space); ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm2_cnt_blk, FADT71->pm2_cnt_len, FADT71->pm2_cnt_blk, pm2_address_space); ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm_tmr_blk, FADT71->pm_tm_len, FADT71->pm_tmr_blk, pm_timer_address_space); ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe0blk, FADT71->gpe0blk_len, FADT71->gpe0blk, gpe0address_space); ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe1_blk, FADT71->gpe1_blk_len, FADT71->gpe1_blk, gpe1_address_space); #else /* ACPI 1.0 FACS */ /* The BIOS stored FADT should agree with Revision 1.0 */ FADT1 = (fadt_descriptor_rev1*) acpi_gbl_FADT; /* * Copy the table header and the common part of the tables * The 2.0 table is an extension of the 1.0 table, so the * entire 1.0 table can be copied first, then expand some * fields to 64 bits. */ MEMCPY (FADT2, FADT1, sizeof (fadt_descriptor_rev1)); /* Convert table pointers to 64-bit fields */ ACPI_STORE_ADDRESS (FADT2->Xfirmware_ctrl, FADT1->firmware_ctrl); ACPI_STORE_ADDRESS (FADT2->Xdsdt, FADT1->dsdt); /* System Interrupt Model isn't used in ACPI 2.0*/ /* FADT2->Reserved1 = 0; */ /* This field is set by the OEM to convey the preferred */ /* power management profile to OSPM. It doesn't have any*/ /* 1.0 equivalence. Since we don't know what kind of */ /* 32-bit system this is, we will pick unspecified. */ FADT2->prefer_PM_profile = PM_UNSPECIFIED; /* Processor Performance State Control. This is the value */ /* OSPM writes to the SMI_CMD register to assume processor */ /* performance state control responsibility. There isn't */ /* any equivalence in 1.0. So leave it zeroed. */ FADT2->pstate_cnt = 0; /* Support for the _CST object and C States change notification.*/ /* This data item hasn't any 1.0 equivalence so leaving it zero.*/ FADT2->cst_cnt = 0; /* Since there isn't any equivalence in 1.0 and since it */ /* is highly likely that a 1.0 system has legacy support. */ FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES; /* * Convert the V1.0 Block addresses to V2.0 GAS structures * in this order: * * PM 1_a Events * PM 1_b Events * PM 1_a Control * PM 1_b Control * PM 2 Control * PM Timer Control * GPE Block 0 * GPE Block 1 */ ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_evt_blk, FADT1->pm1_evt_len, FADT1->pm1a_evt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_evt_blk, FADT1->pm1_evt_len, FADT1->pm1b_evt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1a_cnt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1b_cnt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm2_cnt_blk, FADT1->pm2_cnt_len, FADT1->pm2_cnt_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm_tmr_blk, FADT1->pm_tm_len, FADT1->pm_tmr_blk); ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe0blk, FADT1->gpe0blk_len, FADT1->gpe0blk); ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe1_blk, FADT1->gpe1_blk_len, FADT1->gpe1_blk); #endif } /* * Global FADT pointer will point to the common V2.0 FADT */ acpi_gbl_FADT = FADT2; acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR); /* Free the original table */ table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT]; acpi_tb_delete_single_table (table_desc); /* Install the new table */ table_desc->pointer = (acpi_table_header *) acpi_gbl_FADT; table_desc->base_pointer = acpi_gbl_FADT; table_desc->allocation = ACPI_MEM_ALLOCATED; table_desc->length = sizeof (fadt_descriptor_rev2); /* Dump the entire FADT */ ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Hex dump of common internal FADT, size %d (%X)\n", acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.length)); DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->header.length); return_ACPI_STATUS (AE_OK); }
ACPI_STATUS AcpiPsParseLoop ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_PARSE_OBJECT *Op = NULL; /* current op */ const ACPI_OPCODE_INFO *OpInfo; ACPI_PARSE_OBJECT *Arg = NULL; ACPI_PARSE2_OBJECT *DeferredOp; UINT32 ArgCount; /* push for fixed or var args */ UINT32 ArgTypes = 0; UINT32 AmlOffset; UINT16 Opcode; ACPI_PARSE_OBJECT PreOp; ACPI_PARSE_STATE *ParserState; UINT8 *AmlOpStart; FUNCTION_TRACE_PTR ("PsParseLoop", WalkState); ParserState = WalkState->ParserState; #ifndef PARSER_ONLY if (WalkState->WalkType & WALK_METHOD_RESTART) { /* We are restarting a preempted control method */ if (AcpiPsHasCompletedScope (ParserState)) { /* * We must check if a predicate to an IF or WHILE statement * was just completed */ if ((ParserState->Scope->ParseScope.Op) && ((ParserState->Scope->ParseScope.Op->Opcode == AML_IF_OP) || (ParserState->Scope->ParseScope.Op->Opcode == AML_WHILE_OP)) && (WalkState->ControlState) && (WalkState->ControlState->Common.State == CONTROL_PREDICATE_EXECUTING)) { /* * A predicate was just completed, get the value of the * predicate and branch based on that value */ Status = AcpiDsGetPredicateValue (WalkState, NULL, TRUE); if (ACPI_FAILURE (Status) && ((Status & AE_CODE_MASK) != AE_CODE_CONTROL)) { if (Status == AE_AML_NO_RETURN_VALUE) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invoked method did not return a value, %s\n", AcpiFormatException (Status))); } ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GetPredicate Failed, %s\n", AcpiFormatException (Status))); return_ACPI_STATUS (Status); } Status = AcpiPsNextParseState (WalkState, Op, Status); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); } else if (WalkState->PrevOp) { /* We were in the middle of an op */ Op = WalkState->PrevOp; ArgTypes = WalkState->PrevArgTypes; } } #endif /* * Iterative parsing loop, while there is more aml to process: */ while ((ParserState->Aml < ParserState->AmlEnd) || (Op)) { if (!Op) { /* Get the next opcode from the AML stream */ AmlOpStart = ParserState->Aml; AmlOffset = ParserState->Aml - ParserState->AmlStart; Opcode = AcpiPsPeekOpcode (ParserState); /* * First cut to determine what we have found: * 1) A valid AML opcode * 2) A name string * 3) An unknown/invalid opcode */ OpInfo = AcpiPsGetOpcodeInfo (Opcode); switch (ACPI_GET_OP_TYPE (OpInfo)) { case ACPI_OP_TYPE_OPCODE: /* Found opcode info, this is a normal opcode */ ParserState->Aml += AcpiPsGetOpcodeSize (Opcode); ArgTypes = OpInfo->ParseArgs; break; case ACPI_OP_TYPE_ASCII: case ACPI_OP_TYPE_PREFIX: /* * Starts with a valid prefix or ASCII char, this is a name * string. Convert the bare name string to a namepath. */ Opcode = AML_INT_NAMEPATH_OP; ArgTypes = ARGP_NAMESTRING; break; case ACPI_OP_TYPE_UNKNOWN: /* The opcode is unrecognized. Just skip unknown opcodes */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found unknown opcode %lX at AML offset %X, ignoring\n", Opcode, AmlOffset)); DUMP_BUFFER (ParserState->Aml, 128); /* Assume one-byte bad opcode */ ParserState->Aml++; continue; } /* Create Op structure and append to parent's argument list */ if (OpInfo->Flags & AML_NAMED) { PreOp.Value.Arg = NULL; PreOp.Opcode = Opcode; while (GET_CURRENT_ARG_TYPE (ArgTypes) != ARGP_NAME) { Arg = AcpiPsGetNextArg (ParserState, GET_CURRENT_ARG_TYPE (ArgTypes), &ArgCount); AcpiPsAppendArg (&PreOp, Arg); INCREMENT_ARG_LIST (ArgTypes); } /* We know that this arg is a name, move to next arg */ INCREMENT_ARG_LIST (ArgTypes); if (WalkState->DescendingCallback != NULL) { /* * Find the object. This will either insert the object into * the namespace or simply look it up */ Status = WalkState->DescendingCallback (Opcode, NULL, WalkState, &Op); if (Op == NULL) { continue; } Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } if (ACPI_FAILURE (Status)) { goto CloseThisOp; } } AcpiPsAppendArg (Op, PreOp.Value.Arg); AcpiGbl_Depth++; if (Op->Opcode == AML_REGION_OP) { DeferredOp = (ACPI_PARSE2_OBJECT *) Op; /* * Defer final parsing of an OperationRegion body, * because we don't have enough info in the first pass * to parse it correctly (i.e., there may be method * calls within the TermArg elements of the body. * * However, we must continue parsing because * the opregion is not a standalone package -- * we don't know where the end is at this point. * * (Length is unknown until parse of the body complete) */ DeferredOp->Data = AmlOpStart; DeferredOp->Length = 0; } } else { /* Not a named opcode, just allocate Op and append to parent */ OpInfo = AcpiPsGetOpcodeInfo (Opcode); Op = AcpiPsAllocOp (Opcode); if (!Op) { return_ACPI_STATUS (AE_NO_MEMORY); } if (OpInfo->Flags & AML_CREATE) { /* * Backup to beginning of CreateXXXfield declaration * BodyLength is unknown until we parse the body */ DeferredOp = (ACPI_PARSE2_OBJECT *) Op; DeferredOp->Data = AmlOpStart; DeferredOp->Length = 0; } AcpiPsAppendArg (AcpiPsGetParentScope (ParserState), Op); if ((WalkState->DescendingCallback != NULL)) { /* * Find the object. This will either insert the object into * the namespace or simply look it up */ Status = WalkState->DescendingCallback (Opcode, Op, WalkState, &Op); Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } if (ACPI_FAILURE (Status)) { goto CloseThisOp; } } } Op->AmlOffset = AmlOffset; if (OpInfo) { ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Op=%p Opcode=%4.4lX Aml %p Oft=%5.5lX\n", Op, Op->Opcode, ParserState->Aml, Op->AmlOffset)); } } /* Start ArgCount at zero because we don't know if there are any args yet */ ArgCount = 0; if (ArgTypes) /* Are there any arguments that must be processed? */ { /* get arguments */ switch (Op->Opcode) { case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ case AML_WORD_OP: /* AML_WORDDATA_ARG */ case AML_DWORD_OP: /* AML_DWORDATA_ARG */ case AML_QWORD_OP: /* AML_QWORDATA_ARG */ case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ /* fill in constant or string argument directly */ AcpiPsGetNextSimpleArg (ParserState, GET_CURRENT_ARG_TYPE (ArgTypes), Op); break; case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ AcpiPsGetNextNamepath (ParserState, Op, &ArgCount, 1); ArgTypes = 0; break; default: /* Op is not a constant or string, append each argument */ while (GET_CURRENT_ARG_TYPE (ArgTypes) && !ArgCount) { AmlOffset = ParserState->Aml - ParserState->AmlStart; Arg = AcpiPsGetNextArg (ParserState, GET_CURRENT_ARG_TYPE (ArgTypes), &ArgCount); if (Arg) { Arg->AmlOffset = AmlOffset; AcpiPsAppendArg (Op, Arg); } INCREMENT_ARG_LIST (ArgTypes); } /* For a method, save the length and address of the body */ if (Op->Opcode == AML_METHOD_OP) { DeferredOp = (ACPI_PARSE2_OBJECT *) Op; /* * Skip parsing of control method or opregion body, * because we don't have enough info in the first pass * to parse them correctly. */ DeferredOp->Data = ParserState->Aml; DeferredOp->Length = (UINT32) (ParserState->PkgEnd - ParserState->Aml); /* * Skip body of method. For OpRegions, we must continue * parsing because the opregion is not a standalone * package (We don't know where the end is). */ ParserState->Aml = ParserState->PkgEnd; ArgCount = 0; } break; } } /* * Zero ArgCount means that all arguments for this op have been processed */ if (!ArgCount) { /* completed Op, prepare for next */ OpInfo = AcpiPsGetOpcodeInfo (Op->Opcode); if (OpInfo->Flags & AML_NAMED) { if (AcpiGbl_Depth) { AcpiGbl_Depth--; } if (Op->Opcode == AML_REGION_OP) { DeferredOp = (ACPI_PARSE2_OBJECT *) Op; /* * Skip parsing of control method or opregion body, * because we don't have enough info in the first pass * to parse them correctly. * * Completed parsing an OpRegion declaration, we now * know the length. */ DeferredOp->Length = (UINT32) (ParserState->Aml - DeferredOp->Data); } } if (OpInfo->Flags & AML_CREATE) { /* * Backup to beginning of CreateXXXfield declaration (1 for * Opcode) * * BodyLength is unknown until we parse the body */ DeferredOp = (ACPI_PARSE2_OBJECT *) Op; DeferredOp->Length = (UINT32) (ParserState->Aml - DeferredOp->Data); } /* This op complete, notify the dispatcher */ if (WalkState->AscendingCallback != NULL) { Status = WalkState->AscendingCallback (WalkState, Op); Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } } CloseThisOp: /* * Finished one argument of the containing scope */ ParserState->Scope->ParseScope.ArgCount--; /* Close this Op (may result in parse subtree deletion) */ if (AcpiPsCompleteThisOp (WalkState, Op)) { Op = NULL; } switch (Status) { case AE_OK: break; case AE_CTRL_TRANSFER: /* * We are about to transfer to a called method. */ WalkState->PrevOp = Op; WalkState->PrevArgTypes = ArgTypes; return_ACPI_STATUS (Status); break; case AE_CTRL_END: AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); Status = WalkState->AscendingCallback (WalkState, Op); Status = AcpiPsNextParseState (WalkState, Op, Status); AcpiPsCompleteThisOp (WalkState, Op); Op = NULL; Status = AE_OK; break; case AE_CTRL_TERMINATE: Status = AE_OK; /* Clean up */ do { if (Op) { AcpiPsCompleteThisOp (WalkState, Op); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } while (Op); return_ACPI_STATUS (Status); break; default: /* All other non-AE_OK status */ if (Op == NULL) { AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } WalkState->PrevOp = Op; WalkState->PrevArgTypes = ArgTypes; /* * TEMP: */ return_ACPI_STATUS (Status); break; } /* This scope complete? */ if (AcpiPsHasCompletedScope (ParserState)) { AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); } else { Op = NULL; } } /* ArgCount is non-zero */ else { /* complex argument, push Op and prepare for argument */ AcpiPsPushScope (ParserState, Op, ArgTypes, ArgCount); Op = NULL; } } /* while ParserState->Aml */ /* * Complete the last Op (if not completed), and clear the scope stack. * It is easily possible to end an AML "package" with an unbounded number * of open scopes (such as when several AML blocks are closed with * sequential closing braces). We want to terminate each one cleanly. */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Package complete at Op %p\n", Op)); do { if (Op) { if (WalkState->AscendingCallback != NULL) { Status = WalkState->AscendingCallback (WalkState, Op); Status = AcpiPsNextParseState (WalkState, Op, Status); if (Status == AE_CTRL_PENDING) { Status = AE_OK; goto CloseThisOp; } if (Status == AE_CTRL_TERMINATE) { Status = AE_OK; /* Clean up */ do { if (Op) { AcpiPsCompleteThisOp (WalkState, Op); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } while (Op); return_ACPI_STATUS (Status); } else if (ACPI_FAILURE (Status)) { AcpiPsCompleteThisOp (WalkState, Op); return_ACPI_STATUS (Status); } } AcpiPsCompleteThisOp (WalkState, Op); } AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount); } while (Op); return_ACPI_STATUS (Status); }
/* * Processing. * */ int PLUGIN_PROCESS(int stage, sip_ticket_t *ticket){ /* stage contains the PLUGIN_* value - the stage of SIP processing. */ int sts; char *buff; size_t buflen; osip_body_t *body; sdp_message_t *sdp; int content_length; osip_content_type_t *content_type; char clen[8]; /* content length: probably never more than 7 digits !*/ // // check that we have the expected payload "application/sdp" // // get content length content_length=0; if (ticket->sipmsg && ticket->sipmsg->content_length && ticket->sipmsg->content_length->value) { sts=sscanf(ticket->sipmsg->content_length->value, "%i", &content_length); } // check if we have a content type defined and that payload length >0 content_type=osip_message_get_content_type(ticket->sipmsg); if ((content_length == 0) || (content_type == NULL) || (content_type->type == NULL) || (content_type->subtype == NULL)) { DEBUGC(DBCLASS_PLUGIN, "%s: no content", name); return STS_SUCCESS; } // check content type: must be "application/sdp" if ((strncmp(content_type->type, "application", sizeof("application")) != 0) || (strncmp(content_type->subtype, "sdp", sizeof("sdp")) != 0)) { DEBUGC(DBCLASS_PLUGIN, "%s: unsupported content-type %s/%s", name, content_type->type, content_type->subtype); return STS_SUCCESS; } DEBUGC(DBCLASS_PLUGIN, "%s: content-type %s/%s, size=%i", name, content_type->type, content_type->subtype, content_length); // // parse the payload // // get a pointer to the payload of the SIP packet sts = osip_message_get_body(ticket->sipmsg, 0, &body); if (sts != 0) { DEBUGC(DBCLASS_PLUGIN, "%s: no body found in message", name); return STS_SUCCESS; } // dump it into a buffer sts = sip_body_to_str(body, &buff, &buflen); if (sts != 0) { WARN("%s: unable to sip_body_to_str", name); return STS_SUCCESS; } // and parse it into an SDP structure sts = sdp_message_init(&sdp); sts = sdp_message_parse (sdp, buff); if (sts != 0) { WARN("%s: unable to sdp_message_parse() body", name); DUMP_BUFFER(-1, buff, buflen); osip_free(buff); buff=NULL; sdp_message_free(sdp); return STS_SUCCESS; } osip_free(buff); buff=NULL; // // now do the codec filtering magic... sdp_filter_codec(sdp); // // replace the original payload with the new modified payload // // remove old body from SIP packet sts = osip_list_remove(&(ticket->sipmsg->bodies), 0); osip_body_free(body); body=NULL; // dump new body to buffer sdp_message_to_str(sdp, &buff); buflen=strlen(buff); // free sdp structure (no longer needed) sdp_message_free(sdp); sdp=NULL; // put new body into SIP message sts=sip_message_set_body(ticket->sipmsg, buff, buflen); if (sts != 0) { ERROR("%s: unable to sip_message_set_body body", name); DUMP_BUFFER(-1, buff, buflen); buflen=0; } // free buffer osip_free(buff); buff=NULL; // // set new content length // // remove old content leght field osip_content_length_free(ticket->sipmsg->content_length); ticket->sipmsg->content_length=NULL; // set new content length sprintf(clen,"%ld",(long)buflen); sts = osip_message_set_content_length(ticket->sipmsg, clen); return STS_SUCCESS; }
/* * sends an UDP datagram to the specified destination * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error * 函数修改说明: * 修改人: l67187 * 修改目的: 解决代理和绑定时没有默认路由,sip alg无法工作的问题 * 修改方案: 在报文发送时,bind上网关发送侧的ip地址,使用网关源地址路由 * 具体修改: 原alg 使用 初始化时创建的 sip_udp_socket,绑定了空地址 * 无法再次绑定,修改后,在该函数中不在使用 sip_udp_socket发送报文 * 而是重新创建一个socket发送,之后就关闭释放资源 */ int sipsock_send(struct in_addr addr, int port, int protocol, char *buffer, int size) { struct sockaddr_in dst_addr; struct sockaddr_in stLocalAddr; int sock; int sts = -1; /* first time: allocate a socket for sending if (sip_udp_socket == 0) { ERROR("SIP socket not allocated"); return STS_FAILURE; } */ if (buffer == NULL) { ERROR("sipsock_send got NULL buffer"); return STS_FAILURE; } if (protocol != PROTO_UDP) { ERROR("sipsock_send: only UDP supported by now"); return STS_FAILURE; } if (1 == g_lsockFlg) { dst_addr.sin_family = AF_INET; memcpy(&dst_addr.sin_addr.s_addr, &addr, sizeof(struct in_addr)); dst_addr.sin_port= htons(port); if ((1 == IpisInNet(utils_inet_ntoa(addr), g_acBrIpAddr, g_acBrMask)) || (1 == IpisInNet(utils_inet_ntoa(addr), g_acPPPoEIpAddr, g_acPPPoEMask))) { sts = sendto(sip_udp_socket, buffer, size, 0, (const struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr)); } else /* wan 侧 */ { // TODO: 这里需要优化,目前PPPoE代理的时候没有默认路由 // 因此需要进行判断,如果没有默认路由那么就需要使用使用sip_udp_wan_socket // 发包,否则一直使用 sip_udp_socket 发包 // if (没有默认路由) if (0 != sip_udp_wan_socket) { sts = sendto(sip_udp_wan_socket, buffer, size, 0, (const struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr)); } else if (0 == sip_udp_wan_socket) { sts = sendto(sip_udp_socket, buffer, size, 0, (const struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr)); } else { ERROR("no proper socket fd to send out"); } } if (sts == -1) { if (errno != ECONNREFUSED) { ERROR("sendto() [%s:%i size=%i] call failed: %s", utils_inet_ntoa(addr), port, size, strerror(errno)); return STS_FAILURE; } DEBUGC(DBCLASS_BABBLE,"sendto() [%s:%i] call failed: %s", utils_inet_ntoa(addr), port, strerror(errno)); } } else { sock=socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { printsip("Sip: socket() call failed: %s",strerror(errno)); return STS_FAILURE; } dst_addr.sin_family = AF_INET; memcpy(&dst_addr.sin_addr.s_addr, &addr, sizeof(struct in_addr)); dst_addr.sin_port= htons(port); DEBUGC(DBCLASS_NET,"send UDP packet to %s: %i", utils_inet_ntoa(addr),port); printsip("Sip:send UDP packet to %s: %i\r\n", utils_inet_ntoa(addr),port); DUMP_BUFFER(DBCLASS_NETTRAF, buffer, size); /* 本地发送源 */ bzero(&stLocalAddr, 0); /* 目的ip为LAN侧ip */ if ((1 == IpisInNet(utils_inet_ntoa(addr), g_acBrIpAddr, g_acBrMask)) || (1 == IpisInNet(utils_inet_ntoa(addr), g_acPPPoEIpAddr, g_acPPPoEMask))) { get_ip_by_ifname(configuration.inbound_if, &stLocalAddr.sin_addr); } else { get_ip_by_ifname(configuration.outbound_if, &stLocalAddr.sin_addr); } /* if (g_lPacketDir == 0) { get_ip_by_ifname(configuration.outbound_if,&stLocalAddr.sin_addr); // stLocalAddr.sin_port = htons(atoi(pszLocalPort)); } else { get_ip_by_ifname(configuration.inbound_if,&stLocalAddr.sin_addr); // stLocalAddr.sin_port = htons(atoi(pszLocalPort)); } */ stLocalAddr.sin_family = AF_INET; if (bind(sock, (struct sockaddr *)&stLocalAddr, sizeof(stLocalAddr)) < 0) { perror("bind"); } else { printsip("Sip: bind src ip:[%s]\r\n", inet_ntoa(stLocalAddr.sin_addr)); } // if (0 != sip_udp_socket) #if 0 if ((1 == IpisInNet(utils_inet_ntoa(addr), g_acBrIpAddr, g_acBrMask)) || (1 == IpisInNet(utils_inet_ntoa(addr), g_acPPPoEIpAddr, g_acPPPoEMask))) #else if (0) #endif { sts = sendto(sock, buffer, size, 0, (const struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr)); } else if (0 != sip_udp_socket) { sts = sendto(sip_udp_socket, buffer, size, 0, (const struct sockaddr *)&dst_addr, (socklen_t)sizeof(dst_addr)); } else { printf("no proper socket found \r\n"); } if (sts == -1) { if (errno != ECONNREFUSED) { ERROR("sendto() [%s:%i size=%i] call failed: %s", utils_inet_ntoa(addr), port, size, strerror(errno)); close(sock); return STS_FAILURE; } DEBUGC(DBCLASS_BABBLE,"sendto() [%s:%i] call failed: %s", utils_inet_ntoa(addr), port, strerror(errno)); } close(sock); } return STS_SUCCESS; }
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf, size_t size, loff_t *pos) { int status; size_t total_len; void *wbuf; void *actual_data; struct ctrl_pkt *cpkt; struct rmnet_ctrl_dev *dev = file->private_data; if (!dev) return -ENODEV; if (size <= 0) return -EINVAL; if (!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status)) return -ENETRESET; DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name); #ifdef CONFIG_QCT_9K_MODEM if (get_radio_flag() & RADIO_FLAG_MORE_LOG) pr_info("[RMNET] W: %i\n", size); #endif total_len = size; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4); wbuf = kmalloc(total_len , GFP_KERNEL); if (!wbuf) return -ENOMEM; cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL); if (!cpkt) { kfree(wbuf); return -ENOMEM; } actual_data = cpkt->data = wbuf; cpkt->data_size = total_len; cpkt->ctxt = dev; if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) { actual_data = wbuf + sizeof(struct mux_hdr); rmnet_usb_ctrl_mux(dev->ch_id, cpkt); } status = copy_from_user(actual_data, buf, size); if (status) { dev_err(dev->devicep, "%s: Unable to copy data from userspace %d\n", __func__, status); kfree(wbuf); kfree(cpkt); return status; } DUMP_BUFFER("Write: ", size, buf); #ifdef CONFIG_QCT_9K_MODEM status = rmnet_usb_ctrl_write(dev, cpkt, size); if (status == size) return size; else pr_err("[%s] status %d\n", __func__, status); #else status = rmnet_usb_ctrl_write_cmd(dev->cudev, USB_CDC_SEND_ENCAPSULATED_COMMAND, 0, cpkt->data, cpkt->data_size); if (status > 0) dev->cudev->snd_encap_cmd_cnt++; kfree(cpkt->data); kfree(cpkt); #endif return status; }